Programming/C

C언어) 간단한 미로찾기 게임

쫑드기 2020. 6. 2. 21:13

<프로그램 개요>

- 아주 간단한 미로 찾기 게임이다. 

- 주인공(?)이 종점에 도착하면 프로그램은 종료한다.

 

<소스 코드>

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
#include <stdio.h>
#include<windows.h>
#include<conio.h>
 
#define MAX_SIZE 12
#define XPOS 50
#define YPOS 5
 
#define LEFT 75
#define RIGHT 77
#define UP 72
#define DOWN 80
 
char maze[MAX_SIZE][MAX_SIZE] = { { '1','1','1','1','1','1','1','1','1','1','1','1' },  //미로 그리기
                                 { 'x','0','1','1','1','1','1','1','1','1','1','1' },
                                 { '1','0','1','1','0','0','0','1','1','1','1','1' },
                                 { '1','0','0','0','0','1','0','1','1','0','0','0' },
                                 { '1','0','1','0','1','1','0','1','1','0','1','0' },
                                 { '1','1','1','1','1','1','0','0','0','0','1','y' },
                                 { '1','1','1','1','1','1','1','1','0','1','1','1' },
                                 { '1','1','1','1','1','1','1','1','0','0','0','1' },
                                 { '1','1','1','1','1','1','1','1','0','0','0','1' },
                                 { '1','1','1','1','1','1','1','1','1','1','0','0' },
                                 { '1','1','1','1','1','1','1','1','1','1','1','1' },
                                 { '1','1','1','1','1','1','1','1','1','1','1','1' },
                                   };
 
void GotoXY(int x,int y);
void print_mazeGame(char maze[][MAX_SIZE],int row);
int is_block(char maze[][MAX_SIZE],int row,int col);
void move_maze(char maze[][MAX_SIZE],int *row,int *col);
void CursorView(char show);
void complete_exit();
 
int main(void)
{    
    int row=1,col=0//시작 위치 초기화
 
    CursorView(0); 

GotoXY(XPOS -3 , YPOS -2 );
printf("쫑드기의 간단한 미로 찾기 게임");
 
    while (1//게임 start
    {
        print_mazeGame(maze,12); 
        move_maze(maze,&row,&col); 
    }
 
    return 0;
}
 
void CursorView(char show) //커서를 없애는 함수
{
    HANDLE hConsole;
    CONSOLE_CURSOR_INFO ConsoleCursor;
    hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    ConsoleCursor.bVisible = show;
    ConsoleCursor.dwSize = 1;
    SetConsoleCursorInfo(hConsole,&ConsoleCursor);
}
 
void GotoXY(int x,int y) //콘솔 위에 커서 위치를 바꾸어 원하는 곳에 미로를 출력하기 위한 함수
{
    COORD Pos;
    Pos.X = x;
    Pos.Y = y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),Pos);
}
 
int GetKey() //키를 받아들이는 함수
{
    if (_kbhit() != 0//키 입력이 유효할 경우
    {
        return _getch(); //입력한 키 반환
    }
 
    return 0//그렇지 않을 경우 0반환
}
 
void print_mazeGame(char maze[][MAX_SIZE],int row) //미로 frame(틀)을 그려주는 함수
{
 
    for (int i = 0; i < row; i++)
    {
        GotoXY(XPOS,YPOS + i);
        for (int j = 0; j < MAX_SIZE; j++)
        {
            if (maze[i][j] == '1')
                printf("■");
            else if (maze[i][j] == 'y')
                printf("★");
            else if (maze[i][j] == '0')
                printf("□");
            else
                printf("●");
        }
        puts("");
    }
}
 
int is_block(char maze[][MAX_SIZE], int i, int j)
{
 
    if (maze[i][j] == '1' || maze[i][j] == 'y'//미로가 벽일 경우, 종점일 경우
        return 1;
    else 
        return 0;
}
 
int is_finish(char maze[][MAX_SIZE],int i,int j)
{
 
    if (maze[i][j] == 'y'//종점일 경우
        return 1;
    else
        return 0;
}
 
void complete_exit() //완료한 후 프로그램을 종료시키는 함수
{
    printf("Complete!!!\n");
    exit(0);
}
 
void move_maze(char maze[][MAX_SIZE], int *row, int *col) //객체(게임 주인공?)을 움직이는 함수
{
    int chr; //키를 받아들이기 위한 변수
    int i = *row; //1
    int j = *col; //0
 
    
    chr = GetKey();
    
    if (chr == 0 || chr == 0xe0// 본문에서 설명하겠습니다.
    {
        chr = GetKey();
        switch (chr)
        {
            case UP: 
                i--;
                if (!(is_block(maze,i,j))) //블럭이 아닐 경우 객체를 옮길 수 있음
                {
                    maze[*row][j] = '0'//이전 블록에 0을 삽입 
                    maze[i][j] = 'x'//방향키를 옮긴 뒤 x를 삽입
                    *row -= 1;
                }
                else if (is_finish(maze,i,j)) //종점일 경우
                {
                    maze[*row][j] = '0';
                    maze[i][j] = 'x';
                    print_mazeGame(maze,12);
                    complete_exit();
                }
                break;
 
            case DOWN:
                i++;
                if (!(is_block(maze,i,j)))
                {
                    maze[*row][j] = '0';
                    maze[i][j] = 'x';
                    *row += 1;
                }
                else if (is_finish(maze,i,j))
                {
                    maze[*row][j] = '0';
                    maze[i][j] = 'x';
                    print_mazeGame(maze,12);
                    complete_exit();
                }
                break;
 
            case LEFT:
                j--;
                if (!(is_block(maze,i,j)))
                {
                    maze[i][*col] = '0';
                    maze[i][j] = 'x';
                    *col -= 1;
                }
                else if (is_finish(maze,i,j))
                {
                    maze[i][*col] = '0';
                    maze[i][j] = 'x';
                    print_mazeGame(maze,12);
                    complete_exit();
                }
                break;
 
            case RIGHT:
                j++;
                if (!(is_block(maze,i,j)))
                {
                    maze[i][*col] = '0';
                    maze[i][j] = 'x';
                    *col += 1;
                }
                else if (is_finish(maze,i,j))
                {
                    maze[i][*col] = '0';
                    maze[i][j] = 'x';
                    print_mazeGame(maze,12);
                    complete_exit();
                }
                break;
        }
    }
    
}
 
 
cs
 
 
 

 

 

<소 코드 설명>

※ 키를 입력받아 ←,→,↑,↓으로 이동시켜주는 코드입니다. 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

int chr;
chr = GetKey();
    
    if (chr == 0 || chr == 0xe0
        chr = GetKey();
        switch (chr)
        {
            case UP: 
                break;
 
            case DOWN:
                break;
 
            case LEFT:   
                break;
 
            case RIGHT:          
                break;
        }
    }
cs

 

여기서 문자의 키를 입력받는데 왜 chr을 int 형으로 선언을 하느냐에 의문을 가질 수도 있습니다.

int 형으로 받는 이유는 0xE0은 224를 뜻하기 때문에 char(1byte -128~127의 값)로 받는다면 문제가 생깁니다. 

여기서 0xE0은 무엇일까요?

 

getch 함수는 방향키나 fucntion키를 누르는 등 문자 이외의 키를 누르면 확장키(ASCII코드 이외의 코드)를 의미하는 
0xE0이나 0을 반환한다고 합니다. 여기서 getch 함수를 한 번 더 호출하면 그 확장키의 코드를 조사하도록 되어 있습니다. 


만약 0xE0이나 0을 조사하지 않고 getch 함수도 한 번 더 호출하지 않는다면, 방향키를 누르는 순간 K, M, H, P가 입력될 것입니다. 각각 Left, Right, Up, Down을 뜻하는 75, 77, 72, 80과 충돌하게 되죠.

 

그러므로 if구문으로 0xE0이나 0의 반환을 확인하고 한 번더 chr = GetKey();를 선언하여 방향키를 확인하는 것입니다.

 

 

<실행 결과>

 

<느낀 점>

코드를 깔끔하게 정리하려고 노력했지만, 여전히 지저분한 코드들이 많다. 그래도 내가 직접 만들었다는 것에 의의를 두고 뿌듯함을 느껴야겠다. 앞으로도 계속 빠이팅이다!

 

 

틀린 부분 있으면 피드백 부탁드립니다.

감사합니다. 좋은 하루 보내세요~!