개발로 사고하기

행렬을 활용한 Tic Tac Toe 게임- AI와 2인 플레이어 모드 분기 구현

tues 2025. 8. 13. 20:26

https://tuesday04.tistory.com/84

 

행렬을 활용한 틱택토(Tic Tac Toe) 게임- React 마이그레이션

https://tuesday04.tistory.com/83 행렬을 활용한 틱택토(Tic Tac Toe) 게임 로직 해설 (Javascript)🧠 문제 정의와 상태 표현1. 보드 상태의 추상화틱택토는 3×3 정사각형 보드에서 두 명의 플레이어가 번갈아가

tuesday04.tistory.com

 

먼저 완성본 !!

 

https://github.com/veryyounng/game/tree/eaad280d54a4d6396cddac4866a2a486dcc95dd4

 

GitHub - veryyounng/game

Contribute to veryyounng/game development by creating an account on GitHub.

github.com

 

✨ 구현 목표

  • 게임 시작 시 플레이 모드를 선택할 수 있게 합니다.
  • 선택한 모드에 따라:
    • AI 모드에서는 사용자가 X, AI가 O로 자동 응답
    • 2인 모드에서는 X와 O가 번갈아 플레이

 

⚙️ 구조 설계 및 원리

📌1. gameMode 상태로 모드 관리

const [gameMode, setGameMode] = useState<'AI' | '2P' | null>(null);

 

  • 모드가 null이면 모드 선택 화면을 렌더링
  • 선택 이후에는 본격적인 게임 UI를 보여줍니다

📌 2. 모드 선택 UI는 조건부 렌더링으로 표시

if (gameMode === null) {
  return (
    <div> {/* 버튼 2개 */}
      <button onClick={() => setGameMode('AI')}>AI와 플레이</button>
      <button onClick={() => setGameMode('2P')}>2인 플레이</button>
    </div>
  );
}

 

  • 사용자가 버튼을 클릭하면 해당 모드로 gameMode 상태가 설정됩니다.
  • 이 값이 설정되면 게임판이 나타나고, 게임이 시작됩니다.

📌 3. 클릭 시 AI 동작은 모드에 따라 분기 처리

핵심은 handleClick() 내부의 이 부분입니다:

if (gameMode === 'AI' && nextTurn === 'O') {
  setTimeout(() => {
    makeAIMove(newBoard);
  }, 500);
}
  • 2인 플레이 모드(2P)에서는 이 로직이 아예 실행되지 않습니다.
  • AI 모드일 때만, 사용자가 클릭 후 일정 시간 뒤에 AI의 차례(O)가 자동으로 실행됩니다.

📌 4. AI의 동작은 makeAIMove()로 분리

const makeAIMove = (currentBoard: (string | null)[]) => {
  const emptyIndices = currentBoard
    .map((val, idx) => (val === null ? idx : null))
    .filter((val): val is number => val !== null);

  const randomIndex = emptyIndices[Math.floor(Math.random() * emptyIndices.length)];

  const updatedBoard = [...currentBoard];
  updatedBoard[randomIndex] = 'O';
  setBoard(updatedBoard);
  setTurn('X');
};

 

  • 현재 보드에서 빈 칸만 골라 랜덤하게 선택
  • AI는 항상 O를 사용하며, 선택 후 턴을 다시 X로 돌립니다

📌 5. 승자 메시지도 모드에 따라 다르게 표현

<h2>
  {winner ? (
    gameMode === 'AI'
      ? winner === 'X' ? '이기셨습니다!' : '졌습니다...'
      : `Winner: ${winner}`
  ) : board.every(cell => cell !== null)
      ? (gameMode === 'AI' ? '무승부입니다.' : 'Draw!')
      : `Next Player: ${turn}`}
</h2>

 

  • AI 모드: 사용자 중심 메시지 (이기셨습니다!, 졌습니다...)
  • 2인 모드: Winner: X / Winner: O 형식의 중립 메시지

🍥 향후 확장 방향

현재 구현된 AI는 실제로는 단순 랜덤 로직입니다.

하지만 내부 구조는 추후 미니맥스 기반의 완전한 틱택토 AI로 확장할 수 있도록 분리해 두었습니다.
첫 단계에서는 사용자가 “반응하는 상대”를 경험하는 데 집중했습니다.