Skip to content

Commit 8cd84cc

Browse files
authored
Merge pull request #440 from blake-lowe/crossplay-layout
Support Crossplay Layout, Distribution, and Rules
2 parents fc5a39a + 28d094b commit 8cd84cc

File tree

19 files changed

+169
-52
lines changed

19 files changed

+169
-52
lines changed

ai/bot/elite.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ func endGameBest(ctx context.Context, p *BotTurnPlayer, endgamePlies int) (*move
111111
gameCopy := p.Game.Copy()
112112
gameCopy.SetBackupMode(game.SimulationMode)
113113
gameCopy.SetStateStackLength(endgamePlies + 1)
114-
gen1 := movegen.NewGordonGenerator(gd, gameCopy.Board(), p.Game.Rules().LetterDistribution())
114+
gen1 := movegen.NewGordonGenerator(gd, gameCopy.Board(), p.Game.Rules().LetterDistribution(), p.Game.Rules().BingoBonus())
115115
err = p.endgamer.Init(gen1, gameCopy)
116116
if err != nil {
117117
return nil, err

ai/turnplayer/static_player.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ func AddAIFields(p *turnplayer.BaseTurnPlayer, conf *config.Config, calculators
5757
if err != nil {
5858
return nil, err
5959
}
60-
gen := movegen.NewGordonGenerator(gd, p.Board(), p.Bag().LetterDistribution())
60+
gen := movegen.NewGordonGenerator(gd, p.Board(), p.Bag().LetterDistribution(), p.Rules().BingoBonus())
6161
gen.SetEquityCalculators(calculators)
6262
ret := &AIStaticTurnPlayer{*p, calculators, gen, conf}
6363
return ret, nil

board/board.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -844,16 +844,16 @@ func (g *GameBoard) formedCrossWord(crossVertical bool, letter tilemapping.Machi
844844
// assume the row stays static as we iterate through the letters of the
845845
// word.
846846
func (g *GameBoard) ScoreWord(word tilemapping.MachineWord, row, col, tilesPlayed int,
847-
crossDir BoardDirection, ld *tilemapping.LetterDistribution) int {
847+
crossDir BoardDirection, ld *tilemapping.LetterDistribution, bingoBonus int) int {
848848

849849
// letterScore:
850850
var ls int
851851

852852
mainWordScore := 0
853853
crossScores := 0
854-
bingoBonus := 0
854+
bonus := 0
855855
if tilesPlayed == 7 {
856-
bingoBonus = 50
856+
bonus = bingoBonus
857857
}
858858
wordMultiplier := 1
859859

@@ -904,7 +904,7 @@ func (g *GameBoard) ScoreWord(word tilemapping.MachineWord, row, col, tilesPlaye
904904
crossScores += ls*letterMultiplier*thisWordMultiplier + cs*thisWordMultiplier
905905
}
906906
}
907-
return mainWordScore*wordMultiplier + crossScores + bingoBonus
907+
return mainWordScore*wordMultiplier + crossScores + bonus
908908

909909
}
910910

board/layouts.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,15 @@ var (
77
// SuperCrosswordGameBoard is a board for a bigger Crossword game, featuring
88
// even more wingos and blonks.
99
SuperCrosswordGameBoard []string
10+
// CrossplayGameBoard is a board like Crossword but with alternate wingo blonk
11+
// arrangement.
12+
CrossplayGameBoard []string
1013
)
1114

1215
const (
1316
CrosswordGameLayout = "CrosswordGame"
1417
SuperCrosswordGameLayout = "SuperCrosswordGame"
18+
CrossplayGameLayout = "CrossplayGame"
1519
)
1620

1721
func init() {
@@ -55,4 +59,21 @@ func init() {
5559
` - " - - " - `,
5660
`~ ' = ' = ' ~`,
5761
}
62+
CrossplayGameBoard = []string{
63+
`" = ' = "`,
64+
` - " " - `,
65+
` ' ' `,
66+
`= ' - ' =`,
67+
` ' " " ' `,
68+
` " ' " `,
69+
` " " `,
70+
`' - ' ' - '`,
71+
` " " `,
72+
` " ' " `,
73+
` ' " " ' `,
74+
`= ' - ' =`,
75+
` ' ' `,
76+
` - " " - `,
77+
`" = ' = "`,
78+
}
5879
}

config/config.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ const (
4040
ConfigOpenaiApiKey = "openai-api-key"
4141
ConfigDeepseekApiKey = "deepseek-api-key"
4242
ConfigWooglesApiKey = "woogles-api-key"
43+
ConfigBingoBonus = "bingo-bonus"
4344
ConfigAliases = "aliases"
4445
)
4546

@@ -113,6 +114,7 @@ func (c *Config) Load(args []string) error {
113114
c.BindEnv(ConfigOpenaiApiKey)
114115
c.BindEnv(ConfigDeepseekApiKey)
115116
c.BindEnv(ConfigWooglesApiKey)
117+
c.BindEnv(ConfigBingoBonus)
116118

117119
cfgdir, err := os.UserConfigDir()
118120
if err != nil {
@@ -166,6 +168,7 @@ func (c *Config) Load(args []string) error {
166168
c.SetDefault(ConfigOpenaiApiKey, "")
167169
c.SetDefault(ConfigDeepseekApiKey, "")
168170
c.SetDefault(ConfigWooglesApiKey, "")
171+
c.SetDefault(ConfigBingoBonus, 50)
169172

170173
return nil
171174
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
?,3,0,0
2+
A,9,1,1
3+
B,2,4,0
4+
C,2,3,0
5+
D,4,2,0
6+
E,12,1,1
7+
F,2,4,0
8+
G,3,4,0
9+
H,3,3,0
10+
I,8,1,1
11+
J,1,10,0
12+
K,1,6,0
13+
L,4,2,0
14+
M,2,3,0
15+
N,5,1,0
16+
O,8,1,1
17+
P,2,3,0
18+
Q,1,10,0
19+
R,6,1,0
20+
S,5,1,0
21+
T,6,1,0
22+
U,3,2,1
23+
V,2,6,0
24+
W,2,5,0
25+
X,1,8,0
26+
Y,2,4,0
27+
Z,1,10,0

endgame/negamax/solver.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ func (s *Solver) makeGameCopies() error {
360360
s.movegens = []movegen.MoveGenerator{}
361361
gaddag := s.stmMovegen.(*movegen.GordonGenerator).GADDAG()
362362
for i := 0; i < s.threads-1; i++ {
363-
mg := movegen.NewGordonGenerator(gaddag, s.gameCopies[i].Board(), s.gameCopies[i].Bag().LetterDistribution())
363+
mg := movegen.NewGordonGenerator(gaddag, s.gameCopies[i].Board(), s.gameCopies[i].Bag().LetterDistribution(), s.gameCopies[i].Rules().BingoBonus())
364364
mg.SetSortingParameter(movegen.SortByNone)
365365
mg.SetGenPass(true)
366366
mg.SetPlayRecorder(movegen.AllPlaysSmallRecorder)

equity/calculators_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func TestEndgameTiming(t *testing.T) {
8787
bd := board.MakeBoard(board.CrosswordGameBoard)
8888
ld, err := tilemapping.EnglishLetterDistribution(DefaultConfig.WGLConfig())
8989
assert.Nil(t, err)
90-
generator := movegen.NewGordonGenerator(gd, bd, ld)
90+
generator := movegen.NewGordonGenerator(gd, bd, ld, 50)
9191
tilesInPlay := bd.SetToGame(gd.GetAlphabet(), board.MavenVsMacondo)
9292
cross_set.GenAllCrossSets(bd, gd, ld)
9393
generator.GenAll(tilemapping.RackFromString("AEEORS?", alph), false)
@@ -131,7 +131,7 @@ func TestPreendgameTiming(t *testing.T) {
131131
bd := board.MakeBoard(board.CrosswordGameBoard)
132132
ld, err := tilemapping.EnglishLetterDistribution(DefaultConfig.WGLConfig())
133133
assert.Nil(t, err)
134-
generator := movegen.NewGordonGenerator(gd, bd, ld)
134+
generator := movegen.NewGordonGenerator(gd, bd, ld, 50)
135135
tilesInPlay := bd.SetToGame(gd.GetAlphabet(), board.VsOxy)
136136
cross_set.GenAllCrossSets(bd, gd, ld)
137137
generator.GenAll(tilemapping.RackFromString("OXPBAZE", alph), false)
@@ -170,7 +170,7 @@ func TestOpeningPlayHeuristic(t *testing.T) {
170170
bd := board.MakeBoard(board.CrosswordGameBoard)
171171
ld, err := tilemapping.EnglishLetterDistribution(DefaultConfig.WGLConfig())
172172
assert.Nil(t, err)
173-
generator := movegen.NewGordonGenerator(gd, bd, ld)
173+
generator := movegen.NewGordonGenerator(gd, bd, ld, 50)
174174
cross_set.GenAllCrossSets(bd, gd, ld)
175175
generator.GenAll(tilemapping.RackFromString("AEFLR", alph), false)
176176
els, err := equity.NewCombinedStaticCalculator(

game/backup.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ func (g *Game) Copy() *Game {
166166
maxScorelessTurns: g.maxScorelessTurns,
167167
exchangeLimit: g.exchangeLimit,
168168
players: copyPlayers(g.players),
169+
rules: g.rules,
169170
// stackPtr only changes during a sim, etc. This Copy should
170171
// only be called at the beginning of everything.
171172
stackPtr: 0,

game/game.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -823,7 +823,7 @@ func (g *Game) CreateAndScorePlacementMove(coords string, tiles string, rack str
823823
// ScoreWord assumes the play is always horizontal, so we have to
824824
// do the transpositions beforehand.
825825
score := g.Board().ScoreWord(mw, row, col, tilesPlayed,
826-
crossDir, g.bag.LetterDistribution())
826+
crossDir, g.bag.LetterDistribution(), g.rules.BingoBonus())
827827
// reset row, col back for the actual creation of the play.
828828
if vertical {
829829
row, col = col, row

0 commit comments

Comments
 (0)