15c7959d96
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.
37 lines
910 B
Go
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) }
|