알고리즘 문제/백준

7682 틱택토 (C#) [Gold V]

우대비 2025. 6. 17. 17:01
반응형

이미지를 클리하면 사이트로 이동합니다.

 

 

틱택토 게임은 두 명의 사람이 번갈아가며 말을 놓는 게임입니다.

게임 판의 최종 상태들을 입력으로 받을 때, 그 상태가 게임에서 발생할 수 있는 상태인지 판별해주세요.

가능하다면 valid, 불가능하다면 invalid를 출력합니다.

 

 

 

풀이 방법

이 문제는 여러 조건문을 통해 풀어야하는 문제입니다.

조건 1) O가 X보다 1개 이상 많으면 안됨
조건 2) X가 O보다 2개 이상 많으면 안됨
조건 3) 완성된 형태가 없는데 빈칸이 있으면 안됨
조건 4) X가 이겼는데 개수가 같으면 안됨
조건 5) O가 이겼는데 개수가 다르면 안됨

조건 6) O와 X가 완성한 줄이 각각 하나 이상씩 있으면 안됨

 

게임의 시작은 항상 X가 먼저 하기 때문에 O가 X보다 더 많이 둘 수 없습니다.

또한, 서로 하나씩 두기 때문에 X가 O보다 2개 이상 많으면 안됩니다.

 

입력은 게임의 최종 상태를 입력받은 것이기 때문에, 완성된 줄이 없음에도 빈칸이 있다면 안됩니다.

X가 이기는 상황은 X의 차례일 때 뿐입니다. 게임의 시작을 X가 하기 때문에 X가 이긴다면 O보다 1개 더 많아야합니다.

반대로 O가 이기는 상황은 O와 X의 개수가 같은 상황이어야 합니다.

 

각각 완성된 줄이 하나씩 있으면 안됩니다. 줄은 하나라도 완성되면 게임은 끝납니다.

 

승리 찾기

가로로 연속된 1줄, 세로로 연속된 1줄, 대각선으로 연속된 1줄을 만드는게 승리 조건입니다.

3*3크기의 작은 크기이기 때문에 인덱싱을 통해서도 가능합니다.

 

 

정답 코드

class Program
{
    static void Main(string[] args)
    {
        Solution solution = new Solution();

        while (true)
        {
            string input = Console.ReadLine();
            if (input == "end")
                break;

            Console.WriteLine(solution.solution(input));
        }
    }
}

 

 

public class Solution
{
    static private readonly string VALID = "valid";
    static private readonly string INVALID = "invalid";
    private (int, int) GetWinCnt(List<string> board)
    {
        Dictionary<char, int> dic = new Dictionary<char, int>(){{'X', 0 },{'O', 0 },{'.', 0 },};

        for (int i = 0; i < 3; i++)
        {
            if (board[i][0] == board[i][1] && board[i][1] == board[i][2])
                dic[board[i][0]]++;

            if (board[0][i] == board[1][i] && board[1][i] == board[2][i])
                dic[board[0][i]]++;
        }

        if (board[0][0] == board[1][1] && board[1][1] == board[2][2])
            dic[board[1][1]]++;

        if (board[0][2] == board[1][1] && board[1][1] == board[2][0])
            dic[board[1][1]]++;

        return (dic['X'], dic['O']); 
    }

    public string solution(string board)
    {
        int xCnt = 0;
        int oCnt = 0;
        int eCnt = 0;

        foreach (char c in board)
        {
            if (c == 'X')
                xCnt++;
            else if (c == 'O')
                oCnt++;
            else
                eCnt++;
        }

        var (xWin, oWin) = GetWinCnt(new List<string>() { board.Substring(0, 3), board.Substring(3, 3), board.Substring(6, 3)});
        if ( xWin > 0 && oWin > 0)
            return INVALID;

        if (xWin + oWin == 0 && eCnt > 0)
            return INVALID;

        if (xWin == 1 && xCnt == oCnt) 
            return INVALID;

        if (oWin == 1 && xCnt != oCnt)
            return INVALID;

        if (oCnt > xCnt)
            return INVALID;

        if (xCnt > oCnt+1)
            return INVALID;

        return VALID;
    }
}
반응형
LIST