[C] #4 미로찾기 게임

2021. 9. 30. 12:08·C

미로찾기 기능 구현

저번 시간에 만들었던 의사코드를 이제는 실제 기능으로 구현하려고 한다.

void MoveMaze(현재 플레이어의 위치좌표 (x), (y) 포인터 )
{
    int nkey;

    if (_kbhit())
    {
        nkey = _getch();

        if (nkey == ARROW)
        {
            nkey = _getch();
            switch (nkey)
            {
            case UP:
                if (위쪽이 막히지 않았다면)
								{
									미로의 *(x), *(y)를 길로 변경;
									미로의 *(x), *(y)-1을 플레이어로 변경;
								  *(y)를 *(y)-1 로 변경
								}
								else if (위쪽이 도착지라면)
								{
									미로의 *(x), *(y)를 길로 변경;
									미로의 *(x), *(y)-1을 플레이어로 변경;
									프로그램 종료;
								}	
                break;

            case DOWN:
                if (아래쪽이 막히지 않았다면)
								{
									미로의 *(x), *(y)를 길로 변경;
									미로의 *(x), *(y)+1을 플레이어로 변경;
								  *(y)를 *(y)+1 로 변경
								}
								else if (아래쪽이 도착지라면)
								{
									미로의 *(x), *(y)를 길로 변경;
									미로의 *(x), *(y)-1을 플레이어로 변경;
									프로그램 종료;
								}	
                break;

            case LEFT:
								if (왼쪽이 막히지 않았다면)
								{
									미로의 *(x), *(y)를 길로 변경;
									미로의 *(x)-1, *(y)을 플레이어로 변경;
								  *(x)를 *(x)-1 로 변경
								}
								else if (왼쪽이 도착지라면)
								{
									미로의 *(x), *(y)를 길로 변경;
									미로의 *(x), *(y)-1을 플레이어로 변경;
									프로그램 종료;
								}	
                break;

            case RIGHT:
                if (오른쪽이 막히지 않았다면)
								{
									미로의 *(x), *(y)를 길로 변경;
									미로의 *(x)+1, *(y)을 플레이어로 변경;
								  *(x)를 *(x)+1 로 변경
								}
								else if (오른쪽이 도착지라면)
								{
									미로의 *(x), *(y)를 길로 변경;
									미로의 *(x), *(y)-1을 플레이어로 변경;
									프로그램 종료;
								}	
                break;
            }
        }

    }

}
IsBlock 함수

(막히지 않았다면) 기능은 주어진 좌표가 막힌 곳, 혹은 도착지인지 판정하는 함수로 구현하고자 한다.

2차원 배열에서 막힌 곳은 '1', 도착지는 'y'로 설정했으므로 다음과 같이 구현이 될 수 있다.

int IsBlock(int i, int j)
{

    if (maze[i][j] == '1' || maze[i][j] == 'y')
        return 1;
    else
        return 0;
}

해당 좌표가 막힌 곳이거나 도착지라면 1을 리턴, 그렇지 않다면 0을 리턴

 

IsFinish

(도착지라면) 기능은 좌표가 도착지인지 확인하면 된다.

즉, 해당 좌표가 y인지 확인하면 된다.

int IsFinish(int i, int j)
{

    if (maze[i][j] == 'y')
        return 1;
    else
        return 0;
}

해당좌표가 도착지라면 1을 리턴, 아니라면 0을 리턴

 

좌표 포인터

1, 2, 3단계 미로를 다 출력해보면 플레이어의 위치가 3행 2열 위치에 고정되어 있다는 것을 알 수 있다.

즉, 현재 플레이어 위치좌표 x, y 포인터를 받는 것은 다음과 같이 수정할 수 있다.

// 의사 코드

void MoveMaze(현재 플레이어의 위치좌표 (x), (y) 포인터 )
{
	//...
}

// 수정된 코드

void MoveMaze(int *row, int *col )
{
	//...
}

int main(void)
{
		//...
    int row = 2, col = 1; //시작 위치 초기화

    while (1)
    {
        //PrintMazeGame();
        MoveMaze(&row, &col);
    }

    return 0;
}

MoveMaze 함수의 매개변수를 포인터인 int* row, int* col 로 설정했다.

그리고 main 함수에서 row = 2, col = 1로 시작 위치를 초기화했다. (3행 2열)

그 후, 매개변수로 포인터를 받기 때문에 주소값을 넣어줘야 한다.

 

기능 구현

함수의 매개변수를 완성했으므로 의사코드 기능을 실제 코드로 구현하겠다.

우선, 이전 코드에서 매개변수를 *(x) --> *col, *(y) --> *row 로 바꿔야 한다.

 

위쪽으로 가는 경우,

case UP:
                if (!(IsBlock(*row-1, *col)))
                {
                    maze[*row][*col] = '0';
                    maze[*row-1][*col] = 'x';
                    *row -= 1;
                }
								else if (IsFinish(*row-1, *col))
                {
                    // 임시로 강제종료!
										exit(0);
                }
                break;
IsBlock
// if (위쪽이 막히지 않았다면)
if (!(IsBlock(*row-1, *col))) // 리턴값이 1이므로, !를 붙이세요!
{
    //...
}

매개변수로 *row-1을 사용한 이유는?

--> 이동하고자 하는 좌표가 한 칸 위의 좌표이기 때문이다.

좌표값 예시 그림

 

if (!(IsBlock(*row-1, *col)))
{
	// 미로의 *(x), *(y)를 길로 변경;
	maze[*row][*col] = '0';
	
	// 미로의 *(x), *(y)-1을 플레이어로 변경;
	maze[*row-1][*col] = 'x';
	
	// *(y)를 *(y)-1 로 변경
	*row -= 1;
}

막힌 곳이 아니라면, 이동시켜야 한다.

현재 좌표를 길로 바꾸고 이동할 좌표를 플레이어로 변경시키면 된다.

위쪽으로 이동하는 것이므로 *row의 값을 *row-1로 변경시키면 된다.

 

IsFinish
//else if (위쪽이 도착지라면)

else if (IsFinish(*row-1, *col))
{
    // 임시로 강제종료!
		exit(0);
}

IsBlock 함수와 마찬가지로 매개변수는 *row-1을 사용해줬다.

도착지라면 exit 함수를 통해 콘솔을 강제 종료하도록 했다.

 

최종 코드

// maze.c

#include "mheader.h"

int main(void)
{
    int row = 2, col = 1;
    char level;
    CursorView(0);

    GotoXY(XP, YP - 3);
    printf("미로 찾기 게임\n");
    GotoXY(XP, YP - 2);
    printf("난이도를 선택하세요. (1, 2, 3) ");
    scanf("%c", &level);

    LoadMaze(level);

    while (1)
    {
        PrintMazeGame();
        PlayMaze(&row, &col);
    }
}
// mheader.h

#ifndef HEADER
#define HEADER

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <Windows.h>
#include <conio.h>

#define SIZE 19
#define XP 40
#define YP 5

#define LEFT 75
#define RIGHT 77
#define UP 72
#define DOWN 80
#define ARROW 224

void LoadMaze(char num);
void GotoXY(int x, int y);
void PrintMazeGame();
void CursorView(char show);
void PlayMaze(int* row, int* col);
int IsBlock(int i, int j);
int IsFinish(int i, int j);

char maze[SIZE][SIZE];

#endif
// mheader.c

#include "mheader.h"

void LoadMaze(char num)
{
    char path[20] = "./Maze";
    strcat(path, &num);
    strcat(path, ".txt");

    char str_tmp[50] = { 0, };
    FILE* f = fopen(path, "r");

    for (int i = 0; i < SIZE; i++)
    {
        fgets(str_tmp, 50, f);
        char* ptr = strtok(str_tmp, "\t");
        for (int j = 0; j < SIZE; j++)
        {
            maze[i][j] = *ptr;
            ptr = strtok(NULL, "\t");
        }
    }
    fclose(f);
}

void GotoXY(int x, int y)
{
    COORD Pos;
    Pos.X = x;
    Pos.Y = y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Pos);
}

void PrintMazeGame()
{

    for (int i = 0; i < SIZE; i++)
    {
        GotoXY(XP, YP + i);
        for (int j = 0; j < 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("");
    }
}

void CursorView(char show)
{
    CONSOLE_CURSOR_INFO ConsoleCursor;
    ConsoleCursor.bVisible = show;
    ConsoleCursor.dwSize = 1;
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &ConsoleCursor);
}

void PlayMaze(int* row, int* col)
{
    int nkey;

    if (_kbhit())
    {
        nkey = _getch();

        if (nkey == ARROW)
        {
            nkey = _getch();
            switch (nkey)
            {
            case UP:
                if (!(IsBlock(*row - 1, *col)))
                {
                    maze[*row][*col] = '0';
                    maze[*row - 1][*col] = 'x';
                    *row -= 1;
                }
                else if (IsFinish(*row - 1, *col))
                {
                    exit(0);
                }
                break;

            case DOWN:
                if (!(IsBlock(*row + 1, *col)))
                {
                    maze[*row][*col] = '0';
                    maze[*row + 1][*col] = 'x';
                    *row += 1;
                }
                else if (IsFinish(*row + 1, *col))
                {
                    exit(0);
                }
                break;

            case LEFT:
                if (!(IsBlock(*row, *col-1)))
                {
                    maze[*row][*col] = '0';
                    maze[*row][*col-1] = 'x';
                    *col -= 1;
                }
                else if (IsFinish(*row, *col-1))
                {
                    exit(0);
                }
                break;

            case RIGHT:
                if (!(IsBlock(*row, *col + 1)))
                {
                    maze[*row][*col] = '0';
                    maze[*row][*col + 1] = 'x';
                    *col += 1;
                }
                else if (IsFinish(*row, *col + 1))
                {
                    exit(0);
                }
                break;
            }
        }

    }
}

int IsBlock(int i, int j)
{

    if (maze[i][j] == '1' || maze[i][j] == 'y')
        return 1;
    else
        return 0;
}

int IsFinish(int i, int j)
{

    if (maze[i][j] == 'y')
        return 1;
    else
        return 0;
}

'C' 카테고리의 다른 글

[C] 미로찾기 게임 최종  (0) 2021.10.02
[C] #5 미로찾기 게임  (0) 2021.10.02
[C] #3 미로찾기 게임  (0) 2021.09.30
[C] #2 미로찾기 게임  (0) 2021.09.28
[C] #1 미로찾기 게임  (0) 2021.09.27
'C' 카테고리의 다른 글
  • [C] 미로찾기 게임 최종
  • [C] #5 미로찾기 게임
  • [C] #3 미로찾기 게임
  • [C] #2 미로찾기 게임
Rix
Rix
  • Rix
    The Nights
    Rix
  • 전체
    오늘
    어제
  • 글쓰기 관리
    • 분류 전체보기 (106)
      • 알고리즘 (5)
        • Python (1)
        • C++ (6)
      • CS (0)
      • Backend (20)
        • 로드맵 (1)
        • Java (17)
        • Spring (2)
      • TIL (0)
      • Flutter (13)
      • Python (7)
        • 디스코드 챗봇 (1)
        • 문법 (1)
        • 머신러닝 (2)
      • C (28)
        • 문법 (19)
      • ETC (2)
        • Git (2)
        • GitHub (1)
        • Hacking (4)
      • Game (13)
        • Unity (13)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Failed to create GICache
    절대강좌유니티
    C심화
    C
    1152
    문자열 함수
    이중포인터
    미로찾기
    백준
    DART
    Unity
    공백포함
    이미지분류
    2차원 배열
    nullsafety
    콘솔창
    코뮤니티
    c언어
    1546
    TensorFlow
  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.3
Rix
[C] #4 미로찾기 게임
상단으로

티스토리툴바