Files
Ilia Denisov 15c7959d96 Implement Scrabble move generator (DAWG) with English and Russian rules
A Go library that returns every legal play ranked by score and scores or
validates plays, using the Appel-Jacobson DAWG algorithm over
github.com/iliadenisov/dafsa v1.1.0.

- DAWG move generation (across / down / both), full tournament scoring with a
  per-tile breakdown; public Solver: GenerateMoves (ranked), ScorePlay,
  ValidatePlay.
- Rulesets: English Scrabble, Russian Scrabble, Эрудит (parameterizable Ruleset).
- cmd/builddict (build the DAWG from the dictionaries submodule), cmd/stress
  (self-play benchmark), selfplay engine; brute-force test oracle.
- A GADDAG was implemented, benchmarked and removed (the DAWG was smaller and
  faster for a scoring solver); see RESULTS.md and ALGORITHM.md.
2026-06-01 16:07:32 +02:00

37 lines
910 B
Go

package scrabble
import (
"sort"
"strconv"
"strings"
)
// moveKey is a canonical string identifying a play (direction plus its placed tiles),
// used to de-duplicate and compare generated moves.
func moveKey(dir Direction, p []Placement) string {
ps := append([]Placement(nil), p...)
sort.Slice(ps, func(i, j int) bool {
if ps[i].Row != ps[j].Row {
return ps[i].Row < ps[j].Row
}
return ps[i].Col < ps[j].Col
})
var sb strings.Builder
sb.WriteByte('0' + byte(dir))
for _, pl := range ps {
sb.WriteByte(';')
sb.WriteString(strconv.Itoa(pl.Row))
sb.WriteByte(',')
sb.WriteString(strconv.Itoa(pl.Col))
sb.WriteByte(',')
sb.WriteString(strconv.Itoa(int(pl.Letter)))
if pl.Blank {
sb.WriteByte('*')
}
}
return sb.String()
}
// Key returns the canonical identifier of the move (direction plus its placed tiles).
func (m Move) Key() string { return moveKey(m.Dir, m.Tiles) }