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

2023-11-21 07:10

本文主要是介绍德州扑克比较大小的go语言暴力实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

德州扑克的规则

在这里插入图片描述

项目实现了什么

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

项目的运行速度

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

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

我的项目结构

在这里插入图片描述

5张牌的实现方式

package fireimport ("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]intcardSizeMap2 map[byte]intmax1, max2   byte
}// SizeTranByte 对面值转译整对应的byte值  -- 方便大小比较
func SizeTranByte(card byte) (res byte) {switch card {case 50:// 2res = 0x02case 51:res = 0x03case 52:res = 0x04case 53:res = 0x05case 54:res = 0x06case 55:res = 0x07case 56:res = 0x08case 57:res = 0x09case 84:res = 0x0Acase 74:res = 0x0Bcase 81:res = 0x0Ccase 75:res = 0x0Dcase 65:res = 0x0Ecase 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 Matcherr = 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.Alicebobs[k] = v.Bobresults[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 = 1if colorLen > 1 {// 非同花switch sizeLen {case 4:// 一对judeCardType = 9returncase 2: // 3带2  或是 4带1// 遍历map valuefor _, v := range cardSizeMap {if v == 4 {judeCardType = 3return}}judeCardType = 4returncase 3:// 3条 或是 两对for _, v := range cardSizeMap {if v == 3 {judeCardType = 7return}}judeCardType = 8returncase 5:// 单牌或是顺子isShun, max := IsShunZiNew(card)if isShun {resMax = maxjudeCardType = 6return}judeCardType = 10return}} else {// 同花 或是 同花顺isShun, max := IsShunZiNew(card)if isShun {resMax = maxjudeCardType = 1} else {judeCardType = 5}}return}// IsShunZiNew 判断是否是顺子 返回顺子的最大值和是否是顺子
func IsShunZiNew(card []byte) (shunZi bool, max byte) {shunZi = falsesaves := make([]byte, 14)// 把扑克牌放如slice中for i, v := range card {if i%2 == 0 {switch v {case 50:saves[1] = vcase 51:saves[2] = vcase 52:saves[3] = vcase 53:saves[4] = vcase 54:saves[5] = vcase 55:saves[6] = vcase 56:saves[7] = vcase 57:saves[8] = vcase 84:saves[9] = vcase 74:saves[10] = vcase 81:saves[11] = vcase 75:saves[12] = vcase 65:saves[13] = vsaves[0] = vdefault:fmt.Println("无法解析的扑克牌", "card --v=", v)}}}// 判断数组是否连续 倒序遍历sum := 0for i := len(saves) - 1; i >= 0; i-- {// slice有值if saves[i] != 0x00 {sum++} else {sum = 0}// 5个连续if sum >= 5 {shunZi = truemax = 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 := 0for k := range com.cardSizeMap1 {cardSizeSlice1[i] = SizeTranByte(k)i++}i = 0for 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 bytevar pair2 bytei := 0for k, v := range com.cardSizeMap1 {k = SizeTranByte(k) // 对牌子转译,才可以比较大小if v == 2 {pair1 = k} else {cardSizeSlice1[i] = ki++}}i = 0for 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 bytevar val2 bytei := 0for k, v := range com.cardSizeMap1 {k = SizeTranByte(k) // 转译面值成可以比较的if v == 2 {pairs1[i] = ki++} else {val1 = k}}i = 0for k, v := range com.cardSizeMap2 {k = SizeTranByte(k)if v == 2 {pairs2[i] = ki++} 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 bytevar three2 bytei := 0for k, v := range com.cardSizeMap1 {k = SizeTranByte(k)cardSizeSlice1[i] = kif v == 3 {three1 = k} else {i++}}i = 0for k, v := range com.cardSizeMap2 {k = SizeTranByte(k)cardSizeSlice2[i] = kif 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 bytevar four2 byte// 存放单牌的面值var val1 bytevar val2 bytefor 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 bytevar three2 byte// 存放对子的面值var two1 bytevar two2 bytefor 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带2result = 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 sevenimport ("NewPocker/fire""fmt""time"
)// Seven 调用同类型比较函数们的参数传入
type Seven struct {// 存放面值的mapcardSizeMap1, cardSizeMap2   map[byte]intcardColorMap1, cardColorMap2 map[byte]intmax1, max2                   bytecard1, card2                 []byte
}// IsShunZi 判断是不是顺子,并且返回顺子的最大值  传进来的已经转译好的面值
func IsShunZi(seq []byte) (flag bool, max byte) {flag = falsesaves := make([]byte, 14)// 遍历序列, 存放入对应的序列for _, v := range seq {switch v {case 0x02:saves[1] = vcase 0x03:saves[2] = vcase 0x04:saves[3] = vcase 0x05:saves[4] = vcase 0x06:saves[5] = vcase 0x07:saves[6] = vcase 0x08:saves[7] = vcase 0x09:saves[8] = vcase 0x0A:saves[9] = vcase 0x0B:saves[10] = vcase 0x0C:saves[11] = vcase 0x0D:saves[12] = vcase 0x0E:saves[13] = vsaves[0] = vdefault:fmt.Println("无法解析的扑克牌", "card --v=", v)}}// 判断数组是否连续sum := 0for i := len(saves) - 1; i >= 0; i-- {if saves[i] != 0x00 {// slice有值sum++} else {// 没值重置sum = 0}// 判断到有连续5个if sum >= 5 {flag = truemax = 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 := falsefor _, v := range cardColorMap {if v >= 5 { // 5个花色一样的flag = truebreak}}if flag {// 已经是同花// 然后判断是不是顺子seq := SameFlowerSeq(cardColorMap, card)isShun, max := IsShunZi(seq)if isShun {// 同花顺resMax = maxcardType = 1return}// 单纯的同花cardType = 5return}// 然后再根据存放面值的map长度来判断类型switch sizeLen {case 7: // 不是顺子 就是7个单牌// 判断是不是顺子if isShun, max := fire.IsShunZiNew(card); isShun {cardType = 6 // 顺子的类型resMax = maxreturn}cardType = 10 // 单牌的类型returncase 6: // 1对 或是 顺子// 判断是不是顺子if isShun, max := fire.IsShunZiNew(card); isShun {resMax = maxcardType = 6return}// 返回一对的类型cardType = 9returncase 5: // 可以是顺子 两对 或是 3条// 顺子大先判断是不是顺子if isShun, max := fire.IsShunZiNew(card); isShun {resMax = maxcardType = 6return}// cardSizeMap 的key是面值 value是该面值出现的次数// 然后判断是不是3条for _, v := range cardSizeMap {if v == 3 {cardType = 7 // 3条return}}// 2对cardType = 8returncase 4: // 可以是 4条 3带2  两对(3个对子)for _, v := range cardSizeMap {if v == 4 {// 4条cardType = 3return} else if v == 3 {// 3条cardType = 4return}}// 剩下两对cardType = 8returncase 3: // 4条(4条1对) 3带2(3条和3条, 3条和两对)for _, v := range cardSizeMap {if v == 4 {cardType = 3return}}cardType = 4returncase 2: // 4条(4条和3条)cardType = 3return}return}// SingleCard 同类型单牌比较 返回值0是平局 1是前面赢 2是后面赢
func (sevenCom *Seven) SingleCard() (result int) {// 用于存放面值大小的slicecardSizeSlice1 := make([]byte, len(sevenCom.cardSizeMap1))cardSizeSlice2 := make([]byte, len(sevenCom.cardSizeMap2))i := 0for k := range sevenCom.cardSizeMap1 {cardSizeSlice1[i] = fire.SizeTranByte(k)i++}i = 0for 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) {// 存放 单牌的面值的slicecardSizeSlice1 := make([]byte, len(sevenCom.cardSizeMap1))cardSizeSlice2 := make([]byte, len(sevenCom.cardSizeMap1))// 存放对子的面值var val1 bytevar val2 bytei := 0for k, v := range sevenCom.cardSizeMap1 {k = fire.SizeTranByte(k)if v == 2 {val1 = kcontinue}cardSizeSlice1[i] = ki++}i = 0for k, v := range sevenCom.cardSizeMap2 {k = fire.SizeTranByte(k)if v == 2 {val2 = kcontinue}cardSizeSlice2[i] = ki++}// 先对比对子的面值大小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) {// 存放对子的slicepairs1 := make([]byte, 3)pairs2 := make([]byte, 3)// 存放单牌的slicevals1 := make([]byte, 3)vals2 := make([]byte, 3)j := 0i := 0for k, v := range sevenCom.cardSizeMap1 {k = fire.SizeTranByte(k)if v == 2 {pairs1[i] = ki++} else {vals1[j] = kj++}}i = 0j = 0for k, v := range sevenCom.cardSizeMap2 {k = fire.SizeTranByte(k)if v == 2 {pairs2[i] = ki++} else {vals2[j] = kj++}}// 对对子序列排序  逆序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) {// 存放单牌的slicecardSizeSlice1 := make([]byte, len(sevenCom.cardSizeMap1))cardSizeSlice2 := make([]byte, len(sevenCom.cardSizeMap2))// 存放3条的面值var three1 bytevar three2 bytei := 0for k, v := range sevenCom.cardSizeMap1 {k = fire.SizeTranByte(k)if v == 3 {three1 = k} else {cardSizeSlice1[i] = ki++}}i = 0for k, v := range sevenCom.cardSizeMap2 {k = fire.SizeTranByte(k)if v == 3 {three2 = k} else {cardSizeSlice2[i] = ki++}}// 比较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 bytesliceLen := 0for k, v := range cardColorMap {if v >= 5 {color = k    // 记录颜色sliceLen = v // 颜色出现的次数break}}sizeSlice = make([]byte, sliceLen) // 大小为颜色出现的次数j := 0for 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 := 0j := 0for k, v := range sevenCom.cardSizeMap1 {k = fire.SizeTranByte(k) // 对面值进行转译 才可以大小比较if v == 3 {threes1[i] = ki++} else if v == 2 {twos1[j] = kj++}}i = 0j = 0for k, v := range sevenCom.cardSizeMap2 {k = fire.SizeTranByte(k)if v == 3 {threes2[i] = ki++} else if v == 2 {twos2[j] = kj++}}// 对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 bytevar four2 bytei := 0for k, v := range sevenCom.cardSizeMap1 {k = fire.SizeTranByte(k) // 面值转换才可以用于比较if v == 4 {four1 = k} else {cardSizeSlice1[i] = ki++}}i = 0for k, v := range sevenCom.cardSizeMap2 {k = fire.SizeTranByte(k)if v == 4 {four2 = k} else {cardSizeSlice2[i] = ki++}}// 先比较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 := 0for i := 0; i < len(alices); i++ {result := -1val1, 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带2result = 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 sevenJokerimport ("NewPocker/fire""fmt""time"
)// comSevenJoker 调用同类型比较函数传入的参数
type comSevenJoker struct {cardSizeMap1, cardSizeMap2 map[byte]intresCard1, resCard2         bytejoker1, joker2             int // 记录癞子数量
}// SameFlowerSeq 找到同花对应的面值序列
func SameFlowerSeq(cardColorMap map[byte]int, card []byte, joker int) (sizeSlice []byte) {// 存放同花的花色var color bytesliceLen := 0for k, v := range cardColorMap {if v+joker >= 5 { // joker是癞子假设癞子变花色color = ksliceLen = v + jokerbreak}}sizeSlice = make([]byte, sliceLen)j := 0for 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] = 0x0Ej++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] = vcase 0x03:saves[2] = vcase 0x04:saves[3] = vcase 0x05:saves[4] = vcase 0x06:saves[5] = vcase 0x07:saves[6] = vcase 0x08:saves[7] = vcase 0x09:saves[8] = vcase 0x0A:saves[9] = vcase 0x0B:saves[10] = vcase 0x0C:saves[11] = vcase 0x0D:saves[12] = vcase 0x0E:saves[13] = vsaves[0] = vcase 0x10:saves[14] = vdefault: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 = truemax = saves[i+4]return}}} else {tmp := jokersum = 0for i := len(saves) - 1; i >= 0; i-- {if saves[i] != 0 {sum++} else if joker > 0 {joker--sum++} else {// 这里是回退到一开始的下一个i = i + sum - joker// 重置 joker 和sumjoker = tmpsum = 0}if sum >= 5 {// 是顺子max = saves[i+4]if max == 0 {// 那么癞子就变成这个下标对应的值max = IndexTranByte(i + 4)}shunZi = truereturn}}}return
}// IndexTranByte 当是顺子时,癞子去补顺子的最大值调用这个函数去转换下标对应的面值
func IndexTranByte(index int) (b byte) {switch index {// 这个癞子补充的值,不可能是很前面的case 4:b = 0x05case 5:b = 0x06case 6:b = 0x07case 7:b = 0x08case 8:b = 0x09case 9:b = 0x0Acase 10:b = 0x0Bcase 11:b = 0x0Ccase 12:b = 0x0Dcase 13:b = 0x0Ecase 14:b = 0x10default:fmt.Println("IsShunZi say 无法解析的扑克牌", "card --b=", b)}return
}// IsShunZiNoTran 判断是不是顺子,并且返回顺子的最大牌面值 传进来的card还没有转译
func IsShunZiNoTran(card []byte, joker int) (shunZi bool, max byte) {shunZi = falsesaves := make([]byte, 14)// 将面值对号入座for i, v := range card {if i%2 == 0 {switch v {case 50:saves[1] = vcase 51:saves[2] = vcase 52:saves[3] = vcase 53:saves[4] = vcase 54:saves[5] = vcase 55:saves[6] = vcase 56:saves[7] = vcase 57:saves[8] = vcase 84:saves[9] = vcase 74:saves[10] = vcase 81:saves[11] = vcase 75:saves[12] = vcase 65:saves[13] = vsaves[0] = vcase 88:// continue// fmt.Println("88")default:fmt.Println("无法解析的扑克牌", "card --v=", v)}}}// 下面判断数组是否连续sum := 0if joker < 1 {// 没有癞子的顺子for i := len(saves) - 1; i >= 0; i-- {if saves[i] != 0x00 {sum++} else {sum = 0}if sum >= 5 {shunZi = truemax = saves[i+4]return}}} else {tmp := jokersum = 0for i := len(saves) - 1; i >= 0; i-- {if saves[i] != 0 {sum++} else if joker > 0 {joker--sum++} else {// 这里是回退到一开始的下一个i = i + sum - jokerjoker = tmpsum = 0}if sum >= 5 {// 是顺子max = saves[i+4]if max == 0 {// 需要癞子来补充这个最大的面值max = IndexFindByte(i + 4)}shunZi = truereturn}}}return
}// IndexFindByte 下标转成面值的byte
func IndexFindByte(index int) (b byte) {switch index {case 5:b = 54case 6:b = 55case 7:b = 56case 8:b = 57case 9:b = 84case 10:b = 74case 11:b = 81case 12:b = 75case 13:b = 65case 0:b = 65case 88:case 1:b = 50case 2:b = 51case 3:b = 52case 4:b = 53default: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 := falsefor _, v := range cardColorMap {if v+joker >= 5 {flag = truebreak}}if flag {// 同花// 判断是不是顺子seq := SameFlowerSeq(cardColorMap, card, joker)isShun, max := IsShunZi(seq[0:len(seq)-joker], joker)if isShun {// 同花顺resCard = maxcardType = 1return}if joker == 0 {cardType = 5return}// 有癞子的情况下,是同花,也有可能是变成4条 或是 三带2 它们都比同花大i := 0for _, v := range cardSizeMap {if v+joker == 4 {// 4 条cardType = 3return} else if v+joker == 3 {i++}}if i == 2 {// 3带2cardType = 4return}cardType = 5return}// 不是同花// 根据面值的map长度判断switch sizeLen {case 7: // 单牌也没有癞子// 判断是不是顺子if isShun, max := IsShunZiNoTran(card, joker); isShun {cardType = 6resCard = maxreturn}cardType = 10returncase 6: // 可能 顺子 单牌+癞子 或是 一对if isShun, max := IsShunZiNoTran(card, joker); isShun {resCard = maxcardType = 6return}// 就算有癞子也是一对, 因为癞子不放入map,map len为6 如果有癞子的话,其他牌是单牌cardType = 9returncase 5: // 顺子 3条 或是 两对// 判断是不是顺子if isShun, max := IsShunZiNoTran(card, joker); isShun {resCard = maxcardType = 6return}// 有癞子的五张牌一定是3条if joker > 0 {cardType = 7return}for _, v := range cardSizeMap {if v == 3 {// 3条cardType = 7return}}// 2对cardType = 8returncase 4: // 因为最多只有一个癞子 就可能出现4条  3带2 或是 2对(3个对子) 有癞子的话也不组顺子,因为可以组4条或是3带2比顺子大i := 0j := 0for _, v := range cardSizeMap {if v+joker == 4 {// 4条cardType = 3return} else if v+joker == 3 {//  有可能是本来有两对再加一个癞子i++} else if v == 2 {j++}}if j < 2 {cardType = 4return}// 这里的j=3,也就是三对并且没有癞子的cardType = 8returncase 3: // 不是3带2 就是4条了for _, v := range cardSizeMap {if v+joker == 4 {cardType = 3return}}cardType = 4returncase 2: // 只能是4条cardType = 3return}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) {// 存放单牌的slicecardSizeSlice1 := make([]byte, len(sevenJoker.cardSizeMap1))cardSizeSlice2 := make([]byte, len(sevenJoker.cardSizeMap2))// 存放4条的面值var four1 bytevar four2 bytei := 0for k, v := range sevenJoker.cardSizeMap1 {k = fire.SizeTranByte(k)if v+sevenJoker.joker1 == 4 {if four1 < k {four1 = k}} else {cardSizeSlice1[i] = ki++}}i = 0for k, v := range sevenJoker.cardSizeMap2 {k = fire.SizeTranByte(k)if v+sevenJoker.joker2 == 4 {if four2 < k {four2 = k}} else {cardSizeSlice2[i] = ki++}}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条的slicethrees1 := make([]byte, 3)threes2 := make([]byte, 3)// 存放对子的slicetwos1 := make([]byte, 3)twos2 := make([]byte, 3)i := 0j := 0for k, v := range sevenJoker.cardSizeMap1 {k = fire.SizeTranByte(k)if v+sevenJoker.joker1 == 3 {threes1[i] = ki++} else if v == 2 {twos1[j] = kj++}}i = 0j = 0for k, v := range sevenJoker.cardSizeMap2 {k = fire.SizeTranByte(k)if v+sevenJoker.joker2 == 3 {threes2[i] = ki++} else if v == 2 {twos2[j] = kj++}}// 对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) {// 存放单牌的slicecardSizeSlice1 := make([]byte, len(sevenJoker.cardSizeMap1))cardSizeSlice2 := make([]byte, len(sevenJoker.cardSizeMap2))// 存放3条的面值var three1 bytevar three2 bytei := 0for k, v := range sevenJoker.cardSizeMap1 {k = fire.SizeTranByte(k)if v+sevenJoker.joker1 == 3 {three1 = k} else {cardSizeSlice1[i] = ki++}}i = 0for k, v := range sevenJoker.cardSizeMap2 {k = fire.SizeTranByte(k)if v+sevenJoker.joker2 == 3 {three2 = k} else {cardSizeSlice2[i] = ki++}}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) {// 记录对子的slicepairs1 := make([]byte, 3)pairs2 := make([]byte, 3)// 记录单牌的slicevals1 := make([]byte, 3)vals2 := make([]byte, 3)j := 0i := 0for k, v := range sevenJoker.cardSizeMap1 {k = fire.SizeTranByte(k)if v+sevenJoker.joker1 == 2 {pairs1[i] = ki++} else {vals1[j] = kj++}}i = 0j = 0for k, v := range sevenJoker.cardSizeMap2 {k = fire.SizeTranByte(k)if v+sevenJoker.joker2 == 2 {pairs2[i] = ki++} else {vals2[j] = kj++}}// 对 对子 逆序列排序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 bytevar val2 bytei := 0for k, v := range sevenJoker.cardSizeMap1 {k = fire.SizeTranByte(k)if v == 2 {val1 = kcontinue}cardSizeSlice1[i] = ki++}i = 0for k, v := range sevenJoker.cardSizeMap2 {k = fire.SizeTranByte(k)if v == 2 {val2 = kcontinue}cardSizeSlice2[i] = ki++}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) {// 存放单牌的slicecardSizeSlice1 := make([]byte, len(sevenJoker.cardSizeMap1))cardSizeSlice2 := make([]byte, len(sevenJoker.cardSizeMap2))i := 0for k := range sevenJoker.cardSizeMap1 {cardSizeSlice1[i] = fire.SizeTranByte(k)i++}i = 0for 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 := 0for 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带2result = 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地址

下载可以直接运行

这篇关于德州扑克比较大小的go语言暴力实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/400681

相关文章

百度/小米/滴滴/京东,中台架构比较

小米中台建设实践 01 小米的三大中台建设:业务+数据+技术 业务中台--从业务说起 在中台建设中,需要规范化的服务接口、一致整合化的数据、容器化的技术组件以及弹性的基础设施。并结合业务情况,判定是否真的需要中台。 小米参考了业界优秀的案例包括移动中台、数据中台、业务中台、技术中台等,再结合其业务发展历程及业务现状,整理了中台架构的核心方法论,一是企业如何共享服务,二是如何为业务提供便利。

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略 1. 特权模式限制2. 宿主机资源隔离3. 用户和组管理4. 权限提升控制5. SELinux配置 💖The Begin💖点点关注,收藏不迷路💖 Kubernetes的PodSecurityPolicy(PSP)是一个关键的安全特性,它在Pod创建之前实施安全策略,确保P