Skip to content

Commit

Permalink
feat: enabled new game button
Browse files Browse the repository at this point in the history
refactor: wrap map initialization with resetMap func
  • Loading branch information
thisisWooyeol committed Sep 15, 2024
1 parent 284321d commit 0f9cb2e
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 22 deletions.
48 changes: 26 additions & 22 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,29 @@ import './App.css';

import { useEffect, useState } from 'react';

import { getRandomInitPos, getRandomPos, isGameLose, isGameWin, type Map2048, moveMapIn2048Rule, stringDirectionMap } from './Map2048';
import { getRandomPos, isGameLose, isGameWin, type Map2048, moveMapIn2048Rule, resetMap, stringDirectionMap } from './Map2048';


function App() {
const rowLength: number = 4;
const columnLength: number = 4;
const initPos: number[] = getRandomInitPos(rowLength, columnLength);
const [map, setMap] = useState<Map2048>(resetMap(rowLength, columnLength));

const [keyPressed, setKeyPressed] = useState<string>('');
const [gameStatus, setGameStatus] = useState<'playing' | 'win' | 'lose'>('playing');

const [map, setMap] = useState<Map2048>(
Array.from({ length: rowLength }, (_, rowIndex) =>
Array.from(
{ length: columnLength },
(_, columnIndex) => {
return initPos.some(pos =>
pos === rowIndex * rowLength + columnIndex) ? 2 : null;
},
),
)
);
const newGameHandler = () => {
setMap(resetMap(rowLength, columnLength));
setGameStatus('playing');
};
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>
);
};

useEffect(() => {
const handleKeyUp = (event: WindowEventMap['keyup']) => {
Expand All @@ -41,6 +42,9 @@ function App() {
}, []);

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

const direction = stringDirectionMap[keyPressed];
if (direction !== undefined) {
const {result, isMoved} = moveMapIn2048Rule(map, direction);
Expand All @@ -66,7 +70,7 @@ function App() {
setGameStatus('lose');
console.info('You lose!');
}
}, [keyPressed, map]);
}, [gameStatus, keyPressed, map]);

return (
<div className='flex items-center justify-center h-screen'>
Expand Down Expand Up @@ -101,10 +105,8 @@ function App() {
<p>Original game link at <a href='https://play2048.co/'style={{color: 'blue'}}>here!</a></p>
</div>
<div>
<button className='bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded'>
New Game
</button>
</div>
{newGameButton('New Game')}
</div>
</div>

{/* Game 2048 board */}
Expand All @@ -123,13 +125,15 @@ function App() {

{/* Game status */}
{gameStatus === 'win' &&
<div className='absolute inset-0 bg-green-400 bg-opacity-50 rounded-lg flex items-center justify-center text-5xl font-extrabold'>
You Win!
<div className='absolute inset-0 bg-teal-300 bg-opacity-50 rounded-lg flex flex-col items-center justify-center'>
<p className='text-5xl font-extrabold mb-4'>You Win!</p>
{newGameButton('Play again?')}
</div>
}
{gameStatus === 'lose' &&
<div className='absolute inset-0 bg-red-400 bg-opacity-50 rounded-lg flex items-center justify-center text-5xl font-extrabold'>
You Lose! Try again?
<div className='absolute inset-0 bg-red-300 bg-opacity-50 rounded-lg flex flex-col items-center justify-center'>
<p className='text-5xl font-extrabold mb-4'>You Lose!</p>
{newGameButton('Try again?')}
</div>
}
</div>
Expand Down
19 changes: 19 additions & 0 deletions src/Map2048.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,25 @@ export const moveMapIn2048Rule = (
type DirectionDegreeMap = Record<Direction, RotateDegree>;
type MoveResult = { result: Map2048; isMoved: boolean };

/**
* 2048 게임에서, Map을 초기화하는 함수입니다.
* @param rowLength Map의 행 길이
* @param columnLength Map의 열 길이
* @returns columnLength * rowLength 크기의 2048 게임 Map
*/
export const resetMap = (rowLength: number, columnLength: number) : Map2048 => {
const initPos: number[] = getRandomInitPos(rowLength, columnLength);
return Array.from({ length: rowLength }, (_, rowIndex) =>
Array.from(
{ length: columnLength },
(_, columnIndex) => {
return initPos.some(pos =>
pos === rowIndex * rowLength + columnIndex) ? 2 : null;
},
),
);
};

/**
* 2048 게임에서, Map의 2개의 초기 블록 위치를 반환하는 함수입니다.
* @param rowLength Map의 행 길이
Expand Down

0 comments on commit 0f9cb2e

Please sign in to comment.