package game import ( "reflect" "testing" "scrabble/backend/internal/account" "scrabble/backend/internal/engine" ) // TestMainWordTilesHorizontalWithBlank checks that a horizontal main word is decoded into // tiles along its row, that the per-letter value is looked up from the value table, and that // a blank cell (here the middle 'a') is rendered with a zero value regardless of its letter // value — the blank flag is taken from the placed-blank set, not from this move's own tiles. func TestMainWordTilesHorizontalWithBlank(t *testing.T) { rec := engine.MoveRecord{Dir: engine.Horizontal, MainRow: 7, MainCol: 5, Words: []string{"cat"}} blanks := map[[2]int]bool{{7, 6}: true} values := map[string]int{"c": 3, "a": 1, "t": 1} got := mainWordTiles(rec, blanks, values) want := []account.BestMoveTile{ {Letter: "c", Value: 3, Blank: false}, {Letter: "a", Value: 0, Blank: true}, {Letter: "t", Value: 1, Blank: false}, } if !reflect.DeepEqual(got, want) { t.Errorf("mainWordTiles = %+v, want %+v", got, want) } } // TestMainWordTilesVerticalCyrillic checks vertical walk and multi-byte (Cyrillic) letters: // the word must be split by rune, not byte, and laid down its column. func TestMainWordTilesVerticalCyrillic(t *testing.T) { rec := engine.MoveRecord{Dir: engine.Vertical, MainRow: 3, MainCol: 8, Words: []string{"съёмка"}} values := map[string]int{"с": 1, "ъ": 10, "ё": 4, "м": 2, "к": 2, "а": 1} got := mainWordTiles(rec, map[[2]int]bool{}, values) want := []account.BestMoveTile{ {Letter: "с", Value: 1}, {Letter: "ъ", Value: 10}, {Letter: "ё", Value: 4}, {Letter: "м", Value: 2}, {Letter: "к", Value: 2}, {Letter: "а", Value: 1}, } if !reflect.DeepEqual(got, want) { t.Errorf("mainWordTiles = %+v, want %+v", got, want) } } // TestMainWordTilesNoWord checks the defensive nil for a record carrying no words. func TestMainWordTilesNoWord(t *testing.T) { if got := mainWordTiles(engine.MoveRecord{}, nil, nil); got != nil { t.Errorf("mainWordTiles(no words) = %+v, want nil", got) } }