Add support for up to 6 players.
This commit is contained in:
+21
-10
@@ -19,27 +19,35 @@ type ctx struct {
|
||||
}
|
||||
|
||||
func newCtx(v *game.View, m *Memory) *ctx {
|
||||
cx := &ctx{v: v, m: m, me: &v.Players[v.YouSeat], oppSeat: m.Opp.Seat, pools: map[int][]game.Card{}}
|
||||
cx := &ctx{v: v, m: m, me: v.PlayerView(v.YouSeat), oppSeat: v.YourOpponent, pools: map[int][]game.Card{}}
|
||||
// The round's pairing says exactly who the bot is preparing for, so it
|
||||
// plans against that one rival even at a six-player table. Falling back to
|
||||
// any other seat keeps a malformed view from wedging the bot.
|
||||
if cx.oppSeat == cx.me.Seat || cx.oppSeat < 0 {
|
||||
// Memory hasn't observed yet (shouldn't happen in practice).
|
||||
for _, p := range v.Players {
|
||||
if p.Seat != v.YouSeat {
|
||||
cx.oppSeat = p.Seat
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return cx
|
||||
}
|
||||
|
||||
// opp is the model of the opponent this round's battle is against.
|
||||
func (cx *ctx) opp() *OppModel { return cx.m.Opp(cx.oppSeat) }
|
||||
|
||||
func (cx *ctx) nextSimID() string {
|
||||
cx.simID++
|
||||
return fmt.Sprintf("sim-%d", cx.simID)
|
||||
}
|
||||
|
||||
// unseenPool lists the printed cards of a tier that the bot cannot account
|
||||
// for anywhere it can see — its own deck, the opponent model, the shop row.
|
||||
// for anywhere it can see — its own deck, every opponent model, the shop row.
|
||||
// Hidden opponent cards are drawn from this pool, so the bot's guesses
|
||||
// respect card counting without peeking at the real decks.
|
||||
// respect card counting without peeking at the real decks. It counts against
|
||||
// the whole table's known cards, and against the combined contents of every
|
||||
// pack in play, which is what a human counting cards would be working from.
|
||||
func (cx *ctx) unseenPool(tier int) []game.Card {
|
||||
if pool, ok := cx.pools[tier]; ok {
|
||||
return pool
|
||||
@@ -53,14 +61,16 @@ func (cx *ctx) unseenPool(tier int) []game.Card {
|
||||
for _, c := range cx.me.Deck {
|
||||
note(c)
|
||||
}
|
||||
for _, c := range cx.m.Opp.Known {
|
||||
note(c)
|
||||
for _, opp := range cx.m.Opps {
|
||||
for _, c := range opp.Known {
|
||||
note(c)
|
||||
}
|
||||
}
|
||||
for _, c := range cx.v.ShopRow {
|
||||
note(c)
|
||||
}
|
||||
var pool []game.Card
|
||||
for _, c := range game.TierContentsForPack(cx.v.Pack, tier) {
|
||||
for _, c := range game.TierContentsForPacks(cx.v.Packs, tier) {
|
||||
if seen[c.Name] > 0 {
|
||||
seen[c.Name]--
|
||||
continue
|
||||
@@ -75,10 +85,11 @@ func (cx *ctx) unseenPool(tier int) []game.Card {
|
||||
// known cards as-is, hidden cards drawn from the unseen pool of their tier
|
||||
// (or their named template, when a pick was later revealed).
|
||||
func (cx *ctx) sampleOppDeck() []game.Card {
|
||||
deck := append([]game.Card(nil), cx.m.Opp.Known...)
|
||||
for _, h := range cx.m.Opp.Hidden {
|
||||
opp := cx.opp()
|
||||
deck := append([]game.Card(nil), opp.Known...)
|
||||
for _, h := range opp.Hidden {
|
||||
var c game.Card
|
||||
if t, ok := templateByName(cx.v.Pack, h.Name); ok {
|
||||
if t, ok := templateByName(cx.v.Packs, h.Name); ok {
|
||||
c = t
|
||||
} else if pool := cx.unseenPool(h.Tier); len(pool) > 0 {
|
||||
c = pool[rand.IntN(len(pool))]
|
||||
|
||||
Reference in New Issue
Block a user