Add support for up to 6 players.

This commit is contained in:
Greyson Parrelli
2026-07-28 07:36:09 -04:00
parent e542118175
commit a4f5f6910d
38 changed files with 2306 additions and 713 deletions
+22 -9
View File
@@ -36,9 +36,11 @@ func winScore(res *game.BattleResult, mySeat int) float64 {
default:
base = 0
}
// Survivors is indexed by battle side, not by seat.
mySide := res.Side(mySeat)
margin := 0
for seat, s := range res.Survivors {
if seat == mySeat {
for side, s := range res.Survivors {
if side == mySide {
margin += s
} else {
margin -= s
@@ -58,19 +60,30 @@ func (cx *ctx) winProb(myDeck []game.Card, oppDecks [][]game.Card, simsPer int)
total, n := 0.0, 0
for _, opp := range oppDecks {
for range simsPer {
var res *game.BattleResult
if cx.me.Seat == 0 {
res = game.SimulateBattle(cx.v.Round, cx.v.PrioritySeat, myDeck, opp, nil)
} else {
res = game.SimulateBattle(cx.v.Round, cx.v.PrioritySeat, opp, myDeck, nil)
}
total += winScore(res, cx.me.Seat)
// The bot's own deck always takes scratch seat 0, so a rollout reads
// the same however the real table happens to be seated.
res := game.SimulateBattle(cx.v.Round, cx.simFirstSeat(), myDeck, opp, nil)
total += winScore(res, 0)
n++
}
}
return total / float64(n)
}
// simFirstSeat picks who acts first in a rollout, with the bot at seat 0. Two
// players pass a priority token the bot can see, so it plans against the real
// one; bigger tables flip a coin for each battle, which the bot can't know in
// advance — it rolls too, and averages over both possibilities.
func (cx *ctx) simFirstSeat() int {
if len(cx.v.Players) == 2 {
if cx.v.PrioritySeat == cx.me.Seat {
return 0
}
return 1
}
return rand.IntN(2)
}
// keepValue ranks a single card's worth to the bot's future: what it loses
// by selling or trading it away. Temporary cards (apples) are nearly free to
// lose — they vanish after the next battle anyway.