카테고리 없음
[TIL] 유니티 스파르타 7기 6일차 - 틱택토
맏난거
2025. 1. 27. 20:41
/*
0 0 0
0 0 0
0 0 0
*/
namespace SpartaCSharp
{
internal class Program
{
static void Main(string[] args)
{
TickTackTok tic = new TickTackTok();
while (true)
{
if (tic.MyTurn)
{
while (true)
{
tic.ShowBoard(); // 현재 보드판 상황
int idx = tic.GetInputValue(); // 입력값
if (tic.SetBoard(idx) > 0) // 보드판 수정
break;
}
}
else
{
tic.RunComputer(); // 컴퓨터 차례
}
if (tic.Winner != 0) break;
}
if (tic.Winner == (int)ObjectType.PLAYER) Console.WriteLine("승리!");
else if (tic.Winner == (int)ObjectType.COMPUTER) Console.WriteLine("패배!");
else Console.WriteLine("비겼다!");
}
}
}
public struct TickTackTok
{
public TickTackTok()
{
this.size = 3;
MyTurn = (new Random().Next(0,2) == 0) ? true : false;
board = new int[size * size];
randomArray = CreateRandomArray();
}
int[] CreateRandomArray(int count = 1000)
{
int length = size * size;
int[] arr = new int[length];
for (int i = 0; i < arr.Length; i++)
arr[i] = i;
Random rand = new Random();
for(int i = 0; i < count; i++)
{
int idx1 = rand.Next(0, length - 1);
int idx2 = rand.Next(0, length - 1);
if (idx1 == idx2) continue;
int swap = arr[idx1];
arr[idx1] = arr[idx2];
arr[idx2] = swap;
}
return arr;
}
ObjectType GetBoard(int idx)
{
return (board[idx] == 0) ? ObjectType.DEFAULT : (board[idx] == 1) ? ObjectType.PLAYER : ObjectType.COMPUTER;
}
public int GetInputValue()
{
int value = 0;
while (true)
{
Console.Write($"숫자를 입력해주세요(1~{size * size}) : "); // 3x3
if (int.TryParse(Console.ReadLine(), out value))
{
value -= 1;
if (value < 0 || value >= size * size) continue;
return value;
}
continue;
}
}
public void ShowBoard()
{
for(int i = 0; i < size * size; i++)
{
if (i != 0 && i % size == 0) Console.WriteLine("|");
switch (GetBoard(i))
{
case ObjectType.DEFAULT:
Console.Write("| ");
break;
case ObjectType.PLAYER:
Console.Write("|● ");
break;
case ObjectType.COMPUTER:
Console.Write("| X");
break;
}
}
Console.WriteLine("|\n");
}
public int SetBoard(int idx)
{
if (GetBoard(idx) != ObjectType.DEFAULT)
{
Console.Clear();
Console.WriteLine("다시 한번 확인 해주세요");
return -1;
}
board[idx] = (int)(MyTurn ? ObjectType.PLAYER : ObjectType.COMPUTER);
Winner = CheckWin();
MyTurn = !MyTurn;
return 1;
}
public void RunComputer()
{
int idx = 0;
while (idx < size * size)
{
if (GetBoard(randomArray[idx]) != ObjectType.DEFAULT)
{
idx++;
continue;
}
SetBoard(randomArray[idx]);
break;
}
}
public int CheckWin()
{
/*
0 1 2
3 4 5
6 7 8
00 01 02 03
04 05 06 07
08 09 10 11
12 13 14 15
*/
// 가로
for(int idx = 0; idx < size; idx++)
{
if(GetBoard(size * idx) != ObjectType.DEFAULT)
{
if (GetBoard(size * idx) == GetBoard(size * idx + 1) && GetBoard(size * idx) == GetBoard(size * idx + 2))
return (int)(MyTurn ? ObjectType.PLAYER : ObjectType.COMPUTER);
}
}
// 세로
for (int idx = 0; idx < size; idx++)
{
if (GetBoard(idx) != ObjectType.DEFAULT)
{
if ( GetBoard(idx) == GetBoard(size + idx) && GetBoard(idx) == GetBoard(size*2 + idx) )
return (int)(MyTurn ? ObjectType.PLAYER : ObjectType.COMPUTER);
}
}
int count = 0; // 대각선 체크
// 대각선 01
for (int idx = 0; idx < size - 1; idx++)
{
if (GetBoard((size + 1) * idx) != ObjectType.DEFAULT)
{
if (GetBoard((size + 1) * idx) == GetBoard((size + 1) * (idx + 1)))
count++;
}
}
if (count == size - 1) return (int)(MyTurn ? ObjectType.PLAYER : ObjectType.COMPUTER);
count = 0;
// 대각선 02
for (int idx = 0; idx < size - 1; idx++)
{
if (GetBoard((size-1) * (idx + 1)) != ObjectType.DEFAULT)
{
if (GetBoard((size - 1) * (idx + 1)) == GetBoard((size - 1) * (idx + 2)))
count++;
}
}
if (count == size - 1) return (int)(MyTurn ? ObjectType.PLAYER : ObjectType.COMPUTER);
count = 0;
for (int i = 0; i < size * size; i++)
{
if(GetBoard(i) != ObjectType.DEFAULT)
count++;
}
if (count >= size * size) return (int)ObjectType.DRAW;
return (int)ObjectType.DEFAULT;
}
public int Winner { get; set; }
public bool MyTurn { get; set; }
int size;
int[] board;
int[] randomArray;
}
enum ObjectType
{
DEFAULT,
PLAYER,
COMPUTER,
DRAW,
}
오늘은 C# 문법 종합반 강의 2주차 과제로 틱택토 게임을 만들어봤습니다.
클래스는 그다음 장에 배워서 구조체로 만들었고,
최대한 깔끔하게 코딩하고 싶어서 시간을 투자했습니다.
시작전에 AI와 플레이어 선공격을 먼저 정할 수 있고,
AI는 인덱스가 들어있는 배열들을 섞어서 다음 인덱스를 호출 => 만약 뽑은 인덱스가 있으면 다음 인덱스를 호출하도록 설정
CheckWin() 메서드 같은 경우에는 가로, 세로, 대각선 2개 체크하고,
보드판에 남는 공간이 없으면 비겼다 출력.
문제있으면 댓글 적어주세요.