코린이 부트캠프 일상

코린이 8일차 /C# 콘솔로 틱택토(Tic Tac Toe)만들기

게발인개발자 2023. 11. 8. 20:06

개인과제로 틱택토라는 게임을 만들라는 과제가 있었다.

 

(틱택토 플레이 영상)

틱택토은 일명 오목에서 5개가 아닌 3개로 먼저 한줄을 만들면 이기는 게임이다.(물론 무승부가 많은 것 같다.)

 

처음에 이게임을 만들라고 했을 때 정말 손을 댈 수가 없었다.....

그래서 나는 계속 플레이 해보고 게임에 필요한 것을 파악하기로 했다.

게임을 계속 플레이 하면서 필요하다고 느낀 것을 정리해 보았다.

 

1. 플레이어 2명(순서대로 한 번씩 진행)

2. 9칸 크기의 게임판

3. 선택하면 칸에 표시하기

4. 게임 종료 조건

 

나는 내 지식을 활용해서 필요조건에 살을 추가해 보았다.

 

1. 플레이어 2명(순서대로 한 번씩 진행)

-뭔가 if문과 2로 나눈 나머지를 사용하면 순서대로 플레이 할 수 있다고 생각했다.

static int Player = 1;

static void Main(string[] args)
{
  if (Player % 2 == 0)
  {
   Console.WriteLine("플레이어 2의 차례")
   }
   else 
   {
    Console.WriteLine("플레이어 1의 차례")
   }
}

이렇게 코드를 짜봤다.

 

2. 9칸 짜리 판

 static void Board()
        {
            Console.WriteLine("     |     |     ");
            Console.WriteLine("  0  |  1  |  2  ");
            Console.WriteLine("_____|_____|_____");
            Console.WriteLine("     |     |     ");
            Console.WriteLine("  3  |  4  |  5  ");
            Console.WriteLine("_____|_____|_____");
            Console.WriteLine("     |     |     ");
            Console.WriteLine("  6  |  7  |  8  ");
            Console.WriteLine("     |     |     ");
        }

이렇게 만들었는데

저 숫자들을 입력을 하면 바뀌는 함수가 필요하겠다고 생각이 들어 단순히 string이 아닌 Char[]을 활용해서 문자의 열로 구분을 줄 수 있겠다고 생각했다.

  static int Player = 1;
  static char[] arr = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
  
  static void Main(string[] args)
   {
     if (player % 2 == 0)
                {
                    Console.WriteLine("플레이어 2의 차례");
                }
                else
                {
                    Console.WriteLine("플레이어 1의 차례");
                }
    }
    static void Board()
        {
            Console.WriteLine("     |     |     ");
            Console.WriteLine("  {0}  |  {1}  |  {2}  ", arr[1], arr[2], arr[3]);
            Console.WriteLine("_____|_____|_____");
            Console.WriteLine("     |     |     ");
            Console.WriteLine("  {0}  |  {1}  |  {2}  ", arr[4], arr[5], arr[6]);
            Console.WriteLine("_____|_____|_____");
            Console.WriteLine("     |     |     ");
            Console.WriteLine("  {0}  |  {1}  |  {2}  ", arr[7], arr[8], arr[9]);
            Console.WriteLine("     |     |     ");
        }

이렇게 문자의 열을 칸에 배치해주었다.

 

3. 선택하면 칸에 표시하기

선택을 한다는 것을 칸 안의 숫자를 입력하면 각 플레이어를 나타낼 수 있는 표시로 바꿔 준다는 것으로 생각하여

   static int choice;
    
    
    
    string line = Console.ReadLine();  //입력 받은 것은 String으로 인식되기 때문에 string line으로 받아주고
     bool res = int.TryParse(line, out choice); // int.TryParse를 통해 범위 안의 숫자를 선택했는지 판단한다.

    if(res == true)
                {
                    if (arr[choice] != 'X' && arr[choice] != 'O')
                    {
                        if(player % 2 == 0)
                        {
                            arr[choice] = 'O';   //플레이어 2번 선택은 O로 표시
                        }
                        else
                        {
                            arr[choice] = 'X';  //플레이어 1번 선택은 1로 표시
                        }


                    }
string line = Console.ReadLine();
bool res = int.TryParse(line, out choice);

이 2줄 만드는 것이 제일 힘들었다.... TryParse를 몰랐기 때문에...

즉 위에 코드에서  입력한 문자가 숫자로 바꿀 수 없는 문자라면 입력이 안된다는 코드...

(예를 들어 플레이어가 게임을 진행하면서 원하는 칸을 바꾸려면 해당 칸 번호만 입력해야 되는데 "6번", "6번을 선택"이라고 입력했을 때 그 값을 무효화 시키겨 아무 일도 안일어나게 하는것)

 

TryParse

int.TryParse("체크해야될 값",out 리턴값)

 

4. 게임 종료 조건

-게임이 종료 되기 위해서는 게임의 결과가 필요하다.

-3줄을 완성했을때(가로,세로,대각선 / 플레이어 1,2)

-더 이상 선택할 칸이 없을 경우---> 무승부

 

static int flag = 0;

flag = CheckWin();

        static int CheckWin()
        {
            // 가로 승리 조건
            if (arr[1] == arr[2] && arr[2] == arr[3])
            {
                return 1;
            }
            else if (arr[4] == arr[5] && arr[5] == arr[6])
            {
                return 1;
            }
            else if (arr[7] == arr[8] && arr[8] == arr[9])
            {
                return 1;
            }

            // 세로 승리 조건
            else if (arr[1] == arr[4] && arr[4] == arr[7])
            {
                return 1;
            }
            else if (arr[2] == arr[5] && arr[5] == arr[8])
            {
                return 1;
            }
            else if (arr[3] == arr[6] && arr[6] == arr[9])
            {
                return 1;
            }

            // 대각선 승리조건
            else if (arr[1] == arr[5] && arr[5] == arr[9])
            {
                return 1;
            }
            else if (arr[3] == arr[5] && arr[5] == arr[7])
            {
                return 1;
            }
            
            // 무승부
            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; }
            }

 

이 모든 과정이 게임이 이길 때 까지 반복을 해줘야하니깐 do while문을 사용해서 합쳐주었습니다.

 

namespace _2_6
{
    internal class Program
    {
        static char[] arr = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
        static int player = 1;
        static int choice;
        static int flag = 0;

        static void Main(string[] args)
        {
            do
            {
                Console.Clear();// 이 코드가 없으니깐 계속 게임판이 새로 생겨 시각적으로 불편해서 
                 //칸을 선택한 후 전에 문자열 게임판 삭제하기 위해 추가
                 
                Console.WriteLine("플레이어 1: X 와 플레이어 2: O");
                Console.WriteLine("\n");

                if (player % 2 == 0)
                {
                    Console.WriteLine("플레이어 2의 차례");
                }
                else
                {
                    Console.WriteLine("플레이어 1의 차례");
                }

                Console.WriteLine("\n");
                Board();

                string line = Console.ReadLine();
                bool res = int.TryParse(line, out choice);

                if(res == true)
                {
                    if (arr[choice] != 'X' && arr[choice] != 'O')
                    {
                        if(player % 2 == 0)
                        {
                            arr[choice] = 'O';
                        }
                        else
                        {
                            arr[choice] = 'X';
                        }

                        player++;
                    }
                    else
                    {
                        Console.WriteLine("죄송합니다. {0} 행은 이미 {1}로 표시되어 있습니다.", choice, arr[choice]);
                        Console.ReadLine();
                    }
                }
                else
                {
                    Console.WriteLine("숫자를 입려해주세요.");
                }

                flag = CheckWin();
            }
            while (flag != -1 && flag != 1);

            if(flag == 1)  // 각 플레이어 승리 시 멘트 추가
            {
                Console.WriteLine("플레이어 {0}이(가) 이겼습니다.", (player % 2) + 1);
            }
            else
            {
                Console.WriteLine("무승부"); //무승부시 멘트 추가
            }

            Console.ReadLine();
        }

        static void Board()
        {
            Console.WriteLine("     |     |     ");
            Console.WriteLine("  {0}  |  {1}  |  {2}  ", arr[1], arr[2], arr[3]);
            Console.WriteLine("_____|_____|_____");
            Console.WriteLine("     |     |     ");
            Console.WriteLine("  {0}  |  {1}  |  {2}  ", arr[4], arr[5], arr[6]);
            Console.WriteLine("_____|_____|_____");
            Console.WriteLine("     |     |     ");
            Console.WriteLine("  {0}  |  {1}  |  {2}  ", arr[7], arr[8], arr[9]);
            Console.WriteLine("     |     |     ");
        }

        static int CheckWin()
        {
            // 가로 승리 조건
            if (arr[1] == arr[2] && arr[2] == arr[3])
            {
                return 1;
            }
            else if (arr[4] == arr[5] && arr[5] == arr[6])
            {
                return 1;
            }
            else if (arr[7] == arr[8] && arr[8] == arr[9])
            {
                return 1;
            }

            // 세로 승리 조건
            else if (arr[1] == arr[4] && arr[4] == arr[7])
            {
                return 1;
            }
            else if (arr[2] == arr[5] && arr[5] == arr[8])
            {
                return 1;
            }
            else if (arr[3] == arr[6] && arr[6] == arr[9])
            {
                return 1;
            }

            // 대각선 승리조건
            else if (arr[1] == arr[5] && arr[5] == arr[9])
            {
                return 1;
            }
            else if (arr[3] == arr[5] && arr[5] == arr[7])
            {
                return 1;
            }
            
            // 무승부
            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; }
            
        }
    }
}

 

잘 작동해서 뿌듯하다. 

내일도 강의 내용 복습하고 하나 더 만들어 볼 예정이다!!!