213 lines
5.5 KiB
Go
Raw Permalink Normal View History

2025-06-04 09:51:39 +08:00
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
}
}
}