상현에 하루하루
All 개발자의 하루

Tic Tac Toe 승패검사

( 업데이트: )

우리가 Tic-Tac-Toe 게임을 시작한다면, 보드의 현재 상태가 해결되었는지 아닌지를 알고 싶습니까? 우리의 목표는 우리를 위해 그것을 확인하는 기능을 만드는 것입니다.

보드가 3×3 배열의 형태로 가정합니다.

0 은 스팟이 비어있는 상태

1X가 둔상태

2O가 둔상태입니다.

[[0,0,1], [0,1,2], [2,1,0]]
  • 보드가 아직 완료되지 않은 경우 (빈 지점이 있음) return -1
  • X가 이기면 return 1
  • O가 이기면 return 2
  • 무승부인 경우 return 0

Tic-Tac_toe 게임에서 전달된 보드가 유효하다고 가정할 수 있습니다.


function isSolved(board) {
  let result = null;

  // 무승부
  let draw = true;
  for(let i in board) {
    if (Array.isArray(board[i]) &&board[i].includes(0)) draw = false;
  }
  // 세로직선
  function row(line, target) {
    const row1 = board[line][0];
    const row2 = board[line][1];
    const row3 = board[line][2];
    return row1 === target && row1 === row2 && row1 === row3 ? target : false;
  }
  // 가로직선
  function col(line, target) {
    const col1 = board[0][line];
    const col2 = board[1][line];
    const col3 = board[2][line];
    return col1 === target && col1 === col2 && col1 === col3 ? target : false;
  }
  // 대각선
  function cross(direction,target) {
    const _1 = direction === 'left' ? board[0][0] : board[2][2];
    const _2 = direction === 'left' ? board[1][1] : board[1][1];
    const _3 = direction === 'left' ? board[2][2] : board[0][0];
    if (_1 === target && _1 === _2 && _1 === _3) return target;
    return _1 === target && _1 === _2 && _1 === _3 ? target : false;
  }
  result = 
    row(0, 1) || 
    row(0, 2) || 
    row(1, 1) || 
    row(1, 2) || 
    row(2, 1) || 
    row(2, 2) || 
    col(0, 1) || 
    col(0, 2) || 
    col(1, 1) || 
    col(1, 2) || 
    col(2, 1) || 
    col(2, 2) || 
    cross('left', 1) ||
    cross('left', 2) ||
    cross('right', 1) ||
    cross('right', 2)
    ;
  if (draw) return 0;
  return draw || result || -1;
}

각 케이스마다 함수로 구현해서 확인하였다. 올바른 방식이긴했지만 알고리즘 자체가 너무 길었다고 생각했는데 그냥 정규식으로 확인하는 것을 보고서 조금더 단순하게 생각할 필요가 있다 생각했다

Best Case

function isSolved(board) {
   board = board.join('-').replace(/,/g,'');
   if(/222|2...2...2|2....2....2|2..2..2/.test(board)) return 2;
   if(/111|1...1...1|1....1....1|1..1..1/.test(board)) return 1;
   if(/0/.test(board)) return -1;
   return 0;
}