add error message and fix guess status logic
This commit is contained in:
parent
a33d1c08de
commit
099b46849c
4 changed files with 57 additions and 16 deletions
14
src/App.tsx
14
src/App.tsx
|
@ -1,15 +1,16 @@
|
|||
import { useState, useEffect } from "react";
|
||||
import { Alert } from "./components/alerts/Alert";
|
||||
import { Grid } from "./components/grid/Grid";
|
||||
import { Keyboard } from "./components/keyboard/Keyboard";
|
||||
import { WinModal } from "./components/win-modal/WinModal";
|
||||
import { getGuessStatuses } from "./lib/statuses";
|
||||
import { solution, isWordInWordList, isWinningWord } from "./lib/words";
|
||||
import { isWordInWordList, isWinningWord } from "./lib/words";
|
||||
|
||||
function App() {
|
||||
const [guesses, setGuesses] = useState<string[]>([]);
|
||||
const [currentGuess, setCurrentGuess] = useState("");
|
||||
const [isGameWon, setIsGameWon] = useState(false);
|
||||
const [isWinModalOpen, setIsWinModalOpen] = useState(false);
|
||||
const [isWordNotFoundAlertOpen, setIsWordNotFoundAlertOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (isGameWon) {
|
||||
|
@ -29,8 +30,10 @@ function App() {
|
|||
|
||||
const onEnter = () => {
|
||||
if (!isWordInWordList(currentGuess)) {
|
||||
return console.error("not in word list");
|
||||
// TODO add messaging for user
|
||||
setIsWordNotFoundAlertOpen(true);
|
||||
setTimeout(() => {
|
||||
setIsWordNotFoundAlertOpen(false);
|
||||
}, 2000);
|
||||
}
|
||||
if (currentGuess.length === 5 && guesses.length < 6 && !isGameWon) {
|
||||
if (isWinningWord(currentGuess)) {
|
||||
|
@ -42,7 +45,8 @@ function App() {
|
|||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="py-8 max-w-7xl mx-auto sm:px-6 lg:px-8">
|
||||
<Alert message="Word not found" isOpen={isWordNotFoundAlertOpen} />
|
||||
<Grid guesses={guesses} currentGuess={currentGuess} />
|
||||
<Keyboard
|
||||
onChar={onChar}
|
||||
|
|
30
src/components/alerts/Alert.tsx
Normal file
30
src/components/alerts/Alert.tsx
Normal file
|
@ -0,0 +1,30 @@
|
|||
import { Fragment } from "react";
|
||||
import { Transition } from "@headlessui/react";
|
||||
|
||||
type Props = {
|
||||
isOpen: boolean;
|
||||
message: string;
|
||||
};
|
||||
|
||||
export const Alert = ({ isOpen, message }: Props) => {
|
||||
return (
|
||||
<Transition
|
||||
show={isOpen}
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300 transition"
|
||||
enterFrom="opacity-0"
|
||||
enterTo="opacity-100"
|
||||
leave="transition ease-in duration-100"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
<div className="absolute top-2.5 left-1/2 transform -translate-x-1/2 max-w-sm w-full bg-rose-200 shadow-lg rounded-lg pointer-events-auto ring-1 ring-black ring-opacity-5 overflow-hidden">
|
||||
<div className="p-4">
|
||||
<p className="text-sm text-center font-medium text-gray-900">
|
||||
{message}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
);
|
||||
};
|
|
@ -12,7 +12,7 @@ export const Grid = ({ guesses, currentGuess }: Props) => {
|
|||
guesses.length < 5 ? Array.from(Array(5 - guesses.length)) : [];
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="pb-6">
|
||||
{guesses.map((guess, i) => (
|
||||
<CompletedRow key={i} guess={guess} />
|
||||
))}
|
||||
|
@ -20,6 +20,6 @@ export const Grid = ({ guesses, currentGuess }: Props) => {
|
|||
{empties.map((_, i) => (
|
||||
<EmptyRow key={i} />
|
||||
))}
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -59,21 +59,27 @@ export const getStatuses = (
|
|||
|
||||
export const getGuessStatuses = (guess: string): CharStatus[] => {
|
||||
const splitSolution = solution.split("");
|
||||
const solutionCharsTaken = splitSolution.map((x) => false);
|
||||
const splitGuess = guess.split("");
|
||||
|
||||
const statuses: CharStatus[] = [];
|
||||
const solutionCharsTaken = splitSolution.map((_) => false);
|
||||
|
||||
guess.split("").forEach((letter, i) => {
|
||||
// handle the correct case
|
||||
const statuses: CharStatus[] = Array.from(Array(guess.length));
|
||||
|
||||
// handle all correct cases first
|
||||
splitGuess.forEach((letter, i) => {
|
||||
if (letter === splitSolution[i]) {
|
||||
statuses.push("correct");
|
||||
statuses[i] = "correct";
|
||||
solutionCharsTaken[i] = true;
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
splitGuess.forEach((letter, i) => {
|
||||
if (statuses[i]) return;
|
||||
|
||||
// handles the absent case
|
||||
if (!splitSolution.includes(letter)) {
|
||||
statuses.push("absent");
|
||||
// handles the absent case
|
||||
statuses[i] = "absent";
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -81,12 +87,13 @@ export const getGuessStatuses = (guess: string): CharStatus[] => {
|
|||
const indexOfPresentChar = splitSolution.findIndex(
|
||||
(x, index) => x === letter && !solutionCharsTaken[index]
|
||||
);
|
||||
|
||||
if (indexOfPresentChar > -1) {
|
||||
statuses.push("present");
|
||||
statuses[i] = "present";
|
||||
solutionCharsTaken[indexOfPresentChar] = true;
|
||||
return;
|
||||
} else {
|
||||
statuses.push("absent");
|
||||
statuses[i] = "absent";
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue