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;
}

 

 

 

문제 자체는 간단하였으나, 모든 상황에서 일어날 수 있는 경우를 다 생각해서 꼼꼼하게 예외처리를 해주는것이 중요한 문제였다.