Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion automatic/automatic_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func (r *GameRunner) CompVsCompStatic(addToHistory bool) error {

func (r *GameRunner) playFull(addToHistory bool, gidx int) error {
r.StartGame(gidx)
log.Trace().Msgf("playing full, game %v", r.game.History().Uid)
log.Trace().Msgf("playing full, game %v", r.game.Uid())

for r.game.Playing() == pb.PlayState_PLAYING {
err := r.PlayBestTurn(r.game.PlayerOnTurn(), addToHistory)
Expand Down
5 changes: 3 additions & 2 deletions automatic/logfile_analysis.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,8 @@ func ExportGCG(cfg *config.Config, filename, letterdist, lexicon, boardlayout, g

for _, row := range gameLines {
pidx := 0
if g.History().Players[1].Nickname == row[0] {
history := g.GenerateSerializableHistory()
if history.Players[1].Nickname == row[0] {
pidx = 1
}
err = g.SetRackFor(pidx, tilemapping.RackFromString(row[3], g.Alphabet()))
Expand Down Expand Up @@ -270,7 +271,7 @@ func ExportGCG(cfg *config.Config, filename, letterdist, lexicon, boardlayout, g
}
}
}
contents, err := gcgio.GameHistoryToGCG(g.History(), true)
contents, err := gcgio.GameToGCG(g.Game, true)
if err != nil {
return err
}
Expand Down
16 changes: 10 additions & 6 deletions bot/bot.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,16 +118,18 @@ func (bot *Bot) Deserialize(data []byte) (*game.Game, *pb.BotRequest, error) {
if err != nil {
return nil, nil, err
}
ng.PlayToTurn(nturns)
ngHistory := ng.GenerateSerializableHistory()
ng.PlayToTurn(nturns, ngHistory.LastKnownRacks)
// debugWriteln(ng.ToDisplayText())
return ng, req, nil
}

func evalSingleMove(g *bot.BotTurnPlayer, evtIdx int) *pb.SingleEvaluation {
evts := g.History().Events
history := g.GenerateSerializableHistory()
evts := history.Events
playedEvt := evts[evtIdx]

g.PlayToTurn(evtIdx)
g.PlayToTurn(evtIdx, history.LastKnownRacks)
moves := g.GenerateMoves(100000)
// find the played move in the list of moves
topEquity := moves[0].Equity()
Expand Down Expand Up @@ -170,8 +172,9 @@ func evalSingleMove(g *bot.BotTurnPlayer, evtIdx int) *pb.SingleEvaluation {

func (bot *Bot) evaluationResponse(req *pb.EvaluationRequest) *pb.BotResponse {

evts := bot.game.History().Events
players := bot.game.History().Players
history := bot.game.GenerateSerializableHistory()
evts := history.Events
players := history.Players
evals := []*pb.SingleEvaluation{}

for idx, evt := range evts {
Expand Down Expand Up @@ -200,7 +203,8 @@ func (b *Bot) handle(data []byte) *pb.BotResponse {
botType := req.BotType

leavesFile := ""
if ng.History().BoardLayout == board.SuperCrosswordGameLayout {
history := ng.GenerateSerializableHistory()
if history.BoardLayout == board.SuperCrosswordGameLayout {
leavesFile = "super-leaves.klv2"
}

Expand Down
2 changes: 1 addition & 1 deletion bot/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type Client struct {
}

func MakeRequest(game *bot.BotTurnPlayer, cfg *config.Config) ([]byte, error) {
history := game.History()
history := game.GenerateSerializableHistory()
if history.Lexicon == "" {
history.Lexicon = cfg.GetString(config.ConfigDefaultLexicon)
}
Expand Down
6 changes: 3 additions & 3 deletions cgp/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,9 @@ func ParseCGP(cfg *config.Config, cgpstr string) (*ParsedCGP, error) {
}
g.SetMaxScorelessTurns(maxScorelessTurns)
g.SetScorelessTurns(nzero)
g.History().StartingCgp = cgpstr
g.History().Uid = gid
g.History().IdAuth = "" // maybe provide this later, id
g.SetStartingCGP(cgpstr)
g.SetUid(gid)
g.SetIdAuth("") // maybe provide this later, id

log.Debug().Msgf("got gid %v", gid)
return &ParsedCGP{Game: g, Opcodes: opcodes}, nil
Expand Down
12 changes: 4 additions & 8 deletions cmd/eval/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,31 +146,27 @@
}

func getEquityLoss(filepath string, lexicon string, playerName string, gameid int, eqlossData *EqlossData) (float64, error) {
rules, err := game.NewBasicGameRules(DefaultConfig, lexicon, board.CrosswordGameLayout, "english", game.CrossScoreAndSet, game.VarClassic)

Check failure on line 149 in cmd/eval/main.go

View workflow job for this annotation

GitHub Actions / build

declared and not used: rules
if err != nil {
panic(err)
}

gameHistory, err := gcgio.ParseGCG(DefaultConfig, filepath)
g, err := gcgio.ParseGCG(DefaultConfig, filepath)
if err != nil {
panic(err)
}
gameHistory := g.GenerateSerializableHistory()
p1Nickname := gameHistory.Players[0].Nickname
p2Nickname := gameHistory.Players[1].Nickname
if playerName != p1Nickname && playerName != p2Nickname {
panic(fmt.Sprintf("player %s not found in (%s, %s) for game %d", playerName, p1Nickname, p2Nickname, gameid))
}

gameHistory.ChallengeRule = pb.ChallengeRule_FIVE_POINT

g, err := game.NewFromHistory(gameHistory, rules, 0)
if err != nil {
panic(err)
}
g.SetChallengeRule(pb.ChallengeRule_FIVE_POINT)

totalEqloss := 0.0
numMoves := 0
history := g.History()
history := g.GenerateSerializableHistory()
players := history.Players
botConfig := &bot.BotConfig{Config: *DefaultConfig}
for evtIdx, evt := range history.Events {
Expand All @@ -178,7 +174,7 @@
(evt.Type == pb.GameEvent_TILE_PLACEMENT_MOVE ||
evt.Type == pb.GameEvent_EXCHANGE ||
evt.Type == pb.GameEvent_PASS) {
err := g.PlayToTurn(evtIdx)

Check failure on line 177 in cmd/eval/main.go

View workflow job for this annotation

GitHub Actions / build

not enough arguments in call to g.PlayToTurn
if err != nil {
panic(err)
}
Expand Down
3 changes: 2 additions & 1 deletion cmd/lambda/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ func HandleRequest(ctx context.Context, evt bot.LambdaEvent) (string, error) {
ctx, cancel = context.WithTimeout(ctx, time.Duration(maxTimeShouldTake)*time.Second)
ctx = logger.WithContext(ctx)

lexicon := g.History().Lexicon
history := g.GenerateSerializableHistory()
lexicon := history.Lexicon
if lexicon == "" {
lexicon = cfg.GetString(config.ConfigDefaultLexicon)
logger.Info().Msgf("cgp file had no lexicon, so using default lexicon %v",
Expand Down
16 changes: 11 additions & 5 deletions endgame/negamax/solver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,13 @@ func setUpSolver(lex, distName string, bvs board.VsWho, plies int, rack1, rack2
}
cross_set.GenAllCrossSets(g.Board(), gd, dist)

g.SetRacksForBoth([]*tilemapping.Rack{
err = g.SetRacksForBoth([]*tilemapping.Rack{
tilemapping.RackFromString(rack1, alph),
tilemapping.RackFromString(rack2, alph),
})
if err != nil {
panic(err)
}
g.SetPointsFor(0, p1pts)
g.SetPointsFor(1, p2pts)
g.SetPlayerOnTurn(onTurn)
Expand Down Expand Up @@ -288,9 +291,10 @@ func TestPolishFromGcg(t *testing.T) {
cfg.Set(config.ConfigDefaultLexicon, "OSPS49")
cfg.Set(config.ConfigDefaultLetterDistribution, "polish")

gameHistory, err := gcgio.ParseGCG(cfg, "../../gcgio/testdata/polish_endgame.gcg")
parsedGame, err := gcgio.ParseGCG(cfg, "../../gcgio/testdata/polish_endgame.gcg")
is.NoErr(err)
gameHistory.ChallengeRule = pb.ChallengeRule_SINGLE
parsedGame.SetChallengeRule(pb.ChallengeRule_SINGLE)
gameHistory := parsedGame.GenerateSerializableHistory()

g, err := game.NewFromHistory(gameHistory, rules, 46)
is.NoErr(err)
Expand Down Expand Up @@ -357,8 +361,9 @@ func TestProperIterativeDeepening(t *testing.T) {
is.NoErr(err)
for _, plies := range plyCount {

gameHistory, err := gcgio.ParseGCG(DefaultConfig, "../../gcgio/testdata/noah_vs_mishu.gcg")
parsedGame, err := gcgio.ParseGCG(DefaultConfig, "../../gcgio/testdata/noah_vs_mishu.gcg")
is.NoErr(err)
gameHistory := parsedGame.GenerateSerializableHistory()

g, err := game.NewFromHistory(gameHistory, rules, 28)
is.NoErr(err)
Expand Down Expand Up @@ -401,8 +406,9 @@ func TestFromGCG(t *testing.T) {
rules, err := game.NewBasicGameRules(DefaultConfig, "CSW19", board.CrosswordGameLayout, "English", game.CrossScoreAndSet, game.VarClassic)
is.NoErr(err)

gameHistory, err := gcgio.ParseGCG(DefaultConfig, "../../gcgio/testdata/vs_frentz.gcg")
parsedGame, err := gcgio.ParseGCG(DefaultConfig, "../../gcgio/testdata/vs_frentz.gcg")
is.NoErr(err)
gameHistory := parsedGame.GenerateSerializableHistory()

g, err := game.NewFromHistory(gameHistory, rules, 22)
is.NoErr(err)
Expand Down
55 changes: 30 additions & 25 deletions game/challenge.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ var (
// must already be started with StartGame above (call immediately afterwards).
// It would default to the 0 state (VOID) otherwise.
func (g *Game) SetChallengeRule(rule pb.ChallengeRule) {
g.history.ChallengeRule = rule
g.challengeRule = rule
}

// ChallengeEvent should only be called if there is a history of events.
Expand All @@ -30,10 +30,10 @@ func (g *Game) SetChallengeRule(rule pb.ChallengeRule) {
// out with a phony).
// Return playLegal, error
func (g *Game) ChallengeEvent(addlBonus int, millis int) (bool, error) {
if len(g.history.Events) == 0 {
if len(g.events) == 0 {
return false, errors.New("this game has no history")
}
if g.history.ChallengeRule == pb.ChallengeRule_VOID {
if g.challengeRule == pb.ChallengeRule_VOID {
return false, errors.New("challenges are not valid in void")
}
if len(g.lastWordsFormed) == 0 {
Expand All @@ -44,7 +44,7 @@ func (g *Game) ChallengeEvent(addlBonus int, millis int) (bool, error) {
illegalWords := validateWords(g.lexicon, g.lastWordsFormed, g.rules.Variant())
playLegal := len(illegalWords) == 0

lastEvent := g.history.Events[g.turnnum-1]
lastEvent := g.events[g.turnnum-1]
log.Info().Interface("lastEvent", lastEvent).Msg("in challenge event")
cumeScoreBeforeChallenge := lastEvent.Cumulative

Expand All @@ -65,7 +65,7 @@ func (g *Game) ChallengeEvent(addlBonus int, millis int) (bool, error) {
var err error
// This ideal system makes it so someone always loses
// the game.
if g.history.ChallengeRule == pb.ChallengeRule_TRIPLE {
if g.challengeRule == pb.ChallengeRule_TRIPLE {
// Set the winner and loser before calling PlayMove, as
// that changes who is on turn
var winner int32
Expand All @@ -78,21 +78,20 @@ func (g *Game) ChallengeEvent(addlBonus int, millis int) (bool, error) {
// Take the play off the board.
g.addEventToHistory(offBoardEvent)
g.UnplayLastMove()
g.history.LastKnownRacks[challengee] = lastEvent.Rack
// Note: rack will be restored from lastEvent.Rack later
}
g.history.Winner = winner
g.winner = winner

// Don't call AddFinalScoresToHistory, this will
// overwrite the correct winner
g.playing = pb.PlayState_GAME_OVER
g.history.PlayState = g.playing

// This is the only case where the winner needs to be determined
// independently from the score, so we copy just these lines from
// AddFinalScoresToHistory.
g.history.FinalScores = make([]int32, len(g.players))
g.finalScores = make([]int32, len(g.players))
for pidx, p := range g.players {
g.history.FinalScores[pidx] = int32(p.points)
g.finalScores[pidx] = int32(p.points)
}

} else if !playLegal {
Expand All @@ -104,18 +103,25 @@ func (g *Game) ChallengeEvent(addlBonus int, millis int) (bool, error) {
// Unplay the last move to restore everything as it was board-wise
// (and un-end the game if it had ended)
g.UnplayLastMove()
g.history.PlayState = g.playing

// We must also set the last known rack of the challengee back to
// their rack before they played the phony.
g.history.LastKnownRacks[challengee] = lastEvent.Rack
// Explicitly set racks for both players. This prevents a bug where
// part of the game may have been loaded from a GameHistory (through the
// PlayGameToTurn flow) and the racks continually get reset.
err = g.SetRacksForBoth([]*tilemapping.Rack{
tilemapping.RackFromString(g.history.LastKnownRacks[0], g.alph),
tilemapping.RackFromString(g.history.LastKnownRacks[1], g.alph),
})

// We must restore the challengee's rack to what it was before the phony.
// First get the current rack for the player who didn't play the phony
challengerRack := g.RackLettersFor(g.onturn)

// Build the racks array with the challengee's rack from before the phony
var racksToSet []*tilemapping.Rack
if challengee == 0 {
racksToSet = []*tilemapping.Rack{
tilemapping.RackFromString(lastEvent.Rack, g.alph),
tilemapping.RackFromString(challengerRack, g.alph),
}
} else {
racksToSet = []*tilemapping.Rack{
tilemapping.RackFromString(challengerRack, g.alph),
tilemapping.RackFromString(lastEvent.Rack, g.alph),
}
}
err = g.SetRacksForBoth(racksToSet)
if err != nil {
return playLegal, err
}
Expand Down Expand Up @@ -152,7 +158,7 @@ func (g *Game) ChallengeEvent(addlBonus int, millis int) (bool, error) {
}
}

switch g.history.ChallengeRule {
switch g.challengeRule {
case pb.ChallengeRule_DOUBLE:
// This "draconian" American system makes it so someone always loses
// their turn.
Expand Down Expand Up @@ -186,7 +192,6 @@ func (g *Game) ChallengeEvent(addlBonus int, millis int) (bool, error) {

if g.playing == pb.PlayState_WAITING_FOR_FINAL_PASS {
g.playing = pb.PlayState_GAME_OVER
g.history.PlayState = g.playing
// Game is actually over now, after the failed challenge.
// do calculations with the player on turn being the player who
// didn't challenge, as this is a special event where the turn
Expand All @@ -199,7 +204,7 @@ func (g *Game) ChallengeEvent(addlBonus int, millis int) (bool, error) {

// Finally set the last words formed to nil.
g.lastWordsFormed = nil
g.turnnum = len(g.history.Events)
g.turnnum = len(g.events)
return playLegal, err
}

Expand Down
Loading
Loading