Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 74 additions & 51 deletions workspaces/simon-game/src/app/components/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from "react";
import React, { useEffect, useState } from "react";

import { Box } from "./Box.tsx";
import { playNote } from "../util/playNote.ts";
Expand All @@ -24,55 +24,78 @@ export function App() {
const [gameState, setGameState] = useState<GameState>("pre-game");
const [correctMoves, setCorrectMoves] = useState<readonly number[]>([]);

if (gameState === "pre-game") {
return (
<div style={{ display: "flex", gap: 10 }}>
<button
onClick={() => {
setGameState("cpu-turn");
setCorrectMoves((prev) => [...prev, randNum(4)]); // TODO: Add to cpu-turn state instead once created
}}
>
Start Game
</button>
Simon Game
</div>
);
}
useEffect(() => {
if (gameState !== "cpu-turn") {
return;
}
setCorrectMoves((prev) => [...prev, randNum(4)]);
setPlayerMoves([]);
setGameState("player-turn");
}, [gameState]);

const newGame = () => {
setGameState("cpu-turn");
setCorrectMoves([]);
setPlayerMoves([]);
};

return (
<>
<div style={{ display: "flex", gap: 10 }}>
{config.boxes.map((box, index) => (
<Box
key={index}
color={box.color}
onClick={() => {
playNote(box.frequency);
setPlayerMoves(() => {
const newPlayerMoves = [...playerMoves, index];
const isSequenceCorrect = isPrefixCorrect(
newPlayerMoves,
correctMoves,
);
if (!isSequenceCorrect) {
setGameState("game-over");
return newPlayerMoves;
}
if (newPlayerMoves.length === correctMoves.length) {
setGameState("cpu-turn");
return [];
}
setGameState("player-turn");
return newPlayerMoves;
});
}}
/>
))}
</div>
<pre>Game State: {gameState}</pre>
<pre>Player Moves: {JSON.stringify(playerMoves, null, 2)}</pre>
<pre>Correct Moves: {JSON.stringify(correctMoves, null, 2)}</pre>
</>
);
switch (gameState) {
case "cpu-turn": {
return (
<>
<div style={{ display: "flex", gap: 10 }}>
{config.boxes.map((box, index) => (
<Box key={index} color={box.color} isDisabled />
))}
</div>
<pre>Game State: {gameState}</pre>
<pre>Player Moves: {JSON.stringify(playerMoves, null, 2)}</pre>
<pre>Correct Moves: {JSON.stringify(correctMoves, null, 2)}</pre>
</>
);
}
case "game-over": {
return (
<>
<h1>Game Over ... Start again ...</h1>
<button onClick={newGame}>New Game</button>
</>
);
}
case "player-turn": {
return (
<>
<div style={{ display: "flex", gap: 10 }}>
{config.boxes.map((box, index) => (
<Box
key={index}
color={box.color}
onClick={() => {
playNote(box.frequency);
const newPlayerMoves = [...playerMoves, index];
setPlayerMoves(newPlayerMoves);
if (!isPrefixCorrect(newPlayerMoves, correctMoves)) {
setGameState("game-over");
} else if (newPlayerMoves.length === correctMoves.length) {
setGameState("cpu-turn");
}
}}
/>
))}
</div>
<pre>Game State: {gameState}</pre>
<pre>Player Moves: {JSON.stringify(playerMoves, null, 2)}</pre>
<pre>Correct Moves: {JSON.stringify(correctMoves, null, 2)}</pre>
</>
);
}
case "pre-game": {
return (
<div style={{ display: "flex", gap: 10 }}>
<button onClick={newGame}>Start Game</button>
Simon Game
</div>
);
}
}
}
12 changes: 7 additions & 5 deletions workspaces/simon-game/src/app/components/Box.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@ import React from "react";
type Props = {
color?: string;
height?: number;
width?: number;
isDisabled?: boolean;
margin?: number;
onClick: () => void;
onClick?: () => void;
width?: number;
};

export function Box({
color = "lightblue",
height = 100,
width = 100,
isDisabled = false,
margin,
onClick,
width = 100,
}: Props) {
return (
<button
Expand All @@ -23,10 +25,10 @@ export function Box({
width,
borderRadius: 20, // rounded corners
margin, // spaces between boxes
cursor: "pointer",
cursor: isDisabled ? undefined : "pointer",
border: 0,
}}
onClick={onClick}
onClick={isDisabled ? undefined : onClick}
/>
);
}
Loading