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