keyboard, fix clue bugs, length slider
This commit is contained in:
105
src/Game.tsx
105
src/Game.tsx
@@ -1,7 +1,8 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { Row, RowState } from "./Row";
|
||||
import { pick, wordLength } from "./util";
|
||||
import dictionary from "./dictionary.json";
|
||||
import { Clue, clue, clueClass } from "./clue";
|
||||
import { Keyboard } from "./Keyboard";
|
||||
|
||||
enum GameState {
|
||||
Playing,
|
||||
@@ -10,35 +11,40 @@ enum GameState {
|
||||
|
||||
interface GameProps {
|
||||
target: string;
|
||||
wordLength: number;
|
||||
maxGuesses: number;
|
||||
}
|
||||
|
||||
function Game(props: GameProps) {
|
||||
const [gameState, setGameState] = useState(GameState.Playing);
|
||||
const [guesses, setGuesses] = useState<string[]>([]);
|
||||
const [currentGuess, setCurrentGuess] = useState<string>("");
|
||||
const maxGuesses = 6;
|
||||
|
||||
const onKey = (key: string) => {
|
||||
console.log(key);
|
||||
if (gameState !== GameState.Playing) return;
|
||||
if (guesses.length === props.maxGuesses) return;
|
||||
if (/^[a-z]$/.test(key)) {
|
||||
setCurrentGuess((guess) => (guess + key).slice(0, props.wordLength));
|
||||
} else if (key === "Backspace") {
|
||||
setCurrentGuess((guess) => guess.slice(0, -1));
|
||||
} else if (key === "Enter") {
|
||||
if (currentGuess.length !== props.wordLength) {
|
||||
// TODO show a helpful message
|
||||
return;
|
||||
}
|
||||
if (!dictionary.includes(currentGuess)) {
|
||||
// TODO show a helpful message
|
||||
return;
|
||||
}
|
||||
setGuesses((guesses) => guesses.concat([currentGuess]));
|
||||
setCurrentGuess((guess) => "");
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const onKeyDown = (e: KeyboardEvent) => {
|
||||
console.log(e.key)
|
||||
if (gameState !== GameState.Playing) return;
|
||||
if (guesses.length === maxGuesses) return;
|
||||
if (/^[a-z]$/.test(e.key)) {
|
||||
setCurrentGuess((guess) => (guess + e.key).slice(0, wordLength));
|
||||
} else if (e.key === "Backspace") {
|
||||
setCurrentGuess((guess) => guess.slice(0, -1));
|
||||
} else if (e.key === "Enter") {
|
||||
if (currentGuess.length !== wordLength) {
|
||||
// TODO show a helpful message
|
||||
return;
|
||||
}
|
||||
if (!dictionary.includes(currentGuess)) {
|
||||
// TODO show a helpful message
|
||||
return;
|
||||
}
|
||||
setGuesses((guesses) => guesses.concat([currentGuess]));
|
||||
setCurrentGuess((guess) => "");
|
||||
}
|
||||
onKey(e.key);
|
||||
};
|
||||
|
||||
document.addEventListener("keydown", onKeyDown);
|
||||
@@ -49,40 +55,37 @@ function Game(props: GameProps) {
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [currentGuess]);
|
||||
|
||||
let rowDivs = [];
|
||||
let i = 0;
|
||||
for (const guess of guesses) {
|
||||
rowDivs.push(
|
||||
<Row
|
||||
key={i++}
|
||||
rowState={RowState.LockedIn}
|
||||
letters={guess}
|
||||
target={props.target}
|
||||
/>
|
||||
);
|
||||
}
|
||||
if (rowDivs.length < maxGuesses) {
|
||||
rowDivs.push(
|
||||
<Row
|
||||
key={i++}
|
||||
rowState={RowState.Pending}
|
||||
letters={currentGuess}
|
||||
target={props.target}
|
||||
/>
|
||||
);
|
||||
while (rowDivs.length < maxGuesses) {
|
||||
rowDivs.push(
|
||||
let letterInfo = new Map<string, Clue>();
|
||||
const rowDivs = Array(props.maxGuesses)
|
||||
.fill(undefined)
|
||||
.map((_, i) => {
|
||||
const guess = [...guesses, currentGuess][i] ?? "";
|
||||
const cluedLetters = clue(guess, props.target);
|
||||
if (i < guesses.length) {
|
||||
for (const { clue, letter } of cluedLetters) {
|
||||
if (clue === undefined) break;
|
||||
const old = letterInfo.get(letter);
|
||||
if (old === undefined || clue > old) {
|
||||
letterInfo.set(letter, clue);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (
|
||||
<Row
|
||||
key={i++}
|
||||
rowState={RowState.Pending}
|
||||
letters=""
|
||||
target={props.target}
|
||||
key={i}
|
||||
wordLength={props.wordLength}
|
||||
rowState={i < guesses.length ? RowState.LockedIn : RowState.Pending}
|
||||
cluedLetters={cluedLetters}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return <div className="Game">{rowDivs}</div>;
|
||||
return (
|
||||
<div className="Game">
|
||||
{rowDivs}
|
||||
<Keyboard letterInfo={letterInfo} onKey={onKey} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Game;
|
||||
|
||||
Reference in New Issue
Block a user