728x90
728x90
실행 영상입니다.
친구와 함께 C# 스터디를 하며 예제로 2048 게임을 제작해보았습니다.
Visual Studio(2019)로 C# 콘솔 앱을 통해 제작하였습니다.
생각보다 알고리즘이 수학적으로 복잡해서 설계하는데 노력을 기울였습니다.
이런 사소한 예제를 하는 데에도 수학이 쓰이는구나를 깨닫고 수학 공부를 열심히 하는 계기가 되었습니다.
이와 같이 오랜 시간 알고리즘을 고민한 후 작업에 돌입했습니다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MiniGameProject
{
class Program
{
static void Main(string[] args)
{
Console.SetWindowSize(30, 15);
Console.Title = "2048 C# version. developed by Hoeun Lee";
int[,] Arr = new int[4, 4];
int count = 0;
int finish = 0;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
Arr[i, j] = 0;
}
}
Arr[1, 1] = 2;
Arr[3, 1] = 2;
int mX, mY, nX, nY, lX, lY, newValue;
while (true)
{
Random r1 = new Random();
Random r2 = new Random();
Random r3 = new Random();
Random r4 = new Random();
mX = r1.Next(0, 4);
mY = r2.Next(0, 4);
nX = r3.Next(0, 4);
nY = r4.Next(0, 4);
if ((Arr[mX, mY] == 0) && (Arr[nX, nY] == 0))
{
Arr[mX, mY] = 2;
Arr[nX, nY] = 2;
PrintArr(Arr, count);
break;
}
}
while (true)
{
ConsoleKeyInfo keys;
do
{
if (Console.KeyAvailable)
{
keys = Console.ReadKey(true);
switch (keys.Key)
{
case ConsoleKey.UpArrow:
Console.WriteLine("UP");
Arr = MoveVertical(Arr, 1);
while (true)
{
Random r5 = new Random();
Random r6 = new Random();
Random r7 = new Random();
lX = r5.Next(0, 4);
lY = r6.Next(0, 4);
newValue = 2 * (r7.Next(1, 3));
if (Arr[lX, lY] == 0)
{
Arr[lX, lY] = newValue;
break;
}
}
PrintArr(Arr, count);
count++;
finish = FinishCheck(Arr);
break;
case ConsoleKey.DownArrow:
Console.WriteLine("DOWN");
Arr = MoveVertical(Arr, 2);
while (true)
{
Random r5 = new Random();
Random r6 = new Random();
Random r7 = new Random();
lX = r5.Next(0, 4);
lY = r6.Next(0, 4);
newValue = 2 * (r7.Next(1, 3));
if (Arr[lX, lY] == 0)
{
Arr[lX, lY] = newValue;
break;
}
}
PrintArr(Arr, count);
count++;
finish = FinishCheck(Arr);
break;
case ConsoleKey.LeftArrow:
Console.WriteLine("LEFT");
Arr = MoveHorizontal(Arr, 3);
while (true)
{
Random r5 = new Random();
Random r6 = new Random();
Random r7 = new Random();
lX = r5.Next(0, 4);
lY = r6.Next(0, 4);
newValue = 2 * (r7.Next(1, 3));
if (Arr[lX, lY] == 0)
{
Arr[lX, lY] = newValue;
break;
}
}
PrintArr(Arr, count);
count++;
finish = FinishCheck(Arr);
break;
case ConsoleKey.RightArrow:
Console.WriteLine("RIGHT");
Arr = MoveHorizontal(Arr, 4);
while (true)
{
Random r5 = new Random();
Random r6 = new Random();
Random r7 = new Random();
lX = r5.Next(0, 4);
lY = r6.Next(0, 4);
newValue = 2 * (r7.Next(1, 3));
if (Arr[lX, lY] == 0)
{
Arr[lX, lY] = newValue;
break;
}
}
PrintArr(Arr, count);
count++;
finish = FinishCheck(Arr);
break;
}
}
} while (finish == 0);
break;
}
Console.WriteLine("게임 종료!");
Console.WriteLine("");
}
private static int[,] MoveVertical(int[,] Arr, int direct)
{
int countCheck = 0;
int[] temp = new int[4];
for (int i = 0; i < 4; i++)
{
temp[i] = 0;
}
if (direct == 1) // Upside
{
for (int j = 0; j < 4; j++)
{
for (int i = 0; i < 4; i++)
{
if (i == 0 && Arr[0, j] == 0) // 첫번째 칸 0
{
countCheck = 1;
}
else if (i == 0 && Arr[0, j] != 0) // 첫번째 칸 0 아닐 때
{
temp[0] = Arr[0, j];
countCheck = 1;
}
else if ((i != 0) && (Arr[i, j] == 0)) // 둘~넷째 칸 0
{
}
else if ((i != 0) && (Arr[i, j] != 0)) // 둘~넷째 칸 0 아닐 때
{
if ((temp[countCheck - 1] != Arr[i, j]) && (temp[countCheck - 1] != 0)) // 다른 수일 때
{
temp[countCheck] = Arr[i, j];
countCheck++;
}
else if ((temp[countCheck - 1] != Arr[i, j]) && (temp[countCheck - 1] == 0))
{
temp[countCheck - 1] = Arr[i, j];
countCheck++;
}
else if ((temp[countCheck - 1] == Arr[i, j])) // 같은 수일 때
{
temp[countCheck - 1] = 2 * temp[countCheck - 1];
}
}
}
for (int k = 0; k < 4; k++)
{
Arr[k, j] = temp[k];
temp[k] = 0;
}
countCheck = 0;
}
Console.WriteLine("Entered : Up");
}
else
{
for (int j = 0; j < 4; j++)
{
for (int i = 3; i >= 0; i--)
{
if (i == 3 && Arr[3, j] == 0)
{
countCheck = 2;
}
else if (i == 3 && Arr[3, j] != 0)
{
temp[3] = Arr[3, j];
countCheck = 2;
}
else if ((i != 3) && (Arr[i, j] == 0))
{
}
else if ((i != 3) && (Arr[i, j] != 0))
{
if ((temp[countCheck + 1] != Arr[i, j]) && (temp[countCheck + 1] != 0))
{
temp[countCheck] = Arr[i, j];
countCheck--;
}
else if ((temp[countCheck + 1] != Arr[i, j]) && (temp[countCheck + 1] == 0))
{
temp[countCheck + 1] = Arr[i, j];
countCheck--;
}
else if ((temp[countCheck + 1] == Arr[i, j]))
{
temp[countCheck + 1] = 2 * temp[countCheck + 1];
}
}
}
for (int k = 3; k >= 0; k--)
{
Arr[k, j] = temp[k];
temp[k] = 0;
}
countCheck = 0;
}
Console.WriteLine("Entered : Down");
}
return Arr;
}
private static int[,] MoveHorizontal(int[,] Arr, int direct)
{
int countCheck = 0;
int[] temp = new int[4];
for (int i = 0; i < 4; i++)
{
temp[i] = 0;
}
if (direct == 3)
{
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if (j == 0 && Arr[i, 0] == 0)
{
countCheck = 1;
}
else if (j == 0 && Arr[i, 0] != 0)
{
temp[0] = Arr[i, 0];
countCheck = 1;
}
else if ((j != 0) && (Arr[i, j] == 0))
{
}
else if ((j != 0) && (Arr[i, j] != 0))
{
if ((temp[countCheck - 1] != Arr[i, j]) && (temp[countCheck - 1] != 0))
{
temp[countCheck] = Arr[i, j];
countCheck++;
}
else if ((temp[countCheck - 1] != Arr[i, j]) && (temp[countCheck - 1] == 0))
{
temp[countCheck - 1] = Arr[i, j];
countCheck++;
}
else if ((temp[countCheck - 1] == Arr[i, j]))
{
temp[countCheck - 1] = 2 * temp[countCheck - 1];
}
}
}
for (int k = 0; k < 4; k++)
{
Arr[i, k] = temp[k];
temp[k] = 0;
}
countCheck = 0;
}
Console.WriteLine("Entered : Left");
}
else
{
for (int i = 0; i < 4; i++)
{
for (int j = 3; j >= 0; j--)
{
if (j == 3 && Arr[i, 3] == 0)
{
countCheck = 2;
}
else if (j == 3 && Arr[i, 3] != 0)
{
temp[3] = Arr[i, 3];
countCheck = 2;
}
else if ((j != 3) && (Arr[i, j] == 0))
{
}
else if ((j != 3) && (Arr[i, j] != 0))
{
if ((temp[countCheck + 1] != Arr[i, j]) && (temp[countCheck + 1] != 0))
{
temp[countCheck] = Arr[i, j];
countCheck--;
}
else if ((temp[countCheck + 1] != Arr[i, j]) && (temp[countCheck + 1] == 0))
{
temp[countCheck + 1] = Arr[i, j];
countCheck--;
}
else if ((temp[countCheck + 1] == Arr[i, j]))
{
temp[countCheck + 1] = 2 * temp[countCheck + 1];
}
}
}
for (int k = 3; k >= 0; k--)
{
Arr[i, k] = temp[k];
temp[k] = 0;
}
countCheck = 0;
}
Console.WriteLine("Entered : Right");
}
return Arr;
}
private static void PrintArr(int[,] Arr, int count)
{
Console.Clear();
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
Console.Write(Arr[i, j] + " ");
if (j == 3)
{
Console.WriteLine("");
}
}
}
Console.WriteLine("");
Console.WriteLine("");
Console.WriteLine("점수 : " + 1000 * count);
}
private static int FinishCheck(int[,] Arr)
{
int FillCount = 0;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if (Arr[i, j] != 0)
{
FillCount++;
}
}
}
if (FillCount == 16)
{
return 1;
}
else
{
return 0;
}
}
}
}
덕분에 매우 뿌듯했고 C#에 대해 어느 정도 이해력을 갖추었고 객체지향 프로그래밍 언어의 특성을 잘 이해할 수 있게 되었습니다.
728x90
728x90