Games: in-progress hub status + distribution-aware word-search placement (Codex)
- Play hub: word cards now surface IN-PROGRESS games too (not just won/lost) so "continue on another device" shows at a glance — card reads "5:3…" and the selection option says "Continue · 3/6". - Word Search generator: replace "prefer any crossing" with a SCORED placement — score = overlap*4 - local crowding (filled neighbours that aren't crossings) — then pick among the best ~20%. Keeps the organic interlocking but spreads words across the board instead of clumping around the first-placed (longest) words. Every word still placed (tests green). NOTE: changes today's grid layouts, so an in-progress word search resets once. 237 pytest + 11 vitest green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -24,8 +24,11 @@
|
||||
function readWord(v) {
|
||||
try {
|
||||
const s = JSON.parse(localStorage.getItem(`goodnews:word:${v}:${date}`) || 'null');
|
||||
if (s && (s.status === 'won' || s.status === 'lost')) {
|
||||
return { status: s.status, tries: (s.guesses || []).length, max: v === '6' ? 7 : 6 };
|
||||
const tries = (s?.guesses || []).length;
|
||||
// Surface in-progress too (so "continue on another device" shows on the card),
|
||||
// not just finished games.
|
||||
if (s && (s.status === 'won' || s.status === 'lost' || (s.status === 'playing' && tries > 0))) {
|
||||
return { status: s.status, tries, max: v === '6' ? 7 : 6 };
|
||||
}
|
||||
} catch { /* ignore */ }
|
||||
return null;
|
||||
@@ -79,7 +82,7 @@
|
||||
function wordLabel() {
|
||||
const a = wordStatus['5'], b = wordStatus['6'];
|
||||
if (!a && !b) return 'Guess the day’s word';
|
||||
const part = (s, mx) => s ? (s.status === 'won' ? `${s.tries}/${mx}` : 'X') : '–';
|
||||
const part = (s, mx) => !s ? '–' : s.status === 'won' ? `${s.tries}/${mx}` : s.status === 'lost' ? 'X' : `${s.tries}…`;
|
||||
return `Today · 5:${part(a, 6)} 6:${part(b, 7)}`;
|
||||
}
|
||||
function wsHubLabel() {
|
||||
@@ -93,7 +96,9 @@
|
||||
function wordOpt(v) {
|
||||
const s = wordStatus[v];
|
||||
if (!s) return 'Play';
|
||||
return s.status === 'won' ? `Solved ${s.tries}/${s.max}` : 'Out of guesses';
|
||||
if (s.status === 'won') return `Solved ${s.tries}/${s.max}`;
|
||||
if (s.status === 'lost') return 'Out of guesses';
|
||||
return `Continue · ${s.tries}/${s.max}`;
|
||||
}
|
||||
function wsOpt(sz) {
|
||||
const s = readWsSize(sz);
|
||||
|
||||
Reference in New Issue
Block a user