Machineboy空

Excercism - State of Tic-Tac-Toe 본문

Computer/Coding Test

Excercism - State of Tic-Tac-Toe

안녕도라 2025. 2. 17. 16:03

문제요약

틱택토 게임의 상태를 반환하라.

  • Win
  • Draw
  • Ongoing
  • Invalid

 

https://exercism.org/tracks/csharp/exercises/state-of-tic-tac-toe

 

State of Tic-Tac-Toe in C# on Exercism

Can you solve State of Tic-Tac-Toe in C#? Improve your C# skills with support from our world-class team of mentors.

exercism.org


난이도

Medium


풀이 포인트

  • Invalid 조건 꼼꼼히 따져주기

REVIEW

 

Excercism의 허점을 발견했다.

분명 완벽하지 않은 풀이인데 주어진 테스트 케이스들만 통과시켰더니 정답풀이라고 해주더라.

3*3 칸 밖에 되지 않아 차력으로 모든 경우의 수를 나열해도 맞출 수 있는 문제다.

Invalid가 되는 조건을 꼼꼼히 따져주는 게 이 문제의 포인트였다!

 

승부가 결정되고 나서도 계속 게임을 진행했는지에 관한 체크를 어떻게 하는지가 포인트.

승리 카운트를 따로 해주고, 둘 다 승리할 수 없음을 잘 카운트해주면 된다.


CODE

using System;

public enum State
{
    Win,
    Draw,        // 모두 차있고 winner가 나오지 않은 경우
    Ongoing,
    Invalid      //  X < O 거나 winner 가 두 명
}

public class TicTacToe
{
    private string[] rows;

    public TicTacToe(string[] rows)
    {
        this.rows = rows;
    }

    public State State
    {
        get
        {
            int xCnt = 0, oCnt = 0;

            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    if (rows[i][j] == 'X') xCnt++;
                    if (rows[i][j] == 'O') oCnt++;
                }
            }

            if (xCnt < oCnt || xCnt - oCnt > 1) return State.Invalid;  // X가 O보다 적거나, X가 O보다 1개 이상 많으면 Invalid

            bool xWin = false, oWin = false;

            // 승리 조건 체크 함수
            bool CheckWin(char player)
            {
                for (int i = 0; i < 3; i++)
                {
                    if ((rows[i][0] == player && rows[i][1] == player && rows[i][2] == player) ||
                        (rows[0][i] == player && rows[1][i] == player && rows[2][i] == player))
                        return true;
                }
                if ((rows[0][0] == player && rows[1][1] == player && rows[2][2] == player) ||
                    (rows[0][2] == player && rows[1][1] == player && rows[2][0] == player))
                    return true;
                return false;
            }

            xWin = CheckWin('X');
            oWin = CheckWin('O');

            if (xWin && oWin) return State.Invalid;  // 두 플레이어가 동시에 승리할 수 없음
            if (xWin && xCnt <= oCnt) return State.Invalid;  // X가 이겼는데 O가 같거나 많으면 Invalid
            if (oWin && xCnt != oCnt) return State.Invalid;  // O가 이겼는데 X가 O보다 많으면 Invalid

            if (xWin || oWin) return State.Win;

            if (xCnt + oCnt == 9) return State.Draw;

            return State.Ongoing;
        }
    }
}