이중 동적 할당을 활용하여 원하는 크기의 미로를 만들었으며,
stack을 활용하여 탈출 가능한 미로를 판별하고, 미로 게임을 진행 하도록 프로그램을 작성하였습니다.
https://youtu.be/UJwUcwXcFN4?si=b-xJkZxb3YuJqPUm
stack.h
#ifndef STACK_H
#define STACK_H
typedef struct {
int r;
int c;
}element;
typedef struct {
int capacity;
int top;
element* data;
}StackType;
void init_stack(StackType* s) {
s->capacity = 1;
s->top = -1;
s->data = (element*)malloc(sizeof(element) * s->capacity);
}
int is_full(StackType* s) {
return s->top == (s->capacity - 1);
}
int is_empty(StackType* s) {
return s->top == -1;
}
void push(StackType* s, element item) {
if (is_full(s)) {
s->capacity *= 2;
s->data = (element*)realloc(s->data, sizeof(element) * s->capacity);
}
s->data[++(s->top)] = item;
}
element pop(StackType* s) {
if (is_empty(s)) {
fprintf(stderr, "스택 공백 에러\n");
exit(1);
}
else return s->data[(s->top)--];
}
void break_stack(StackType* s) {
free(s->data);
}
#endif
maze.h
#ifndef MAZE_H
#define MAZE_H
element here, entry;
char** maze;
int heart = 3;
void print_maze(element size) {
printf("\n");
for (int i = 0; i < size.r; i++) {
for (int j = 0; j < size.c; j++) {
printf("%c", maze[i][j]);
}
printf("\n");
}
}
void make_maze(element size) {
maze = (char**)malloc(sizeof(char*) * size.r);
for (int i = 0; i < size.r; i++) {
maze[i] = (char*)malloc(sizeof(char) * size.c);
}
}
void input_random_maze(element size) {
for (int i = 0; i < size.r; i++) {
for (int j = 0; j < size.c; j++) {
if (i == 0 || j == 0 || size.r - 1 == i || size.c - 1 == j)
maze[i][j] = '1';
else
maze[i][j] = rand() % 2 + '0';
}
}
maze[rand() % (size.r - 2) + 1][rand() % (size.c - 2) + 1] = 'x';
entry.r = rand() % (size.r - 2) + 1;
entry.c = rand() % (size.c - 2) + 1;
maze[entry.r][entry.c] = 'e';
}
int push_loc(StackType* s, int r, int c, element size) {
//printf("%d %d\n", r, c);
if (r < 0 || r > size.r - 1 || c < 0 || c>size.c - 1) { // 미로의 테두리가 무조건 '1' 이기 때문에 없어도 되는 조건이긴 하다
//printf("리턴\n");
return 0;
}
if (maze[r][c] != '.' && maze[r][c] != '1') {
element temp;
temp.r = r;
temp.c = c;
push(s, temp);
return 1;
}
else if (maze[r][c] == '1') {
heart--;
return 0;
}
}
int check_maze(element size) {
StackType s;
int r, c;
init_stack(&s);
here = entry;
while (maze[here.r][here.c] != 'x') {
r = here.r;
c = here.c;
maze[r][c] = '.';
push_loc(&s, r - 1, c, size);
push_loc(&s, r, c - 1, size);
push_loc(&s, r + 1, c, size);
push_loc(&s, r, c + 1, size);
if (is_empty(&s)) {
break_stack(&s);
return 0;
}
else {
here = pop(&s);
}
}
break_stack(&s);
return 1;
}
void init_maze(element size) {
for (int i = 0; i < size.r; i++)
for (int j = 0; j < size.c; j++)
if (maze[i][j] == '.')
maze[i][j] = '0';
maze[entry.r][entry.c] = 'e';
heart = 3;
}
void print_heart() {
for (int i = 0; i < heart; i++) {
printf("♥");
}
for (int i = 0; i < 3 - heart; i++) {
printf("♡");
}
}
void break_maze(element size) {
for (int i = 0; i < size.r; i++) {
free(maze[i]);
}
free(maze);
}
int get_score(double duration) {
int score;
if (heart == 3) score = 100;
else if (heart == 2) score = 75;
else score = 50;
if (duration < 30)
score *= 1.5;
else if (duration < 60)
score *= 1.25;
else if (duration < 90)
score *= 1.;
else if (duration < 120)
score *= 0.8;
else
score *= 0.6;
return score;
}
#endif
main.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <Windows.h>
#include "stack.h"
#include "maze.h"
int main() {
srand(time(NULL));
StackType s;
element size;
int r, c, count = 0, ch1, ch2;
double duration;
clock_t start, finish;
init_stack(&s);
printf("미로의 크기를 입력하시오(예시: 6x6):");
scanf("%d x %d", &size.r, &size.c);
while (1) {
make_maze(size);
//input_maze(size);
input_random_maze(size);
printf("--- 초기 미로 맵 ---\n");
print_maze(size);
printf("--------------------\n");
if (check_maze(size)) {
init_maze(size);
printf("미로 탈출을 시작합니다.\n");
start = clock();
break;
}
else {
Sleep(1000);
printf("탈출 불가능한 미로가 생성되었습니다.\n");
printf("미로를 재 생성합니다.\n");
Sleep(1000);
system("cls");
}
}
Sleep(2000);
here = entry;
while (maze[here.r][here.c] != 'x') {
r = here.r;
c = here.c;
maze[r][c] = '.';
system("cls");
printf("[%d번째 이동]--------------------", ++count);
print_heart();
print_maze(size);
printf("-------------------------------\n");
while (1) {
Sleep(1000);
fflush(stdin);
if (heart == 0) {
printf("목숨이 다했습니다.\n");
printf("미로 탈출 실패\n");
break_maze(size);
break_stack(&s);
return 0;
}
if (_kbhit()) {
ch1 = _getch();
if (ch1 == 224) {
ch2 = _getch();
if (ch2 == 72) {
if (push_loc(&s, r - 1, c, size) == 0) {
system("cls");
printf("[%d번째 이동]--------------------", ++count);
print_heart();
print_maze(size);
printf("-------------------------------\n");
continue;
}
break;
}
else if (ch2 == 80) {
if (push_loc(&s, r + 1, c, size) == 0) {
system("cls");
printf("[%d번째 이동]--------------------", ++count);
print_heart();
print_maze(size);
printf("-------------------------------\n");
continue;
}
break;
}
else if (ch2 == 75) {
if (push_loc(&s, r, c - 1, size) == 0) {
system("cls");
printf("[%d번째 이동]--------------------", ++count);
print_heart();
print_maze(size);
printf("-------------------------------\n");
continue;
}
break;
}
else if (ch2 == 77) {
if (push_loc(&s, r, c + 1, size) == 0) {
system("cls");
printf("[%d번째 이동]--------------------", ++count);
print_heart();
print_maze(size);
printf("-------------------------------\n");
continue;
}
break;
}
//switch (ch2) { // switch 랑 goto 같이 쓰는 것보다 if 랑 break 쓰는게 더 좋을 듯 싶음
//printf("화살표 누름\n");
//case 72: push_loc(&s, r - 1, c, size); goto next;// 상
//case 80: push_loc(&s, r + 1, c, size); goto next;// 하
//case 75: push_loc(&s, r, c - 1, size); goto next;// 좌
//case 77: push_loc(&s, r, c + 1, size); goto next;// 우
//}
}
}
}
// next:
if (is_empty(&s)) {
printf("미로 탈출 실패\n");
break_maze(size);
break_stack(&s);
return 0;
}
else {
here = pop(&s);
//printf("here: %d %d\n", here.r, here.c);
}
}
finish = clock();
printf("미로 탈출 성공\n");
duration = (double)(finish - start) / CLOCKS_PER_SEC;
printf("미로를 탈출하는데 %.2f초 걸렸습니다.\n", duration);
printf("score: %d\n", get_score(duration));
break_maze(size);
break_stack(&s);
}'자료구조' 카테고리의 다른 글
| [C언어| 원형 연결 리스트로 큐 구현] 러시안 룰렛 게임 (0) | 2025.05.12 |
|---|---|
| [C언어| 연결리스트] 연결리스트로 표현한 다항식 (0) | 2025.05.12 |
| [쉽게 풀어 쓴 자료구조] 4장 연습문제 EXERCISE (programming) (0) | 2025.04.02 |