From 169f8abfabf6f202edf3ca66368b4e6eb0b251d4 Mon Sep 17 00:00:00 2001 From: skedwards88 Date: Thu, 7 Dec 2023 08:48:43 -0800 Subject: [PATCH 1/9] rename file --- src/logic/{getSolutionFromPieces.js => getGridFromPieces.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/logic/{getSolutionFromPieces.js => getGridFromPieces.js} (100%) diff --git a/src/logic/getSolutionFromPieces.js b/src/logic/getGridFromPieces.js similarity index 100% rename from src/logic/getSolutionFromPieces.js rename to src/logic/getGridFromPieces.js From affa4095ac7512184b41908ebb67b092d4eb11f6 Mon Sep 17 00:00:00 2001 From: skedwards88 Date: Thu, 7 Dec 2023 09:02:27 -0800 Subject: [PATCH 2/9] update functions to act on solution vs actual --- src/logic/gameSolvedQ.js | 2 +- src/logic/getGridFromPieces.js | 16 +- src/logic/getSolutionFromPieces.test.js | 296 +++++++++++++++++++++++- src/logic/getWordsFromPieces.js | 6 +- 4 files changed, 300 insertions(+), 20 deletions(-) diff --git a/src/logic/gameSolvedQ.js b/src/logic/gameSolvedQ.js index 9313556..e4c85d6 100644 --- a/src/logic/gameSolvedQ.js +++ b/src/logic/gameSolvedQ.js @@ -49,7 +49,7 @@ export function gameSolvedQ(pieces, gridSize) { }; } - const originalWords = getWordsFromPieces({ pieces, gridSize }); + const originalWords = getWordsFromPieces({ pieces, gridSize, solution:true }); const { gameIsSolved, reason } = crosswordValidQ({ grid: grid, diff --git a/src/logic/getGridFromPieces.js b/src/logic/getGridFromPieces.js index 6aa4042..7d25a87 100644 --- a/src/logic/getGridFromPieces.js +++ b/src/logic/getGridFromPieces.js @@ -1,4 +1,7 @@ -export function getSolutionFromPieces({ pieces, gridSize }) { +export function getGridFromPieces({ pieces, gridSize, solution }) { + // Compiles a 2D array representing the letter locations on the board + // If solution is true, uses the solutionTop/solutionLeft value of each piece + // otherwise, uses the boardTop/boardLeft value if (pieces === undefined) { throw new Error("Pieces must be defined."); } @@ -11,11 +14,17 @@ export function getSolutionFromPieces({ pieces, gridSize }) { Array.from({ length: gridSize }, () => "") ); + const topKey = solution ? "solutionTop" : "boardTop"; + const leftKey = solution ? "solutionLeft" : "boardLeft"; + for (const piece of pieces) { + if (!solution && (piece[topKey] == undefined || piece[leftKey] == undefined)) { + continue; + } const letters = piece.letters; - let top = piece.solutionTop; + let top = piece[topKey]; for (let rowIndex = 0; rowIndex < letters.length; rowIndex++) { - let left = piece.solutionLeft; + let left = piece[leftKey]; for (let colIndex = 0; colIndex < letters[rowIndex].length; colIndex++) { if (letters[rowIndex][colIndex]) { if (grid[top][left] == undefined) { @@ -28,6 +37,5 @@ export function getSolutionFromPieces({ pieces, gridSize }) { top += 1; } } - return grid; } diff --git a/src/logic/getSolutionFromPieces.test.js b/src/logic/getSolutionFromPieces.test.js index 34418bf..61dbaa4 100644 --- a/src/logic/getSolutionFromPieces.test.js +++ b/src/logic/getSolutionFromPieces.test.js @@ -1,7 +1,7 @@ -import { getSolutionFromPieces } from "./getSolutionFromPieces"; +import { getGridFromPieces } from "./getGridFromPieces"; -describe("getSolutionFromPieces", () => { - test("it returns a 2D array representing the placement of the pieces in a grid", () => { +describe("getGridFromPieces", () => { + test("if `solution` is true, it returns a 2D array representing the placement of the pieces in a grid based on the solution", () => { const pieces = [ { letters: [ @@ -112,11 +112,243 @@ describe("getSolutionFromPieces", () => { ["", "", "", "", "E", "", "E", "A", "R", "N", "S", ""], ["V", "I", "S", "O", "R", "", "", "", "", "", "", ""], ]; - expect(getSolutionFromPieces({ pieces, gridSize: 12 })).toEqual( + expect(getGridFromPieces({ pieces, gridSize: 12, solution: true })).toEqual( expectedGrid ); }); + test("if `solution` is false, it returns a 2D array representing the placement of the pieces in a grid", () => { + const pieces = [ + { + letters: [ + ["", "C", ""], + ["L", "A", "Y"], + ["", "R", ""], + ], + boardTop: 5, + boardLeft: 7, + }, + { + letters: [["K"], ["N"], ["O"]], + boardTop: 2, + boardLeft: 10, + }, + { letters: [["N", "S"]], boardTop: 10, boardLeft: 9 }, + { letters: [["E", "A"]], boardTop: 10, boardLeft: 6 }, + { letters: [["B"], ["S"]], boardTop: 5, boardLeft: 10 }, + { + letters: [ + ["I", "", ""], + ["V", "", ""], + ["E", "Z", "E"], + ], + boardTop: 3, + boardLeft: 3, + }, + { letters: [["A"], ["W"]], boardTop: 3, boardLeft: 5 }, + { + letters: [ + ["S", "P", "A"], + ["", "R", ""], + ["", "E", ""], + ], + boardTop: 0, + boardLeft: 0, + }, + { + letters: [ + ["", "", "E"], + ["S", "O", "R"], + ], + boardTop: 10, + boardLeft: 2, + }, + { + letters: [ + ["", "F", ""], + ["", "E", ""], + ["B", "R", "E"], + ], + boardTop: 3, + boardLeft: 0, + }, + { letters: [["V", "I"]], boardTop: 11, boardLeft: 0 }, + { + letters: [ + ["N", "S"], + ["A", ""], + ["T", "E"], + ], + boardTop: 0, + boardLeft: 3, + }, + { + letters: [ + ["", "N", ""], + ["S", "I", "M"], + ["", "C", ""], + ], + boardTop: 7, + boardLeft: 3, + }, + { + letters: [ + ["", "", "R"], + ["", "", "A"], + ["L", "L", "S"], + ], + boardTop: 0, + boardLeft: 5, + }, + { letters: [["F"]], boardTop: 1, boardLeft: 5 }, + { letters: [["P"], ["Y"]], boardTop: 3, boardLeft: 7 }, + { letters: [["D", "E"]], boardTop: 6, boardLeft: 5 }, + { + letters: [ + ["P", "L", "E"], + ["", "", "E"], + ["", "", "R"], + ], + boardTop: 8, + boardLeft: 6, + }, + ]; + + const expectedGrid = [ + ["S", "P", "A", "N", "S", "", "", "R", "", "", "", ""], + ["", "R", "", "A", "", "F", "", "A", "", "", "", ""], + ["", "E", "", "T", "E", "L", "L", "S", "", "", "K", ""], + ["", "F", "", "I", "", "A", "", "P", "", "", "N", ""], + ["", "E", "", "V", "", "W", "", "Y", "", "", "O", ""], + ["B", "R", "E", "E", "Z", "E", "", "", "C", "", "B", ""], + ["", "", "", "", "", "D", "E", "L", "A", "Y", "S", ""], + ["", "", "", "", "N", "", "", "", "R", "", "", ""], + ["", "", "", "S", "I", "M", "P", "L", "E", "", "", ""], + ["", "", "", "", "C", "", "", "", "E", "", "", ""], + ["", "", "", "", "E", "", "E", "A", "R", "N", "S", ""], + ["V", "I", "S", "O", "R", "", "", "", "", "", "", ""], + ]; + expect( + getGridFromPieces({ pieces, gridSize: 12, solution: false }) + ).toEqual(expectedGrid); + }); + + test("if `solution` is false, any pieces that are not on the board are excluded", () => { + const pieces = [ + { + letters: [ + ["", "C", ""], + ["L", "A", "Y"], + ["", "R", ""], + ], + boardTop: 5, + boardLeft: 7, + }, + { + letters: [["K"], ["N"], ["O"]], + boardTop: 2, + boardLeft: 10, + }, + { letters: [["N", "S"]], boardTop: 10, boardLeft: 9 }, + { letters: [["E", "A"]], boardTop: 10, boardLeft: 6 }, + { letters: [["B"], ["S"]], boardTop: 5, boardLeft: 10 }, + { + letters: [ + ["I", "", ""], + ["V", "", ""], + ["E", "Z", "E"], + ], + boardTop: undefined, + boardLeft: undefined, + }, + { letters: [["A"], ["W"]], boardTop: 3, boardLeft: 5 }, + { + letters: [ + ["S", "P", "A"], + ["", "R", ""], + ["", "E", ""], + ], + boardTop: 0, + boardLeft: 0, + }, + { + letters: [ + ["", "", "E"], + ["S", "O", "R"], + ], + boardTop: 10, + boardLeft: 2, + }, + { + letters: [ + ["", "F", ""], + ["", "E", ""], + ["B", "R", "E"], + ], + boardTop: 3, + boardLeft: 0, + }, + { letters: [["V", "I"]], boardTop: 11, boardLeft: 0 }, + { + letters: [ + ["N", "S"], + ["A", ""], + ["T", "E"], + ], + boardTop: 0, + boardLeft: 3, + }, + { + letters: [ + ["", "N", ""], + ["S", "I", "M"], + ["", "C", ""], + ], + boardTop: 7, + boardLeft: 3, + }, + { + letters: [ + ["", "", "R"], + ["", "", "A"], + ["L", "L", "S"], + ], + boardTop: 0, + boardLeft: 5, + }, + { letters: [["F"]], boardTop: 1, boardLeft: 5 }, + { letters: [["P"], ["Y"]], boardTop: 3, boardLeft: 7 }, + { letters: [["D", "E"]], boardTop: 6, boardLeft: 5 }, + { + letters: [ + ["P", "L", "E"], + ["", "", "E"], + ["", "", "R"], + ], + boardTop: undefined, + boardLeft: undefined, + }, + ]; + + const expectedGrid = [ + ["S", "P", "A", "N", "S", "", "", "R", "", "", "", ""], + ["", "R", "", "A", "", "F", "", "A", "", "", "", ""], + ["", "E", "", "T", "E", "L", "L", "S", "", "", "K", ""], + ["", "F", "", "", "", "A", "", "P", "", "", "N", ""], + ["", "E", "", "", "", "W", "", "Y", "", "", "O", ""], + ["B", "R", "E", "", "", "", "", "", "C", "", "B", ""], + ["", "", "", "", "", "D", "E", "L", "A", "Y", "S", ""], + ["", "", "", "", "N", "", "", "", "R", "", "", ""], + ["", "", "", "S", "I", "M", "", "", "", "", "", ""], + ["", "", "", "", "C", "", "", "", "", "", "", ""], + ["", "", "", "", "E", "", "E", "A", "", "N", "S", ""], + ["V", "I", "S", "O", "R", "", "", "", "", "", "", ""], + ]; + expect( + getGridFromPieces({ pieces, gridSize: 12, solution: false }) + ).toEqual(expectedGrid); + }); + test("any overlapping positions are overwritten", () => { const pieces = [ { @@ -135,7 +367,7 @@ describe("getSolutionFromPieces", () => { ["L", "A", "Y"], ["", "R", ""], ]; - expect(getSolutionFromPieces({ pieces, gridSize: 3 })).toEqual( + expect(getGridFromPieces({ pieces, gridSize: 3, solution: true })).toEqual( expectedGrid ); }); @@ -147,7 +379,7 @@ describe("getSolutionFromPieces", () => { ["", "", ""], ["", "", ""], ]; - expect(getSolutionFromPieces({ pieces, gridSize: 3 })).toEqual( + expect(getGridFromPieces({ pieces, gridSize: 3, solution: true })).toEqual( expectedGrid ); }); @@ -166,18 +398,58 @@ describe("getSolutionFromPieces", () => { { letters: [["", "T", "O"]], solutionTop: 0, solutionLeft: 0 }, ]; - expect(() => getSolutionFromPieces({ pieces, gridSize: 2 })).toThrow( - "A piece falls outside of the grid boundary." - ); + expect(() => + getGridFromPieces({ pieces, gridSize: 2, solution: true }) + ).toThrow("A piece falls outside of the grid boundary."); }); - test("an error is thrown if either input is undefined", () => { - expect(() => getSolutionFromPieces({ gridSize: 2 })).toThrow( + test("an error is thrown if either pieces or gridSize is undefined", () => { + expect(() => getGridFromPieces({ gridSize: 2 })).toThrow( "Pieces must be defined." ); - expect(() => getSolutionFromPieces({ pieces: [] })).toThrow( + expect(() => getGridFromPieces({ pieces: [] })).toThrow( "Grid size must be defined." ); }); }); + +test("if `solution` is false, and no pieces are on the board, an empty grid is returned", () => { + const pieces = [ + { + letters: [ + ["", "C", ""], + ["L", "A", "Y"], + ["", "R", ""], + ], + boardTop: undefined, + boardLeft: undefined, + }, + { + letters: [["K"], ["N"], ["O"]], + boardTop: undefined, + boardLeft: undefined, + }, + { letters: [["N", "S"]], boardTop: undefined, boardLeft: undefined }, + { letters: [["E", "A"]], boardTop: undefined, boardLeft: undefined }, + { letters: [["B"], ["S"]], boardTop: undefined, boardLeft: undefined }, + ]; + + const expectedGrid = [ + ["", "", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", "", ""], + ]; + expect(getGridFromPieces({ pieces, gridSize: 12, solution: false })).toEqual( + expectedGrid + ); +}); diff --git a/src/logic/getWordsFromPieces.js b/src/logic/getWordsFromPieces.js index 299fbf0..56f0080 100644 --- a/src/logic/getWordsFromPieces.js +++ b/src/logic/getWordsFromPieces.js @@ -1,8 +1,8 @@ -import { getSolutionFromPieces } from "./getSolutionFromPieces"; +import { getGridFromPieces } from "./getGridFromPieces"; import { getWordsFromGrid } from "./getWordsFromGrid"; -export function getWordsFromPieces({ pieces, gridSize }) { - const grid = getSolutionFromPieces({ pieces, gridSize }); +export function getWordsFromPieces({ pieces, gridSize, solution }) { + const grid = getGridFromPieces({ pieces, gridSize, solution }); const words = getWordsFromGrid(grid); From e414fdfb82351d65d8b607758173d9dab9b69351 Mon Sep 17 00:00:00 2001 From: skedwards88 Date: Thu, 7 Dec 2023 09:03:09 -0800 Subject: [PATCH 3/9] rename file to match new function name --- .../{getSolutionFromPieces.test.js => getGridFromPieces.test.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/logic/{getSolutionFromPieces.test.js => getGridFromPieces.test.js} (100%) diff --git a/src/logic/getSolutionFromPieces.test.js b/src/logic/getGridFromPieces.test.js similarity index 100% rename from src/logic/getSolutionFromPieces.test.js rename to src/logic/getGridFromPieces.test.js From 9db23ee7d7a53663eb954f481a99cf758cadc47c Mon Sep 17 00:00:00 2001 From: skedwards88 Date: Thu, 7 Dec 2023 09:05:22 -0800 Subject: [PATCH 4/9] reflect horizontal and vertical validity --- src/App.css | 22 +++++++++++ src/components/Board.js | 81 +++++++++++++++++++++++++++++++++++++++++ src/components/Piece.js | 22 +++++++++++ 3 files changed, 125 insertions(+) diff --git a/src/App.css b/src/App.css index b62f852..4dcaf7f 100644 --- a/src/App.css +++ b/src/App.css @@ -342,6 +342,7 @@ a { font-size: calc(0.9 * var(--box-size)); background-color: var(--dark-color); color: var(--light-color); + position: relative; } .letter.filled { @@ -354,10 +355,31 @@ a { color: rgb(226 88 88); } +.letter.verticalValid::before{ + content: ''; + position: absolute; + left: 18%; + top: 38%; + width: 1px; + height: 6px; + background-color: var(--light-color); +} + +.letter.horizontalValid::after{ + content: ''; + position: absolute; + left: 10%; + top: 45%; + height: 1px; + width: 6px; + background-color: var(--light-color); +} + .letter-border { box-sizing: border-box; width: calc(var(--box-size) + 1px); height: calc(var(--box-size) + 1px); + z-index: 1; } .borderTop { diff --git a/src/components/Board.js b/src/components/Board.js index c618b8e..8d49e60 100644 --- a/src/components/Board.js +++ b/src/components/Board.js @@ -1,6 +1,11 @@ import React from "react"; import Piece from "./Piece"; import DragShadow from "./DragShadow"; +import { getGridFromPieces } from "../logic/getGridFromPieces"; +import { isKnown } from "@skedwards88/word_logic"; +import { trie } from "../logic/trie"; +import { getWordsFromPieces } from "../logic/getWordsFromPieces"; +import { transposeGrid } from "@skedwards88/word_logic"; // Returns a grid with the number of letters at each location in the grid export function countingGrid(height, width, pieces) { @@ -25,6 +30,79 @@ export function countingGrid(height, width, pieces) { return grid; } +function getHorizontalValidityGrid({grid, originalWords}) { + // return a 2D array of bools indicating whether + // the position corresponds to a letter on the board + // that is part of a valid horizontal word + const height = grid.length; + const width = grid[0].length; + + const horizontalValidityGrid = Array(height) + .fill(undefined) + .map(() => Array(width).fill(false)); + + for (const [rowIndex, row] of grid.entries()) { + let word = ""; + let indexes = []; + for (const [columnIndex, letter] of row.entries()) { + if (letter != "") { + word += letter; + indexes.push(columnIndex); + } else { + if (word.length > 1) { + // If the word is one of the original words, always consider it valid (in case we updated the dictionary in the interim). + // Otherwise, check whether it is a word in the trie. + let isWord = originalWords.includes(word); + if (!isWord) { + ({ isWord } = isKnown(word, trie)); + } + if (isWord) { + indexes.forEach( + (index) => (horizontalValidityGrid[rowIndex][index] = true) + ); + } + } + word = ""; + indexes = []; + } + } + // Also end the word if we reach the end of the row + if (word.length > 1) { + // If the word is one of the original words, always consider it valid (in case we updated the dictionary in the interim). + // Otherwise, check whether it is a word in the trie. + let isWord = originalWords.includes(word); + if (!isWord) { + ({ isWord } = isKnown(word, trie)); + } + if (isWord) { + indexes.forEach( + (index) => (horizontalValidityGrid[rowIndex][index] = true) + ); + } + } + } + + return horizontalValidityGrid; +} + +function getWordValidityGrids({ pieces, gridSize }) { + const originalWords = getWordsFromPieces({ + pieces, + gridSize, + solution: true, + }); + + const grid = getGridFromPieces({ pieces, gridSize, solution: false }); + + const horizontalValidityGrid = getHorizontalValidityGrid({grid, originalWords}) + + const transposedGrid = transposeGrid(grid); + const horizontalTransposedValidityGrid = getHorizontalValidityGrid({grid: transposedGrid, originalWords}); + const verticalValidityGrid = transposeGrid(horizontalTransposedValidityGrid); + + return [horizontalValidityGrid, verticalValidityGrid]; +} + export default function Board({ pieces, gridSize, @@ -38,6 +116,7 @@ export default function Board({ ); const overlapGrid = countingGrid(gridSize, gridSize, boardPieces); + const [horizontalValidityGrid, verticalValidityGrid] = getWordValidityGrids({ pieces, gridSize }); const pieceElements = boardPieces.map((piece) => ( )); diff --git a/src/components/Piece.js b/src/components/Piece.js index bf4ccf3..2bb0270 100644 --- a/src/components/Piece.js +++ b/src/components/Piece.js @@ -6,6 +6,8 @@ function Letter({ pieceRowIndex, pieceColIndex, overlapping, + isHorizontallyValid, + isVerticallyValid, gameIsSolved, dispatchGameState, }) { @@ -28,6 +30,12 @@ function Letter({ if (overlapping) { className += " overlapping"; } + if (isHorizontallyValid) { + className += " horizontalValid"; + } + if (isVerticallyValid) { + className += " verticalValid"; + } return (
1 } + isHorizontallyValid={ + isOnBoard && + horizontalValidityGrid[piece.boardTop + rowIndex][ + piece.boardLeft + colIndex + ] + } + isVerticallyValid={ + isOnBoard && + verticalValidityGrid[piece.boardTop + rowIndex][ + piece.boardLeft + colIndex + ] + } gameIsSolved={gameIsSolved} dispatchGameState={dispatchGameState} /> From d027df175e2c2e6b47bcd8e04a99949cec8ac11b Mon Sep 17 00:00:00 2001 From: skedwards88 Date: Mon, 5 Feb 2024 06:45:32 -0800 Subject: [PATCH 5/9] change word validity styling --- src/App.css | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/App.css b/src/App.css index 4dcaf7f..0820399 100644 --- a/src/App.css +++ b/src/App.css @@ -355,31 +355,33 @@ a { color: rgb(226 88 88); } -.letter.verticalValid::before{ +.letter.verticalValid:not(.filled)::before { content: ''; position: absolute; - left: 18%; - top: 38%; - width: 1px; - height: 6px; + left: calc(50% - (10% / 2)); + top: 0%; + width: 10%; + height: 100%; background-color: var(--light-color); + opacity: 15%; } -.letter.horizontalValid::after{ +.letter.horizontalValid:not(.filled)::after{ content: ''; position: absolute; - left: 10%; - top: 45%; - height: 1px; - width: 6px; + left: 0; + top: calc(50% - (10% / 2)); + height: 10%; + width: 100%; background-color: var(--light-color); + opacity: 15%; } .letter-border { box-sizing: border-box; width: calc(var(--box-size) + 1px); height: calc(var(--box-size) + 1px); - z-index: 1; + position: relative; } .borderTop { From 144575685c95fe169581c28d1a8096d6619271f3 Mon Sep 17 00:00:00 2001 From: skedwards88 Date: Mon, 5 Feb 2024 07:04:36 -0800 Subject: [PATCH 6/9] put validity indication behind toggle --- src/App.css | 20 ++++++++++++++++++++ src/components/Board.js | 3 ++- src/components/Game.js | 1 + src/components/Piece.js | 4 ++-- src/components/Settings.js | 17 +++++++++++++++++ src/images/checkmark-black.svg | 4 ++++ src/logic/gameInit.js | 2 ++ 7 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 src/images/checkmark-black.svg diff --git a/src/App.css b/src/App.css index 0820399..a99993f 100644 --- a/src/App.css +++ b/src/App.css @@ -72,6 +72,26 @@ button:disabled { -webkit-overflow-scrolling: auto; } +/* Checkbox styling */ +input[type="checkbox" i] { + all: unset; + text-decoration: none; + text-align: center; + appearance: none; + width: calc(var(--default-box-size) * 0.8); + height: calc(var(--default-box-size) * 0.8); + border-radius: 2px; + background-color: var(--light-color); + border: 3px solid var(--light-color); +} + +input[type="checkbox" i]:checked { + background-image: url("./images/checkmark-black.svg"); + background-position: center; + background-repeat: no-repeat; + background-size: contain; +} + /* Slider setting styling */ input[type="range"] { appearance: none; diff --git a/src/components/Board.js b/src/components/Board.js index 8d49e60..63bcc05 100644 --- a/src/components/Board.js +++ b/src/components/Board.js @@ -110,13 +110,14 @@ export default function Board({ dragDestination, gameIsSolved, dispatchGameState, + indicateValidity, }) { const boardPieces = pieces.filter( (piece) => piece.boardTop >= 0 && piece.boardLeft >= 0 ); const overlapGrid = countingGrid(gridSize, gridSize, boardPieces); - const [horizontalValidityGrid, verticalValidityGrid] = getWordValidityGrids({ pieces, gridSize }); + const [horizontalValidityGrid, verticalValidityGrid] = indicateValidity ? getWordValidityGrids({ pieces, gridSize }) : [undefined, undefined]; const pieceElements = boardPieces.map((piece) => ( {gameState.allPiecesAreUsed ? (
+ +
+
+ +
+ Indicate whether letters form a valid word +
+
+ +
+
From b982319da469347fc6cf2d26def87ee86fdc58bd Mon Sep 17 00:00:00 2001 From: skedwards88 Date: Tue, 6 Feb 2024 07:53:45 -0800 Subject: [PATCH 8/9] allow indicateValidity to change mid game --- src/components/Settings.js | 3 ++- src/logic/gameReducer.js | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/Settings.js b/src/components/Settings.js index 75e6f1e..ae8d0df 100644 --- a/src/components/Settings.js +++ b/src/components/Settings.js @@ -50,6 +50,7 @@ export default function Settings({ setDisplay, dispatchGameState, gameState }) { id="indicateValidity" type="checkbox" defaultChecked={gameState.indicateValidity} + onChange={() => dispatchGameState({action: "changeIndicateValidity"})} /> @@ -63,7 +64,7 @@ export default function Settings({ setDisplay, dispatchGameState, gameState }) { aria-label="cancel" onClick={() => setDisplay("game")} > - Cancel + Return diff --git a/src/logic/gameReducer.js b/src/logic/gameReducer.js index 32ec5c5..5a4a659 100644 --- a/src/logic/gameReducer.js +++ b/src/logic/gameReducer.js @@ -501,6 +501,8 @@ function updateCompletionState(gameState) { export function gameReducer(currentGameState, payload) { if (payload.action === "newGame") { return gameInit({ ...payload, seed: undefined, useSaved: false }); + } if (payload.action === "changeIndicateValidity") { + return {...currentGameState, indicateValidity: !currentGameState.indicateValidity}; } else if (payload.action === "getHint") { sendAnalytics("hint"); From 48b32a4d6f2f13edc312936368156675f035edf6 Mon Sep 17 00:00:00 2001 From: skedwards88 Date: Tue, 6 Feb 2024 08:02:09 -0800 Subject: [PATCH 9/9] prettier --- src/App.css | 6 +++--- src/components/App.js | 11 +++++++++-- src/components/Board.js | 16 ++++++++++++---- src/components/Settings.js | 5 +++-- src/logic/gameReducer.js | 7 +++++-- src/logic/gameSolvedQ.js | 6 +++++- src/logic/getGridFromPieces.js | 5 ++++- 7 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/App.css b/src/App.css index a99993f..b6e31a4 100644 --- a/src/App.css +++ b/src/App.css @@ -376,7 +376,7 @@ a { } .letter.verticalValid:not(.filled)::before { - content: ''; + content: ""; position: absolute; left: calc(50% - (10% / 2)); top: 0%; @@ -386,8 +386,8 @@ a { opacity: 15%; } -.letter.horizontalValid:not(.filled)::after{ - content: ''; +.letter.horizontalValid:not(.filled)::after { + content: ""; position: absolute; left: 0; top: calc(50% - (10% / 2)); diff --git a/src/components/App.js b/src/components/App.js index 7dfa528..8769c28 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -125,7 +125,11 @@ export default function App() { case "daily": // force reinitialize the daily state if the day has changed if (dailyGameState.seed != getDailySeed()) { - dailyDispatchGameState({action: "newGame", isDaily: true, useSaved: false}); + dailyDispatchGameState({ + action: "newGame", + isDaily: true, + useSaved: false, + }); } return (
@@ -142,7 +146,10 @@ export default function App() {
diff --git a/src/components/Board.js b/src/components/Board.js index 63bcc05..a1f467c 100644 --- a/src/components/Board.js +++ b/src/components/Board.js @@ -30,7 +30,7 @@ export function countingGrid(height, width, pieces) { return grid; } -function getHorizontalValidityGrid({grid, originalWords}) { +function getHorizontalValidityGrid({ grid, originalWords }) { // return a 2D array of bools indicating whether // the position corresponds to a letter on the board // that is part of a valid horizontal word @@ -94,10 +94,16 @@ function getWordValidityGrids({ pieces, gridSize }) { const grid = getGridFromPieces({ pieces, gridSize, solution: false }); - const horizontalValidityGrid = getHorizontalValidityGrid({grid, originalWords}) + const horizontalValidityGrid = getHorizontalValidityGrid({ + grid, + originalWords, + }); const transposedGrid = transposeGrid(grid); - const horizontalTransposedValidityGrid = getHorizontalValidityGrid({grid: transposedGrid, originalWords}); + const horizontalTransposedValidityGrid = getHorizontalValidityGrid({ + grid: transposedGrid, + originalWords, + }); const verticalValidityGrid = transposeGrid(horizontalTransposedValidityGrid); return [horizontalValidityGrid, verticalValidityGrid]; @@ -117,7 +123,9 @@ export default function Board({ ); const overlapGrid = countingGrid(gridSize, gridSize, boardPieces); - const [horizontalValidityGrid, verticalValidityGrid] = indicateValidity ? getWordValidityGrids({ pieces, gridSize }) : [undefined, undefined]; + const [horizontalValidityGrid, verticalValidityGrid] = indicateValidity + ? getWordValidityGrids({ pieces, gridSize }) + : [undefined, undefined]; const pieceElements = boardPieces.map((piece) => ( dispatchGameState({action: "changeIndicateValidity"})} + onChange={() => + dispatchGameState({ action: "changeIndicateValidity" }) + } /> -