Promote development → master (initial production release: pre-release line + Stage 18) #104

Merged
developer merged 307 commits from development into master 2026-06-22 05:05:48 +00:00
2 changed files with 7 additions and 4 deletions
Showing only changes of commit d0681c5efe - Show all commits
+2 -2
View File
@@ -107,7 +107,7 @@ describe('placementFromHint', () => {
});
describe('previewFromHint', () => {
it('reuses the hint move as a legal preview, carrying score, words and direction', () => {
it('reuses the hint move as a legal preview, lower-casing words to match evaluate', () => {
const preview = previewFromHint({
player: 0,
action: 'play',
@@ -120,7 +120,7 @@ describe('previewFromHint', () => {
score: 18,
total: 42,
});
expect(preview).toEqual({ legal: true, score: 18, words: ['CAT', 'AN'], dir: 'V' });
expect(preview).toEqual({ legal: true, score: 18, words: ['cat', 'an'], dir: 'V' });
});
});
+5 -2
View File
@@ -59,10 +59,13 @@ export function placementFromHint(tiles: Tile[], rack: string[]): Placement {
* previewFromHint turns a hint's move into a move preview. A hint is the engine's own
* top-ranked, fully scored legal play, so its move already carries the score, words and
* direction an evaluate would compute for the same placement; reusing it lets the client
* skip a redundant evaluate round-trip after auto-placing the hint.
* skip a redundant evaluate round-trip after auto-placing the hint. The words are
* lower-cased to match the evaluate result the caption renders: a hint's MoveRecord words
* are upper-cased on decode (for the move-history view), whereas an EvalResult keeps the
* backend's lower case, so reusing them verbatim would otherwise change the caption's case.
*/
export function previewFromHint(move: MoveRecord): EvalResult {
return { legal: true, score: move.score, words: move.words, dir: move.dir };
return { legal: true, score: move.score, words: move.words.map((w) => w.toLowerCase()), dir: move.dir };
}
function usedIndexes(p: Placement): Set<number> {