플레이어는 총 2명으로 구성되며, 차례대로 순서를 진행한다.
한 플레이어가 O(X) 를 3개 연속으로 배치하면 승리한다.
세로
1 4 7
2 5 8
3 6 9
가로
1 2 3
4 5 6
7 8 9
대각
1 5 9
3 5 7
각 칸의 중앙에는 숫자가 위치한다. 이 숫자는 플레이어의 행동에 따라 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(" | | ");
}
}
}
코드를 모두 쳐보고, 생각해보고 해석하고 이해했다.
아직도 많이 부족한 것 같지만, 이런 작업이 늘어날 수록 로직을 더 쉽게 이해하겠지!
내일도 달려보자!