C

[C] #2 미로찾기 게임

Rix 2021. 9. 28. 23:11

#1에서 만들었던 미로를 0, 1이 아닌 다른 것들로 해서 좀 더 미로답게 만들 것이다.

그러기 위해서 필요한 코드는 다음과 같다.

#define XP 40
#define YP 5

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("●");
        }
        printf("\n");
    }
}
선언부
#define XP 40
#define YP 5

콘솔의 중간에 미로를 출력하기 위해, XP와 YP라는 이름으로 기본 좌표값을 설정

 

GotoXY
void PrintMazeGame()
{
    for (int i = 0; i < SIZE; i++)
    {
        GotoXY(XP, YP + i);
				/....
}

미로찾기의 알고리즘은 다음과 같다.

1. 미로 불러오기 및 변환

2. 콘솔창에 미로 그리기

3. 키 입력 받기

4. 이동, 혹은 클리어

5. 2~4 반복

 

여기서, 2번이 PrintMazeGame 함수이다.

2~4를 반복해서 수행해야 하므로, 지정된 위치에 미로를 반복해서 그려줘야 한다.

즉, 메인함수를 다음과 같이 구성해야 하는 것이다.

int main(void)
{
    /...
    LoadMaze(Level);

    while (1)
    {
        // 2. 미로를 출력하는 함수 ( 위의 PrintMazeGame() )
        // 3. 키 입력을 받아, 이동 혹은 클리어를 판정하는 함수
    }

    return 0;
}

 

미로를 출력하는 함수는 다음과 같다.

// main.c
#include "header.h"

#define XP 40
#define YP 5
void PrintMazeGame();

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

    LoadMaze(level);
    while (1)
    {
        PrintMazeGame();
    }
}

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("");
    }
}

--> 하지만 출력할 때 커서가 계속 이동하면서 깜빡임이 생기게 된다.

 

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

CONSOLE_CURSOR_INFO 구조체를 생성한다.

커서의 두께를 의미하는 dwSize, 커서의 노출 여부를 결정하는 bVisible을 멤버 변수로 갖는다.

 

ConsoleCursor.bVisible = show;
ConsoleCursor.dwSize = 1;

매개변수로 show를 받는다.

해당 변수는 True, False 의미를 갖는 1, 0이 될 것이므로 bVisible의 값으로 설정한다.

 

SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &ConsoleCursor);

콘솔의 핸들값과 콘솔 커서 정보를 받아서 해당 콘솔의 설정을 변경하는 함수이다.

 

CursorView 함수는 메인함수에서 한 번만 사용하면 된다.

 

<전체 코드>

// header.h
#ifndef HEADER
#define HEADER

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

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

void LoadMaze(char num);
void GotoXY(int x, int y);
void PrintMazeGame();
void CursorView(char show);

char maze[SIZE][SIZE];

#endif
// header.c
#include "header.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);
}
// main.c

#include "header.h"

int main(void)
{
    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();
    }
}