C#/알고리즘 문제 풀기
프로그래머스 - 혼자서 하는 틱택토
Toa_
2025. 6. 10. 20:52
이번 문제는 혼자서 틱택토를 할 때 일어나는 실수와 관련된 여러 경우의 수를 따지고, 나올수 있는 경우의 수인지 실수를 하여 잘못된 경우의 수가 발생 하였는지 를 확인하는 문제이다.
구체적인 알고리즘을 사용한다기 보다는, 기본적인 형식을 만들고, 각 경우의 수에 따른 예외처리를 진행하는 방식으로 진행하면 될것 같았다.
먼저 승리 여부를 중심으로 여러 경우의 수를 나누었다.
public bool IsWin(char[,] board, char player)
{
for (int i = 0; i < 3; i++)
{
// 가로
if (board[i, 0] == player && board[i, 1] == player && board[i, 2] == player)
return true;
// 세로
if (board[0, i] == player && board[1, i] == player && board[2, i] == player)
return true;
}
// 대각선
if (board[0, 0] == player && board[1, 1] == player && board[2, 2] == player)
return true;
if (board[0, 2] == player && board[1, 1] == player && board[2, 0] == player)
return true;
return false;
}
그리고 기본적인 board의 2차원 배열을 만들고
이에 따른 각 조건들의 예외처리를 진행하는 방식으로 solution 함수를 만들었다
조건
- 모든 칸이 비어있음 == 시작하지 않음 => 가능한 조건
- X의 개수가 O의 개수보다 많거나, O의 개수가 X의 개수보다 2개이상(많은 경우) 차이나는 경우 => 불가능한 경우
- X가 이긴 경우 O의 개수가 X의 개수와 같지 않음 => 불가능한 경우
- O가 이긴 경우 X의 개수보다 1개 많음이 아닌 경우 => 불가능한 경우
- X와 O가 동시에 이긴 경우 => 불가능한 경우
위의 모든 경우를 순서대로 진행하고, 모두 통과하였을 경우의 나머지는 가능한 경우값을 리턴하는 방식으로 구현했다.
public int solution(string[] board)
{
// 길이가 3인 board를 2차원 배열로 변환.
int rows = board.Length;
int cols = board[0].Length;
char[,] result = new char[rows, cols];
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
result[i, j] = board[i][j];
}
}
// 조건 처리 시작
// 1. 모든 칸이 비어있음 == 시작하지 않음 => 가능한 조건.
if (board.All(x => x == "...")) return 1;
// 2. X의 개수가 O의 개수보다 많거나, O의 개수가 X의 개수보다 2개이상(많은 경우) 차이나는 경우
int xCount = 0;
int oCount = 0;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
if (result[i, j] == 'X') xCount++;
else if (result[i, j] == 'O') oCount++;
}
}
if (!(oCount == xCount || oCount == xCount + 1)) return 0;
// 각각의 승리 여부 체크
bool xWin = IsWin(result, 'X');
bool oWin = IsWin(result, 'O');
// 3. X가 이긴 경우 O의 개수가 X의 개수와 같지 않음 => 불가능한 경우
if (xWin && xCount != oCount) return 0;
// 4. O가 이긴 경우 X의 개수보다 1개 많음이 아닌 경우 => 불가능한 경우
if (oWin && oCount != xCount + 1) return 0;
// 5. X와 O가 동시에 이긴 경우 => 불가능한 경우
if(xWin&&oWin) return 0;
// 나머지
return 1;
}
문제 자체는 간단하였으나, 모든 상황에서 일어날 수 있는 경우를 다 생각해서 꼼꼼하게 예외처리를 해주는것이 중요한 문제였다.