207 lines
5.1 KiB
Go
207 lines
5.1 KiB
Go
package poker
|
|
|
|
import (
|
|
"fmt"
|
|
"math/rand"
|
|
"samba/pkg/log"
|
|
)
|
|
|
|
// 从大到小 unknow表示剩余花色
|
|
var sortMineiroCleanPoker = []*Poker{{Point: Point4, Color: Club}, {Point: Point7, Color: Heart},
|
|
{Point: PointA, Color: Spade}, {Point: Point7, Color: Diamond},
|
|
{Point: Point3, Color: Unknown}, {Point: Point2, Color: Unknown}, {Point: PointA, Color: Unknown},
|
|
{Point: PointK, Color: Unknown}, {Point: PointJ, Color: Unknown}, {Point: PointQ, Color: Unknown}}
|
|
|
|
// 所有牌
|
|
var allMineiroCleanPoker = []*Poker{{Point: Point4, Color: Club},
|
|
{Point: Point7, Color: Heart}, {Point: Point7, Color: Diamond},
|
|
{Point: Point3, Color: Spade}, {Point: Point3, Color: Heart}, {Point: Point3, Color: Club}, {Point: Point3, Color: Diamond},
|
|
{Point: Point2, Color: Spade}, {Point: Point2, Color: Heart}, {Point: Point2, Color: Club}, {Point: Point2, Color: Diamond},
|
|
{Point: PointA, Color: Spade}, {Point: PointA, Color: Heart}, {Point: PointA, Color: Club}, {Point: PointA, Color: Diamond},
|
|
{Point: PointK, Color: Spade}, {Point: PointK, Color: Heart}, {Point: PointK, Color: Club}, {Point: PointK, Color: Diamond},
|
|
{Point: PointJ, Color: Spade}, {Point: PointJ, Color: Heart}, {Point: PointJ, Color: Club}, {Point: PointJ, Color: Diamond},
|
|
{Point: PointQ, Color: Spade}, {Point: PointQ, Color: Heart}, {Point: PointQ, Color: Club}, {Point: PointQ, Color: Diamond},
|
|
}
|
|
|
|
// Mineiro脏
|
|
type MineiroCleanPokers struct {
|
|
pokers []*Poker // 发牌,去掉鬼牌的所有牌
|
|
|
|
gmPokers []*Poker // gm配牌
|
|
}
|
|
|
|
func NewMineiroCleanPokers() *MineiroCleanPokers {
|
|
pokers := &MineiroCleanPokers{
|
|
pokers: make([]*Poker, 0),
|
|
}
|
|
return pokers
|
|
}
|
|
|
|
func (p *MineiroCleanPokers) Pokers() []*Poker {
|
|
return p.pokers
|
|
}
|
|
|
|
func (p *MineiroCleanPokers) GhostPoker() *Poker {
|
|
return nil
|
|
}
|
|
|
|
func (p *MineiroCleanPokers) MaxPoint() Point {
|
|
return Point4
|
|
}
|
|
|
|
func (p *MineiroCleanPokers) GetColorValue(pk *Poker) int {
|
|
switch pk.Color {
|
|
case Spade:
|
|
return 2
|
|
case Heart:
|
|
return 3
|
|
case Club:
|
|
return 4
|
|
case Diamond:
|
|
return 1
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (p *MineiroCleanPokers) DebugSortPoker() string {
|
|
large := ""
|
|
small := ""
|
|
for i := len(sortMineiroCleanPoker) - 1; i > -1; i-- {
|
|
pk := sortMineiroCleanPoker[i]
|
|
if pk.Color == Unknown {
|
|
small += pk.Point.String() + " "
|
|
} else {
|
|
large += pk.ToString() + " "
|
|
}
|
|
}
|
|
return small + "- " + large
|
|
}
|
|
|
|
func (p *MineiroCleanPokers) findSortPos(p1 *Poker) int {
|
|
for pos, pk := range sortMineiroCleanPoker {
|
|
if pk.Point == p1.Point && (pk.Color == p1.Color || pk.Color == Unknown) {
|
|
return pos
|
|
}
|
|
}
|
|
log.Error(fmt.Sprintf("not find poker:%v in sortMineiroCleanPoker", p1.ToString()))
|
|
return 1000
|
|
}
|
|
|
|
// Cmp p1<p2:CppSmall
|
|
func (p *MineiroCleanPokers) Cmp(p1, p2 *Poker) CmpPokerPoint {
|
|
// 暗牌
|
|
if p1.IsDark || p2.IsDark {
|
|
if p1.IsDark && p2.IsDark {
|
|
return CppEqual
|
|
} else if p1.IsDark {
|
|
return CppSmall
|
|
} else {
|
|
return CppBig
|
|
}
|
|
}
|
|
|
|
pos1 := p.findSortPos(p1)
|
|
pos2 := p.findSortPos(p2)
|
|
if pos1 > pos2 {
|
|
return CppSmall
|
|
} else if pos1 == pos2 {
|
|
return CppEqual
|
|
} else {
|
|
return CppBig
|
|
}
|
|
}
|
|
|
|
// 洗牌
|
|
func (p *MineiroCleanPokers) Shuffle() {
|
|
if !p.gmShuffle() {
|
|
p.randShuffle()
|
|
}
|
|
for _, pk := range p.pokers {
|
|
pk.IsDark = false
|
|
}
|
|
}
|
|
|
|
func (p *MineiroCleanPokers) randShuffle() {
|
|
p.pokers = p.pokers[0:0]
|
|
for _, pk := range allMineiroCleanPoker {
|
|
p.pokers = append(p.pokers, pk)
|
|
}
|
|
rand.Shuffle(len(p.pokers), func(i, j int) {
|
|
p.pokers[i], p.pokers[j] = p.pokers[j], p.pokers[i]
|
|
})
|
|
}
|
|
|
|
func (p *MineiroCleanPokers) gmShuffle() bool {
|
|
if len(p.gmPokers) == 0 {
|
|
return false
|
|
}
|
|
p.pokers = p.gmPokers
|
|
return true
|
|
}
|
|
|
|
func (p *MineiroCleanPokers) IsBigPoker(pk *Poker, rank int) bool {
|
|
return p.findSortPos(pk) < rank
|
|
}
|
|
|
|
// IsGoodPoker 是否好牌
|
|
func (p *MineiroCleanPokers) IsGoodPoker(pk *Poker) bool {
|
|
// 前两张为好牌
|
|
return p.findSortPos(pk) < 2
|
|
}
|
|
|
|
// IsBadPoker 是否差牌
|
|
func (p *MineiroCleanPokers) IsBadPoker(pk *Poker) bool {
|
|
// 后两张为差牌
|
|
return p.findSortPos(pk) >= len(sortMineiroCleanPoker)-2
|
|
}
|
|
|
|
func (p *MineiroCleanPokers) SetGmPoker(gmPokers [][]int, ghostPoker int, seat int) {
|
|
_ = ghostPoker
|
|
if len(gmPokers) == 0 {
|
|
p.gmPokers = nil
|
|
return
|
|
}
|
|
|
|
p.gmPokers = make([]*Poker, 0)
|
|
|
|
sets := make([]*Poker, 0) // 补集
|
|
for _, pk := range allMineiroCleanPoker {
|
|
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) >= 3 {
|
|
break
|
|
}
|
|
pks = append(pks, pk)
|
|
}
|
|
if len(pks) < 3 {
|
|
for i := len(pks); i < 3; i++ {
|
|
pks = append(pks, sets[step])
|
|
step++
|
|
}
|
|
}
|
|
log.Debug(fmt.Sprintf("seat:%v 取第%v组牌. normalPks:%v", i%len(gmPokers), (len(gmPokers)-seat+i)%len(gmPokers), PokersToString(pks)))
|
|
p.gmPokers = append(p.gmPokers, pks...)
|
|
}
|
|
for ; step < len(sets); step++ {
|
|
p.gmPokers = append(p.gmPokers, sets[step])
|
|
}
|
|
log.Debug(fmt.Sprintf("配牌:%v", PokersToString(p.gmPokers)))
|
|
}
|