Maze

여러가지 탐색방법을 이용해서 미로찾기를 구현해보았습니다.

Recursion(순환)

구현

#include <stdio.h>
#include "color.h"


#define MAX 10
#define PATH 0
#define WALL 1
#define BLOCKED 2  // 방문+경로상에 있지 않은 것
#define VISITED 3  // 방문+경로가 될 가능성이 있는것

int maze[MAX+2][MAX+2]= {
    {4,4,4,4,4,4,4,4,4,4,4,4},
    {4,0,0,0,0,0,0,0,0,0,1,4},
    {4,0,1,1,0,1,1,0,1,1,1,4},
    {4,0,0,1,0,1,0,0,0,0,1,4},
    {4,0,1,0,1,0,1,1,1,0,0,4},
    {4,0,0,0,1,0,1,0,0,1,0,4},
    {4,0,1,0,1,0,0,0,1,1,0,4},
    {4,0,1,1,1,0,1,0,0,1,1,4},
    {4,0,1,0,0,0,1,1,1,0,1,4},
    {4,0,0,0,1,0,0,0,1,0,1,4},
    {4,0,1,1,1,0,1,0,0,0,0,4},
    {4,4,4,4,4,4,4,4,4,4,4,4}
};

int find_path(int x, int y){
    if(x<1 ||y<1||x>MAX||y>MAX)return 0;
    else if(maze[x][y] != PATH)return 0;
    else if(x==MAX&&y==MAX){
        maze[x][y]=VISITED;
        return 1;
    }else{
        maze[x][y] = VISITED;
        if(find_path(x-1, y)||find_path(x, y+1)||find_path(x+1, y)||find_path(x, y-1)) return 1;
        maze[x][y]=BLOCKED;
        return 0;
    }
}

int main(int argc, const char * argv[]) {
    print_maze(1, 1);
    find_path(1, 1);
    print_maze(MAX, MAX);
    return 0;
}

Stack(DFS)

stack을 이용해서 미로를 푸는 코드입니다.

규칙

우선 입구는 (1,1)이며, 출구는 (n-2,n-2)입니다.

다음과 같은 규칙으로 길을 찾을 것입니다!

  • 이미 방문한 위치에는 표시를 해서 무한루프를 방지한다.

  • 현재 위치에서 일정한 규칙으로 다음 위치로 이동한다.

    • 북, 동, 남, 서의 순서로 검사합니다.

    • 그 방향으로 갈 수 있으면, 즉, 아직 안 가본 위치 && 벽이 아니면 그 방향으로간다.

  • 아무 방향으로도 갈 수 없으면 그 위치에 오기 직전 위치로 되돌아간다.

위의 규칙을 자세히 살펴보면

  1. 현재 위치는 출발점이다.

  2. 다음을 반복한다.

    1. 현재 위치에 방문했다는 표시를 한다.(노란색)

    2. 현재 위치가 출구라면 종료한다.

    3. 현재 위치에서 북, 동, 남, 서 4방향에 대해 순서대로

      1. 그 방향으로 이동할 수 있는지(벽, 미로의 외부, 이미 방문한 위치)가 아닌지 검사한다.

      2. 만약 갈 수 있으면 그 방향으로 이동한다.

    4. 만약 3번에서 4방향 중 어느 쪽으로도 가지 못했다면 현재 위치에 도달하기 직전 위치로 돌아간다.

1,2,3,4의 과정을 되풀이하여 최종적으로 출구에 도달하면 미로찾기는 성공하게 됩니다.

C언어 구현

Position

  • position.h

  • position.c

Stack

  • stack.h

  • stack.c

Color

Main

  • 스택을 이용하는 방법은 한쪽 방향으로 갈 수 있는 만큼 깊이 간므로 DFS방법이다.

Queue(BFS)

규칙

다음과 같은 순서로 cell들을 방문한다.

  • L0 = {s}, 여기서 s는 출발 지점

  • L1 = L0에서 1번에 갈 수 있는 모든 셀들

  • L2 = L1에서 1번에 갈 수 있는 모든 셀들 중에 L0에 속하지 않는 셀들

  • Ln = Ln-1에서 1번에 갈 수 있는 셀들 중에 Ln-2에 속하지 않는 셀들

스택에서는 북->동->남->서로 찾기 때문에 최단 경로로 찾는지 보장할 수 없다. 하지만 큐에서는 동심원 형태로 찾기때문에 입구에서 출구까지 최단 경로를 찾을 수 있다.

출구에서 숫자가 감소하는 방향으로 따라가면 입구에 도달한다.

구현

Position

스택과 동일

Queue

Main

  • movable함수

  • print_maze

  • final_path

마지막으로 찾은 최종 경로를 표시해주기 위한 함수입니다.

Dijkstra

A*

A* 알고리즘 에 알고리즘에 대해서 자세히 설명되어있다.

queue

enQueue할 때, 삽입정렬을 해서 값을 넣어준다. (가중치가 낮은 값을 먼저 꺼내기 위해서!)

heuristic

open list

astar

backtracking

print

main

Last updated

Was this helpful?