Unity/수업과제

과제 - 2048 게임

ljw4104 2021. 3. 20. 16:17

 

Study08.zip
0.04MB

흰색에 빨간색이면 잘 보일 줄 알았는데 숫자가 너무 얇아서 잘 보이지 않는다.

화살표를 눌렀을 때의 알고리즘은 다음과같다.

 

각 방향으로 움직이되 향하는 방향의 다음 인덱스의 값이 0이거나 판의 끝이 아닐경우에만 움직인다.

다 움직였을때는 각 방향의 다음 인덱스와 값이 같은지를 비교하고 값이 같으면 서로 합쳐진다.

 

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Media;

namespace Study08
{
    public struct Position
    {
        public int row;
        public int col;
        public Position(int xPos, int yPos)
        {
            this.row = xPos;
            this.col = yPos;
        }
    }
    //게임을 구동하는 클래스
    public class GameLauncher
    {
        private int[,] arrPlate;              //판
        private int turn;
        private int score;
        public GameLauncher()
        {

        }

        //초기화
        public void Init()
        {
            Console.Clear();
            score = 0;
            turn = 0;

            int menu = ViewTitle();
            if (menu == 1)
            {
                CreatePlate();
                StartGame();
            }
            else
            {
                EndGame();
            }
        }

        //새로운 판을 생성
        public void CreatePlate()
        {
            this.arrPlate = new int[5, 5];          //5x5 판 생성
            CreateBlock();
            Print();
        }

        //빈 자리 중 한 칸에 랜덤하게 2 또는 4가 나온다
        public void CreateBlock()
        {
            Random r = new Random();
            int row;
            int col;
            do
            {
                if (!CheckZero())
                {
                    Print();
                    Console.WriteLine("\t\t\t\t\t\t빈\t칸\t 없\t음");
                    EndGame();
                }
                row = r.Next(0, arrPlate.GetLength(0));
                col = r.Next(0, arrPlate.GetLength(1));
            } while (arrPlate[row, col] != 0); ;
            arrPlate[row, col] = (r.Next(1, 101) <= 50 ? 2 : 4);
        }

        //게임 시작
        public void StartGame()
        {
            while (true)
            {
                ConsoleKeyInfo keyInfo = Console.ReadKey();
                Console.WriteLine();
                Console.Clear();
                Console.BackgroundColor = ConsoleColor.White;
                Console.ForegroundColor = ConsoleColor.Red;
                bool isMove = false;
                if (keyInfo.Key == ConsoleKey.LeftArrow)
                {
                    for (int i = 0; i < arrPlate.GetLength(0); i++)
                    {
                        for (int j = 1; j < arrPlate.GetLength(1); j++)
                        {
                            //첫번째 가로줄부터 왼쪽부터 오른쪽으로 탐색.
                            //맨 왼쪽에 있는것은 판별할 이유가 없기에 인덱스 1번부터 시작
                            int pos = 0;
                            if (arrPlate[i, j] != 0)
                            {
                                pos = j;
                                while (pos > 0 && arrPlate[i, pos - 1] == 0)
                                {
                                	isMove = true;
                                    //index가 1 이상이고 왼쪽이 0(빈칸)이면 서로 교체
                                    //왼쪽이 0이 아닌 숫자가 있거나 pos가 0이 될때까지 이동
                                    Swap(new Position(i, pos--), new Position(i, pos));
                                }
                            }

                            if (pos > 0 && pos < arrPlate.Length && arrPlate[i, pos - 1] == arrPlate[i, pos])
                            {
                            	isMove = true;
                                //교체후 왼쪽에 같은 숫자가 있으면 왼쪽 칸은 x2 , 오른쪽 칸은 0으로 채우고 스코어 + 1
                                arrPlate[i, pos - 1] *= 2;
                                arrPlate[i, pos] = 0;
                                score++;
                            }
                        }
                    }
                }
                else if (keyInfo.Key == ConsoleKey.RightArrow)
                {
                    for (int i = 0; i < arrPlate.GetLength(0); i++)
                    {
                        for (int j = arrPlate.GetLength(1) - 2; j >= 0; j--)
                        {
                            //첫번째 가로줄부터 오른쪽에서 왼쪽으로 탐색
                            //맨 오른쪽에 있는것은 판별할 필요 없음. 맨 오른쪽 인덱스-1 부터 탐색 시작
                            int pos = 0;
                            if (arrPlate[i, j] != 0)
                            {
                                pos = j;
                                while (pos < arrPlate.GetLength(1) - 1 && arrPlate[i, pos + 1] == 0)
                                {
                                	isMove = true;
                                    //index가 맨 오른쪽보다 작고 오른쪽이 0(빈칸)이면 서로 교체
                                    //오른쪽이 0이 아닌 숫자가 있거나 pos가 마지막 인덱스가 될때까지 이동
                                    Swap(new Position(i, pos++), new Position(i, pos));
                                }
                            }

                            if (pos >= 0 && pos < arrPlate.GetLength(1) - 1 && arrPlate[i, pos + 1] == arrPlate[i, pos])
                            {
                            	isMove = true;
                                //오른쪽값과 비교해서 오른쪽과 같으면 오른쪽에 있는 칸을 x2, 본인 칸을 0으로 만듬
                                arrPlate[i, pos + 1] *= 2;
                                arrPlate[i, pos] = 0;
                                score++;

                            }
                        }
                    }
                }
                else if (keyInfo.Key == ConsoleKey.UpArrow)
                {
                    //위쪽 화살표와 오른쪽 화살표는 왼쪽 오른쪽 할때를 90도 뒤집었다 생각하면 된다. 즉 i,j값이 뒤바뀐다
                    //나머지는 동일
                    for (int i = 0; i < arrPlate.GetLength(1); i++)
                    {
                        int pos = 0;
                        for (int j = 0; j < arrPlate.GetLength(0); j++)
                        {
                            if (arrPlate[j, i] != 0)
                            {
                                pos = j;
                                while (pos > 0 && arrPlate[pos - 1, i] == 0)
                                {
                                	isMove = true;
                                    Swap(new Position(pos--, i), new Position(pos, i));
                                }
                            }
                            if (pos > 0 && arrPlate[pos, i] == arrPlate[pos - 1, i])
                            {
                            	isMove = true;
                                arrPlate[pos - 1, i] *= 2;
                                arrPlate[pos, i] = 0;
                                score++;
                            }
                        }
                    }
                }
                else if (keyInfo.Key == ConsoleKey.DownArrow)
                {
                    for (int i = 0; i < arrPlate.GetLength(1); i++)
                    {
                        for (int j = arrPlate.GetLength(0) - 2; j >= 0; j--)
                        {
                            int pos = 0;
                            if (arrPlate[j, i] != 0)
                            {
                                pos = j;
                                while (pos < arrPlate.GetLength(0) - 1 && arrPlate[pos + 1, i] == 0)
                                {
                                	isMove = true;
                                    Swap(new Position(pos++, i), new Position(pos, i));
                                }
                                if (pos < arrPlate.GetLength(0) - 1 && arrPlate[pos, i] == arrPlate[pos + 1, i])
                                {
                                	isMove = true;
                                    arrPlate[pos, i] = 0;
                                    arrPlate[pos + 1, i] *= 2;
                                    score++;
                                }
                            }
                        }
                    }
                }
                else if (keyInfo.Key == ConsoleKey.Escape)
                {
                    Console.Clear();
                    this.EndGame();
                }
                if(isMove){
                	CreateBlock();
                	turn++;
                }
                Print();
            }
        }

        //게임 종료
        public void EndGame()
        {
            Console.WriteLine("\n\n\n\n\n\t\t\t\t\t\t게\t임\t종\t료");
            System.Diagnostics.Process.GetCurrentProcess().Kill();          //프로세스 강제종료
        }

        private void Swap(Position a, Position b)
        {
            int temp = arrPlate[a.row, a.col];
            arrPlate[a.row, a.col] = arrPlate[b.row, b.col];
            arrPlate[b.row, b.col] = temp;
        }

        private void Print()
        {
            Console.Clear();
            Console.BackgroundColor = ConsoleColor.White;
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("\n\n\t\t\t\t\t\t턴 : {0}, 점수 : {1}", turn, turn + score * 3);
            Console.WriteLine("\n\n\n\n");
            Console.WriteLine("\t\t\t\t==============================================");
            for (int i = 0; i < arrPlate.GetLength(0); i++)
            {
                Console.Write("\t\t\t\t");
                for (int j = 0; j < arrPlate.GetLength(1); j++)
                {
                    if (j == 0)
                    {
                        Console.Write("||");
                    }
                    Console.Write("{0, 5}", arrPlate[i, j]);
                    if (j == arrPlate.GetLength(1) - 1)
                    {
                        Console.Write(" ||");
                    }
                    else
                    {
                        Console.Write("  ||");
                    }
                }
                Console.WriteLine();
                Console.WriteLine("\t\t\t\t==============================================");
            }
        }

        //판에 0이 적어도 하나정도는 있는가?, 굳이 0이 몇개있는지와 어디에 0이 있는지는 알 필요가 없다.
        private bool CheckZero()
        {
            for (int i = 0; i < arrPlate.GetLength(0); i++)
            {
                for (int j = 0; j < arrPlate.GetLength(1); j++)
                {
                    if (arrPlate[i, j] == 0)
                        return true;
                }
            }
            return false;
        }

        private int ViewTitle()
        {
            string title = @"                                kkkkkkO000KKKKKKKKKKKKK000KKKKKKKKKKKKKKKK0Okkkkkk
                                kkkO0KXNNNNNNNNNNNNNNNNXKKNWWWWWWWWWWWWWWWWNX0Okkk
                                kkOKNNNNNNNNXXNNNNNNNNNXKKNWWWWWWWWWWNWWWWWWWWX0kk
                                k0XNNNNNX0xdddxOKNNNNNNXKKNWWWWWWNKkdddx0NWWWWWN0k
                                OKNNNNNNXOkOOxlcxKNNNNNXKKNWWWWWNOllk0xllOWWWWWWXO
                                OXNNNNNNNNNNN0ocxXNNNNNXKKNWWWWWXdcdXWKdcxXWWWWWN0
                                0XNNNNNNNNNKkolxKNNNNNNXKKNWWWWWKocxNWXdcdXWWWWWN0
                                OXNNNNNNNKkoox0XNNNNNNNXKKNWWWWWXdcdXWKocxNWWWWWN0
                                OXNNNNNN0occoxxxOXNNNNNXKKNWWWWWW0oldkdldKWWWWWWN0
                                OXNNNNNN0kxxxxxxOXNNNNNXKKNWWWWWWWXOkkO0NWWWWWWWN0
                                OXNNNNNNNNNNNNNNNNNNNNNXKKNWWWWWWWWWWWWWWWWWWWWWN0
                                OKXXXXXXXXXXXXXXXXXXXXXK0KXNNNNNNNNNNNNNNNNNNNNNX0
                                O0KKKKKKKKKKKKKKKKKKKKK0OOO000000000000000000000OO
                                OXXXXXXXXXXXXXXXXXNXXXXX0OOOOOOOOOOOOOOOOOOOOOOOOk
                                OXXXXXXXXXXXXXKXXXXXXXXK0OOOOOOOOOO00000OOOOOOOOOO
                                OXNXXXXXXXXXOdoxKNXXXXXK0OOOOOOOO0XNNNNNX0OOOOOOOO
                                OXXXXXXNNXKxolco0XXXXXNX0OOOOOOO0XWWX0XWWXOOOOOOOO
                                OXXXXXXNX0dokxco0NXXXXXX0OOOOOOOOKNWNXNWX0OOOOOOOO
                                OXXXXXXXOook0xcoOXXXXXXX0OOOOOOO0KNWNNWWXK0OOOOOOk
                                OKXXXNXKxloddlcldOXXXXXK0OOOOOOO0NWNK0KNMX0OOOOOOk
                                O0XXXXXXKKKK0xcoOXXXXXXK0OOOOOOO0XWWNXNWNX0OOOOOOk
                                kOKXXXXXXXXXXKO0XXXXXXXK0OOOOOOOO00KXXXK00OOOOOOkk
                                kkk0KXXXXXXXXXXNNXXXXXXK0OOOOOOOOOOOOOOOOOOOOOOkkk
                                kkkkOO0KKXXXXXXXXXXXXXXKOOOOOOOOOOOOOOOOOOOOkkkkkk
                                kkkkkkkkOOOOOOOOOOOOOOOOOOOOOOOOOkkkkkkkkkkkkkkkkk";
            Console.WriteLine(title);
            int menu = 0;
            Console.WriteLine("\n                                       1: START GAME\t2:SHUT DOWN");
            menu = Convert.ToInt32(Console.ReadLine());

            return menu;

        }
    }
}