diff options
author | pommicket <pommicket@gmail.com> | 2025-09-18 19:11:45 -0400 |
---|---|---|
committer | pommicket <pommicket@gmail.com> | 2025-09-18 19:11:45 -0400 |
commit | 7e81a85ee374ad70341835decae5c3808fce2ba5 (patch) | |
tree | 01a070eba197a1c2575349b2494f7137924ecc08 | |
parent | 083d80072756fa839fd3f10d414692f2be38fba0 (diff) |
Saving + loading
-rw-r--r-- | pub/blankplays.js | 102 | ||||
-rw-r--r-- | pub/index.html | 18 |
2 files changed, 94 insertions, 26 deletions
diff --git a/pub/blankplays.js b/pub/blankplays.js index c31fc05..964aade 100644 --- a/pub/blankplays.js +++ b/pub/blankplays.js @@ -1,11 +1,18 @@ 'use strict'; +/* +TODO: +- clear solution +*/ + const N = 15; // board size const NOTHING = "β
"; const EMAIL = 'pommicket' + '@pommicket.com'; -let lexicon = new URL(location.href).searchParams.get('lexicon') || 'nwl23'; +let lexicon = new URL(location.href).searchParams.get('lexicon') + || localStorage.getItem('prevLexicon') || 'nwl23'; +localStorage.setItem('prevLexicon', lexicon); function updateBoardSize() { let boardElem = document.getElementById('board'); @@ -57,12 +64,42 @@ function pointValue(letter) { } let boardSquareElems = []; -let currSolution = []; +let currAttempt = []; let board = []; let trueSolution = []; -let skipWordsOfLength = 2; +let skipWordsOfLength = parseInt(localStorage.getItem(`skip-${lexicon}`)) || 2; let alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''); let finished = false; +let challengeId; + +function loadAttempt() { + let saveDataStr = localStorage.getItem(`attempt-${lexicon}`); + if (!saveDataStr) return null; + let saveData = JSON.parse(saveDataStr); + if (saveData.id !== challengeId) { + // old data + return; + } + for (let row = 0; row < 15; row++) { + for (let col = 0; col < 15; col++) { + for (let letter of saveData.solution[row][col]) { + addToSolution(row, col, letter); + } + } + } + if (saveData.finished) + showSolution(); +} + +function saveAttempt() { + let saveData = { + version: 1, + id: challengeId, + solution: currAttempt, + finished: finished, + }; + localStorage.setItem(`attempt-${lexicon}`, JSON.stringify(saveData)); +} function getFontSizeForPossibilities(n) { return (n === 1 ? 100 @@ -85,18 +122,19 @@ function updatePossibilities(highlightElem, letters) { function addToSolution(row, col, letter) { let highlight = document.querySelector(`.highlight[data-row="${row}"][data-col="${col}"]`); if (letter === NOTHING) { - currSolution[row][col] = []; + currAttempt[row][col] = []; highlight.classList.add('nothing'); updatePossibilities(highlight, []); deselectTile(); return; } - let letters = currSolution[row][col]; + let letters = currAttempt[row][col]; if (letters.indexOf(letter) !== -1) return; letters.push(letter); letters.sort(); highlight.classList.remove('nothing'); updatePossibilities(highlight, letters); + saveAttempt(); } function removeFromSolution(row, col, letter) { @@ -105,15 +143,16 @@ function removeFromSolution(row, col, letter) { highlight.classList.remove('nothing'); return; } - let letters = currSolution[row][col]; + let letters = currAttempt[row][col]; let idx = letters.indexOf(letter); if (idx === -1) return; letters.splice(idx, 1); updatePossibilities(highlight, letters); + saveAttempt(); } function toggleInSolution(row, col, letter) { - let letters = currSolution[row][col]; + let letters = currAttempt[row][col]; let idx = letters.indexOf(letter); if (idx === -1) { addToSolution(row, col, letter); @@ -155,7 +194,7 @@ function selectTile(elem, row, col) { placing.classList.remove('placing'); elem.classList.add('selected'); if (finished) { - let guess = currSolution[row][col]; + let guess = currAttempt[row][col]; let solution = trueSolution[row][col]; for (let letter of alphabet) { let inGuess = guess.indexOf(letter) !== -1; @@ -176,7 +215,7 @@ function selectTile(elem, row, col) { } else { document.getElementById('select-heading').style.display = 'block'; document.getElementById('place-heading').style.display = 'none'; - for (let letter of currSolution[row][col]) { + for (let letter of currAttempt[row][col]) { document.querySelector(`.tile[data-letter="${letter}"]`) .classList.add('possible'); } @@ -222,7 +261,7 @@ function clickedSquare(highlight, row, col) { } else if (e.button === 2) { if (highlight.classList.contains('nothing')) { highlight.classList.remove('nothing'); - } else if (currSolution[row][col].length === 0) { + } else if (currAttempt[row][col].length === 0) { highlight.classList.add('nothing'); if (highlight.classList.contains('selected')) deselectTile(); @@ -251,6 +290,7 @@ function includeSquare(row, col) { } async function loadChallenge(id) { + challengeId = id; let result = await fetch(`challenges-${lexicon}/${id}.txt`); if (result.status === 404) { alert(`Challenge for today hasn't been uploaded. @@ -259,7 +299,7 @@ Please e-mail ${EMAIL}`); } else if (Math.floor(result.status / 100) !== 2) { alert(`Error getting today's challenge. Try refreshing the page, or clearing your browser's cache for this site. -If problem persists, e-mail ${EMAIL}.`); +If problem persists, e-mail ${EMAIL}.`); } // TODO : check format & report error if wrong let body = await result.text(); @@ -288,6 +328,9 @@ If problem persists, e-mail ${EMAIL}.`); for (let row = 0; row < 15; row++) for (let col = 0; col < 15; col++) trueSolution[row][col].sort(); + updateBoard(); + loadAttempt(); + } function updateBoard() { @@ -310,7 +353,7 @@ function updateBoard() { let possibilities = document.createElement('span'); possibilities.classList.add('possibilities'); highlight.appendChild(possibilities); - updatePossibilities(highlight, currSolution[row][col]); + updatePossibilities(highlight, currAttempt[row][col]); boardSquareElems[row][col].appendChild(highlight); highlight.addEventListener('contextmenu', (e) => e.preventDefault()); highlight.addEventListener('mousedown', clickedSquare(highlight, row, col)); @@ -343,6 +386,7 @@ function updateSkipWordsOfLength() { let skip2s = document.getElementById('skip-2s'); let skip3s = document.getElementById('skip-3s'); skipWordsOfLength = skip3s.checked ? 3 : skip2s.checked ? 2 : 1; + localStorage.setItem(`skip-${lexicon}`, skipWordsOfLength); for (let row = 0; row < 15; row++) { for (let col = 0; col < 15; col++) { if (!includeSquare(row, col)) continue; @@ -355,6 +399,7 @@ function updateSkipWordsOfLength() { function showSolution() { finished = true; + saveAttempt(); deselectTile(); document.getElementById('select-nothing').style.display = 'none'; document.getElementById('select-heading').style.display = 'none'; @@ -367,12 +412,13 @@ function showSolution() { for (let col = 0; col < 15; col++) { if (!includeSquare(row, col)) continue; - let guess = currSolution[row][col]; + let guess = currAttempt[row][col]; let solution = trueSolution[row][col]; let highlightElem = document.querySelector(`[data-row="${row}"][data-col="${col}"]`); let possibilitiesElem = highlightElem.querySelector('.possibilities'); possibilitiesElem.innerHTML = ''; let totalLength = 0; + let allCorrect = true; for (let letter of alphabet) { let inGuess = guess.indexOf(letter) !== -1; let inSolution = solution.indexOf(letter) !== -1; @@ -384,22 +430,31 @@ function showSolution() { if (!inGuess && inSolution) { span.classList.add('missed'); if (!skipDueToLength(row, col)) missedPlays += 1; + allCorrect = false; } else if (inGuess && !inSolution) { span.classList.add('wrong'); if (!skipDueToLength(row, col)) incorrectPlays += 1; + allCorrect = false; } else { span.classList.add('correct'); if (!skipDueToLength(row, col)) correctPlays += 1; } possibilitiesElem.appendChild(span); } - if (solution.length === 0) { + highlightElem.classList.remove('nothing'); + if (allCorrect) + highlightElem.classList.add('all-correct'); + else if (solution.length === 0) highlightElem.classList.add('nothing'); + else + highlightElem.classList.add('some-mistakes'); + + if (totalLength) { + let fontSize = getFontSizeForPossibilities(totalLength); + possibilitiesElem.style.fontSize = fontSize; } else { - highlightElem.classList.remove('nothing'); + highlightElem.remove(); } - let fontSize = getFontSizeForPossibilities(totalLength); - possibilitiesElem.style.fontSize = fontSize; } } // show stats @@ -438,9 +493,16 @@ function showSolution() { } function startup() { + let lexiconSelect = document.getElementById('lexicon'); + lexiconSelect.value = lexicon; + lexiconSelect.addEventListener('change', () => { + location.search = `?lexicon=${lexiconSelect.value}`; + }); let boardElem = document.getElementById('board'); let skip2s = document.getElementById('skip-2s'); let skip3s = document.getElementById('skip-3s'); + skip2s.checked = skipWordsOfLength >= 2; + skip3s.checked = skipWordsOfLength >= 3; skip2s.addEventListener('change', () => { if (!skip2s.checked) skip3s.checked = false; @@ -458,7 +520,7 @@ function startup() { rowElem.classList.add('board-row'); boardElem.appendChild(rowElem); boardSquareElems.push([]); - currSolution.push([]); + currAttempt.push([]); for (let col = 0; col < N; col++) { let squareElem = document.createElement('div'); squareElem.classList.add('board-square'); @@ -466,7 +528,7 @@ function startup() { if (bonus) squareElem.classList.add(bonus); rowElem.appendChild(squareElem); boardSquareElems[row].push(squareElem); - currSolution[row].push([]); + currAttempt[row].push([]); } } let selectContainer = document.getElementById('select-container'); @@ -513,7 +575,7 @@ function startup() { rowContainer.appendChild(elem); } } - loadChallenge('00000').then(() => updateBoard()); + loadChallenge('00000'); } window.addEventListener('load', startup); diff --git a/pub/index.html b/pub/index.html index 5ffdcb6..04db2a4 100644 --- a/pub/index.html +++ b/pub/index.html @@ -19,7 +19,7 @@ grid-auto-flow: column; } .board-square { - margin: 2px; + margin: 1px; background-color: #dde; line-height: 1; position: relative; @@ -28,7 +28,7 @@ background-color: #acf; } .board-square.triple-letter { - background-color: #99f; + background-color: #afc; } .board-square.double-word { background-color: #fac; @@ -54,7 +54,7 @@ font-weight: normal; } .highlight { - border: 4px solid #ff0; + border: 4px solid rgba(60,60,60,0.6); width: calc(100% - 8px); height: calc(100% - 8px); position: absolute; @@ -66,9 +66,15 @@ .highlight.nothing { border: 4px solid #f00; } - .highlight.selected { + #board .highlight.selected { border: 4px solid #00f; } + .highlight.all-correct { + border: 4px solid #0a0; + } + .highlight.some-mistakes { + border: 4px solid #f80; + } .possibilities { word-break: break-all; } @@ -154,7 +160,7 @@ color: #800; } .solution-letter.correct { - color: #040; + color: #060; } .solution-letter.missed { color: #00a; @@ -186,7 +192,7 @@ <option value="nwl23">π¨π¦πΊπΈNWL23</option> <option value="csw24">π¬π§ CSW24</option> </select></label> - <label><input type="checkbox" id="skip-2s" checked> Skip 2βs</label> + <label><input type="checkbox" id="skip-2s"> Skip 2βs</label> <label><input type="checkbox" id="skip-3s"> Skip 3βs</label> <button id="submit">All done!</button> <div id="board"></div> |