fix(engine,wasm,web): detect no-legal-moves correctly and surface banner
Build and Deploy / build-and-push (push) Successful in 4m24s
Build and Deploy / build-and-push (push) Successful in 4m24s
Engine: replace broken has_legal_moves loop (which checked buried mid-column cards without sequence validation) with a delegation to possible_instructions(), mirroring the hint system's logic exactly. WASM: add has_moves: bool to GameSnapshot, computed in snap() using the same stock/waste/possible_instructions check so the web client gets the flag in every state update at no extra round-trip cost. Web: show a non-blocking no-moves banner (slide-up toast) with Undo and New Game actions when has_moves is false and the game is not won. Banner hides automatically once a move restores legal play (e.g. after undo). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -136,11 +136,12 @@ const btnBoardUndo = document.getElementById("btn-board-undo");
|
||||
const btnNew = document.getElementById("btn-new");
|
||||
const chkDraw3 = document.getElementById("chk-draw3");
|
||||
const btnTheme = document.getElementById("btn-theme");
|
||||
const winOverlay = document.getElementById("win-overlay");
|
||||
const winScore = document.getElementById("win-score");
|
||||
const winMoves = document.getElementById("win-moves");
|
||||
const winTime = document.getElementById("win-time");
|
||||
const btnWinNew = document.getElementById("btn-win-new");
|
||||
const winOverlay = document.getElementById("win-overlay");
|
||||
const winScore = document.getElementById("win-score");
|
||||
const winMoves = document.getElementById("win-moves");
|
||||
const winTime = document.getElementById("win-time");
|
||||
const btnWinNew = document.getElementById("btn-win-new");
|
||||
const noMovesBanner = document.getElementById("no-moves-banner");
|
||||
|
||||
// ── Scale to fit ─────────────────────────────────────────────────────────────
|
||||
// Scales #card-area to fill #board without overflowing either dimension.
|
||||
@@ -391,9 +392,12 @@ function render(s) {
|
||||
clearSave();
|
||||
stopTimer();
|
||||
if (acTimer) { clearInterval(acTimer); acTimer = null; }
|
||||
if (noMovesBanner) noMovesBanner.classList.add("hidden");
|
||||
showWin(s);
|
||||
} else {
|
||||
saveState();
|
||||
const noMoves = !s.has_moves && !s.is_auto_completable;
|
||||
if (noMovesBanner) noMovesBanner.classList.toggle("hidden", !noMoves);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -479,6 +483,8 @@ function attachHandlers() {
|
||||
btnUndo.addEventListener("click", doUndo);
|
||||
btnBoardUndo.addEventListener("click", doUndo);
|
||||
btnNew.addEventListener("click", () => startGame(randomSeed()));
|
||||
document.getElementById("btn-no-moves-undo")?.addEventListener("click", doUndo);
|
||||
document.getElementById("btn-no-moves-new")?.addEventListener("click", () => startGame(randomSeed()));
|
||||
btnWinNew.addEventListener("click", () => startGame(randomSeed()));
|
||||
chkDraw3.addEventListener("change", () => {
|
||||
drawThree = chkDraw3.checked;
|
||||
|
||||
Reference in New Issue
Block a user