142 lines
2.6 KiB
Go
Raw Permalink Normal View History

2025-06-04 09:51:39 +08:00
package poker
import (
"samba/pkg/log"
"samba/util/util"
)
// AllocAct 配牌行为
type AllocAct int
const (
// AllocBad 配差牌
AllocBad = AllocAct(iota) - 1
// AllocNormal 普通配牌
AllocNormal
// AllocGood 配好牌
AllocGood
)
func (a AllocAct) String() string {
switch a {
case AllocBad:
return "配差牌"
case AllocNormal:
return "普通配牌"
case AllocGood:
return "配好牌"
default:
return "unknown"
}
}
const (
// 每一点幸运值对应的概率
pAsLuckyPoint = 1
)
// AllocActByLuckyPoint 根据幸运点数返回配牌行为
func AllocActByLuckyPoint(lucky int) AllocAct {
if lucky > 0 {
return util.Tie(util.RandHappened(lucky*pAsLuckyPoint), AllocGood, AllocNormal)
}
if lucky < 0 {
return util.Tie(util.RandHappened((-lucky)*pAsLuckyPoint), AllocBad, AllocNormal)
}
return AllocNormal
}
// Allocator 幸运值配牌器
type Allocator struct {
pks []*Poker
idx int
goodPksIdx []int
badPksIdx []int
}
func (a *Allocator) Init(pkg IPokerGenerator, pokers []*Poker) {
a.pks = make([]*Poker, len(pokers))
for idx, poker := range pokers {
switch {
case pkg.IsGoodPoker(poker):
a.goodPksIdx = append(a.goodPksIdx, idx)
case pkg.IsBadPoker(poker):
a.badPksIdx = append(a.badPksIdx, idx)
}
a.pks[idx] = poker
}
}
// Alloc 根据行为配牌
// act AllocAct 为配牌行为
// num int 为期望的配牌数量
// 若好牌、差牌的牌池为空也就是说被其他玩家配牌则会进行普通配牌此时ok返回false
// 只要有一张牌符合了配牌条件则ok为true
func (a *Allocator) Alloc(act AllocAct, num int) (pks []*Poker, ok bool) {
pks = make([]*Poker, num)
for i := 0; i < num; i++ {
var pok bool
switch act {
case AllocGood:
pks[i], pok = a.popGoodPoker()
case AllocBad:
pks[i], pok = a.popBadPoker()
case AllocNormal:
pks[i] = a.popPoker()
pok = true
}
ok = ok || pok
}
return pks, ok
}
func (a *Allocator) popGoodPoker() (*Poker, bool) {
for {
if len(a.goodPksIdx) <= 0 {
return a.popPoker(), false
}
idx := a.goodPksIdx[0]
pk := a.pks[idx]
a.pks[idx] = nil
a.goodPksIdx = a.goodPksIdx[1:]
if pk != nil {
return pk, true
}
}
}
func (a *Allocator) popBadPoker() (*Poker, bool) {
for {
if len(a.badPksIdx) <= 0 {
return a.popPoker(), false
}
idx := a.badPksIdx[0]
pk := a.pks[idx]
a.pks[idx] = nil
a.badPksIdx = a.badPksIdx[1:]
if pk != nil {
return pk, true
}
}
}
func (a *Allocator) popPoker() *Poker {
for {
if a.idx >= len(a.pks) {
log.Error("pokers is nil")
return nil
}
idx := a.idx
a.idx++
pk := a.pks[idx]
if pk != nil {
a.pks[idx] = nil
return pk
}
}
}