[TIL] C# - day 20 [Code Review]

뭉크의 개발·2023년 8월 15일
0

C# - Camp

목록 보기
3/18
post-thumbnail

🐧 Tic Tac Toe Game

🐧 Function

  1. 게임 진행 조건
  2. 플레이어 순서
  3. 메인 함수

게임 진행 조건

  • 플레이어는 총 2명으로 구성되며, 차례대로 순서를 진행한다.

  • 한 플레이어가 O(X) 를 3개 연속으로 배치하면 승리한다.

  1. 세로
    1 4 7
    2 5 8
    3 6 9

  2. 가로
    1 2 3
    4 5 6
    7 8 9

  3. 대각
    1 5 9
    3 5 7

  • 누구도 3개 연속 배치하지 못하면, 무승부로 끝난다.
    모든 수가 O 또는 X로 채워져 있어야 한다.
    즉, 맵 안에 숫자가 존재하지 않는다.

각 칸의 중앙에는 숫자가 위치한다. 이 숫자는 플레이어의 행동에 따라 O 또는 X로 변한다.

숫자는 1 ~ 9로 구성되어있다.

맵의 가로선, 세로선, 공백은 변하지 않는다. (리터럴? 상수? 한 번 정리해야겠다.)

숫자를 배열로 구성하여 플레이어 입력 시, 숫자를 입력한 O 또는 X로 Replace한다.

플레이어 순서

플레이어는 총 2명으로, 예를 들어 플레이어 1이 O면 플레이어2는 X다.
1이 배치를 완료하면, 2가 배치한다.

메인 함수

메인에서 게임을 알려주고, 플레이어의 턴을 알려준다.

게임의 결과와 종료를 알린다.

예외처리

플레이어가 이미 O 또는 X로 배치된 칸을 선택하면, 배치할 수 없다는 메시지를 출력한다.

플레이어가 정해진 칸 이외의 칸을 선택하면 1~9까지 숫자 중 선택하라는 메시지를 출력한다.

🐧 게임에 구현한다면?

static void Map()
        {
            Console.WriteLine("     |     |     ");
            Console.WriteLine($"  {_arr[0]}  |  {_arr[1]}  |  {_arr[2]}  ");
            Console.WriteLine("_____|_____|_____");
            Console.WriteLine("     |     |     ");
            Console.WriteLine($"  {_arr[3]}  |  {_arr[4]}  |  {_arr[5]}  ");
            Console.WriteLine("_____|_____|_____");
            Console.WriteLine("     |     |     ");
            Console.WriteLine($"  {_arr[6]}  |  {_arr[7]}  |  {_arr[8]}  ");
            Console.WriteLine("     |     |     ");

        }

namespace TicTacToePractice
{
    internal class Program
    {
        static char[] _arr = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; // char -> 단 하나의 문자이기 때문에!
        static int _goal; // 게임 승패여부 1 = 승리, 0 = 무승부, -1 = 패배
        static int _choice;
        static int _player1 = 1;

        static void Main(string[] args)
        {
            do
            {
                // 게임 시작
                Console.Clear();
                Console.WriteLine("Tic Tac Toe Game!");
                Console.WriteLine("Player 1 : X, Player 2 : O");
                Console.WriteLine("\n");

                // 플레이어 순서 출력
                if (_player1 % 2 == 0) // _player1 변수가 짝수일 때는 Player 2의 차례, 홀수일 때는 Player 1의 차례
                {
                    Console.WriteLine("Player 2's turn ");
                }
                else
                {
                    Console.WriteLine("Player 1's turn");
                }

                Console.WriteLine("\n");
                Map(); // 게임 맵 출력

                string _input = Console.ReadLine();
                bool _res = int.TryParse(_input, out _choice); // 사용자 입력을 정수로 변환

                if (_res = true) // 사용자 입력이 성공적으로 정수로 변환되었을 때
                {
                    if (_arr[_choice] != 'X' && _arr[_choice] != 'O') // 선택한 위치가 'X'나 'O'로 이미 마킹되지 않았을 때
                    {
                        if (_player1 % 2 == 0) // 플레이어 2의 차례일 때
                        {
                            _arr[_choice] = 'O';
                        }
                        else // 플레이어 1의 차례일 때
                        {
                            _arr[_choice] = 'X';
                        }

                        _player1++;  // 플레이어 순서 변경
                    }
                    else  // 선택한 위치가 이미 마킹된 경우
                    {
                        Console.WriteLine($"Sorry, the {_choice} array is already marked {_arr[_choice]}. Please try again.");
                        Console.ReadLine();
                    }
                }
                else // 사용자 입력이 정수로 변환되지 않은 경우
                {
                    Console.WriteLine($"Please enter only numbers from 1 to 9.");
                }
                _goal = GameLogic(); // 게임 로직 실행 및 결과 받아옴
            } 
            while (_goal != -1 && _goal != 1); // 게임이 종료 상태가 아닐 때까지 반복

            if (_goal == 1) // 게임 승리 상태인 경우
            {
                Console.WriteLine($"Player {(_player1 % 2) * 1} is Win!");
            }
            else // 무승부 상태인 경우
            {
                Console.WriteLine("Draw!");
            }
            
            Console.ReadLine(); // 사용자 입력 기다림
        }

        static int GameLogic()
        {
            // 가로
            if (_arr[1] == _arr[2] && _arr[2] == _arr[3]) // 123
            {
                return 1;
            }
            if (_arr[4] == _arr[5] && _arr[5] == _arr[6]) // 456
            {
                return 1;
            }
            if (_arr[7] == _arr[8] && _arr[8] == _arr[9]) // 789
            {
                return 1;
            }

            // 세로
            else if (_arr[1] == _arr[4] && _arr[4] == _arr[7]) // 147
            {
                return 1;
            }
            else if (_arr[2] == _arr[5] && _arr[5] == _arr[8]) // 258
            {
                return 1;
            }
            else if (_arr[3] == _arr[6] && _arr[6] == _arr[9]) // 369
            {
                return 1;
            }

            else if (_arr[1] == _arr[5] && _arr[5] == _arr[9]) // 159
            {
                return 1;
            }
            else if (_arr[3] == _arr[5] && _arr[5] == _arr[7]) // 357
            {
                return 1;
            }
            // 모든 칸이 해당된 배열의 값과 다르면 무승부 ! -> O와 X로 모두 채워짐.
            else if (_arr[1] != '1' && _arr[2] != '2' && _arr[3] != '3' && _arr[4] != '4' && _arr[5] != '5' && _arr[6] != '6' && _arr[7] != '7' && _arr[8] != '8' && _arr[9] != '9')
            {
                return -1;
            }
            else { return 0; }


        }

        static void Map()
        {
            Console.WriteLine("     |     |     ");
            Console.WriteLine($"  {_arr[0]}  |  {_arr[1]}  |  {_arr[2]}  ");
            Console.WriteLine("_____|_____|_____");
            Console.WriteLine("     |     |     ");
            Console.WriteLine($"  {_arr[3]}  |  {_arr[4]}  |  {_arr[5]}  ");
            Console.WriteLine("_____|_____|_____");
            Console.WriteLine("     |     |     ");
            Console.WriteLine($"  {_arr[6]}  |  {_arr[7]}  |  {_arr[8]}  ");
            Console.WriteLine("     |     |     ");
        }
    }
}

🐧 느낀점

코드를 모두 쳐보고, 생각해보고 해석하고 이해했다.

아직도 많이 부족한 것 같지만, 이런 작업이 늘어날 수록 로직을 더 쉽게 이해하겠지!

내일도 달려보자!

0개의 댓글