德州扑克比较大小的go语言暴力实现

德州扑克的规则

在这里插入图片描述

项目实现了什么

  • 5张牌的比较
  • 7张牌的比较
  • 7张牌+赖子的比较(最多只有一张赖子的情况)

项目的运行速度

5张牌,不算读取文件,压力测试下的速度
go test -bench=".*" -benchmem在这里插入图片描述
7张牌的速度

在这里插入图片描述
7张加赖子的速度
在这里插入图片描述

我的项目结构

在这里插入图片描述

5张牌的实现方式

package fire

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"time"
)

// Poker 存放 文件中比较数据的结构体
type poker struct {
	Alice  string `json:"alice"`
	Bob    string `json:"bob"`
	Result int    `json:"result"`
}

// Match 用于 存放读取文件的json格式数据
type Match struct {
	Matches []poker `json:"matches"`
}

//  CardCom用于同类型比较的函数传递参数
type cardCom struct {
	cardSizeMap1 map[byte]int
	cardSizeMap2 map[byte]int
	max1, max2   byte
}

// SizeTranByte 对面值转译整对应的byte值  -- 方便大小比较
func SizeTranByte(card byte) (res byte) {

	switch card {
	case 50:
		// 2
		res = 0x02
	case 51:
		res = 0x03
	case 52:
		res = 0x04
	case 53:
		res = 0x05
	case 54:
		res = 0x06
	case 55:
		res = 0x07
	case 56:
		res = 0x08
	case 57:
		res = 0x09
	case 84:
		res = 0x0A
	case 74:
		res = 0x0B
	case 81:
		res = 0x0C
	case 75:
		res = 0x0D
	case 65:
		res = 0x0E
	case 88:
		res = 0x10

	}
	return
}

// ReadFile 把数据从文件中读取出来 分别放在切片中返回
func ReadFile(filename string) (alices, bobs []string, results []int) {
	buf, err := ioutil.ReadFile(filename)
	if err != nil {
		panic(err)
	}
	var matches Match
	err = json.Unmarshal(buf, &matches)
	if err != nil {
		panic(err)
	}

	alices = make([]string, len(matches.Matches))
	bobs = make([]string, len(matches.Matches))
	results = make([]int, len(matches.Matches))

	for k, v := range matches.Matches {
		alices[k] = v.Alice
		bobs[k] = v.Bob
		results[k] = v.Result
	}
	return
}

// JudgmentGroupNew 判断牌的类型
func JudgmentGroupNew(card []byte) (judeCardType uint8, cardSizeMap map[byte]int, resMax byte) {
	cardColorMap := make(map[byte]int, 5)
	cardSizeMap = make(map[byte]int, 5)
	// 扫描牌 分别放好大小,花色   --key放的是花色或是面值,--value放的是出现的次数
	for i, v := range card {
		if i%2 == 0 {
			// 存放大小
			if _, ok := cardSizeMap[v]; ok {
				cardSizeMap[v] ++
			} else {
				cardSizeMap[v] = 1
			}
			// 存放颜色
		} else {
			if _, ok := cardColorMap[v]; ok {
				cardColorMap[v] ++
			} else {
				cardColorMap[v] = 1
			}
		}
	}
	// 获取map的长度
	sizeLen := len(cardSizeMap)
	colorLen := len(cardColorMap)
	// 同花的时候,5个颜色一样,所以 colorLen = 1
	if colorLen > 1 {
		// 非同花
		switch sizeLen {
		case 4:
			// 一对
			judeCardType = 9
			return
		case 2: // 3带2  或是 4带1
			// 遍历map value
			for _, v := range cardSizeMap {
				if v == 4 {
					judeCardType = 3
					return
				}
			}
			judeCardType = 4
			return
		case 3:
			// 3条 或是 两对
			for _, v := range cardSizeMap {
				if v == 3 {
					judeCardType = 7
					return
				}
			}
			judeCardType = 8
			return
		case 5:
			// 单牌或是顺子
			isShun, max := IsShunZiNew(card)
			if isShun {
				resMax = max
				judeCardType = 6
				return
			}
			judeCardType = 10
			return

		}

	} else {
		// 同花 或是 同花顺
		isShun, max := IsShunZiNew(card)
		if isShun {
			resMax = max
			judeCardType = 1
		} else {
			judeCardType = 5
		}

	}

	return

}

// IsShunZiNew 判断是否是顺子 返回顺子的最大值和是否是顺子
func IsShunZiNew(card []byte) (shunZi bool, max byte) {
	shunZi = false
	saves := make([]byte, 14)
	// 把扑克牌放如slice中
	for i, v := range card {
		if i%2 == 0 {
			switch v {
			case 50:
				saves[1] = v
			case 51:
				saves[2] = v
			case 52:
				saves[3] = v
			case 53:
				saves[4] = v
			case 54:
				saves[5] = v
			case 55:
				saves[6] = v
			case 56:
				saves[7] = v
			case 57:
				saves[8] = v
			case 84:
				saves[9] = v
			case 74:
				saves[10] = v
			case 81:
				saves[11] = v
			case 75:
				saves[12] = v
			case 65:
				saves[13] = v
				saves[0] = v
			default:
				fmt.Println("无法解析的扑克牌", "card --v=", v)
			}
		}

	}
	// 判断数组是否连续 倒序遍历
	sum := 0
	for i := len(saves) - 1; i >= 0; i-- {
		// slice有值
		if saves[i] != 0x00 {
			sum++
		} else {
			sum = 0
		}
		// 5个连续
		if sum >= 5 {
			shunZi = true
			max = saves[i+4] // 返回顺子的最大值
			return
		}
	}
	return
}

// QuickSortByte 快排 对字节 逆序
func QuickSortByte(bs []byte) []byte {
	if len(bs) <= 1 {
		return bs
	}
	splitdata := bs[0]           // 第一个数据
	low := make([]byte, 0, 0)    // 比我小的数据
	hight := make([]byte, 0, 0)  // 比我大的数据
	mid := make([]byte, 0, 0)    // 与我一样大的数据
	mid = append(mid, splitdata) // 加入一个
	for i := 1; i < len(bs); i++ {
		if bs[i] > splitdata {
			low = append(low, bs[i])
		} else if bs[i] < splitdata {
			hight = append(hight, bs[i])
		} else {
			mid = append(mid, bs[i])
		}
	}
	low, hight = QuickSortByte(low), QuickSortByte(hight)
	myarr := append(append(low, mid...), hight...)
	return myarr
}

// SingleCardCompareSizeNew 同类型单牌比较 返回值是比较结果 0是平局 1是前面赢 2是后面赢
func (com *cardCom) SingleCardCompareSizeNew() (result int) {

	cardSizeSlice1 := make([]byte, len(com.cardSizeMap1))
	cardSizeSlice2 := make([]byte, len(com.cardSizeMap1))

	// 遍历map,把面值放到slice中
	i := 0
	for k := range com.cardSizeMap1 {
		cardSizeSlice1[i] = SizeTranByte(k)
		i++
	}
	i = 0
	for k := range com.cardSizeMap2 {
		cardSizeSlice2[i] = SizeTranByte(k)
		i++
	}

	// 比较5张牌的面值
	result = SingleCardSizeCom(5, cardSizeSlice1, cardSizeSlice2)

	return
}

// SingleCardSizeCom 对比单牌 大小0是平局 1是前面赢 2是后面赢
func SingleCardSizeCom(comLen int, cardSizeSlice1, cardSizeSlice2 []byte) (result int) {
	// 对传进来的slice逆序排序
	cardSizeSlice1 = QuickSortByte(cardSizeSlice1)
	cardSizeSlice2 = QuickSortByte(cardSizeSlice2)

	// 一个个对比
	for i := 0; i < comLen; i++ {
		if cardSizeSlice1[i] > cardSizeSlice2[i] {
			return 1
		} else if cardSizeSlice1[i] < cardSizeSlice2[i] {
			return 2
		}
	}
	return 0
}

// aPairComNew 同类型一对比较 0是平局 1是前面赢 2是后面赢
func (com *cardCom) aPairComNew() (result int) {
	// 用于存放单牌的面值
	cardSizeSlice1 := make([]byte, len(com.cardSizeMap1))
	cardSizeSlice2 := make([]byte, len(com.cardSizeMap1))
	// 用于存放对子的面值
	var pair1 byte
	var pair2 byte
	i := 0
	for k, v := range com.cardSizeMap1 {
		k = SizeTranByte(k) // 对牌子转译,才可以比较大小
		if v == 2 {
			pair1 = k
		} else {
			cardSizeSlice1[i] = k
			i++
		}
	}
	i = 0
	for k, v := range com.cardSizeMap2 {
		if v == 2 {
			pair2 = SizeTranByte(k)

		} else {
			cardSizeSlice2[i] = SizeTranByte(k)
			i++
		}
	}
	// 先比较对子的大小
	if pair1 > pair2 {
		return 1
	} else if pair1 < pair2 {
		return 2
	} else {
		// 再单牌大小
		result = SingleCardSizeCom(3, cardSizeSlice1, cardSizeSlice2)
		return
	}

}

// twoPairComNew 同类型的两对比较 0是平局 1是前面赢 2是后面赢
func (com *cardCom) twoPairComNew() (result int) {
	// 用于存放两对的牌子
	pairs1 := make([]byte, 2)
	pairs2 := make([]byte, 2)
	// 用于存放单牌
	var val1 byte
	var val2 byte

	i := 0
	for k, v := range com.cardSizeMap1 {
		k = SizeTranByte(k) // 转译面值成可以比较的
		if v == 2 {
			pairs1[i] = k
			i++
		} else {
			val1 = k
		}
	}
	i = 0
	for k, v := range com.cardSizeMap2 {
		k = SizeTranByte(k)
		if v == 2 {
			pairs2[i] = k
			i++
		} else {
			val2 = k
		}

	}
	// 比较对子的大小
	result = SingleCardSizeCom(2, pairs1, pairs2)
	if result != 0 {
		return
	}

	// 再比较单牌的大小
	if val1 > val2 {
		return 1
	} else if val1 < val2 {
		return 2
	} else {
		return 0
	}

}

// onlyThreeComNew 同类型的三条比较 0是平局 1是前面赢 2是后面赢
func (com *cardCom) onlyThreeComNew() (result int) {
	// 用于存放单牌的面值
	cardSizeSlice1 := make([]byte, len(com.cardSizeMap1))
	cardSizeSlice2 := make([]byte, len(com.cardSizeMap1))
	// 用于存放三条的面值
	var three1 byte
	var three2 byte
	i := 0
	for k, v := range com.cardSizeMap1 {
		k = SizeTranByte(k)
		cardSizeSlice1[i] = k
		if v == 3 {
			three1 = k
		} else {
			i++
		}
	}
	i = 0
	for k, v := range com.cardSizeMap2 {
		k = SizeTranByte(k)
		cardSizeSlice2[i] = k
		if v == 3 {
			three2 = k
		} else {
			i++
		}
	}
	// 先比较三条的面值
	if three1 > three2 {
		return 1
	} else if three1 < three2 {
		return 2
	} else {
		// 再比较单牌的
		result = SingleCardSizeCom(2, cardSizeSlice1, cardSizeSlice2)
		return
	}
}

// onlyShunZiNew 同类型顺子的比较 0是平局 1是前面赢 2是后面赢
func (com *cardCom) onlyShunZiNew() (result int) {
	// max 是顺子的最大的牌,只要比较这张牌就行了
	if com.max1 > com.max2 {
		return 1
	} else if com.max1 < com.max2 {
		return 2
	}
	return 0
}

// onlySameFlowerNew 是同类型同花的比较 0是平局 1是前面赢 2是后面赢
func (com *cardCom) onlySameFlowerNew() (result int) {
	// 同类型同花 只要比较牌面值最大的,可以看着是单牌比较面值大小
	result = com.SingleCardCompareSizeNew()
	return
}

// straightFlushNew 同类型同花顺比较 0是平局 1是前面赢 2是后面赢
func (com *cardCom) straightFlushNew() (result int) {
	// 同类型同花顺比较,可以看作顺子之间比较
	return com.onlyShunZiNew()
}

// fourComNew 同类型4条比较 0是平局 1是前面赢 2是后面赢
func (com *cardCom) fourComNew() (result int) {
	// 存放四条的面值
	var four1 byte
	var four2 byte
	// 存放单牌的面值
	var val1 byte
	var val2 byte

	for k, v := range com.cardSizeMap1 {
		k = SizeTranByte(k) // 对面值转译成可以比较的
		if v == 4 {
			four1 = k
		} else {
			val1 = k
		}
	}
	for k, v := range com.cardSizeMap2 {
		k = SizeTranByte(k) // 对面值转译成可以比较的
		if v == 4 {
			four2 = k
		} else {
			val2 = k
		}
	}
	// 先比较4条大小
	if four1 > four2 {
		return 1
	} else if four1 < four2 {
		return 2
	} else {
		// 再比较单牌的大小
		if val1 > val2 {
			return 1
		} else if val1 < val2 {
			return 2
		} else {
			return 0
		}
	}
}

// threeAndTwoNew 同类型3带2比较  0是平局 1是前面赢 2是后面赢
func (com *cardCom) threeAndTwoNew() (result int) {
	// 存放3条的面值
	var three1 byte
	var three2 byte
	// 存放对子的面值
	var two1 byte
	var two2 byte
	for k, v := range com.cardSizeMap1 {
		if v == 3 {
			three1 = SizeTranByte(k)
		} else {
			two1 = SizeTranByte(k)
		}
	}
	for k, v := range com.cardSizeMap2 {
		if v == 3 {
			three2 = SizeTranByte(k)
		} else {
			two2 = SizeTranByte(k)
		}
	}
	// 先对比3条的面值
	if three1 > three2 {
		return 1
	} else if three1 < three2 {
		return 2
	} else {
		// 再对比对子的面值
		if two1 > two2 {
			return 1
		} else if two1 < two2 {
			return 2
		} else {
			return 0
		}
	}

}

// PokerMan 5张遍历判断 文件扑克牌的函数
func PokerMan() {
	file := "../resources/match_result.json"
	alices, bobs, results := ReadFile(file)
	t1 := time.Now()
	k := 0
	// 遍历全部对比
	for i := 0; i < len(alices); i++ {
		result := -1
		// 分牌型
		val1, cardSizesMap1, max1 := JudgmentGroupNew([]byte(alices[i]))
		val2, cardSizesMap2, max2 := JudgmentGroupNew([]byte(bobs[i]))
		if val1 < val2 {
			result = 1
		} else if val1 > val2 {
			result = 2
		} else {
			// 牌型相同的处理情况
			// ...
			cardCom := cardCom{
				cardSizeMap1: cardSizesMap1,
				cardSizeMap2: cardSizesMap2,
				max1:         max1,
				max2:         max2,
			}
			switch val1 {
			case 10:
				// 同类型下的单张大牌比较
				result = cardCom.SingleCardCompareSizeNew()
			case 9:
				// 同类型的一对
				result = cardCom.aPairComNew()
			case 8:
				// 同类型两对
				result = cardCom.twoPairComNew()
			case 7:
				// 同类型三条
				result = cardCom.onlyThreeComNew()
			case 6:
				// 同类型顺子
				result = cardCom.onlyShunZiNew()
			case 5:
				// 同类型同花
				result = cardCom.onlySameFlowerNew()
			case 4:
				// 同类型3带2
				result = cardCom.threeAndTwoNew()
			case 3:
				// 同类型四条
				result = cardCom.fourComNew()
			case 1: // 同类型同花顺
				result = cardCom.straightFlushNew()
			}

			// 最后比较结果
		}
		// 打印判断出错的信息
		if result != results[i] {
			k++
			fmt.Printf("[%#v]5张判断错误--->alice:%#v,bob:%#v<----- ===>文档的结果:%#v, 我的结果:%#v <==\n", k, alices[i], bobs[i], results[i], result)
		}
	}
	t2 := time.Now()
	fmt.Println("time--->", t2.Sub(t1))

}

7张牌的实现方式

package seven

import (
	"NewPocker/fire"
	"fmt"
	"time"
)

// Seven 调用同类型比较函数们的参数传入
type Seven struct {
	// 存放面值的map
	cardSizeMap1, cardSizeMap2   map[byte]int
	cardColorMap1, cardColorMap2 map[byte]int
	max1, max2                   byte
	card1, card2                 []byte
}

// IsShunZi 判断是不是顺子,并且返回顺子的最大值  传进来的已经转译好的面值
func IsShunZi(seq []byte) (flag bool, max byte) {
	flag = false
	saves := make([]byte, 14)
	// 遍历序列, 存放入对应的序列
	for _, v := range seq {
		switch v {
		case 0x02:
			saves[1] = v
		case 0x03:
			saves[2] = v
		case 0x04:
			saves[3] = v
		case 0x05:
			saves[4] = v
		case 0x06:
			saves[5] = v
		case 0x07:
			saves[6] = v
		case 0x08:
			saves[7] = v
		case 0x09:
			saves[8] = v
		case 0x0A:
			saves[9] = v
		case 0x0B:
			saves[10] = v
		case 0x0C:
			saves[11] = v
		case 0x0D:
			saves[12] = v
		case 0x0E:
			saves[13] = v
			saves[0] = v
		default:
			fmt.Println("无法解析的扑克牌", "card --v=", v)
		}

	}
	// 判断数组是否连续
	sum := 0
	for i := len(saves) - 1; i >= 0; i-- {
		if saves[i] != 0x00 {
			// slice有值
			sum++
		} else {
			// 没值重置
			sum = 0
		}
		// 判断到有连续5个
		if sum >= 5 {
			flag = true
			max = saves[i+4] // 返回顺子最大值
			return
		}
	}
	return
}

// JudgmentGroup 判断牌型
func JudgmentGroup(card []byte) (cardType uint8, cardSizeMap, cardColorMap map[byte]int, resMax byte) {
	cardColorMap = make(map[byte]int, 7)
	cardSizeMap = make(map[byte]int, 7)
	// 扫描牌 分别放好大小,花色
	for i, v := range card {
		if i%2 == 0 {
			// 大小 判断map是否有值,也就是之前是否出现过  最终 key是面值,value是该面值出现的次数
			if _, ok := cardSizeMap[v]; ok {
				cardSizeMap[v] ++
			} else {
				cardSizeMap[v] = 1
			}
			// 颜色 同上
		} else {
			if _, ok := cardColorMap[v]; ok {
				cardColorMap[v] ++
			} else {
				cardColorMap[v] = 1
			}
		}
	}
	// 获取map的长度
	sizeLen := len(cardSizeMap)
	flag := false
	for _, v := range cardColorMap {
		if v >= 5 { // 5个花色一样的
			flag = true
			break
		}
	}
	if flag {
		// 已经是同花
		// 然后判断是不是顺子
		seq := SameFlowerSeq(cardColorMap, card)
		isShun, max := IsShunZi(seq)
		if isShun {
			// 同花顺
			resMax = max
			cardType = 1
			return
		}
		// 单纯的同花
		cardType = 5
		return
	}
	// 然后再根据存放面值的map长度来判断类型
	switch sizeLen {
	case 7: // 不是顺子 就是7个单牌
		// 判断是不是顺子
		if isShun, max := fire.IsShunZiNew(card); isShun {
			cardType = 6 // 顺子的类型
			resMax = max
			return
		}
		cardType = 10 // 单牌的类型
		return
	case 6: // 1对 或是 顺子
		// 判断是不是顺子
		if isShun, max := fire.IsShunZiNew(card); isShun {
			resMax = max
			cardType = 6
			return
		}
		// 返回一对的类型
		cardType = 9
		return
	case 5: // 可以是顺子 两对 或是 3条
		// 顺子大先判断是不是顺子
		if isShun, max := fire.IsShunZiNew(card); isShun {
			resMax = max
			cardType = 6
			return
		}
		// cardSizeMap 的key是面值 value是该面值出现的次数
		// 然后判断是不是3条
		for _, v := range cardSizeMap {
			if v == 3 {
				cardType = 7 // 3条
				return
			}
		}
		// 2对
		cardType = 8
		return
	case 4: // 可以是 4条 3带2  两对(3个对子)
		for _, v := range cardSizeMap {
			if v == 4 {
				// 4条
				cardType = 3
				return
			} else if v == 3 {
				// 3条
				cardType = 4
				return
			}
		}
		// 剩下两对
		cardType = 8
		return
	case 3: // 4条(4条1对) 3带2(3条和3条, 3条和两对)
		for _, v := range cardSizeMap {
			if v == 4 {
				cardType = 3
				return
			}
		}
		cardType = 4
		return
	case 2: // 4条(4条和3条)
		cardType = 3
		return

	}

	return

}

// SingleCard 同类型单牌比较 返回值0是平局 1是前面赢 2是后面赢
func (sevenCom *Seven) SingleCard() (result int) {
	// 用于存放面值大小的slice
	cardSizeSlice1 := make([]byte, len(sevenCom.cardSizeMap1))
	cardSizeSlice2 := make([]byte, len(sevenCom.cardSizeMap2))
	i := 0
	for k := range sevenCom.cardSizeMap1 {
		cardSizeSlice1[i] = fire.SizeTranByte(k)
		i++
	}
	i = 0
	for k := range sevenCom.cardSizeMap2 {
		cardSizeSlice2[i] = fire.SizeTranByte(k)
		i++
	}
	result = fire.SingleCardSizeCom(5, cardSizeSlice1, cardSizeSlice2)
	return
}

// APair 同类型一对的比较 返回值0是平局 1是前面赢 2是后面赢
func (sevenCom *Seven) APair() (result int) {
	// 存放 单牌的面值的slice
	cardSizeSlice1 := make([]byte, len(sevenCom.cardSizeMap1))
	cardSizeSlice2 := make([]byte, len(sevenCom.cardSizeMap1))
	// 存放对子的面值
	var val1 byte
	var val2 byte
	i := 0
	for k, v := range sevenCom.cardSizeMap1 {
		k = fire.SizeTranByte(k)
		if v == 2 {
			val1 = k
			continue
		}
		cardSizeSlice1[i] = k
		i++
	}
	i = 0
	for k, v := range sevenCom.cardSizeMap2 {
		k = fire.SizeTranByte(k)
		if v == 2 {
			val2 = k
			continue
		}
		cardSizeSlice2[i] = k
		i++
	}
	// 先对比对子的面值大小
	if val1 > val2 {
		return 1
	} else if val1 < val2 {
		return 2
	}
	// 然后对比各自单牌中最大的三种
	result = fire.SingleCardSizeCom(3, cardSizeSlice1, cardSizeSlice2)
	return
}

// TwoPair 同类型两对的比较 返回值0是平局 1是前面赢 2是后面赢
func (sevenCom *Seven) TwoPair() (result int) {
	// 存放对子的slice
	pairs1 := make([]byte, 3)
	pairs2 := make([]byte, 3)
	// 存放单牌的slice
	vals1 := make([]byte, 3)
	vals2 := make([]byte, 3)

	j := 0
	i := 0
	for k, v := range sevenCom.cardSizeMap1 {
		k = fire.SizeTranByte(k)
		if v == 2 {
			pairs1[i] = k
			i++
		} else {
			vals1[j] = k
			j++
		}
	}
	i = 0
	j = 0
	for k, v := range sevenCom.cardSizeMap2 {
		k = fire.SizeTranByte(k)
		if v == 2 {
			pairs2[i] = k
			i++
		} else {
			vals2[j] = k
			j++
		}
	}
	// 对对子序列排序  逆序
	pairs1 = fire.QuickSortByte(pairs1)
	pairs2 = fire.QuickSortByte(pairs2)

	// 对子比较 只是比较最大的两个,因为有可能是3对的
	for i := 0; i < 2; i++ {
		if pairs1[i] > pairs2[i] {
			return 1
		} else if pairs1[i] < pairs2[i] {
			return 2
		}
	}
	// 对剩余的单牌排序
	vals1 = fire.QuickSortByte(vals1)
	vals2 = fire.QuickSortByte(vals2)
	// 跟各自的对子slice的第三个比较, 因为可能存在第三个对子
	if vals1[0] < pairs1[2] {
		vals1[0] = pairs1[2]
	}
	if vals2[0] < pairs2[2] {
		vals2[0] = pairs2[2]
	}
	// 对于剩下的单牌比较,只比较最大的一个
	if vals1[0] > vals2[0] {
		return 1
	} else if vals1[0] < vals2[0] {
		return 2
	} else {
		return 0
	}
}

// OnlyThree 同类型3条比较 返回值0是平局 1是前面赢 2是后面赢
func (sevenCom *Seven) OnlyThree() (result int) {
	// 存放单牌的slice
	cardSizeSlice1 := make([]byte, len(sevenCom.cardSizeMap1))
	cardSizeSlice2 := make([]byte, len(sevenCom.cardSizeMap2))
	// 存放3条的面值
	var three1 byte
	var three2 byte

	i := 0
	for k, v := range sevenCom.cardSizeMap1 {
		k = fire.SizeTranByte(k)
		if v == 3 {
			three1 = k
		} else {
			cardSizeSlice1[i] = k
			i++
		}
	}
	i = 0
	for k, v := range sevenCom.cardSizeMap2 {
		k = fire.SizeTranByte(k)
		if v == 3 {
			three2 = k
		} else {
			cardSizeSlice2[i] = k
			i++
		}
	}
	// 比较3条的面值大小
	if three1 > three2 {
		return 1
	} else if three1 < three2 {
		return 2
	} else {
		// 比较张单牌的大小
		result = fire.SingleCardSizeCom(2, cardSizeSlice1, cardSizeSlice2)
		return
	}

}

// OnlyShunZi 同类型顺子的比较 返回值0是平局 1是前面赢 2是后面赢
func (sevenCom *Seven) OnlyShunZi() (result int) {
	max1 := fire.SizeTranByte(sevenCom.max1)
	max2 := fire.SizeTranByte(sevenCom.max2)
	if max1 > max2 {
		return 1
	} else if max1 < max2 {
		return 2
	} else {
		return 0
	}
}

// SameFlowerSeq 找到同花对应的面值序列
func SameFlowerSeq(cardColorMap map[byte]int, card []byte) (sizeSlice []byte) {
	// 存放同花的花色
	var color byte

	sliceLen := 0
	for k, v := range cardColorMap {
		if v >= 5 {
			color = k    // 记录颜色
			sliceLen = v // 颜色出现的次数
			break
		}
	}
	sizeSlice = make([]byte, sliceLen) // 大小为颜色出现的次数
	j := 0
	for i := 1; i < len(card); i += 2 {
		if card[i] == color {
			sizeSlice[j] = fire.SizeTranByte(card[i-1]) // 取颜色前一个 也就是面值
			j++
		}
	}
	return

}

// onlySameFlower 同类型同花的比较 返回值0是平局 1是前面赢 2是后面赢
func (sevenCom *Seven) onlySameFlower() (result int) {
	// 得到同花对应的面值序列
	sizeSlice1 := SameFlowerSeq(sevenCom.cardColorMap1, sevenCom.card1)
	sizeSlice2 := SameFlowerSeq(sevenCom.cardColorMap2, sevenCom.card2)
	// 只对比各自最大的五个
	result = fire.SingleCardSizeCom(5, sizeSlice1, sizeSlice2)
	return
}

// ThreeAndTwo 同类型3带2的比较 返回值0是平局 1是前面赢 2是后面赢
func (sevenCom *Seven) ThreeAndTwo() (result int) {
	// 存放 3条的面值
	threes1 := make([]byte, 2)
	threes2 := make([]byte, 2)
	// 存放对子的面值
	twos1 := make([]byte, 2)
	twos2 := make([]byte, 2)

	i := 0
	j := 0
	for k, v := range sevenCom.cardSizeMap1 {
		k = fire.SizeTranByte(k) // 对面值进行转译 才可以大小比较
		if v == 3 {
			threes1[i] = k
			i++
		} else if v == 2 {
			twos1[j] = k
			j++
		}
	}
	i = 0
	j = 0
	for k, v := range sevenCom.cardSizeMap2 {
		k = fire.SizeTranByte(k)
		if v == 3 {
			threes2[i] = k
			i++
		} else if v == 2 {
			twos2[j] = k
			j++
		}
	}

	// 对3条的序列进行倒序排序 可能出现2个3条的情况
	threes1 = fire.QuickSortByte(threes1)
	threes2 = fire.QuickSortByte(threes2)
	// 对比3条
	if threes1[0] > threes2[0] {
		return 1
	} else if threes1[0] < threes2[0] {
		return 2
	} else {
		// 对对子的序列进行倒序排序
		twos1 = fire.QuickSortByte(twos1)
		twos2 = fire.QuickSortByte(twos2)
		// 可能出现2个3条的情况
		if twos1[0] < threes1[1] {
			twos1[0] = threes1[1]
		}
		if twos2[0] < threes2[1] {
			twos2[0] = threes2[1]
		}
		// 对比对子
		if twos1[0] > twos2[0] {
			return 1
		} else if twos1[0] < twos2[0] {
			return 2
		} else {
			return 0
		}
	}
}

// FourCom 同类型4条的比较 返回值0是平局 1是前面赢 2是后面赢
func (sevenCom *Seven) FourCom() (result int) {
	// 存放非4条的牌面值
	cardSizeSlice1 := make([]byte, len(sevenCom.cardSizeMap1))
	cardSizeSlice2 := make([]byte, len(sevenCom.cardSizeMap2))
	// 存放4条的面值
	var four1 byte
	var four2 byte

	i := 0
	for k, v := range sevenCom.cardSizeMap1 {
		k = fire.SizeTranByte(k) // 面值转换才可以用于比较
		if v == 4 {
			four1 = k
		} else {
			cardSizeSlice1[i] = k
			i++
		}
	}
	i = 0
	for k, v := range sevenCom.cardSizeMap2 {
		k = fire.SizeTranByte(k)
		if v == 4 {
			four2 = k
		} else {
			cardSizeSlice2[i] = k
			i++
		}
	}
	// 先比较4条的大小
	if four1 > four2 {
		return 1
	} else if four1 < four2 {
		return 2
	} else {
		// 再比较各自单牌中最大一张
		result = fire.SingleCardSizeCom(1, cardSizeSlice1, cardSizeSlice2)
		return
	}

}

// straightFlush 同类型同花顺的比较 返回值0是平局 1是前面赢 2是后面赢
func (sevenCom *Seven) straightFlush() (result int) {
	// 同类型同花顺比较可以看作是同类型顺子比较
	return sevenCom.OnlyShunZi()
}

// PokerMan 7张的主函数
func PokerMan() {
	file := "../resources/seven_cards_with_ghost.json"
	alices := make([]string, 1024)
	bobs := make([]string, 1024)
	results := make([]int, 1024)
	alices, bobs, results = fire.ReadFile(file)
	t1 := time.Now()

	k := 0
	for i := 0; i < len(alices); i++ {
		result := -1
		val1, cardSizesMap1, cardColorMap1, max1 := JudgmentGroup([]byte(alices[i]))
		val2, cardSizesMap2, cardColorMap2, max2 := JudgmentGroup([]byte(bobs[i]))
		seven := &Seven{
			cardSizeMap1:  cardSizesMap1,
			cardSizeMap2:  cardSizesMap2,
			cardColorMap1: cardColorMap1,
			cardColorMap2: cardColorMap2,
			card1:         []byte(alices[i]),
			card2:         []byte(bobs[i]),
			max1:          max1,
			max2:          max2,
		}
		// 牌型比较
		if val1 < val2 {
			result = 1
		} else if val1 > val2 {
			result = 2
		} else {
			// 同牌型下的比较
			switch val1 {
			case 1:
				// 同花顺
				seven.straightFlush()
			case 3:
				// 四条
				result = seven.FourCom()
			case 4:
				// 3带2
				result = seven.ThreeAndTwo()
			case 5:
				// 同花
				result = seven.onlySameFlower()
			case 6:
				// 顺子
				result = seven.OnlyShunZi()
			case 7:
				// 3条
				result = seven.OnlyThree()
			case 8:
				// 2对
				result = seven.TwoPair()
			case 9:
				// 一对
				result = seven.APair()
			case 10:
				// 单牌
				result = seven.SingleCard()
			}
		}

		if results[i] != result {
			fmt.Printf("[%#v]7张判断错误--->alice:%#v,bob:%#v<----- ===>文档的结果:%#v, 我的结果:%#v <==\n",
				k, alices[i], bobs[i], results[i], result)
			k++
		}
	}

	t2 := time.Now()
	fmt.Println("time----->>>", t2.Sub(t1))
}

7张加赖子的实现方式

package sevenJoker

import (
	"NewPocker/fire"
	"fmt"
	"time"
)

// comSevenJoker 调用同类型比较函数传入的参数
type comSevenJoker struct {
	cardSizeMap1, cardSizeMap2 map[byte]int
	resCard1, resCard2         byte
	joker1, joker2             int // 记录癞子数量
}

// SameFlowerSeq 找到同花对应的面值序列
func SameFlowerSeq(cardColorMap map[byte]int, card []byte, joker int) (sizeSlice []byte) {
	// 存放同花的花色
	var color byte
	sliceLen := 0
	for k, v := range cardColorMap {
		if v+joker >= 5 { // joker是癞子假设癞子变花色
			color = k
			sliceLen = v + joker
			break
		}
	}
	sizeSlice = make([]byte, sliceLen)
	j := 0
	for i := 1; i < len(card); i += 2 {
		if card[i] == color {
			sizeSlice[j] = fire.SizeTranByte(card[i-1]) // 花色前一个是它对应的面值,转译成可以比较的
			j++
		}
	}
	// 将所有jock都变A , 因为同花下比较单牌 癞子变最大的单牌
	for joker > 0 && sliceLen != 0 {
		sizeSlice[j] = 0x0E
		j++
		joker--
	}
	return

}

// IsShunZi 判断是不是顺子,返回顺子的一个最大面值 传进来的已经转译好的面值
func IsShunZi(seq []byte, joker int) (shunZi bool, max byte) {
	saves := make([]byte, 15)
	// 遍历seq,把它对应放到saves中,安位入座
	for _, v := range seq {
		switch v {
		case 0x02:
			saves[1] = v
		case 0x03:
			saves[2] = v
		case 0x04:
			saves[3] = v
		case 0x05:
			saves[4] = v
		case 0x06:
			saves[5] = v
		case 0x07:
			saves[6] = v
		case 0x08:
			saves[7] = v
		case 0x09:
			saves[8] = v
		case 0x0A:
			saves[9] = v
		case 0x0B:
			saves[10] = v
		case 0x0C:
			saves[11] = v
		case 0x0D:
			saves[12] = v
		case 0x0E:
			saves[13] = v
			saves[0] = v
		case 0x10:
			saves[14] = v
		default:
			fmt.Println("IsShunZi say 无法解析的扑克牌", "card --v=", v)
		}
	}
	sum := 0
	// 判断数组是否连续
	if joker < 1 {
		// 没有癞子的顺子
		for i := len(saves) - 1; i >= 0; i-- {
			if saves[i] != 0x00 {
				sum++
			} else {
				sum = 0
			}
			if sum >= 5 {
				shunZi = true
				max = saves[i+4]
				return
			}
		}
	} else {
		tmp := joker
		sum = 0
		for i := len(saves) - 1; i >= 0; i-- {
			if saves[i] != 0 {
				sum++
			} else if joker > 0 {
				joker--
				sum++
			} else {
				// 这里是回退到一开始的下一个
				i = i + sum - joker
				// 重置 joker 和sum
				joker = tmp
				sum = 0
			}
			if sum >= 5 {
				// 是顺子
				max = saves[i+4]
				if max == 0 {
					// 那么癞子就变成这个下标对应的值
					max = IndexTranByte(i + 4)
				}
				shunZi = true
				return
			}
		}
	}
	return
}

// IndexTranByte 当是顺子时,癞子去补顺子的最大值调用这个函数去转换下标对应的面值
func IndexTranByte(index int) (b byte) {
	switch index {
	// 这个癞子补充的值,不可能是很前面的
	case 4:
		b = 0x05
	case 5:
		b = 0x06
	case 6:
		b = 0x07
	case 7:
		b = 0x08
	case 8:
		b = 0x09
	case 9:
		b = 0x0A
	case 10:
		b = 0x0B
	case 11:
		b = 0x0C
	case 12:
		b = 0x0D
	case 13:
		b = 0x0E
	case 14:
		b = 0x10
	default:
		fmt.Println("IsShunZi say 无法解析的扑克牌", "card --b=", b)
	}
	return
}

// IsShunZiNoTran 判断是不是顺子,并且返回顺子的最大牌面值 传进来的card还没有转译
func IsShunZiNoTran(card []byte, joker int) (shunZi bool, max byte) {
	shunZi = false
	saves := make([]byte, 14)
	// 将面值对号入座
	for i, v := range card {
		if i%2 == 0 {
			switch v {
			case 50:
				saves[1] = v
			case 51:
				saves[2] = v
			case 52:
				saves[3] = v
			case 53:
				saves[4] = v
			case 54:
				saves[5] = v
			case 55:
				saves[6] = v
			case 56:
				saves[7] = v
			case 57:
				saves[8] = v
			case 84:
				saves[9] = v
			case 74:
				saves[10] = v
			case 81:
				saves[11] = v
			case 75:
				saves[12] = v
			case 65:
				saves[13] = v
				saves[0] = v
			case 88:
				// continue
				// fmt.Println("88")
			default:
				fmt.Println("无法解析的扑克牌", "card --v=", v)
			}
		}

	}
	// 下面判断数组是否连续
	sum := 0

	if joker < 1 {
		// 没有癞子的顺子
		for i := len(saves) - 1; i >= 0; i-- {
			if saves[i] != 0x00 {
				sum++
			} else {
				sum = 0
			}
			if sum >= 5 {
				shunZi = true
				max = saves[i+4]
				return
			}
		}
	} else {
		tmp := joker
		sum = 0
		for i := len(saves) - 1; i >= 0; i-- {
			if saves[i] != 0 {
				sum++
			} else if joker > 0 {
				joker--
				sum++
			} else {
				// 这里是回退到一开始的下一个
				i = i + sum - joker
				joker = tmp
				sum = 0
			}
			if sum >= 5 {
				// 是顺子
				max = saves[i+4]
				if max == 0 {
					// 需要癞子来补充这个最大的面值
					max = IndexFindByte(i + 4)
				}
				shunZi = true
				return
			}
		}
	}

	return
}

// IndexFindByte 下标转成面值的byte
func IndexFindByte(index int) (b byte) {
	switch index {
	case 5:
		b = 54
	case 6:
		b = 55
	case 7:
		b = 56
	case 8:
		b = 57
	case 9:
		b = 84
	case 10:
		b = 74
	case 11:
		b = 81
	case 12:
		b = 75
	case 13:
		b = 65
	case 0:
		b = 65
	case 88:
	case 1:
		b = 50
	case 2:
		b = 51
	case 3:
		b = 52
	case 4:
		b = 53
	default:
		fmt.Println("无法解析的下标", "card --index=", index)

	}
	return
}

//  judgmentGroup 判断牌型  传进来的参数:面值+花色
func judgmentGroup(card [] byte) (cardType uint8, cardSizeMap, cardColorMap map[byte]int, resCard byte, joker int) {
	//  对传进来的牌分拣成  面值 花色
	cardColorMap = make(map[byte]int, 7)
	cardSizeMap = make(map[byte]int, 7)
	// 扫描牌 分别放好大小,花色
	for i, v := range card {
		if i%2 == 0 {
			// 大小
			// 判断是否有癞子
			if v == 88 {
				joker++ // 记录多少个癞子但是不放入map中
				continue
			}
			if _, ok := cardSizeMap[v]; ok {
				cardSizeMap[v]++
			} else {
				cardSizeMap[v] = 1
			}
			// 颜色
		} else {
			if v == 110 { // 癞子的花色,不作处理
				continue
			}
			if _, ok := cardColorMap[v]; ok {
				cardColorMap[v]++
			} else {
				cardColorMap[v] = 1
			}
		}
	}
	sizeLen := len(cardSizeMap)
	flag := false
	for _, v := range cardColorMap {
		if v+joker >= 5 {
			flag = true
			break
		}
	}

	if flag {
		// 同花
		// 判断是不是顺子
		seq := SameFlowerSeq(cardColorMap, card, joker)
		isShun, max := IsShunZi(seq[0:len(seq)-joker], joker)
		if isShun {
			// 同花顺
			resCard = max
			cardType = 1
			return
		}
		if joker == 0 {
			cardType = 5
			return
		}
		// 有癞子的情况下,是同花,也有可能是变成4条 或是 三带2 它们都比同花大
		i := 0
		for _, v := range cardSizeMap {
			if v+joker == 4 {
				// 4 条
				cardType = 3
				return
			} else if v+joker == 3 {
				i++
			}
		}
		if i == 2 {
			// 3带2
			cardType = 4
			return
		}
		cardType = 5
		return

	}
	// 不是同花
	// 根据面值的map长度判断
	switch sizeLen {
	case 7: // 单牌也没有癞子
		// 判断是不是顺子
		if isShun, max := IsShunZiNoTran(card, joker); isShun {
			cardType = 6
			resCard = max
			return
		}
		cardType = 10
		return
	case 6: // 可能 顺子 单牌+癞子 或是 一对
		if isShun, max := IsShunZiNoTran(card, joker); isShun {
			resCard = max
			cardType = 6
			return
		}
		// 就算有癞子也是一对, 因为癞子不放入map,map len为6 如果有癞子的话,其他牌是单牌
		cardType = 9
		return

	case 5: // 顺子 3条 或是 两对
		// 判断是不是顺子
		if isShun, max := IsShunZiNoTran(card, joker); isShun {
			resCard = max
			cardType = 6
			return
		}
		// 有癞子的五张牌一定是3条
		if joker > 0 {
			cardType = 7
			return
		}
		for _, v := range cardSizeMap {
			if v == 3 {
				// 3条
				cardType = 7
				return
			}
		}
		// 2对
		cardType = 8
		return

	case 4: // 因为最多只有一个癞子 就可能出现4条  3带2 或是 2对(3个对子) 有癞子的话也不组顺子,因为可以组4条或是3带2比顺子大
		i := 0
		j := 0
		for _, v := range cardSizeMap {
			if v+joker == 4 {
				// 4条
				cardType = 3
				return
			} else if v+joker == 3 {
				//  有可能是本来有两对再加一个癞子
				i++

			} else if v == 2 {
				j++
			}
		}
		if j < 2 {
			cardType = 4
			return
		}
		// 这里的j=3,也就是三对并且没有癞子的
		cardType = 8
		return
	case 3: // 不是3带2 就是4条了
		for _, v := range cardSizeMap {
			if v+joker == 4 {
				cardType = 3
				return
			}
		}
		cardType = 4
		return
	case 2: // 只能是4条
		cardType = 3
		return

	}

	return
}

// straightFlush 同类型同花顺比较 --1
func (sevenJoker *comSevenJoker) straightFlush() (result int) {
	// 比较顺子最大的牌
	if sevenJoker.resCard1 > sevenJoker.resCard2 {
		return 1
	} else if sevenJoker.resCard1 < sevenJoker.resCard2 {
		return 2
	} else {
		return 0
	}
}

// fourCom 同类型四条比较  --3
func (sevenJoker *comSevenJoker) fourCom() (result int) {
	// 存放单牌的slice
	cardSizeSlice1 := make([]byte, len(sevenJoker.cardSizeMap1))
	cardSizeSlice2 := make([]byte, len(sevenJoker.cardSizeMap2))
	// 存放4条的面值
	var four1 byte
	var four2 byte

	i := 0
	for k, v := range sevenJoker.cardSizeMap1 {
		k = fire.SizeTranByte(k)
		if v+sevenJoker.joker1 == 4 {
			if four1 < k {
				four1 = k
			}
		} else {
			cardSizeSlice1[i] = k
			i++
		}
	}
	i = 0
	for k, v := range sevenJoker.cardSizeMap2 {
		k = fire.SizeTranByte(k)
		if v+sevenJoker.joker2 == 4 {
			if four2 < k {
				four2 = k
			}
		} else {
			cardSizeSlice2[i] = k
			i++
		}
	}

	if four1 > four2 {
		return 1
	} else if four1 < four2 {
		return 2
	} else {
		// 比较单牌中最大的一张
		result = fire.SingleCardSizeCom(1, cardSizeSlice1, cardSizeSlice2)
		return
	}
}

// threeAndTwo同类型3带2比较  --4
func (sevenJoker *comSevenJoker) threeAndTwo() (result int) {
	// 存放3条的slice
	threes1 := make([]byte, 3)
	threes2 := make([]byte, 3)
	// 存放对子的slice
	twos1 := make([]byte, 3)
	twos2 := make([]byte, 3)

	i := 0
	j := 0

	for k, v := range sevenJoker.cardSizeMap1 {
		k = fire.SizeTranByte(k)
		if v+sevenJoker.joker1 == 3 {
			threes1[i] = k
			i++
		} else if v == 2 {
			twos1[j] = k
			j++
		}
	}
	i = 0
	j = 0
	for k, v := range sevenJoker.cardSizeMap2 {
		k = fire.SizeTranByte(k)
		if v+sevenJoker.joker2 == 3 {
			threes2[i] = k
			i++
		} else if v == 2 {
			twos2[j] = k
			j++
		}
	}
	// 对3条排序
	threes1 = fire.QuickSortByte(threes1)
	threes2 = fire.QuickSortByte(threes2)

	// 因为有可能出现 2个3条
	if threes1[0] > threes2[0] {
		return 1
	} else if threes1[0] < threes2[0] {
		return 2
	}

	// 对 对子排序
	twos1 = fire.QuickSortByte(twos1)
	twos2 = fire.QuickSortByte(twos2)

	// 当两个3条的时候, 对子就没有值,那么对子的最大应该是3条的最小
	if twos1[0] < threes1[1] {
		twos1[0] = threes1[1]
	}
	if twos2[0] < threes2[1] {
		twos2[0] = threes2[1]
	}
	if twos1[0] > twos2[0] {
		return 1
	} else if twos1[0] < twos2[0] {
		return 2
	} else {
		return 0
	}
}

// onlyFlush 同类型同花比较  --5  1
func (sevenJoker *comSevenJoker) onlyFlush(cardColorMap1, cardColorMap2 map[byte]int, card1, card2 []byte) (result int) {
	// 找到同花对应的面值序列
	sizeSlice1 := SameFlowerSeq(cardColorMap1, card1, sevenJoker.joker1)
	sizeSlice2 := SameFlowerSeq(cardColorMap2, card2, sevenJoker.joker2)
	// 这个序列可以大于5个, 所以只比较各自最大的五个
	result = fire.SingleCardSizeCom(5, sizeSlice1, sizeSlice2)
	return
}

// OnlyShunZi 同类型顺子比较 --6
func (sevenJoker *comSevenJoker) OnlyShunZi() (result int) {
	v1 := fire.SizeTranByte(sevenJoker.resCard1)
	v2 := fire.SizeTranByte(sevenJoker.resCard2)
	if v1 > v2 {
		return 1
	} else if v1 < v2 {
		return 2
	} else {
		return 0
	}
}

// onlyThree 同类型3条比较  --7
func (sevenJoker *comSevenJoker) onlyThree() (result int) {
	// 存放单牌的slice
	cardSizeSlice1 := make([]byte, len(sevenJoker.cardSizeMap1))
	cardSizeSlice2 := make([]byte, len(sevenJoker.cardSizeMap2))
	// 存放3条的面值
	var three1 byte
	var three2 byte

	i := 0

	for k, v := range sevenJoker.cardSizeMap1 {
		k = fire.SizeTranByte(k)
		if v+sevenJoker.joker1 == 3 {
			three1 = k
		} else {
			cardSizeSlice1[i] = k
			i++
		}
	}
	i = 0
	for k, v := range sevenJoker.cardSizeMap2 {
		k = fire.SizeTranByte(k)
		if v+sevenJoker.joker2 == 3 {
			three2 = k
		} else {
			cardSizeSlice2[i] = k
			i++
		}
	}
	if three1 > three2 {
		return 1
	} else if three1 < three2 {
		return 2
	} else {
		// 比较各自单牌中最大的两个
		result = fire.SingleCardSizeCom(2, cardSizeSlice1, cardSizeSlice2)
		return
	}
}

// TwoPair 同类型两对比较 --8
func (sevenJoker *comSevenJoker) TwoPair() (result int) {
	// 记录对子的slice
	pairs1 := make([]byte, 3)
	pairs2 := make([]byte, 3)
	// 记录单牌的slice
	vals1 := make([]byte, 3)
	vals2 := make([]byte, 3)

	j := 0
	i := 0
	for k, v := range sevenJoker.cardSizeMap1 {
		k = fire.SizeTranByte(k)
		if v+sevenJoker.joker1 == 2 {
			pairs1[i] = k
			i++
		} else {
			vals1[j] = k
			j++
		}
	}
	i = 0
	j = 0
	for k, v := range sevenJoker.cardSizeMap2 {
		k = fire.SizeTranByte(k)
		if v+sevenJoker.joker2 == 2 {
			pairs2[i] = k
			i++
		} else {
			vals2[j] = k
			j++
		}
	}
	// 对 对子 逆序列排序
	pairs1 = fire.QuickSortByte(pairs1)
	pairs2 = fire.QuickSortByte(pairs2)

	// 因为可能出现3个对子,选择选择最大两个比较
	for i := 0; i < 2; i++ {
		if pairs1[i] > pairs2[i] {
			return 1
		} else if pairs1[i] < pairs2[i] {
			return 2
		}
	}

	// 对单牌序列排序
	vals1 = fire.QuickSortByte(vals1)
	vals2 = fire.QuickSortByte(vals2)
	// 如果出现3个对子,让最小的对子跟最大的单牌比较
	if vals1[0] < pairs1[2] {
		vals1[0] = pairs1[2]
	}
	if vals2[0] < pairs2[2] {
		vals2[0] = pairs2[2]
	}
	// 比较单牌最大
	if vals1[0] > vals2[0] {
		return 1
	} else if vals1[0] < vals2[0] {
		return 2
	}
	return 0
}

// OnePair 同类型一对比较 --9
func (sevenJoker *comSevenJoker) OnePair() (result int) {
	cardSizeSlice1 := make([]byte, len(sevenJoker.cardSizeMap1))
	cardSizeSlice2 := make([]byte, len(sevenJoker.cardSizeMap1))
	var val1 byte
	var val2 byte
	i := 0

	for k, v := range sevenJoker.cardSizeMap1 {
		k = fire.SizeTranByte(k)
		if v == 2 {
			val1 = k
			continue
		}
		cardSizeSlice1[i] = k
		i++
	}
	i = 0
	for k, v := range sevenJoker.cardSizeMap2 {
		k = fire.SizeTranByte(k)
		if v == 2 {
			val2 = k
			continue
		}

		cardSizeSlice2[i] = k
		i++
	}

	cardSizeSlice1 = fire.QuickSortByte(cardSizeSlice1)
	cardSizeSlice2 = fire.QuickSortByte(cardSizeSlice2)

	// 癞子组成的对子
	if val1 == 0 {
		val1 = cardSizeSlice1[0]
	}
	if val2 == 0 {
		val2 = cardSizeSlice2[0]
		// fmt.Println("val22222222")
	}

	if val1 > val2 {
		return 1
	} else if val1 < val2 {
		return 2
	}

	comLen := 3
	// 单牌一个个对比
	for i := 0; i < comLen; i++ {
		if cardSizeSlice1[i+sevenJoker.joker1] > cardSizeSlice2[i+sevenJoker.joker2] {
			return 1
		} else if cardSizeSlice1[i+sevenJoker.joker1] < cardSizeSlice2[i+sevenJoker.joker2] {
			return 2
		}
	}

	return 0
}

// SingleCard 同类型单牌比较  --10
func (sevenJoker *comSevenJoker) SingleCard() (result int) {
	// 存放单牌的slice
	cardSizeSlice1 := make([]byte, len(sevenJoker.cardSizeMap1))
	cardSizeSlice2 := make([]byte, len(sevenJoker.cardSizeMap2))
	i := 0
	for k := range sevenJoker.cardSizeMap1 {
		cardSizeSlice1[i] = fire.SizeTranByte(k)
		i++
	}
	i = 0
	for k := range sevenJoker.cardSizeMap2 {
		cardSizeSlice2[i] = fire.SizeTranByte(k)
		i++
	}
	// 对比各自最大的5张
	result = fire.SingleCardSizeCom(5, cardSizeSlice1, cardSizeSlice2)
	return
}

// PokerMan 7张加癞子的主函数
func PokerMan() {
	filePath := "../resources/seven_cards_with_ghost.result.json"
	alices, bobs, results := fire.ReadFile(filePath)
	t1 := time.Now()
	k := 0
	for i := 0; i < len(alices); i++ {

		result := -1
		// 先判断各自的牌型
		cardType1, cardSizesMap1, cardColorMap1, max1, joker1 := judgmentGroup([]byte(alices[i]))
		cardType2, cardSizesMap2, cardColorMap2, max2, joker2 := judgmentGroup([]byte(bobs[i]))
		if cardType1 < cardType2 {
			result = 1
		} else if cardType1 > cardType2 {
			result = 2
		} else {

			csj := &comSevenJoker{
				cardSizeMap1: cardSizesMap1,
				cardSizeMap2: cardSizesMap2,
				resCard1:     max1,
				resCard2:     max2,
				joker1:       joker1,
				joker2:       joker2,
			}
			// 同类型比较
			switch cardType1 {
			case 1:
				// 同花顺
				result = csj.straightFlush()
			case 3:
				// 4条
				result = csj.fourCom()
			case 4:
				// 3带2
				result = csj.threeAndTwo()
			case 5:
				// 同花
				result = csj.onlyFlush(cardColorMap1, cardColorMap2, []byte(alices[i]), []byte(bobs[i]))
			case 6:
				// 顺子
				result = csj.OnlyShunZi()
			case 7:
				// 3条
				result = csj.onlyThree()
			case 8:
				// 两对
				result = csj.TwoPair()
			case 9:
				// 一对
				result = csj.OnePair()
			case 10:
				// 单牌
				result = csj.SingleCard()

			}
		}
		if result != results[i] {
			k++
			fmt.Println("[", k, "]"+"判断有误,alice=", alices[i], " bob=", bobs[i], "  我的结果:", result, "  文档的结果:", results[i])
		}
	}

	t2 := time.Now()
	fmt.Println("time--->", t2.Sub(t1))

}

关于规范化

go语言有golint指令和go vet指令

有关于效率的问题

暴力破解的运行时间太长了,建议:
1.用素数去求,把所有可能性的牌的素数乘积求出来存入表中,然后根据当前的手牌去查询表
利用的是 [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41] 素数相乘的值都是唯一值的这个特点
2.用位运算,首先是牌的储存,2~~A,一共13张牌,用一个14位的二进制区间来储存手牌,比如2-A,将表示为:11111111111110,出现的牌位为1,没出现的位为0,第一位是也是放A,由于德州扑克里面A 2 3 4 5是最小的顺子。

这样的储存方式除了省空间外还有什么优势呢?
我们顺子的判断为例:例如顺子10JQKA,在二进制区间将表示为11111000000000,叫它S
现在我们有手牌2 3 10 J Q K A,那么它的二进制表示是11111000000110,叫它T
那么T&S==S的话,就可以说明T包含一个顺子,并且顺子是10JQKA
S转化为10进制的话是15872

类似的我们将所有可能的顺子预先保存好,如下表(10用T表示):
TJQKA | 9TJQK | 89TJQ | 789TJ | 6789T | 56789 | 45678 | 34567 | 23456 | A2345 |
15872 | 7936 | 3968 | 1984 | 992 | 496 | 248 | 124 | 62 | 31 |

项目的github地址

下载可以直接运行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

困了就喝白茶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值