실습: 탈출게임

2025. 2. 21. 00:36원티드_언리얼RPG 2기/C++

탈출게임
10 * 10 이차원 배열로 맵을 만든다.(출력한다)
WASD 키로 플레이어 (O)가 상하좌우로 이동한다.
플레이어의 시작지점은 {0, 0}, 탈출지점은 {0, 0} 을 제외한 랜덤설정
플레이어가 탈출지점에 도착하면 "탈출에 성공했습니다. 승리!" 출력하고 종료
		
#O########
##########
##########
##########
##########
##########
######E###
##########
##########
##########
#include <iostream>
#include <conio.h>
#include <cstdlib>
#include <ctime>

using namespace std;

const int MAP_SIZE_X = 10;
const int MAP_SIZE_Y = 10;

int main() {
    srand(time(0));

    char puzzleMap[MAP_SIZE_Y][MAP_SIZE_X];

    // 맵 초기화
    for (int i = 0; i < MAP_SIZE_Y; i++) {
        for (int j = 0; j < MAP_SIZE_X; j++) {
            puzzleMap[i][j] = '#';
        }
    }

    int playerX = 0, playerY = 0;
    int escapeX, escapeY;

    // 탈출 위치를 (0,0)이 아닌 랜덤한 곳에 배치
    do {
        escapeX = rand() % MAP_SIZE_X;
        escapeY = rand() % MAP_SIZE_Y;
    } while (escapeX == 0 && escapeY == 0);

    puzzleMap[playerY][playerX] = 'O';
    puzzleMap[escapeY][escapeX] = 'E';

    while (true) {
        // 화면 지우기 
        system("cls");

        // 맵 출력
        for (int i = 0; i < MAP_SIZE_Y; i++) {
            for (int j = 0; j < MAP_SIZE_X; j++) {
                cout << puzzleMap[i][j];
            }
            cout << "\n";
        }

        // 탈출 성공 여부 확인
        if (playerX == escapeX && playerY == escapeY) {
            cout << "탈출에 성공했습니다. 승리!\n";
            break;
        }

        cout << "WASD 키로 이동하세요: ";
        char input = _getch();

        // 이동 전 임시 좌표
        int nextX = playerX;
        int nextY = playerY;

        switch (input) {
            case 'w': case 'W':
                nextY--; 
                break;
            case 's': case 'S':
                nextY++; 
                break;
            case 'a': case 'A':
                nextX--; 
                break;
            case 'd': case 'D':
                nextX++; 
                break;
            default:
            	cout << "잘못된 입력입니다! ";
                break;
        }
        // 배열 범위를 벗어나지 않도록 확인
        if ( (nextX >= 0) && (nextX < MAP_SIZE_X) && (nextY >= 0) && (nextY < MAP_SIZE_Y) ) {
            // 기존 위치 초기화
            puzzleMap[playerY][playerX] = '#';

            // 새로운 위치 업데이트
            playerX = nextX;
            playerY = nextY;
            puzzleMap[playerY][playerX] = 'O';
        }
    }
    return 0;
}

 

실습하며 배운 것

1)  c++에서 rand() 만 사용하면 완벽한 랜덤값이 나오지 않는다. 따라서 time을 seed를 가지고 있는 srand함수를 부르고 rand()함수를 사용해야한다.

 

2) 배열을 이용할때는 항상 배열범위를 벗어나지 않도록 조심해야한다.

배열의 범위를 벗어나서 버퍼 오버플로우가 발생했다

따라서 플레이어가 이동한 좌표를 업데이트 하기전에 배열범위를 벗어나지 않도록 체크 해야했다.

또 다차원배열을 좌표로 나타낼때 순서를 생각해야한다. 맵데이터 배열에서  playerX좌표와 playerY좌표의 위치를 거꾸로 적어서 플레이어의 이동방향이 이상하게 움직였었다.

 

3) 맵데이터는 상수이므로 const int 형으로 배열의 크기를 미리 선언했다. 

 

4)  _getchar() 는 버퍼를 사용하지않아서 즉시 입력을 반환한다. 따라서 wasd입력에 바로 반응할수있다. 

하지만 공백이나 띄어쓰기가 있을때는 getline으로 받아야한다.

 

5) system("cls") 는 이전 출력을 지워주는 윈도우시스템 전용 명령어이다. 콘솔 게임에서 화면을 깔끔하게 갱신할 수 있는 방법이다. 하지만 실행속도가 느려서 "\033[H\033[J"  ANSI 이스케이프코드 를 출력해 커서를 (0,0)으로 이동하는 방법도 쓸 수 있을 것 같다.

'원티드_언리얼RPG 2기 > C++' 카테고리의 다른 글

구조체, 함수  (0) 2025.02.26
포인터, 메모리 영역  (3) 2025.02.21
변수, 상수, 코드표기법  (0) 2025.02.21
실습: 구구단 출력  (0) 2025.02.21
프로그래밍 기초 문법  (0) 2025.02.19