Skip to content

Commit

Permalink
Merge pull request #2 from thisisWooyeol/fix/code-review-woohm402
Browse files Browse the repository at this point in the history
Fix/code review woohm402
  • Loading branch information
thisisWooyeol authored Sep 18, 2024
2 parents 1787935 + 3720bbc commit 667659d
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 76 deletions.
108 changes: 47 additions & 61 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,85 +24,71 @@ function App() {
const columnLength: number = 4;

// Initialize state with data from Local Storage or start fresh
const initialState = loadGameState();
const [map, setMap] = useState<Map2048>(
initialState !== undefined
? initialState.map
: resetMap(rowLength, columnLength),
);
const [score, setScore] = useState<number>(
initialState !== undefined ? initialState.score : 0,
() => loadGameState()?.map ?? resetMap(rowLength, columnLength),
);
const [score, setScore] = useState<number>(loadGameState()?.score ?? 0);
const [bestScore, setBestScore] = useState<number>(
initialState !== undefined ? initialState.bestScore : 0,
loadGameState()?.bestScore ?? 0,
);
const [gameStatus, setGameStatus] = useState<'playing' | 'win' | 'lose'>(
initialState !== undefined ? initialState.gameStatus : 'playing',
loadGameState()?.gameStatus ?? 'playing',
);

const [keyPressed, setKeyPressed] = useState<string>('');
useEffect(() => {
saveGameState({ map, score, bestScore, gameStatus });
}, [map, score, bestScore, gameStatus]);

// Event Handlers
const newGameHandler = useCallback(() => {
const newGameHandler = () => {
setMap(resetMap(rowLength, columnLength));
setScore(0);
setGameStatus('playing');
console.info('New game started!');
}, []);
const newGameButton = useCallback(
(text: string) => {
return (
<button
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
onClick={newGameHandler}
>
{text}
</button>
);
};
const newGameButton = (text: string) => {
return (
<button
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
onClick={newGameHandler}
>
{text}
</button>
);
};

const keyPressHandler = useCallback(
(key: string) => {
if (gameStatus !== 'playing') return;
console.debug('Key Pressed:', key);

const direction = stringDirectionMap[key];
if (direction === undefined) return;

const { result, isMoved, newPoints } = moveMapIn2048Rule(map, direction);
if (isMoved) {
const updatedMap: Map2048 = addRandomBlock(result);
setMap(updatedMap);
setScore((prevScore) => prevScore + newPoints);
setBestScore((prevBestScore) =>
Math.max(prevBestScore, score + newPoints),
);

// check if the game is over
if (isGameWin(updatedMap)) {
setGameStatus('win');
console.info('You win!');
} else if (isGameLose(updatedMap)) {
setGameStatus('lose');
console.info('You lose!');
}
}
},
[newGameHandler],
[gameStatus, map, score],
);

const keyPressHandler = useCallback((key: string) => {
setKeyPressed(key);
console.debug(`Arrow key pressed: ${key}`);
}, []);
useKeyPress(keyPressHandler);

useEffect(() => {
// only move when gameState is playing
if (gameStatus !== 'playing' || keyPressed === '') return;

const direction = stringDirectionMap[keyPressed];
if (direction === undefined) return;

const { result, isMoved, newPoints } = moveMapIn2048Rule(map, direction);
if (isMoved) {
const updatedMap: Map2048 = addRandomBlock(result);
setMap(updatedMap);
setScore((prevScore) => prevScore + newPoints);
}
// Reset keyPressed state after handling
setKeyPressed('');

// check if the game is over
if (isGameWin(result)) {
setGameStatus('win');
console.info('You win!');
} else if (isGameLose(result)) {
setGameStatus('lose');
console.info('You lose!');
}
}, [gameStatus, keyPressed, map]);

useEffect(() => {
setBestScore((prevBestScore) => Math.max(prevBestScore, score));
}, [score]);

useEffect(() => {
saveGameState({ map, score, bestScore, gameStatus });
}, [map, score, bestScore, gameStatus]);

return (
<div className="flex items-center justify-center min-h-screen">
<div className="grid grid-flow-row gap-5 max-w-lg w-full">
Expand Down
4 changes: 1 addition & 3 deletions src/components/GameBoard.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import React from 'react';

import { type Map2048 } from '../utils/Map2048';
import { Tile } from './Tile';

Expand All @@ -8,7 +6,7 @@ type GameBoardProps = {
getCellColor: (value: number | null) => string;
};

export const GameBoard: React.FC<GameBoardProps> = ({ map, getCellColor }) => {
export const GameBoard = ({ map, getCellColor }: GameBoardProps) => {
return (
<div className="grid grid-cols-4 grid-rows-4 gap-4">
{map.map((row, rowIndex) =>
Expand Down
4 changes: 1 addition & 3 deletions src/components/GameInstructions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ type GameInstructionsProps = {
newGameButton: React.ReactNode;
};

export const GameInstructions: React.FC<GameInstructionsProps> = ({
newGameButton,
}) => {
export const GameInstructions = ({ newGameButton }: GameInstructionsProps) => {
return (
<div className="grid grid-cols-4 gap-4 items-center">
<div className="col-span-3 text-left">
Expand Down
4 changes: 2 additions & 2 deletions src/components/GameStatusOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ type GameStatusOverlayProps = {
newGameButton: React.ReactNode;
};

export const GameStatusOverlay: React.FC<GameStatusOverlayProps> = ({
export const GameStatusOverlay = ({
status,
newGameButton,
}) => {
}: GameStatusOverlayProps) => {
const isWin = status === 'win';
const bgColor = isWin
? 'bg-teal-300 bg-opacity-50'
Expand Down
4 changes: 1 addition & 3 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import React from 'react';

type HeaderProps = {
score: number;
bestScore: number;
};

export const Header: React.FC<HeaderProps> = ({ score, bestScore }) => {
export const Header = ({ score, bestScore }: HeaderProps) => {
return (
<div className="flex flex-col sm:flex-row justify-between items-center w-full space-y-2">
{/* Game Title */}
Expand Down
4 changes: 1 addition & 3 deletions src/components/Tile.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import React from 'react';

type TileProps = {
value: number | null;
getCellColor: (value: number | null) => string;
};

export const Tile: React.FC<TileProps> = ({ value, getCellColor }) => {
export const Tile = ({ value, getCellColor }: TileProps) => {
return (
<div
className={`aspect-square rounded flex items-center justify-center text-3xl font-extrabold
Expand Down
11 changes: 10 additions & 1 deletion src/hooks/useKeyPress.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import { useEffect } from 'react';

const ARROW_KEYS = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'];
const ARROW_KEYS = [
'ArrowUp',
'ArrowDown',
'ArrowLeft',
'ArrowRight',
'w',
'a',
's',
'd',
];

export const useKeyPress = (handler: (key: string) => void) => {
useEffect(() => {
Expand Down
4 changes: 4 additions & 0 deletions src/utils/Map2048.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ export const stringDirectionMap: Record<string, Direction> = {
ArrowRight: 'right',
ArrowDown: 'down',
ArrowLeft: 'left',
w: 'up',
d: 'right',
s: 'down',
a: 'left',
};

const validateMapIsNByM = (map: Map2048) => {
Expand Down

0 comments on commit 667659d

Please sign in to comment.