Games batch: neutral words/themes, Word Search sizes + per-word colours
From playtesting findings:
* Pools nearly doubled (115/104 → 228/201) with calm/neutral everyday words
(claps, dance, drench, beach…), not just strictly-upbeat ones — more variety,
~7-month runway. The post-solve "why" prompt reworded to fit neutral words.
* Word Search now stores one theme + word list per day; the grid is built per
request for three SIZE tiers — Small (8×8, 6 words), Medium (11×11, 9),
Large (14×14, 13). Large packs more words = a longer sit ("too fast" fix).
All sizes share the day's theme; every size still code-placed + solvable.
* Word Search themes can now be neutral everyday scenes ("Around the house",
"At the beach", "In the kitchen", "A walk outdoors", "Making music"…), not
only hopeful — same shape as the articles.
* Each found word gets its own colour from a calm palette, in the grid and its
word-list chip. Per-size local progress + best time.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,9 +6,10 @@
|
||||
|
||||
let view = $state('hub'); // 'hub' | 'word' | 'wordsearch'
|
||||
let variant = $state('5');
|
||||
let wsSize = $state('med');
|
||||
let date = $state('');
|
||||
let wordStatus = $state({ 5: null, 6: null }); // null | {status, tries, max}
|
||||
let wsStatus = $state(null); // null | {status, found, total, ms}
|
||||
let wsStatus = $state(null); // null | {status, found, ms}
|
||||
|
||||
function readStatus(v) {
|
||||
try {
|
||||
@@ -20,11 +21,18 @@
|
||||
return null;
|
||||
}
|
||||
function readWs() {
|
||||
try {
|
||||
const s = JSON.parse(localStorage.getItem(`goodnews:wordsearch:${date}`) || 'null');
|
||||
if (s && Array.isArray(s.found)) return { status: s.status, found: s.found.length, ms: s.ms };
|
||||
} catch { /* ignore */ }
|
||||
return null;
|
||||
let inProgress = null;
|
||||
for (const sz of ['small', 'med', 'large']) {
|
||||
try {
|
||||
const s = JSON.parse(localStorage.getItem(`goodnews:wordsearch:${sz}:${date}`) || 'null');
|
||||
if (s && Array.isArray(s.foundWords)) {
|
||||
const st = { status: s.status, found: s.foundWords.length, ms: s.ms };
|
||||
if (st.status === 'done') return st; // prefer a finished one
|
||||
if (st.found > 0 && !inProgress) inProgress = st;
|
||||
}
|
||||
} catch { /* ignore */ }
|
||||
}
|
||||
return inProgress;
|
||||
}
|
||||
function refreshStatus() {
|
||||
wordStatus = { 5: readStatus('5'), 6: readStatus('6') };
|
||||
@@ -104,7 +112,12 @@
|
||||
</div>
|
||||
<WordGame {variant} onstatus={refreshStatus} />
|
||||
{:else if view === 'wordsearch'}
|
||||
<WordSearchGame onstatus={refreshStatus} />
|
||||
<div class="variant">
|
||||
<button class="vchip" class:on={wsSize === 'small'} onclick={() => (wsSize = 'small')}>Small<span>cosy · 6 words</span></button>
|
||||
<button class="vchip" class:on={wsSize === 'med'} onclick={() => (wsSize = 'med')}>Medium<span>9 words</span></button>
|
||||
<button class="vchip" class:on={wsSize === 'large'} onclick={() => (wsSize = 'large')}>Large<span>a longer sit · 13 words</span></button>
|
||||
</div>
|
||||
<WordSearchGame size={wsSize} onstatus={refreshStatus} />
|
||||
{/if}
|
||||
</main>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user