package tienlen import ( "math/rand" "sort" "time" ) //牌序- 2, A, K, Q, J,10, 9, 8, 7, 6, 5, 4, 3 //红桃- 51,50,49,48,47,46,45,44,43,42,41,40,39 //方片- 38,37,36,35,34,33,32,31,30,29,28,27,26 //梅花- 25,24,23,22,21,20,19,18,17,16,15,14,13 //黑桃- 12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 const ( POKER_CNT = 52 PER_CARD_COLOR_MAX = 13 Hand_CardNum = 13 //手牌 Card_Value_2 = 12 //特殊牌值2 Player_Num_Max = 4 //桌上最大人數 HongTao2 = 51 FangPian2 = 38 MeiHua2 = 25 HeiTao2 = 12 ) // 不同牌型分值 const ( hei2 = 0 fang2 = 3 hong2 = 5 zhadan = 20 liandui5 = 21 liandui4 = 18 liandui3 = 15 shunzi8 = 15 shunzi7 = 10 shunzi6 = 5 sanzhang = 3 ) const ( yl_hei2 = 0 yl_fang2 = 3 yl_hong2 = 5 yl_zhadan = 30 yl_liandui5 = 21 yl_liandui4 = 18 yl_liandui3 = 15 yl_shunzi8 = 15 yl_shunzi7 = 10 yl_shunzi6 = 5 yl_sanzhang = 15 ) type Card int type Poker struct { buf [POKER_CNT]Card copyBuf [POKER_CNT]Card tianhuBuf [POKER_CNT]Card isTianhu bool } func (this *Poker) GetPokerBuf() [POKER_CNT]Card { return this.buf } func (this *Poker) CopyPokerBuf() { for i := 0; i < len(this.buf); i++ { this.copyBuf[i] = this.buf[i] } } func (this *Poker) UncopyPokerBuf() { for i := 0; i < len(this.copyBuf); i++ { this.buf[i] = this.copyBuf[i] this.copyBuf[i] = Card(i) } } func (this *Poker) TianhuPokerBuf() { for i := 0; i < len(this.buf); i++ { this.tianhuBuf[i] = this.buf[i] } this.isTianhu = true } func (this *Poker) UnTianhuPokerBuf() { for i := 0; i < len(this.tianhuBuf); i++ { this.buf[i] = this.tianhuBuf[i] this.tianhuBuf[i] = Card(i) } this.isTianhu = false } func (this *Poker) IsTianhuPoker() bool { return this.isTianhu } func NewPoker() *Poker { p := &Poker{} p.init() return p } func (this *Poker) init() { for i := int32(0); i < POKER_CNT; i++ { this.buf[i] = Card(i) } rand.Seed(time.Now().UnixNano()) this.Shuffle() } func (this *Poker) Shuffle() { for i := int32(0); i < POKER_CNT; i++ { j := rand.Intn(int(i) + 1) this.buf[i], this.buf[j] = this.buf[j], this.buf[i] } } // GetCardsGrade 给手牌打分 func GetCardsGrade(cards []int32, yl bool) int { grade := 0 cpCards := []int32{} for _, card := range cards { if card != InvalideCard { cpCards = append(cpCards, card) grade += Value(card) + 1 // 基础分 } } if Have2FourBomb(cpCards) || Have6StraightTwin(cpCards) || Have12Straight(cpCards) { return 9999 } //找单2 for i := 0; i < len(cpCards); i++ { card := cpCards[i] switch card { case HongTao2: if yl { grade += yl_hong2 } else { grade += hong2 } cpCards = append(cpCards[:i], cpCards[i+1:]...) i-- case FangPian2: if yl { grade += yl_fang2 } else { grade += fang2 } cpCards = append(cpCards[:i], cpCards[i+1:]...) i-- case MeiHua2, HeiTao2: if yl { grade += yl_hei2 } else { grade += hei2 } cpCards = append(cpCards[:i], cpCards[i+1:]...) i-- } } // 找炸弹 if len(cpCards) >= 4 { mapBomb := make(map[int32]int) for _, card := range cpCards { mapBomb[int32(Value(card))]++ } bombValue := []int32{} for card, num := range mapBomb { if num == 4 { bombValue = append(bombValue, card) } } if len(bombValue) > 0 { findCards := []int32{} for _, card := range bombValue { for i := int32(0); i < 4; i++ { findCards = append(findCards, card+(i*PER_CARD_COLOR_MAX)) cpCards = DelSliceInt32(cpCards, card+(i*PER_CARD_COLOR_MAX)) } } if yl { grade += len(bombValue) * yl_zhadan } else { grade += len(bombValue) * zhadan } } } //找五连 if len(cpCards) >= 10 { sort.Slice(cpCards, func(i, j int) bool { if cpCards[i] > cpCards[j] { return false } return true }) map5STwin := make(map[int32]int32) for _, card := range cpCards { map5STwin[int32(Value(card))]++ } Value5STwin := []int32{} for card, num := range map5STwin { if num >= 2 { Value5STwin = append(Value5STwin, card) } } sort.Slice(Value5STwin, func(i, j int) bool { if Value5STwin[i] > Value5STwin[j] { return false } return true }) if len(Value5STwin) > 0 { tmpPairs := FindOneStraightWithWidth(5, Value5STwin) if len(tmpPairs) > 0 { findCards := []int32{} for _, card := range tmpPairs { delC := 0 for i := 0; i < len(cpCards); i++ { if cpCards[i] == InvalideCard { continue } if int32(Value(cpCards[i])) == card && (delC < 2) { //删除2次 findCards = append(findCards, card) delC++ cpCards = append(cpCards[:i], cpCards[i+1:]...) i-- continue } } } if yl { grade += yl_liandui5 } else { grade += liandui5 } } } } //找四连 if len(cpCards) >= 8 { sort.Slice(cpCards, func(i, j int) bool { if cpCards[i] > cpCards[j] { return false } return true }) map4STwin := make(map[int32]int32) for _, card := range cpCards { map4STwin[int32(Value(card))]++ } Value4STwin := []int32{} for card, num := range map4STwin { if num >= 2 { Value4STwin = append(Value4STwin, card) } } sort.Slice(Value4STwin, func(i, j int) bool { if Value4STwin[i] > Value4STwin[j] { return false } return true }) if len(Value4STwin) > 0 { tmpPairs := FindOneStraightWithWidth(4, Value4STwin) if len(tmpPairs) > 0 { findCards := []int32{} for _, card := range tmpPairs { delC := 0 for i := 0; i < len(cpCards); i++ { if cpCards[i] != InvalideCard { if int32(Value(cpCards[i])) == card && (delC < 2) { //删除2次 findCards = append(findCards, card) delC++ cpCards = append(cpCards[:i], cpCards[i+1:]...) i-- continue } } } } if yl { grade += yl_liandui4 } else { grade += liandui4 } } } } //找三连 if len(cpCards) >= 6 { sort.Slice(cpCards, func(i, j int) bool { if cpCards[i] > cpCards[j] { return false } return true }) map3STwin := make(map[int32]int32) for _, card := range cpCards { map3STwin[int32(Value(card))]++ } Value3STwin := []int32{} for card, num := range map3STwin { if num >= 2 { Value3STwin = append(Value3STwin, card) } } sort.Slice(Value3STwin, func(i, j int) bool { if Value3STwin[i] > Value3STwin[j] { return false } return true }) if len(Value3STwin) > 0 { tmpPairs := FindOneStraightWithWidth(3, Value3STwin) if len(tmpPairs) > 0 { findCards := []int32{} for _, card := range tmpPairs { delC := 0 for i := 0; i < len(cpCards); i++ { if cpCards[i] == InvalideCard { continue } if int32(Value(cpCards[i])) == card && (delC < 2) { //删除2次 findCards = append(findCards, card) delC++ cpCards = append(cpCards[:i], cpCards[i+1:]...) i-- continue } } } if yl { grade += yl_liandui3 } else { grade += liandui3 } } } } //再找三连 if len(cpCards) >= 6 { sort.Slice(cpCards, func(i, j int) bool { if cpCards[i] > cpCards[j] { return false } return true }) map3STwin := make(map[int32]int32) for _, card := range cpCards { map3STwin[int32(Value(card))]++ } Value3STwin := []int32{} for card, num := range map3STwin { if num >= 2 { Value3STwin = append(Value3STwin, card) } } sort.Slice(Value3STwin, func(i, j int) bool { if Value3STwin[i] > Value3STwin[j] { return false } return true }) if len(Value3STwin) > 0 { tmpPairs := FindOneStraightWithWidth(3, Value3STwin) if len(tmpPairs) > 0 { findCards := []int32{} for _, card := range tmpPairs { delC := 0 for i := 0; i < len(cpCards); i++ { if cpCards[i] == InvalideCard { continue } if int32(Value(cpCards[i])) == card && (delC < 2) { //删除2次 findCards = append(findCards, card) delC++ cpCards = append(cpCards[:i], cpCards[i+1:]...) i-- continue } } } if yl { grade += yl_liandui3 } else { grade += liandui3 } } } } //找8顺子 if len(cpCards) >= 8 { del, tmpCards, _ := delStraight(cpCards, 8) if del { if yl { grade += yl_shunzi8 } else { grade += shunzi8 } cpCards = tmpCards } } // 找三张 if len(cpCards) >= 3 { mapTriple := make(map[int32]int) for _, card := range cpCards { mapTriple[int32(Value(card))]++ } tripleValues := []int32{} for card, num := range mapTriple { if num == 3 { tripleValues = append(tripleValues, card) } } if len(tripleValues) > 0 { findCards := []int32{} for _, value := range tripleValues { delC := 0 for i := 0; i < len(cpCards); i++ { card := cpCards[i] if card != InvalideCard { if Value(card) == int(value) && (delC < 3) { //删除3次 findCards = append(findCards, card) delC++ cpCards = append(cpCards[:i], cpCards[i+1:]...) i-- continue } } } } if yl { grade += len(tripleValues) * yl_sanzhang } else { grade += len(tripleValues) * sanzhang } } } //找7顺子 if len(cpCards) >= 7 { del, tmpCards, _ := delStraight(cpCards, 7) if del { if yl { grade += yl_shunzi7 } else { grade += shunzi7 } cpCards = tmpCards } } //找6顺子 if len(cpCards) >= 6 { del, tmpCards, _ := delStraight(cpCards, 6) if del { if yl { grade += yl_shunzi6 } else { grade += shunzi6 } cpCards = tmpCards } } //再找6顺子 if len(cpCards) >= 6 { del, tmpCards, _ := delStraight(cpCards, 6) if del { if yl { grade += yl_shunzi6 } else { grade += shunzi6 } cpCards = tmpCards } } return grade } // 发顺子(不包括2 最少3顺子) func delStraight(cards []int32, value int) (bool, []int32, []int32) { haveNeed := false needCards := []int32{} if cards == nil || len(cards) < value { return haveNeed, cards, needCards } mapStraights := make(map[int32]int32) for _, card := range cards { if card != InvalideCard && Value(card) != Card_Value_2 { mapStraights[int32(Value(card))]++ } } valueStraights := []int32{} for cardValue, _ := range mapStraights { valueStraights = append(valueStraights, cardValue) } if len(valueStraights) > 0 { sort.Slice(valueStraights, func(i, j int) bool { if valueStraights[i] > valueStraights[j] { return false } return true }) straights := FindStraightWithWidth(value, valueStraights) if len(straights) > 0 { randStraight := straights[rand.Intn(len(straights))] //随机一条顺子 for _, cardValue := range randStraight { delC := 0 for i := 0; i < len(cards); i++ { card := cards[i] if card == InvalideCard { continue } if int32(Value(card)) == cardValue && (delC < 1) { //删除1次 delC++ needCards = append(needCards, card) cards = append(cards[:i], cards[i+1:]...) i-- continue } } } haveNeed = true } } return haveNeed, cards, needCards } // 发连对(不包括2 最少2顺子) func delStraightTwin(cards []int32, value int) (bool, []int32, []int32) { haveNeed := false needCards := []int32{} if cards == nil || len(cards) < value { return haveNeed, cards, needCards } mapStraights := make(map[int32]int32) for _, card := range cards { if card != InvalideCard && Value(card) != Card_Value_2 { mapStraights[int32(Value(card))]++ } } valueStraights := []int32{} for cardValue, count := range mapStraights { if count >= 2 /*&& !common.InSliceInt32(valueStraights, cardValue)*/ { valueStraights = append(valueStraights, cardValue) } } if len(valueStraights) > 0 { sort.Slice(valueStraights, func(i, j int) bool { if valueStraights[i] > valueStraights[j] { return false } return true }) straights := FindStraightWithWidth(value, valueStraights) if len(straights) > 0 { randStraight := straights[rand.Intn(len(straights))] //随机一条顺子 for _, cardValue := range randStraight { delC := 0 for i := 0; i < len(cards); i++ { card := cards[i] if card == InvalideCard { continue } if int32(Value(card)) == cardValue && (delC < 2) { //删除2次 delC++ needCards = append(needCards, card) cards = append(cards[:i], cards[i+1:]...) i-- continue } } } haveNeed = true } } return haveNeed, cards, needCards } func SendHandCard(poker *Poker) []int { poker.Shuffle() buf := poker.GetPokerBuf() cardss := map[int][]int32{} for i, card := range buf { if int32(card) != InvalideCard { index := i / 13 cardss[index] = append(cardss[index], int32(card)) } } type gradeInfo struct { id int grade int cards []int32 } grades := []gradeInfo{} for i, card13 := range cardss { cardTmp := make([]int32, 13) copy(cardTmp, card13) grade := GetCardsGrade(cardTmp, false) gi := gradeInfo{ id: i, grade: grade, cards: card13, } grades = append(grades, gi) } sort.Slice(grades, func(i, j int) bool { return grades[i].grade > grades[j].grade }) //fmt.Println("grades: ", grades) sortGrades := []int{} for _, grade := range grades { sortGrades = append(sortGrades, grade.grade) } return sortGrades } func MinSortCards(cs []int32) { sort.Slice(cs, func(i, j int) bool { vI := Value(cs[i]) vJ := Value(cs[j]) cI := Color(cs[i]) cJ := Color(cs[j]) if vI > vJ { return false } else if vI == vJ { return cI < cJ } return true }) }