문제
틱택토를 진행한 보드판이 주어질 때 해당 보드 판이 정상적으로 진행된 틱택토인지 확인하는 문제이다.
내 풀이
틱택토는 O(선공)와 X(후공)가 번갈아가며 진행하는 게임이다. 각 플레이어는 한 번씩 번갈아 두어야 하므로, 게임이 정상적으로 진행되려면 다음 규칙들이 지켜져야 한다:
- O는 반드시 첫 번째로 둬야 한다
- O와 X는 반드시 번갈아 두어야 한다
- 한 플레이어가 승리하면 게임이 즉시 종료되어야 한다
이러한 규칙들을 바탕으로 정상적이지 않은 틱택토의 경우를 찾아보면
- 선공(O)과 후공(X)의 차이가 2 이상이거나 후공이 선공보다 많이 진행한 경우
- O와 X는 번갈아 두므로 X의 개수는 절대 O의 개수보다 많을 수 없다
- O와 X의 개수 차이는 최대 1까지만 가능하다 예시: 'XXO..' (X가 O보다 많음 → 불가능)
- 선공(O)이 승리하였는데 후공과 선공의 진행 수가 같은 경우
- O가 승리했다면 마지막으로 O를 둔 순간에 승리한 것이므로
- O의 개수는 반드시 X보다 1개 많아야 한다 예시: 'OOO/XXX/..' (O가 이겼는데 X도 3번 둠 → 불가능)
- 후공(X)이 승리하였는데 선공의 수가 후공보다 많은 경우
- X가 승리했다면 마지막으로 X를 둔 순간에 승리한 것이므로
- O와 X의 개수는 반드시 같아야 한다 예시: 'XXX/OO,/O.O' (X가 이겼는데 O를 더 둠 → 불가능)
이를 확인하기 위해서는 두 가지를 체크해야 한다:
- O와 X의 개수를 세어 올바른 순서로 진행되었는지 확인
- 승리 조건을 확인하여 게임이 정상적으로 종료되었는지 확인
선공과 후공의 진행횟수를 확인 하는 코드
- X의 개수(후공)를 세어 xNum에 저장
- O의 개수(선공)를 세어 oNum에 저장
이 값들을 통해 게임이 순서대로 진행되었는지 확인 가능해진다.
boardArr.forEach((row)=>{
row.forEach((space)=> {
if(space === 'X'){
xNum ++;
}
if(space === "O"){
oNum++;
}
})
})
게임이 끝났는지 확인 하는 함수
특정 플레이어(O 또는 X)가 승리했는지 확인하는 함수이다.
- 가로 방향: 한 행의 모든 칸이 같은 모양인지 확인
- 세로 방향: 한 열의 모든 칸이 같은 모양인지 확인
- 대각선 방향: 왼쪽 위에서 오른쪽 아래 방향과 오른쪽 위에서 왼쪽 아래 방향을 확인
- 하나라도 조건을 만족하면 해당 플레이어가 승리한 것으로 판단
const isFinish = (shape) => {
for (let i = 0; i < boardLength; i++) {
if (boardArr[i].every(row => row === shape)) return true; // 행 검사
if (boardArr.every(col => col[i] === shape)) return true; // 열 검사
}
//대각선 검사
if(boardArr[0][0] === shape && boardArr[1][1] === shape && boardArr[2][2] == shape) return true
if(boardArr[0][2] === shape && boardArr[1][1] === shape && boardArr[2][0] == shape) return true
return false;
}
전체코드
function solution(board) {
let xNum = 0; // 후공 횟수
let oNum = 0; // 선공 횟수
const boardArr = board.map((row)=> row.split(''));
const boardLength = 3;
const isFinish = (shape) => {
for (let i = 0; i < boardLength; i++) {
if (boardArr[i].every(row => row === shape)) return true; // 행 검사
if (boardArr.every(col => col[i] === shape)) return true; // 열 검사
}
//대각선 검사
if(boardArr[0][0] === shape && boardArr[1][1] === shape && boardArr[2][2] == shape) return true
if(boardArr[0][2] === shape && boardArr[1][1] === shape && boardArr[2][0] == shape) return true
return false;
}
boardArr.forEach((row)=>{
row.forEach((space)=> {
if(space === 'X'){
xNum ++;
}
if(space === "O"){
oNum++;
}
})
})
const diff = Math.abs(oNum - xNum);
if(diff >= 2 || xNum > oNum) {
return 0;
}
if(diff === 0 && isFinish('O')){
return 0;
}
if(oNum > xNum && isFinish('X')){
return 0;
}
return 1;
}
출처 : 프로그래머스
문제링크 : https://school.programmers.co.kr/learn/courses/30/lessons/160585
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
'알고리즘' 카테고리의 다른 글
프로그래머스 - 숫자 블록 (2) | 2025.01.31 |
---|---|
프로그래머스 - 혼자 놀기의 달인 (0) | 2025.01.31 |
프로그래머스 - 리코쳇로봇 (0) | 2025.01.20 |
프로그래머스 N-Queen (2) | 2025.01.18 |
프로그래머스 - 디펜스게임 (1) | 2025.01.13 |