3월 19일 #콘솔게임 만들기

sejun-Lee·2025년 3월 19일
post-thumbnail

✅미로찾기 3단계 콘솔 게임

namespace ConsoleGame
{
    internal class Program
    {
        struct Position
        {
            public int x;
            public int y;
        }

        static char[][,] maps = new char[][,]
        {
            new char[17, 30] // 1단계 맵 (새로운 구조 추가 가능)
            {
                { '■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■' },
                { '▒',' ','▒',' ',' ',' ',' ',' ','▒',' ',' ',' ',' ',' ',' ','▒','▒',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','▒' },
                { '▒',' ','▒',' ','▒','▒','▒',' ','▒','▒',' ','▒','▒','▒',' ','▒','▒',' ','▒','▒',' ','▒','▒',' ','▒','▒',' ','▒','▒','▒' },
                { '▒',' ','▒',' ',' ',' ','▒',' ','▒','▒',' ','▒',' ','▒',' ','▒','▒',' ','▒','▒','▒','▒','▒',' ','▒',' ',' ','▒',' ','▒' },
                { '▒',' ','▒','▒','▒',' ','▒',' ','▒','▒',' ','▒',' ','▒',' ',' ','▒',' ','▒',' ',' ',' ',' ',' ','▒',' ','▒','▒',' ','▒' },
                { '▒',' ',' ',' ',' ',' ','▒',' ','▒','▒',' ','▒',' ','▒',' ','▒','▒',' ','▒',' ','▒','▒','▒','▒','▒',' ',' ',' ',' ','▒' },
                { '▒','▒','▒','▒','▒','▒','▒',' ','▒','▒',' ',' ',' ','▒',' ','▒','▒',' ','▒',' ',' ',' ',' ','▒','▒','▒','▒','▒',' ','▒' },
                { '▒',' ',' ',' ',' ',' ',' ',' ','▒','▒','▒','▒','▒','▒',' ',' ',' ',' ','▒',' ','▒','▒',' ','▒',' ',' ',' ',' ',' ','▒' },
                { '▒','▒','▒',' ','▒','▒','▒','▒','▒','▒','▒','▒','▒','▒','▒','▒','▒','▒','▒',' ','▒','▒',' ','▒',' ','▒','▒','▒','▒','▒' },
                { '▒',' ','▒',' ','▒',' ',' ',' ','▒',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','▒',' ',' ','▒',' ','▒',' ',' ',' ','▒' },
                { '▒',' ','▒',' ','▒',' ','▒','▒','▒',' ','▒','▒','▒',' ','▒','▒','▒','▒','▒','▒','▒',' ','▒','▒',' ','▒',' ','▒',' ','▒' },
                { '▒',' ','▒',' ','▒',' ','▒',' ','▒',' ','▒',' ','▒',' ','▒',' ',' ',' ',' ',' ',' ',' ','▒',' ',' ','▒',' ','▒',' ','▒' },
                { '▒',' ','▒',' ','▒',' ','▒',' ','▒',' ','▒',' ','▒',' ','▒',' ','▒','▒','▒','▒','▒',' ','▒',' ','▒','▒',' ','▒',' ','▒' },
                { '▒',' ','▒',' ',' ',' ','▒',' ',' ',' ',' ',' ','▒',' ','▒',' ',' ',' ',' ',' ','▒',' ','▒',' ',' ',' ',' ','▒',' ','▒' },
                { '▒',' ','▒',' ','▒',' ','▒','▒','▒','▒','▒','▒','▒',' ','▒','▒','▒','▒','▒',' ','▒',' ','▒','▒','▒','▒','▒','▒',' ','▒' },
                { '▒',' ',' ',' ','▒',' ',' ',' ',' ',' ',' ',' ',' ',' ','▒',' ',' ',' ',' ',' ','▒',' ',' ',' ',' ',' ',' ','▒',' ',' ' },
                { '■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■','■' }
            },
            new char[17, 30] // 2단계 맵
            {
                { '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■' },
                { '▒', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '▒', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '▒', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '▒' },
                { '▒', ' ', '■', '■', '■', '■', '■', '■', '■', ' ', '▒', ' ', '■', '■', '■', '■', '■', '■', '■', ' ', '▒', ' ', '■', '■', '■', '■', '■', '■', ' ', '▒' },
                { '▒', ' ', '▒', ' ', ' ', ' ', ' ', ' ', '▒', ' ', '▒', ' ', '▒', ' ', ' ', ' ', ' ', ' ', '▒', ' ', '▒', ' ', '▒', ' ', ' ', ' ', ' ', '▒', ' ', '▒' },
                { '▒', ' ', '▒', ' ', '■', '■', '■', ' ', '■', ' ', '▒', ' ', '▒', ' ', '■', '■', '■', ' ', '▒', ' ', '▒', ' ', '▒', ' ', '■', '■', ' ', '■', ' ', '▒' },
                { '▒', ' ', '▒', ' ', '▒', ' ', '▒', ' ', ' ', ' ', '▒', ' ', '▒', ' ', '▒', ' ', '▒', ' ', '▒', ' ', '▒', ' ', '▒', ' ', '▒', ' ', ' ', ' ', ' ', '▒' },
                { '▒', ' ', '▒', ' ', '▒', ' ', '■', '■', '■', '■', '■', ' ', '▒', ' ', '▒', ' ', '■', ' ', '■', ' ', '▒', ' ', '▒', ' ', '■', '■', '■', '■', '■', '▒' },
                { '▒', ' ', '▒', ' ', '▒', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '▒', ' ', '▒', ' ', ' ', ' ', ' ', ' ', '▒', ' ', '▒', ' ', ' ', ' ', ' ', ' ', ' ', '▒' },
                { '▒', '■', '■', ' ', '■', '■', '■', '■', '■', '■', '■', ' ', '▒', ' ', '■', '■', '■', '■', '■', '■', '■', ' ', '■', '■', '■', '■', '■', '■', ' ', '▒' },
                { '▒', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '▒', ' ', '▒', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '▒', ' ', ' ', ' ', '▒' },
                { '▒', '■', '■', '■', '■', '■', '■', '■', '■', ' ', '■', ' ', '■', '■', '■', '■', '■', '■', '■', '■', ' ', '■', '■', '■', '■', '■', '■', '■', ' ', '▒' },
                { '▒', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '■', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '▒', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '▒', ' ', '▒' },
                { '▒', ' ', '■', '■', '■', '■', '■', ' ', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', ' ', '■', '■', '■', '■', '■', '■', '■', ' ', '▒', ' ', '▒' },
                { '▒', ' ', ' ', ' ', ' ', ' ', '▒', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '▒', ' ', '▒', ' ', '▒' },
                { '▒', '■', '■', '■', '■', ' ', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', ' ', '▒', ' ', '▒', ' ', '▒' },
                { '▒', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '▒', ' ', '▒', ' ', ' ' },
                { '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■' },
            },
            new char[17, 30] // 3단계 맵
            {
                { '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■' },
                { '▒', ' ', ' ', ' ', ' ', '▒', ' ', '▒', ' ', ' ', ' ', ' ', '▒', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '▒', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '▒' },
                { '▒', ' ', '■', '■', ' ', '▒', ' ', '■', '■', '■', '■', ' ', '▒', ' ', '■', '■', '■', '■', '■', ' ', '■', '■', ' ', '■', '■', '■', '■', '■', ' ', '▒' },
                { '▒', ' ', '▒', ' ', ' ', '▒', ' ', ' ', ' ', ' ', ' ', ' ', '▒', ' ', ' ', ' ', ' ', ' ', '▒', ' ', ' ', ' ', ' ', ' ', ' ', '▒', ' ', ' ', ' ', '▒' },
                { '▒', ' ', '■', '■', '■', '■', '■', '■', ' ', '■', '■', '■', '■', '■', '■', ' ', '■', ' ', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', ' ', '▒' },
                { '▒', ' ', ' ', ' ', ' ', ' ', ' ', '▒', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '▒', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '▒', ' ', '▒' },
                { '▒', ' ', '■', '■', '■', '■', ' ', '■', '■', '■', '■', '■', '■', ' ', '■', '■', '■', '■', '■', '■', ' ', '■', '■', '■', '■', '■', '■', '■', ' ', '▒' },
                { '▒', ' ', '▒', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '▒', ' ', ' ', ' ', ' ', ' ', ' ', '▒', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '▒' },
                { '▒', ' ', '▒', ' ', '■', '■', '■', '■', '■', '■', '■', ' ', '■', '■', '■', '■', '■', '■', ' ', '■', '■', '■', ' ', '■', '■', '■', '■', '■', ' ', '▒' },
                { '▒', ' ', '▒', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '▒', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '▒', ' ', ' ', ' ', ' ', ' ', ' ', '▒', ' ', ' ', '▒' },
                { '▒', ' ', '■', '■', '■', '■', '■', '■', '■', ' ', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', ' ', '■', '■', '■', '▒' },
                { '▒', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '▒', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '▒', ' ', ' ', ' ', ' ', '▒' },
                { '▒', '■', '■', '■', '■', '■', '■', ' ', '▒', ' ', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', ' ', '▒' },
                { '▒', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '▒', ' ', ' ', ' ', ' ', ' ', '▒', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '▒' },
                { '▒', ' ', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', ' ', '▒', ' ', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '▒' },
                { '▒', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '▒', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
                { '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■', '■' }
            }
        };
        static int Level = 0;   // 미로 단계 출력
        static int Count = 0;   // 움직인 횟수 출력
        static bool gameLeset = false;

        static void Main(string[] args)
        {
            while (Level < maps.Length)
            {
                bool gameOver = false;  //게임종료 조건
                
                Position playerPos; //플레이어 위치 선언
                Position goalPos;   //골인지점 선언
                char[,] map;    // 2차원 맵 사용 선언

                Start(out playerPos, out goalPos, out map);     // 게임 준비

                while (gameOver == false)
                {
                    Render(playerPos, goalPos, map);    // 그리기
                    ConsoleKey key = Input();       // 입력
                    Update(key, ref playerPos, goalPos, map, out gameOver);     //처리
                             // playerPos는 꼭 ref를 써야함
                    Reset(key, ref playerPos, goalPos, map, ref gameOver, ref gameLeset);
                }
                
                Level++;    // 다음 레벨(map) 이동

            }
            
            End(ref gameLeset);     //게임종료
        }

        static void Start(out Position playerPos, out Position goalPos, out char[,] map)
        {   // 플레이어 초기 위치
            playerPos.x = 1;
            playerPos.y = 1;
            // 골인 지점
            goalPos.x = 29;
            goalPos.y = 15;

            map = maps[Level]; // 현재 레벨의 맵 로드

        }

        static void Render(Position playerPos, Position goalPos, char[,] map)
        {
            Console.SetCursorPosition(0, 0);    // 맵을 덮어서 그리기 -> 깜박거리지 않음

            PrintMap(map);  // 맵을 가장먼저 그려야 플레이어, 골인지점을 덮어쓰지 않음.
            printPlayer(playerPos); //플레이어 출력
            printGoal(goalPos); // 골인지점 출력
        }

        static ConsoleKey Input() //입력 작업
        {
            return Console.ReadKey(true).Key;   //입력 키 받음
        }

        static void Update(ConsoleKey key, ref Position playerPos, Position goalPos, char[,] map, out bool gameOver)
        {   
            // 입력받은 키로 플레이어 움직임
            Move(key, ref playerPos, map);
            // 종료 조건
            bool success = (playerPos.x == goalPos.x) && (playerPos.y == goalPos.y);    // 캐릭이 도착지점에 도착했을때
            if (success)
            {
                gameOver = true;
            }
            else
            {
                gameOver = false;
            }
        }

        static void Reset(ConsoleKey key, ref Position playerPos, Position goalPos, char[,] map, ref bool gameOver, ref bool gameLeset)    // 재시작 및 종료
        {
            switch (key)
            {
                case ConsoleKey.R:          // R 키를 누를 시 재시작 새로고침
                    playerPos.y = 1;        // player 위치 초기화
                    playerPos.x = 1;

                    Console.Clear();        // 콘솔창 지워서 초기화

                    PrintMap(map);          // 맵을 가장먼저 그려야 플레이어, 골인지점을 덮어쓰지 않음.
                    printPlayer(playerPos); //플레이어 출력
                    printGoal(goalPos);     // 골인지점 출력

                    break;
                case ConsoleKey.G:          // G 키를 누를 시 바로 게임 종료
                    Level = 10;              // Level 을 높게 올리지 않으면 한번에 종료되지 않고 다음단계로 넘어감.
                    gameOver = true;
                    gameLeset = true;
                    break;
            }
        }

        static void Move(ConsoleKey key, ref Position playerPos, char[,] map)   // 캐릭터 움직임
        {
            switch (key)
            {   
                case ConsoleKey.A:              // A 키 입력시
                case ConsoleKey.LeftArrow:      // 왼쪽 방향키 입력시
                    if (map[playerPos.y, playerPos.x - 1] == ' ')   // x 방향 앞이 ' ' 빈 공간일시 
                    {
                        playerPos.x--;                              // x 방향으로 1 움직임
                        Count++;                                    // 움직인 횟수 추가
                    }
                case ConsoleKey.D:
                case ConsoleKey.RightArrow:
                    if (map[playerPos.y, playerPos.x + 1] == ' ')
                    {
                        playerPos.x++;
                        Count++;
                    }
                    break;
                case ConsoleKey.W:
                case ConsoleKey.UpArrow:
                    if (map[playerPos.y - 1, playerPos.x] == ' ')
                    {
                        playerPos.y--;
                        Count++;
                    }
                    break;
                case ConsoleKey.S:
                case ConsoleKey.DownArrow:
                    if (map[playerPos.y + 1, playerPos.x] == ' ')
                    {
                        playerPos.y++;
                        Count++;
                    }
                    break;

            }
        }

        static void PrintMap(char[,] map)
        {
            // 맵 출력     y -> x 순서 바꾸지 말것!
            for (int y = 0; y < map.GetLength(0); y++)
            {					 // GetLength -> 0일경우 map[a,b] 의 a 값을 가져올 수 있음
                for (int x = 0; x < map.GetLength(1); x++)
                {					 // GetLength -> 1일경우 map[a,b] 의 b 값을 가져올 수 있음
                    Console.Write(map[y, x]);
                }
                Console.WriteLine();	// 행 마다 줄바꿈 -> 맵의 새로 완성을 위함
            }
        }

        static void printPlayer(Position playerPos)
        {
            Console.SetCursorPosition(playerPos.x, playerPos.y); // 콘솔 커서 위치 변경

            Console.ForegroundColor = ConsoleColor.Green;   // 출력 글자 색상 변경
            Console.Write("▲");
            Console.ResetColor();                           // 여기까지만 변경
        }

        static void printGoal(Position goalPos)
        {
            Console.SetCursorPosition(goalPos.x, goalPos.y); // 콘솔 커서 위치 변경

            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.Write("G");
            Console.ResetColor();
        }

        static void End(ref bool gameLeset)
        {
            Console.Clear();
            Console.ForegroundColor = ConsoleColor.Magenta;
            if (gameLeset == false)
            {
                if (Count <= 338)   // 최단 거리로 게임 종료시
                {
                    Console.WriteLine($"감사합니다!!!!\n{Count}걸음 <최단 거리!!>로 미로찾기를 끝내셧습니다.!!\n감사합니다!!");
                }
                else if (Count > 338)   // 최단 거리가 아닐시
                {
                    Console.WriteLine($"감사합니다!!!!\n{Count}걸음으로 미로찾기를 끝내셧습니다.!!\n최단 거리에 도전해 보세요!!");
                }
            }
            else
            {
                Console.WriteLine("게임을 포기하셨습니다.\n다음에 다시 도전해 주세요...");
            } 
                Console.ResetColor();
        }
    }
}
profile
초보 개발자

0개의 댓글