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