samba/server/truco/poker/mineiroPokerClean.go
2025-06-04 09:51:39 +08:00

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