Publish as versioned Gitea module; move dictionary pipeline out

- Rename module to gitea.iliadenisov.ru/developer/scrabble-solver so it can be
  consumed as a versioned dependency (no go.work replace / CI clone).
- De-internalize wordlist and dictdawg as public packages.
- Remove cmd/builddict, dictprep/, the dictionaries submodule and the dawg
  Makefile: the word-list parsing and DAWG build now live in the separate
  scrabble-dictionary repository, which publishes the DAWG set as a release artifact.
- internal/dict loads the committed dawg/en_sowpods.dawg fixture for cmd/stress.
- Update README/CLAUDE docs accordingly.
This commit is contained in:
Ilia Denisov
2026-06-04 19:11:46 +02:00
parent 63a7c663bf
commit 256999b42c
41 changed files with 93 additions and 402477 deletions
+2 -2
View File
@@ -1,8 +1,8 @@
package scrabble
import (
"scrabble-solver/board"
"scrabble-solver/internal/encoding"
"gitea.iliadenisov.ru/developer/scrabble-solver/board"
"gitea.iliadenisov.ru/developer/scrabble-solver/internal/encoding"
)
// Apply places a move's newly-placed tiles on the board. The move must be legal for the
+2 -2
View File
@@ -3,8 +3,8 @@ package scrabble
import (
dawg "github.com/iliadenisov/dafsa"
"scrabble-solver/board"
"scrabble-solver/internal/encoding"
"gitea.iliadenisov.ru/developer/scrabble-solver/board"
"gitea.iliadenisov.ru/developer/scrabble-solver/internal/encoding"
)
// letterSet is a bit set over alphabet letter indexes (alphabets are at most 63
+2 -2
View File
@@ -6,8 +6,8 @@ import (
"github.com/iliadenisov/alphabet"
dawg "github.com/iliadenisov/dafsa"
"scrabble-solver/internal/dictdawg"
"scrabble-solver/internal/wordlist"
"gitea.iliadenisov.ru/developer/scrabble-solver/dictdawg"
"gitea.iliadenisov.ru/developer/scrabble-solver/wordlist"
)
func bruteCrossSet(words [][]byte, above, below []byte, size int) letterSet {
+5 -5
View File
@@ -8,9 +8,9 @@ import (
"strings"
"testing"
"scrabble-solver/board"
"scrabble-solver/internal/dictdawg"
"scrabble-solver/rules"
"gitea.iliadenisov.ru/developer/scrabble-solver/board"
"gitea.iliadenisov.ru/developer/scrabble-solver/dictdawg"
"gitea.iliadenisov.ru/developer/scrabble-solver/rules"
)
// TestScoreRealGames replays real tournament games recorded in GCG format and checks that
@@ -19,11 +19,11 @@ import (
//
// The games come from cross-tables.com (annotated self-play) and are stored under
// testdata/. They use the standard English board and SOWPODS, so the test loads the
// committed dawg/en_sowpods.dawg (build it with `make dawg`).
// committed dawg/en_sowpods.dawg.
func TestScoreRealGames(t *testing.T) {
finder, err := dictdawg.Load("../dawg/en_sowpods.dawg")
if err != nil {
t.Skipf("need dawg/en_sowpods.dawg (run `make dawg`): %v", err)
t.Skipf("need dawg/en_sowpods.dawg: %v", err)
}
s := NewSolver(rules.English(), finder)
games, _ := filepath.Glob("testdata/*.gcg")
+3 -3
View File
@@ -1,9 +1,9 @@
package scrabble
import (
"scrabble-solver/board"
"scrabble-solver/rack"
"scrabble-solver/rules"
"gitea.iliadenisov.ru/developer/scrabble-solver/board"
"gitea.iliadenisov.ru/developer/scrabble-solver/rack"
"gitea.iliadenisov.ru/developer/scrabble-solver/rules"
)
// generateBoth runs an across-generator on the board (for horizontal plays) and on its
+4 -4
View File
@@ -3,10 +3,10 @@ package scrabble
import (
dawg "github.com/iliadenisov/dafsa"
"scrabble-solver/board"
"scrabble-solver/internal/encoding"
"scrabble-solver/rack"
"scrabble-solver/rules"
"gitea.iliadenisov.ru/developer/scrabble-solver/board"
"gitea.iliadenisov.ru/developer/scrabble-solver/internal/encoding"
"gitea.iliadenisov.ru/developer/scrabble-solver/rack"
"gitea.iliadenisov.ru/developer/scrabble-solver/rules"
)
// DAWGGenerator generates moves with the Appel-Jacobson two-phase algorithm
+6 -6
View File
@@ -5,12 +5,12 @@ import (
"github.com/iliadenisov/alphabet"
"scrabble-solver/board"
"scrabble-solver/internal/dictdawg"
"scrabble-solver/internal/encoding"
"scrabble-solver/internal/wordlist"
"scrabble-solver/rack"
"scrabble-solver/rules"
"gitea.iliadenisov.ru/developer/scrabble-solver/board"
"gitea.iliadenisov.ru/developer/scrabble-solver/dictdawg"
"gitea.iliadenisov.ru/developer/scrabble-solver/internal/encoding"
"gitea.iliadenisov.ru/developer/scrabble-solver/rack"
"gitea.iliadenisov.ru/developer/scrabble-solver/rules"
"gitea.iliadenisov.ru/developer/scrabble-solver/wordlist"
)
func makeRack(letters string, blanks int) rack.Rack {
+2 -2
View File
@@ -1,8 +1,8 @@
package scrabble
import (
"scrabble-solver/board"
"scrabble-solver/rack"
"gitea.iliadenisov.ru/developer/scrabble-solver/board"
"gitea.iliadenisov.ru/developer/scrabble-solver/rack"
)
// Generator produces every legal play for a position. The DAWG generator
+3 -3
View File
@@ -1,9 +1,9 @@
package scrabble
import (
"scrabble-solver/board"
"scrabble-solver/rack"
"scrabble-solver/rules"
"gitea.iliadenisov.ru/developer/scrabble-solver/board"
"gitea.iliadenisov.ru/developer/scrabble-solver/rack"
"gitea.iliadenisov.ru/developer/scrabble-solver/rules"
)
// dict is a membership set of words (alphabet-index strings) for the oracle.
+3 -3
View File
@@ -5,9 +5,9 @@ import (
"fmt"
"sort"
"scrabble-solver/board"
"scrabble-solver/internal/encoding"
"scrabble-solver/rules"
"gitea.iliadenisov.ru/developer/scrabble-solver/board"
"gitea.iliadenisov.ru/developer/scrabble-solver/internal/encoding"
"gitea.iliadenisov.ru/developer/scrabble-solver/rules"
)
// coord maps a line coordinate (fixed, axis) to a board (row, col) for direction dir.
+3 -3
View File
@@ -3,9 +3,9 @@ package scrabble
import (
"testing"
"scrabble-solver/board"
"scrabble-solver/internal/encoding"
"scrabble-solver/rules"
"gitea.iliadenisov.ru/developer/scrabble-solver/board"
"gitea.iliadenisov.ru/developer/scrabble-solver/internal/encoding"
"gitea.iliadenisov.ru/developer/scrabble-solver/rules"
)
const plain7 = `.......
+3 -3
View File
@@ -7,9 +7,9 @@ import (
dawg "github.com/iliadenisov/dafsa"
"scrabble-solver/board"
"scrabble-solver/rack"
"scrabble-solver/rules"
"gitea.iliadenisov.ru/developer/scrabble-solver/board"
"gitea.iliadenisov.ru/developer/scrabble-solver/rack"
"gitea.iliadenisov.ru/developer/scrabble-solver/rules"
)
// Solver is the high-level entry point: it generates ranked plays and scores or
+3 -3
View File
@@ -5,9 +5,9 @@ import (
"github.com/iliadenisov/alphabet"
"scrabble-solver/board"
"scrabble-solver/internal/dictdawg"
"scrabble-solver/internal/wordlist"
"gitea.iliadenisov.ru/developer/scrabble-solver/board"
"gitea.iliadenisov.ru/developer/scrabble-solver/dictdawg"
"gitea.iliadenisov.ru/developer/scrabble-solver/wordlist"
)
func newTestSolver(t *testing.T) *Solver {