[알고리즘/C++] 프로그래머스 - 혼자서 하는 틱택토 (Lv.2)

0시0분·2024년 5월 17일
0

알고리즘

목록 보기
6/23

✏️ 풀이 방법
정상 플레이 조건은 총 4가지다.
1. O와 X가 동시에 이길 수 없다.
2. X는 O보다 많을 수 없다.
3. O는 X+1보다 많을 수 없다.
4-1. O가 이겼으면 (O의 개수) = (X의 개수) + 1 이다.
4-2. X가 이겼으면 (O의 개수) = (X의 개수) 이다.
종료 조건은 진작 파악을 했는데 대각선 틱택토 검사를 포문 안에서 하는 바람에 헤맸다.

int solution(vector<string> board)
{
    pair<bool, bool> rowTTT = {false, false};
    pair<bool, bool> colTTT = {false, false};
    pair<bool, bool> leftDiagTTT = {false, false};
    pair<bool, bool> rightDiagTTT = {false, false};

    pair<int, int> totalCnt = {0, 0};
    pair<int, int> leftDiagCnt = {0, 0};
    pair<int, int> rightDiagCnt = {0, 0};

    for (int i = 0; i < board.size(); ++i)
    {
        // 대각선 틱택토
        if (board[i][i] == 'O')
        {
            leftDiagCnt.first++;
        }
        else if (board[i][i] == 'X')
        {
            leftDiagCnt.second++;
        }

        if (board[i][board.size() - 1 - i] == 'O')
        {
            rightDiagCnt.first++;
        }
        else if (board[i][board.size() - 1 - i] == 'X')
        {
            rightDiagCnt.second++;
        }
        
        // 행, 열 틱택토
        pair<int, int> rowCnt = {0, 0};
        pair<int, int> colCnt = {0, 0};
        for (int j = 0; j < board[0].size(); ++j)
        {
            if (board[i][j] == 'O')
            {
                totalCnt.first++;
                rowCnt.first++;
            }
            else if (board[i][j] == 'X')
            {
                totalCnt.second++;
                rowCnt.second++;
            }

            if (board[j][i] == 'O')
            {
                colCnt.first++;
            }
            else if (board[j][i] == 'X')
            {
                colCnt.second++;
            }
        }

        if (rowCnt.first == board.size())
            rowTTT.first = true;

        if (rowCnt.second == board.size())
            rowTTT.second = true;

        if (colCnt.first == board.size())
            colTTT.first = true;

        if (colCnt.second == board.size())
            colTTT.second = true;
    }

    if (leftDiagCnt.first == board.size())
        leftDiagTTT.first = true;

    if (leftDiagCnt.second == board.size())
        leftDiagTTT.second = true;

    if (rightDiagCnt.first == board.size())
        rightDiagTTT.first = true;

    if (rightDiagCnt.second == board.size())
        rightDiagTTT.second = true;

    bool oWins = (rowTTT.first || colTTT.first || leftDiagTTT.first || rightDiagTTT.first);
    bool xWins = (rowTTT.second || colTTT.second || leftDiagTTT.second || rightDiagTTT.second);

    if (oWins && xWins) return 0;   // 동시에 이길수 없음

    if (totalCnt.second > totalCnt.first)  return 0;   // X는 O보다 많을 수 없음
    if (totalCnt.first > totalCnt.second + 1)  return 0;   // O는 X + 1 보다 많을 수 없음

    if (oWins && (totalCnt.first != totalCnt.second + 1))  return 0;   // O가 이겼으면 X보다 한개 많아야 함
    if (xWins && (totalCnt.first != totalCnt.second))  return 0;   // X가 이겼으면 O와 개수가 동일해야 함

    return 1;
}

🤔 아쉬운 점
너무 주욱 나열되어 있는 느낌이라 함수로 빼서
O와 X를 따로 검사하도록 해도 괜찮았을 것 같다.

0개의 댓글