Skip to content

Commit

Permalink
move logic around
Browse files Browse the repository at this point in the history
  • Loading branch information
Robert Ferentz committed Jan 23, 2024
1 parent 854a0fa commit e17ffd4
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 54 deletions.
13 changes: 11 additions & 2 deletions src/GameContainer.module.css
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
.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;
border: 1px solid black;
display: flex;
display: grid;
grid: repeat(9, 1fr) / repeat(9, 1fr);
justify-content: center;
justify-content: center;
border-collapse: collapse;
}
}
71 changes: 38 additions & 33 deletions src/GameContainer.tsx
Original file line number Diff line number Diff line change
@@ -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)
}
})
Expand All @@ -35,27 +33,34 @@ export const GameContainer = () => {
setSelected({ x, y })
}
return (
<Show when={gameController.currentBoard.length} fallback="Loading...">
<div class={styles.container}>
<For each={gameController.currentBoard}>
{(row, rowIndex) => (
<For each={row}>
{(item, colIndex) => (
<NumberSquare
tabIndex={(rowIndex() + 1) * (colIndex() + 1)}
onGuess={validateGuess(rowIndex(), colIndex())}
value={item}
bottomBorderDark={(rowIndex() + 1) % 3 === 0}
rightBorderDark={(colIndex() + 1) % 3 === 0}
coords={{ x: colIndex(), y: rowIndex() }}
isSelected={selected()?.x === colIndex() && selected()?.y === rowIndex()}
onSelected={handleSelect}
/>
)}
</For>
)}
</For>
</div>
</Show>
<>
<div class={styles.info}>
<span>Difficulty: {gameController.difficulty}</span>
<span>Mistakes: {gameController.mistakes}</span>
</div>
<div class={styles.container}>
<For each={gameController.currentBoard}>
{(row, rowIndex) => (
<For each={row}>
{(item, colIndex) => (
<NumberSquare
tabIndex={(rowIndex() + 1) * (colIndex() + 1)}
onGuess={handleGuess(rowIndex(), colIndex())}
value={item}
bottomBorderDark={(rowIndex() + 1) % 3 === 0}
rightBorderDark={(colIndex() + 1) % 3 === 0}
coords={{ x: colIndex(), y: rowIndex() }}
isSelected={selected()?.x === colIndex() && selected()?.y === rowIndex()}
onSelected={handleSelect}
isCorrect={gameController.isCorrectGuess(rowIndex(), colIndex(), item)}
isMistake={gameController.isMistakenGuess(rowIndex(), colIndex(), item)}
isFixed={gameController.isFixedValue(rowIndex(), colIndex())}
/>
)}
</For>
)}
</For>
</div>
</>
)
}
10 changes: 7 additions & 3 deletions src/NumberSquare.module.css
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -18,7 +18,7 @@
padding-top: 4px;
}

.label {
.label {
height: 100%;
width: 100%;
}
Expand All @@ -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);
}
22 changes: 12 additions & 10 deletions src/NumberSquare.tsx
Original file line number Diff line number Diff line change
@@ -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 = {
Expand All @@ -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()
Expand All @@ -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) => {
Expand All @@ -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}
>
<div>{props.value || val()}</div>
<div>{props.value || ''}</div>
</div>
)
}
27 changes: 21 additions & 6 deletions src/stores/GameStore.ts
Original file line number Diff line number Diff line change
@@ -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<number[][]>([])
Expand All @@ -8,9 +9,6 @@ const [current, setCurrent] = createStore<number[][]>([])
const [difficulty, setDifficulty] = createSignal<Difficulty>('Easy')
const [mistakes, setMistakes] = createSignal<number>(0)

// export const boardStore = { board, setBoard }
// export const solutionStore = { solution, setSolution }

class GameController {
private storeGame(game: Game) {
setSolution(reconcile(game.solution))
Expand All @@ -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()
}
Expand All @@ -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(
Expand Down Expand Up @@ -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()

0 comments on commit e17ffd4

Please sign in to comment.