diff --git a/src/GameContainer.module.css b/src/GameContainer.module.css index a09c98f..9826b6e 100644 --- a/src/GameContainer.module.css +++ b/src/GameContainer.module.css @@ -1,3 +1,12 @@ +.info { + display: flex; + flex-direction: row; + justify-content: space-evenly; + align-items: center; + margin: 0 auto; + margin-block-end: 1rem; +} + .container { width: fit-content; margin: 0 auto; @@ -5,6 +14,6 @@ display: flex; display: grid; grid: repeat(9, 1fr) / repeat(9, 1fr); - justify-content: center; + justify-content: center; border-collapse: collapse; -} \ No newline at end of file +} diff --git a/src/GameContainer.tsx b/src/GameContainer.tsx index e8e3c90..9a19aa6 100644 --- a/src/GameContainer.tsx +++ b/src/GameContainer.tsx @@ -1,27 +1,25 @@ -import { For, Show, createEffect, createSignal, onMount } from 'solid-js' +import { For, createEffect, createSignal } from 'solid-js' import { NumberSquare } from './NumberSquare' import styles from './GameContainer.module.css' import { gameController } from './stores/GameStore' export const GameContainer = () => { const [selected, setSelected] = createSignal<{ x: number; y: number } | null>(null) - const validateGuess = (row: number, col: number) => { + const handleGuess = (row: number, col: number) => { return (guess: number) => { - const solutionValue = gameController.solutionBoard[row][col] - const isCorrect = guess === solutionValue - if (isCorrect) { - gameController.setCurrentBoardValue(row, col, guess) - } - gameController.saveGame() - return isCorrect + gameController.setCurrentBoardValue(row, col, guess) + gameController.saveGame() } } + - const isSolved = () => gameController.currentBoard.flatMap((m) => m).every((m) => !!m) + createEffect(() => { - if (isSolved()) { + if (gameController.isSolved) { setTimeout(() => { alert('Yay! You did it!') + gameController.deleteGame() + setSelected(null) }, 1000) } }) @@ -35,27 +33,34 @@ export const GameContainer = () => { setSelected({ x, y }) } return ( - -
- - {(row, rowIndex) => ( - - {(item, colIndex) => ( - - )} - - )} - -
-
+ <> +
+ Difficulty: {gameController.difficulty} + Mistakes: {gameController.mistakes} +
+
+ + {(row, rowIndex) => ( + + {(item, colIndex) => ( + + )} + + )} + +
+ ) } diff --git a/src/NumberSquare.module.css b/src/NumberSquare.module.css index 3cfa2e7..eaa0ada 100644 --- a/src/NumberSquare.module.css +++ b/src/NumberSquare.module.css @@ -1,6 +1,6 @@ .square { --sqw: min(calc((99vw - 1rem) / 9), 50px); - border: 1px solid #999; + border: 1px solid #999; display: flex; align-items: center; justify-content: center; @@ -18,7 +18,7 @@ padding-top: 4px; } -.label { +.label { height: 100%; width: 100%; } @@ -33,7 +33,11 @@ color: red; } +.correct { + color: #3774be; +} + .selected { outline: none; - background-color: rgba(0,0,100, .2); + background-color: rgba(0, 0, 100, 0.2); } diff --git a/src/NumberSquare.tsx b/src/NumberSquare.tsx index b62b58e..da64790 100644 --- a/src/NumberSquare.tsx +++ b/src/NumberSquare.tsx @@ -1,4 +1,4 @@ -import { Match, Switch, createEffect, createSignal, createUniqueId, on } from 'solid-js' +import { createEffect } from 'solid-js' import styles from './NumberSquare.module.css' type Coords = { @@ -9,16 +9,17 @@ type NumberSquareProps = { value: number rightBorderDark?: boolean bottomBorderDark?: boolean - onGuess: (guess: number) => boolean + onGuess: (guess: number) => void tabIndex: number coords: Coords isSelected: boolean + isCorrect: boolean + isMistake: boolean + isFixed: boolean onSelected: (coords: Coords) => void } export const NumberSquare = (props: NumberSquareProps) => { - const [val, setVal] = createSignal('') - const [mistake, setMistake] = createSignal(false) let root: HTMLDivElement | undefined const handleInput = (e: KeyboardEvent) => { e.stopPropagation() @@ -41,16 +42,16 @@ export const NumberSquare = (props: NumberSquareProps) => { return } - if (props.value) return + if (props.isFixed) return + const allowInputs = /([1-9]{1,1})/gi if (!allowInputs.test(e.key)) { - setVal('') + props.onGuess(0) return } - setVal(e.key) const guess = parseInt(e.key, 10) - setMistake(!props.onGuess(guess)) + props.onGuess(guess) } const handleClick = (e: MouseEvent) => { @@ -72,14 +73,15 @@ export const NumberSquare = (props: NumberSquareProps) => { classList={{ [styles.rightBorderDark]: props.rightBorderDark, [styles.bottomBorderDark]: props.bottomBorderDark, - [styles.mistake]: mistake(), [styles.selected]: props.isSelected, + [styles.mistake]: props.isMistake && !props.isFixed, + [styles.correct]: props.isCorrect && !props.isFixed, }} tabIndex={props.tabIndex} onKeyDown={handleInput} onClick={handleClick} > -
{props.value || val()}
+
{props.value || ''}
) } diff --git a/src/stores/GameStore.ts b/src/stores/GameStore.ts index 09ddbc5..e1fd965 100644 --- a/src/stores/GameStore.ts +++ b/src/stores/GameStore.ts @@ -1,5 +1,6 @@ import { createStore, reconcile } from 'solid-js/store' -import { Difficulty, Game, generateSudoku } from '../game/generate' +import { generateSudoku } from '../game/generate' +import { Difficulty, Game } from '../game/types' import { createSignal } from 'solid-js' const [puzzle, setPuzzle] = createStore([]) @@ -8,9 +9,6 @@ const [current, setCurrent] = createStore([]) const [difficulty, setDifficulty] = createSignal('Easy') const [mistakes, setMistakes] = createSignal(0) -// export const boardStore = { board, setBoard } -// export const solutionStore = { solution, setSolution } - class GameController { private storeGame(game: Game) { setSolution(reconcile(game.solution)) @@ -20,7 +18,7 @@ class GameController { setMistakes(game.mistakes) } createGame(difficulty: Difficulty): void { - const game = generateSudoku(difficulty) + const game = generateSudoku(difficulty) this.storeGame(game) this.saveGame() } @@ -44,12 +42,14 @@ class GameController { get mistakes(): number { return mistakes() } + get isSolved(): boolean { + return gameController.currentBoard.flatMap((m) => m).every((m) => !!m) + } setCurrentBoardValue(row: number, col: number, value: number): void { setCurrent(row, col, value) } - saveGame(): void { if (!this.currentBoard.length) return localStorage.setItem( @@ -77,6 +77,21 @@ class GameController { mistakes: 0, }) } + + isCorrectGuess(row: number, col: number, value: number): boolean { + if(!value) return false + const correctAnswer = this.solutionBoard[row][col] + return value === correctAnswer + } + + isMistakenGuess(row: number, col: number, value: number): boolean { + if(!value) return false + return !this.isCorrectGuess(row, col, value) + } + + isFixedValue(row: number, col: number): boolean { + return this.puzzleBoard[row][col] !== 0 + } } export const gameController = new GameController()