틱택토 게임 만들기 (with TypeScript)
Game 컴포넌트 구성
App.tsx
grid place-content-center
flex items-center justify-content-center
와 동일 아이템을 상하좌우 중앙으로 배치
Game 컴포넌트 초기구성
Status 컴포넌트 구성
Status 컴포넌트는 Game 내부 컴포넌트로 구성되어야함
Status.tsx
Board 컴포넌트 구성
Board 컴포넌트 또한 Game 컴포넌트 내부에서 구성되어야함
Board.tsx
Square 컴포넌트 구성
Squaer 컴포넌트는 Board 내부에서 구성되어야 한다
Squaer.tsx
렌더링 된 Squaer 컴포넌트
History 컴포넌트 구성
History 컴포넌트는 Game 내에서 구성되어야 함
History.tsx
- 사용자는 해당 컴포넌트로 인해 특정 시점으로 이동할 수 있도록 구성할 예정
Square 컴포넌트 로직 구성
Square 리스트 렌더링
Square 컴포넌트에 children prop을 받도록
children의 타입은?
Board 컴포넌트에서 INITAL_SQUARES라는 상수를 지정해 임의의 null이 담긴 배열을 설정
Array(9).fill(null)
현재 까지 구성된 UI
Square 이벤트 연결
스퀘어 버튼을 사용자가 입력시 플레이어가 위치 해야함
- 해당 함수를
Square
컴포넌트에 props
로 전달해야 함
- 클로저를 사용해서
index
를 전달
handlePlay를 Squaer에 props로 전달할때 ISquareProp 함수 타입정의는 어떻게 해야할까?
게임 인덱스와 넥스트 플레이어
gameIndex, nextPlayer 파생상태 설정
handlePlay 함수 로직 설명
nextPlayer
는 gameIndex
의 파생 상태로서, gameIndex
를 2로 나눴을때 0이면 플레이어1, 0이아니면 플레이어2가 된다
- 리액트의 불변성원칙으로
nextSquares
라는 변수에 useState
로 초기값을 설정했던 squares
를 전개한 배열에 담고
nextSquares[index]
는 map
으로 클릭한 index
에 맞춰서 nextPlayer
가 동적으로 변한다
- 동적으로 변한
nextPlayer
변수를 setSquares
에 담아 squares
를 업데이트하고
- 최종적으로
gameIndex
도 +1 한다
Square 컴포넌트의 비활성 상태 설정
children을 사용해서 isPlayed라는 변수를 설정
handlePlay
함수로 인해 null
로 비어있던 children
이 ➡️ 플레이어 1이나 플레이어 2가 담기면서 false
에서 true
값이 됨
children
값이 존재하거나 비어있지않으면 true
를 반환
disabled
속성에 isPlayed
를 넣어 사용자가 클릭했을 시 버튼이 disabled
되게 구성
위너 체크 및 게임 오버
승리 조건 배열 설정
checkWinner 함수로 승리 조건 로직 설정
승리조건이 맞을때, winner 변수가 값이 채워진다
게임이 종료됬을때 alert창 띄우기
- 변수로 만든 **
winner
**로 조건처리한다
현재까지 구현한 로직
위너의 승리조건 스타일링
winnerClassName 변수를 빈 문자열로 설정
- 설정 후
winner
값이 존재할 경우, 즉 winner
가 생길경우
winner.condition
배열을 구조분해할당해 [x,y,z]
로 나타내고
- 해당 구조분해할당한 원소들을 index값과 조건문에서 비교
- 비교해서
true
가 될때 즉 winner
일때 winnerClassName
을 bg-yellow-100
으로 설정
winnerClassName을 Square 컴포넌트에 props로 전달후 기존 className과 합친다
게임 상수 및 함수 분리관리
상수들은 분리해 constants 폴더에서관리
상태 끌어올리기
현재 squaers 상태가 Board 내에서만 공유되고 있어서 다음플레이어가 누군지 알 수 없음
상태를 최상위인 Game 컴포넌트로 끌어올려야 Status에서도 공유할 수 있음
상태관련 로직들을 짤라내 Game 컴포넌트에 이식
Board 컴포넌트에서props를 받은 후 인터페이스 설정
Status에 상태 전달
Status 컴포넌트에 nextPlayer 상태를 props로 전달한다
Status.tsx
Game 컴포넌트에서 winner 프롭을 전달
StatusMessage
라는 변수를 설정해 삼항연산자로 조건처리
게임이 무승부인지 아닌지를 판별할 상태 필요
- 무승부상태를
props
로 Status
컴포넌트에 전달
게임 히스토리
History 컴포넌트에서 게임의 진행내역을 UI에 출력