package poker import ( "math/rand" "samba/util/util" ) const ( HandlerPokerCount = 9 // 每个玩家的手牌数量 ) // Cacheta type CachetaPokers struct { allPokers []*Poker // 洗牌时用 pokers []*Poker // 发牌 cutPoker *Poker // 切牌 wildPoker *Poker // 万能牌 wildPoker2 *Poker gmPokers []*Poker // gm配牌 gmCutPoker *Poker } func NewCachetaPokers() *CachetaPokers { pokers := &CachetaPokers{ allPokers: make([]*Poker, 0), pokers: make([]*Poker, 0), } for point := PointA; point <= PointK; point++ { pokers.allPokers = append(pokers.allPokers, NewPokerEx(Spade, point, Ext1)) pokers.allPokers = append(pokers.allPokers, NewPokerEx(Heart, point, Ext1)) pokers.allPokers = append(pokers.allPokers, NewPokerEx(Club, point, Ext1)) pokers.allPokers = append(pokers.allPokers, NewPokerEx(Diamond, point, Ext1)) } for point := PointA; point <= PointK; point++ { pokers.allPokers = append(pokers.allPokers, NewPokerEx(Spade, point, Ext2)) pokers.allPokers = append(pokers.allPokers, NewPokerEx(Heart, point, Ext2)) pokers.allPokers = append(pokers.allPokers, NewPokerEx(Club, point, Ext2)) pokers.allPokers = append(pokers.allPokers, NewPokerEx(Diamond, point, Ext2)) } return pokers } func (p *CachetaPokers) Pokers() []*Poker { return p.pokers } func (p *CachetaPokers) CutPoker() *Poker { return p.cutPoker } // 是否万能牌 func (p *CachetaPokers) IsWildPoker(pk *Poker) bool { return p.wildPoker.ToValue() == pk.ToValue() } func (p *CachetaPokers) WildPokers() []*Poker { if p.wildPoker == nil { return nil } return []*Poker{p.wildPoker, p.wildPoker2} } func (p *CachetaPokers) WildPoker() *Poker { return p.wildPoker } // 同花 1:必须是三种花色 2:除万能牌之外,不能出现点数不同 3.万能牌只能有一张或全是万能牌 4.所有牌都是万能牌,花色至少有两种 func (p *CachetaPokers) isKind(pks ...*Poker) bool { wildCnt := 0 // 万能牌数量 diffColor := []int{0, 0, 0, 0, 0} // 多少种花色 colorCnt := 0 point := PointUnknown for _, pk := range pks { diffColor[pk.Color] = 1 // 除万能牌之外,不能出现点数不同 if p.IsWildPoker(pk) { wildCnt++ } else { if point == PointUnknown { point = pk.Point } if pk.Point != point { return false } } } for _, c := range diffColor { colorCnt += c } // 没有万能牌 if wildCnt == 0 { // 只能出现三个花色 return colorCnt == 3 } else if wildCnt == 1 { return colorCnt == 2 || colorCnt == 3 } else { // 1个以上的万能牌,只能所有牌都是万能牌 if wildCnt != len(pks) { return false } else { // 所有牌都是万能牌,且花色至少有两种 return colorCnt >= 2 } } } // 洗牌 func (p *CachetaPokers) Shuffle() { if !p.gmShuffle() { p.randShuffle() } } func (p *CachetaPokers) randShuffle() { rand.Shuffle(len(p.allPokers), func(i, j int) { p.allPokers[i], p.allPokers[j] = p.allPokers[j], p.allPokers[i] }) p.pokers = p.pokers[0:0] for _, poker := range p.allPokers { p.pokers = append(p.pokers, poker) } p.cutPoker = p.pokers[len(p.pokers)-1] p.pokers = p.pokers[:len(p.pokers)-1] point := util.Tie(p.cutPoker.Point == PointK, PointA, p.cutPoker.Point+1) color := util.Tie(p.cutPoker.Color == Spade || p.cutPoker.Color == Club, Spade, Diamond) p.wildPoker = NewPokerEx(color, point, Ext1) color2 := util.Tie(p.cutPoker.Color == Spade || p.cutPoker.Color == Club, Club, Heart) p.wildPoker2 = NewPokerEx(color2, point, Ext1) } func (p *CachetaPokers) gmShuffle() bool { if len(p.gmPokers) == 0 { return false } p.cutPoker = p.gmCutPoker point := util.Tie(p.cutPoker.Point == PointK, PointA, p.cutPoker.Point+1) color := util.Tie(p.cutPoker.Color == Spade || p.cutPoker.Color == Club, Spade, Diamond) p.wildPoker = NewPokerEx(color, point, Ext1) color2 := util.Tie(p.cutPoker.Color == Spade || p.cutPoker.Color == Club, Club, Heart) p.wildPoker2 = NewPokerEx(color2, point, Ext1) p.pokers = p.gmPokers for i, pk := range p.pokers { if pk.ToInt() == p.gmCutPoker.ToInt() { p.pokers = append(p.pokers[:i], p.pokers[i+1:]...) break } } return true } func (p *CachetaPokers) SetGmPoker(gmPokers [][]int, ghostPoker int, seat int) { if len(gmPokers) == 0 { p.gmCutPoker = nil p.gmPokers = nil return } p.gmCutPoker = NewPoker(ghostPoker) p.gmPokers = make([]*Poker, 0) sets := make([]*Poker, 0) // 补集 for _, pk := range p.allPokers { exist := false for _, gmPks := range gmPokers { for _, pkInt := range gmPks { if pk.ToInt() == pkInt { exist = true } } } if !exist { sets = append(sets, pk) } } step := 0 for i := 0; i < len(gmPokers); i++ { pokers := gmPokers[(len(gmPokers)-seat+i)%len(gmPokers)] pks := make([]*Poker, 0) for _, pok := range pokers { pk := NewPoker(pok) if len(pks) >= HandlerPokerCount { break } if pk.Point == p.cutPoker.Point && pk.Color == p.cutPoker.Color { pks = append(pks, sets[step]) step++ } else { pks = append(pks, pk) } } if len(pks) < HandlerPokerCount { for i := len(pks); i < HandlerPokerCount; i++ { pks = append(pks, sets[step]) step++ } } p.gmPokers = append(p.gmPokers, pks...) } for ; step < len(sets); step++ { p.gmPokers = append(p.gmPokers, sets[step]) } for i := 0; i < len(p.gmPokers); i++ { if p.gmPokers[i].ToInt() == p.cutPoker.ToInt() { p.gmPokers = append(p.gmPokers[:i], p.gmPokers[i+1:]...) p.gmPokers = append(p.gmPokers, p.cutPoker) break } } }