213 lines
5.5 KiB
Go
213 lines
5.5 KiB
Go
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
|
||
}
|
||
}
|
||
}
|