2025-06-04 09:51:39 +08:00

213 lines
5.5 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}
}
}