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)์ ๋๋ค.
๋ค์๊ณผ ๊ฐ์ ๊ท์น์ผ๋ก ๊ธธ์ ์ฐพ์ ๊ฒ์ ๋๋ค!
์ด๋ฏธ ๋ฐฉ๋ฌธํ ์์น์๋ ํ์๋ฅผ ํด์ ๋ฌดํ๋ฃจํ๋ฅผ ๋ฐฉ์งํ๋ค.
ํ์ฌ ์์น์์ ์ผ์ ํ ๊ท์น์ผ๋ก ๋ค์ ์์น๋ก ์ด๋ํ๋ค.
๋ถ, ๋, ๋จ, ์์ ์์๋ก ๊ฒ์ฌํฉ๋๋ค.
๊ทธ ๋ฐฉํฅ์ผ๋ก ๊ฐ ์ ์์ผ๋ฉด, ์ฆ, ์์ง ์ ๊ฐ๋ณธ ์์น && ๋ฒฝ์ด ์๋๋ฉด ๊ทธ ๋ฐฉํฅ์ผ๋ก๊ฐ๋ค.
์๋ฌด ๋ฐฉํฅ์ผ๋ก๋ ๊ฐ ์ ์์ผ๋ฉด ๊ทธ ์์น์ ์ค๊ธฐ ์ง์ ์์น๋ก ๋๋์๊ฐ๋ค.
์์ ๊ท์น์ ์์ธํ ์ดํด๋ณด๋ฉด
ํ์ฌ ์์น๋ ์ถ๋ฐ์ ์ด๋ค.
๋ค์์ ๋ฐ๋ณตํ๋ค.
ํ์ฌ ์์น์ ๋ฐฉ๋ฌธํ๋ค๋ ํ์๋ฅผ ํ๋ค.(๋ ธ๋์)
ํ์ฌ ์์น๊ฐ ์ถ๊ตฌ๋ผ๋ฉด ์ข ๋ฃํ๋ค.
ํ์ฌ ์์น์์ ๋ถ, ๋, ๋จ, ์ 4๋ฐฉํฅ์ ๋ํด ์์๋๋ก
๊ทธ ๋ฐฉํฅ์ผ๋ก ์ด๋ํ ์ ์๋์ง(๋ฒฝ, ๋ฏธ๋ก์ ์ธ๋ถ, ์ด๋ฏธ ๋ฐฉ๋ฌธํ ์์น)๊ฐ ์๋์ง ๊ฒ์ฌํ๋ค.
๋ง์ฝ ๊ฐ ์ ์์ผ๋ฉด ๊ทธ ๋ฐฉํฅ์ผ๋ก ์ด๋ํ๋ค.
๋ง์ฝ 3๋ฒ์์ 4๋ฐฉํฅ ์ค ์ด๋ ์ชฝ์ผ๋ก๋ ๊ฐ์ง ๋ชปํ๋ค๋ฉด ํ์ฌ ์์น์ ๋๋ฌํ๊ธฐ ์ง์ ์์น๋ก ๋์๊ฐ๋ค.
1,2,3,4์ ๊ณผ์ ์ ๋ํ์ดํ์ฌ ์ต์ข ์ ์ผ๋ก ์ถ๊ตฌ์ ๋๋ฌํ๋ฉด ๋ฏธ๋ก์ฐพ๊ธฐ๋ ์ฑ๊ณตํ๊ฒ ๋ฉ๋๋ค.
C์ธ์ด ๊ตฌํ
1. ๋ฏธ๋ก๋ 2์ฐจ์ ๋ฐฐ์ด๋ก ๊ตฌํ๋๋ค. maze[x][y]
2. ํ์ฌ ์์น๋ ์ถ๋ฐ์ (1,1)์ด๋ค.
3. ๋ค์์ ๋ฐ๋ณตํ๋ค.
ใฑ. ํ์ฌ ์์น์ ๋ฐฉ๋ฌธํ๋ค๋ ํ์๋ฅผ ํ๋ค.(2)
ใด. ํ์ฌ ์์น๊ฐ ์ถ๊ตฌ๋ผ๋ฉด ์ข
๋ฃํ๋ค. maze[n-2][n-2]
ใท. ํ์ฌ ์์น์์ ๋ถ, ๋, ๋จ, ์ 4๋ฐฉํฅ์ ๋ํด ์์๋๋ก
- ๊ทธ ๋ฐฉํฅ์ผ๋ก ์ด๋ํ ์ ์๋์ง(๋ฒฝ, ๋ฏธ๋ก์ ์ธ๋ถ, ์ด๋ฏธ ๋ฐฉ๋ฌธํ ์์น)๊ฐ ์๋์ง ๊ฒ์ฌํ๋ค.
- ๋ง์ฝ ๊ฐ ์ ์์ผ๋ฉด ํ์ฌ ์์น๋ฅผ ์คํ์ pushํ๊ณ ๊ทธ ๋ฐฉํฅ์ผ๋ก ์ด๋
ใน. ๋ง์ฝ ใท๋ฒ์์ 4๋ฐฉํฅ ์ค ์ด๋ ์ชฝ์ผ๋ก๋ ๊ฐ์ง ๋ชปํ๋ค๋ฉด ์คํ์์ popํ ์์น๋ก ๋์๊ฐ๋ค.
Position
position.h
// position.h
#ifndef position_h
#define position_h
typedef struct pos{
int x,y;
}Position;
Position move_to(Position pos, int dir);
#endif /* position_h */
position.c
// position.c
#include "position.h"
// ๋ถ๋๋จ์๋ฐฉํฅ์ผ๋ก ์ด๋ํ๋ ๊ฒ์ด๋ค. ์ธ๋ก๊ฐ X, ๊ฐ๋ก๊ฐ Y
int offset[4][2] = {
{-1,0},
{0,1},
{1,0},
{0,-1}
};
Position move_to(Position pos,int dir){
Position next;
next.x = pos.x + offset[dir][0];
next.y = pos.y + offset[dir][1];
return next;
}
Stack
stack.h
// stack.h
#ifndef stack_h
#define stack_h
#include <stdio.h>
#include <stdlib.h>
#include "position.h"
typedef struct s{
int dir;
struct s * next;
}Stack;
Stack * new_node(int dir);
void init(Stack **s);
int is_empty(Stack *s);
int peak(Stack *s);
void push(Stack ** top, int dir);
void pop(Stack ** top);
#endif /* stack_h */
stack.c
// stack.c
#include "stack.h"
Stack * new_node(int dir){
Stack * new = (Stack *)malloc(sizeof(Stack));
new->dir = dir;
new->next=NULL;
return new;
}
void init(Stack **s){
*s = NULL; //์คํ์ด๊ธฐํ
}
int is_empty(Stack *s){
// NULL์ด๋ฉด 1(true) ์๋๋ฉด 0(false)
return (s==NULL);
}
int peak(Stack *s){
if(is_empty(s))return -1;
return s->dir;
}
void push(Stack ** top,int dir){
Stack * new = NULL;
if(is_empty(*top)){
new = new_node(dir);
}else{
new = new_node(dir);
new->next=*top;
}
(*top)=new;
}
void pop(Stack ** top){
Stack * p = *top;
if(is_empty(*top))return;
*top = p->next;
free(p);
}
Color
// color.h
#ifndef color_h
#define color_h
#define RESET "\033[0m"
#define BLACK "\033[30m" /* Black */
#define RED "\033[31m" /* Red */
#define GREEN "\033[32m" /* Green */
#define YELLOW "\033[33m" /* Yellow */
#define BLUE "\033[34m" /* Blue */
#define MAGENTA "\033[35m" /* Magenta */
#define CYAN "\033[36m" /* Cyan */
#define WHITE "\033[37m" /* White */
#define BOLDBLACK "\033[1m\033[30m" /* Bold Black */
#define BOLDRED "\033[1m\033[31m" /* Bold Red */
#define BOLDGREEN "\033[1m\033[32m" /* Bold Green */
#define BOLDYELLOW "\033[1m\033[33m" /* Bold Yellow */
#define BOLDBLUE "\033[1m\033[34m" /* Bold Blue */
#define BOLDMAGENTA "\033[1m\033[35m" /* Bold Magenta */
#define BOLDCYAN "\033[1m\033[36m" /* Bold Cyan */
#define BOLDWHITE "\033[1m\033[37m" /* Bold White */
#endif /* color_h */
Main
// main.c
#include "stack.h"
#include "position.h"
#include "color.h"
#include <unistd.h>
#define MAX 8
#define PATH 0 // ์ง๋๊ฐ ์ ์๋ ๊ธธ
#define WALL 1 // ์ง๋๊ฐ ์ ์๋ ๊ธธ == ๋ฒฝ ํฐ์!
#define VISITED 2 // ์ด๋ฏธ ๋ฐฉ๋ฌธํ ์์น
#define BACKTRACKED 3 // ๋ฐฉ๋ฌธํ๋ค ๋๋์ ๋์จ ์์น
#define EDGE 4 // ํ
๋๋ฆฌ
#define clear() printf("\033[H\033[J")
int maze[MAX+2][MAX+2]= {
{4,4,4,4,4,4,4,4,4,4},
{4,0,0,0,0,0,0,0,1,4},
{4,0,1,1,0,1,1,0,1,4},
{4,0,0,0,1,0,0,0,1,4},
{4,0,1,0,0,1,1,0,0,4},
{4,0,1,1,1,0,0,1,1,4},
{4,0,1,0,0,0,1,0,1,4},
{4,0,0,0,1,0,0,0,1,4},
{4,0,1,1,1,0,1,0,0,4},
{4,4,4,4,4,4,4,4,4,4}
};
int n=MAX; // ๋ฏธ๋ก์ ํฌ๊ธฐ
//void make_maze();
void print_maze();
int movable(Position pos,int dir);
int main(int argc, const char * argv[]) {
Stack * top;
init(&top);
// make_maze();
Position cur; // ํญ์ ํ์ฌ ์์น๋ฅผ ํํ
cur.x=1;
cur.y=1;
int init_dir = 0; //ํ ์์น์ ๋์ฐฉํ์ ๋ ์ฒ์์ผ๋ก ์๋ํด ๋ณผ ์ด๋ ๋ฐฉํฅ
while(1){
maze[cur.x][cur.y] = VISITED;
if(cur.x == n && cur.y == n){
print_maze(cur.x,cur.y);
printf("๋ฏธ๋ก๋ฅผ ์ฐพ์์ต๋๋ค!\n");
break;
}
// ๋ฐฉ๋ฌธํ๋์ง ๊ธฐ๋กํ๋ ๋ณ์
int forwarded = 0;
// ๋ถ ๋ ์ ๋จ ์์๋๋ก 0, 1, 2, 3
for(int dir = init_dir; dir<4;dir++){
if(movable(cur,dir)){ //์ด๋๊ฐ๋ฅํ์ง ๊ฒ์ฌ
push(&top,dir); // ์คํ์ ํ์ฌ ์์น ๋์ ์ด๋ํ๋ ๋ฐฉํฅ์ push
cur = move_to(cur,dir);
forwarded = 1;
init_dir = 0; //์ฒ์ ๋ฐฉ๋ฌธํ๋ ์์น์์๋ ํญ์ 0๋ถํฐ ์๋
break;
}
}
// 4๋ฐฉํฅ์ค ์๋ฌด๊ณณ๋ ๊ฐ์ง ๋ชปํ๋ค๋ฉด
if(!forwarded){
// ์๋ค๊ฐ ๋๋์๊ฐ ๊ณณ์์ ํ์
maze[cur.x][cur.y]=BACKTRACKED;
//์๋ ์ถ๊ตฌ๊ฐ ์๋ ๋ฏธ๋ก
if(is_empty(top)){
printf("๊ธธ์ด ์์ต๋๋ค.\n");
break;
}
int d = peak(top);
pop(&top);
// ์ด์ ์์น์์ ์ง๊ธ ์์น์ ์ฌ๋ d๋ฐฉํฅ์ผ๋ก ์ด๋ํ๋ค๋ฉด (d+2)%4๋ฒ ๋ฐฉํฅ์ผ๋ก ์ด๋ํ๋ฉด๋๋ค.
// ๋๋์๊ฐ๋ ๋ฐฉํฅ!
cur = move_to(cur, (d+2)%4);
// ์์น์์ d+1๋ฒ๋ฐฉํฅ๋ถํฐ ์๋ํ๋ฉด๋๋ค.
init_dir = d+1;
print_maze(cur.x, cur.y);
printf("๊ธธ์ด์์ต๋๋ค. ๋๋์๊ฐ๋๋ค.\n");
}
}
return 0;
}
int movable(Position pos, int dir){
Position tmp = move_to(pos, dir);
//1. dir๋ฐฉํฅ์ผ๋ก ์ด๋ํ ์ขํ๊ฐ 0~n-1์ด๋ด์ ์์ด์ผํ๋ค.
print_maze(tmp.x,tmp.y);
printf("maze[%d][%d]=%d\n",tmp.x,tmp.y,maze[tmp.x][tmp.y]);
if( tmp.x<1 || tmp.x>n){
printf("x๋ฒ์์ด๊ณผ\n");
return 0;
}
if(tmp.y<1||tmp.y>n+1){
printf("y๋ฒ์์ด๊ณผ\n");
return 0;
}
//2. wall์ด ์๋๊ณ , ๋ฒฝ์ด์๋์ด์ผํ๋ค.
switch (maze[tmp.x][tmp.y]) {
case 0:
printf("๊ฐ ์ ์๋ ๊ธธ์
๋๋ค.\n");
return 1;
case 1:
printf("๋ฒฝ์
๋๋ค. ๊ฐ ์ ์์ต๋๋ค.\n");
return 0;
case 2:
printf("์ด๋ฏธ ๋ฐฉ๋ฌธํ ๊ธธ์
๋๋ค. ๊ฐ ์ ์์ต๋๋ค.\n");
return 0;
case 3:
printf("์ด๋ฏธ ๋ฐฉ๋ฌธํ ๊ธธ์
๋๋ค. ๊ฐ ์ ์์ต๋๋ค.\n");
return 0;
default:
return 0;
}
}
void print_maze(int x,int y){
sleep(1);
clear();
for(int i=0;i<MAX+2;i++){
for(int j=0;j<MAX+2;j++){
switch (maze[i][j]) {
case 0:
printf(BLACK);
if(i==x&&j==y){
printf(BOLDRED);
}
printf("ใ
");
printf(RESET);
break;
case 1:
if(i==x&&j==y){
printf(BOLDRED);
}
printf("ใ
");
break;
case 2:
printf(BOLDYELLOW);
if(i==x&&j==y){
printf(BOLDRED);
}
printf("ใ
");
printf(RESET);
break;
case 3:
printf(BOLDGREEN);
if(i==x&&j==y){
printf(BOLDRED);
}
printf("ใ
");
printf(RESET);
break;
case 4:
printf(BOLDBLUE);
if(i==x&&j==y){
printf(BOLDRED);
printf("ใ
");
}else
printf("ใ
");
printf(RESET);
break;
default:
break;
}
printf(RESET);
if(j==MAX+1)printf("\n");
}
}
printf(RESET);
}
์คํ์ ์ด์ฉํ๋ ๋ฐฉ๋ฒ์ ํ์ชฝ ๋ฐฉํฅ์ผ๋ก ๊ฐ ์ ์๋ ๋งํผ ๊น์ด ๊ฐ๋ฏ๋ก DFS๋ฐฉ๋ฒ์ด๋ค.
Queue(BFS)
๊ท์น
๋ค์๊ณผ ๊ฐ์ ์์๋ก cell๋ค์ ๋ฐฉ๋ฌธํ๋ค.
L0 = {s}, ์ฌ๊ธฐ์ s๋ ์ถ๋ฐ ์ง์
L1 = L0์์ 1๋ฒ์ ๊ฐ ์ ์๋ ๋ชจ๋ ์ ๋ค
L2 = L1์์ 1๋ฒ์ ๊ฐ ์ ์๋ ๋ชจ๋ ์ ๋ค ์ค์ L0์ ์ํ์ง ์๋ ์ ๋ค
โฆ
Ln = Ln-1์์ 1๋ฒ์ ๊ฐ ์ ์๋ ์ ๋ค ์ค์ Ln-2์ ์ํ์ง ์๋ ์ ๋ค
์คํ์์๋ ๋ถ->๋->๋จ->์๋ก ์ฐพ๊ธฐ ๋๋ฌธ์ ์ต๋จ ๊ฒฝ๋ก๋ก ์ฐพ๋์ง ๋ณด์ฅํ ์ ์๋ค. ํ์ง๋ง ํ์์๋ ๋์ฌ์ ํํ๋ก ์ฐพ๊ธฐ๋๋ฌธ์ ์ ๊ตฌ์์ ์ถ๊ตฌ๊น์ง ์ต๋จ ๊ฒฝ๋ก๋ฅผ ์ฐพ์ ์ ์๋ค.
- ํ๋์ ํ๋ฅผ ๋ง๋ ๋ค.
- ์์น(0,0) ๋ ์ด๋ฏธ ๋ฐฉ๋ฌธํ ์์น์์ ํ์ํ๊ณ , ํ์ ์์น(0,0)์ ๋ฃ๋๋ค.
- ํ๊ฐ ๋น ๋๊น์ง ๋ค์์ ๋ฐ๋ณตํ๋ค.
- ํ์์ ํ๋์ ์์น p๋ฅผ ๊บผ๋ธ๋ค.
- p์์ ํ ์นธ ๋จ์ด์ง ์์น๋ค ์ค์์ ์ด๋ ๊ฐ๋ฅํ๋ฉด์ ์์ง ๋ฐฉ๋ฌธํ์ง ์์ ๋ชจ๋ ์์น๋ค์ ๋ฐฉ๋ฌธ๋ ์์น์์ ํ์ํ๊ณ ํ์ ๋ฃ๋๋ค.
- ๋ง์ฝ ๊ทธ ์์น๊ฐ ์ถ๊ตฌ๋ผ๋ฉด ์ข
๋ฃํ๋ค.
์ถ๊ตฌ์์ ์ซ์๊ฐ ๊ฐ์ํ๋ ๋ฐฉํฅ์ผ๋ก ๋ฐ๋ผ๊ฐ๋ฉด ์ ๊ตฌ์ ๋๋ฌํ๋ค.
๊ตฌํ
Position
์คํ๊ณผ ๋์ผ
Queue
//
// queue.h
// maze_queue
//
// Created by dahye Jeong on 2018. 5. 20..
// Copyright ยฉ 2018๋
dahye Jeong. All rights reserved.
//
#ifndef queue_h
#define queue_h
#include <stdio.h>
#include <stdlib.h>
#include "position.h"
typedef struct node{
Position pos;
struct node * next;
}QNode;
typedef struct que{
QNode *front, *rear;
}Queue;
void enQueue(Queue * q,Position pos);
void deQueue(Queue * q);
Position front(Queue *queue);
Position rear(Queue *queue);
QNode * new_node(Position pos);
Queue * creat_queue(void);
#endif /* queue_h */
//
// queue.c
// maze_queue
//
// Created by dahye Jeong on 2018. 5. 20..
// Copyright ยฉ 2018๋
dahye Jeong. All rights reserved.
//
#include "queue.h"
QNode * new_node(Position pos){
QNode * new = (QNode *)malloc(sizeof(QNode));
new->pos.x = pos.x;
new->pos.y = pos.y;
new->next=NULL;
return new;
}
Queue * creat_queue(void){
Queue * new = (Queue *)malloc(sizeof(Queue));
new->front = new->rear= NULL;
return new;
}
Position front(Queue *q){
return q->front->pos;
}
Position rear(Queue *q){
return q->rear->pos;
}
int is_empty(Queue * q){
return (q->front==NULL && q->rear==NULL);
}
//front ํฌ์ธํฐ๋ ์ญ์ , rear ํฌ์ธํฐ๋ ์ฝ์
ํ ๋ ์ฌ์ฉ
void enQueue(Queue * q,Position pos){
QNode * tmp = new_node(pos);
if(is_empty(q)){
q->front = q->rear = tmp;
return;
}
q->rear->next= tmp;
q->rear=tmp;
}
void deQueue(Queue * q){
if(q->front==NULL){
return;
}
q->front = q->front->next;
if(q->front==NULL) q->rear=NULL;
}
Main
//
// main.c
// maze_queue
//
// Created by dahye Jeong on 2018. 5. 20..
// Copyright ยฉ 2018๋
dahye Jeong. All rights reserved.
//
#include "queue.h"
#include "position.h"
#include "color.h"
#include <unistd.h>
#define MAX 8
#define PATH 0 // ์ง๋๊ฐ ์ ์๋ ๊ธธ
#define WALL 1 // ์ง๋๊ฐ ์ ์๋ ๊ธธ == ๋ฒฝ ํฐ์!
#define EDGE 4 // ํ
๋๋ฆฌ
#define clear() printf("\033[H\033[J")
int maze[MAX+2][MAX+2]= {
{4,4,4,4,4,4,4,4,4,4},
{4,0,0,0,0,0,0,0,1,4},
{4,0,1,1,0,1,1,0,1,4},
{4,0,0,0,1,0,0,0,1,4},
{4,0,1,0,0,1,1,0,0,4},
{4,0,1,1,1,0,0,1,1,4},
{4,0,1,0,0,0,1,0,1,4},
{4,0,0,0,1,0,0,0,1,4},
{4,0,1,1,1,0,1,0,0,4},
{4,4,4,4,4,4,4,4,4,4}
};
void print_maze();
int movable(Position pos,int dir);
int main(int argc, const char * argv[]) {
Queue *q = creat_queue();
Position cur;
cur.x=1;
cur.y=1;
enQueue(q,cur);
// ์ถ๊ฐ ๋ฐฐ์ด์ ์ฌ์ฉํ์ง ์๊ธฐ ์ํด ๋ฐฉ๋ฌธ ํ์๋ฅผ ์์๋ก ์ ์ฅ
maze[1][1]=-1;
int found = 0;
while(!is_empty(q)){
Position cur = front(q);
deQueue(q);
for(int dir=0;dir<4;dir++){
//๊ทธ ์
์ด 1(๋ฒฝ)์ด ์๋๋ฉด์ ๋ฐฉ๋ฌธํ์ง ์์ ๊ณณ์ธ์ง ๊ฒ์ฌ!
if(movable(cur,dir)){
//move_to๋ ๋์ผํ ํจ์
Position pos = move_to(cur,dir);
// ์ถ๊ฐ ๋ฐฐ์ด์ ์ฌ์ฉํ์ง ์๊ธฐ ์ํด ๋ฐฉ๋ฌธ ํ์๋ฅผ ์์๋ก ์ ์ฅ
maze[pos.x][pos.y] = maze[cur.x][cur.y]-1;
if(pos.x==MAX&&pos.y==MAX){
printf("๋ฏธ๋ก๋ฅผ ์ฐพ์์ต๋๋ค.\n");
final_path(pos);
found=1;
exit(0);
}
enQueue(q,pos);
}
}
}
return 0;
}
movableํจ์
int movable(Position pos, int dir){
Position tmp = move_to(pos, dir);
//1. dir๋ฐฉํฅ์ผ๋ก ์ด๋ํ ์ขํ๊ฐ 1~MAX์ด๋ด์ ์์ด์ผํ๋ค.
print_maze(tmp.x,tmp.y);
printf("maze[%d][%d]=%d\n",tmp.x,tmp.y,maze[tmp.x][tmp.y]);
if( tmp.x<1 || tmp.x>MAX){
printf("x๋ฒ์์ด๊ณผ\n");
return 0;
}
if(tmp.y<1||tmp.y>MAX){
printf("y๋ฒ์์ด๊ณผ\n");
return 0;
}
//2. wall์ด ์๋๊ณ , ๋ฒฝ์ด์๋์ด์ผํ๋ค.
switch (maze[tmp.x][tmp.y]) {
case 0:
printf("๊ฐ ์ ์๋ ๊ธธ์
๋๋ค.\n");
return 1;
case 1:
printf("๋ฒฝ์
๋๋ค. ๊ฐ ์ ์์ต๋๋ค.\n");
return 0;
default:
printf("์ด๋ฏธ ๋ฐฉ๋ฌธํ ๊ธธ์
๋๋ค. ๊ฐ ์ ์์ต๋๋ค.\n");
return 0;
}
}
print_maze
void print_maze(int x,int y){
// sleep(1);
// clear();
for(int i=0;i<MAX+2;i++){
for(int j=0;j<MAX+2;j++){
switch (maze[i][j]) {
case 0:
printf(BLACK);
if(i==x&&j==y){
printf(BOLDRED);
}
printf("ใ
");
printf(RESET);
break;
case 1:
if(i==x&&j==y){
printf(BOLDRED);
}
printf("ใ
");
break;
case 4:
printf(BOLDBLUE);
if(i==x&&j==y){
printf(BOLDRED);
printf("ใ
");
}else
printf("ใ
");
printf(RESET);
break;
default:
printf(BOLDYELLOW);
if(i==x&&j==y){
printf(BOLDRED);
}
printf("ใ
");
printf(RESET);
break;
break;
}
printf(RESET);
if(j==MAX+1)printf("\n");
}
}
printf(RESET);
}
final_path
๋ง์ง๋ง์ผ๋ก ์ฐพ์ ์ต์ข ๊ฒฝ๋ก๋ฅผ ํ์ํด์ฃผ๊ธฐ ์ํ ํจ์์ ๋๋ค.
void final_path(Position pos){
Position cur = pos;
Position next;
int offset[4][2] = {
{-1,0},{0,1},{1,0},{0,-1}
};
int num=maze[cur.x][cur.y]+1;
maze[cur.x][cur.y]=FINAL;
while(1){
for(int i=0;i<4;i++){
next.x=cur.x+offset[i][0];
next.y=cur.y+offset[i][1];
if(maze[next.x][next.y]==num){
maze[next.x][next.y]=FINAL;
cur=next;
num++;
break;
}
}
if(cur.x==1&&cur.y==1)break;
}
print_maze(n-2, n-2);
}
Dijkstra
/*
์ถ๋ฐ์ ์ผ๋ก ๋ถํฐ ๋ชจ๋ ๋
ธ๋์ ์ต๋จ๊ฑฐ๋ฆฌ
๋ค์ต์คํธ๋ผ ์ธ์ ๋ฆฌ์คํธ๋ก ๋ฏธ๋ก์ฐพ๊ธฐ ์ต๋จ๊ฑฐ๋ฆฌ ๊ตฌํจ!
*/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include "color.h"
#define MAX 8
#define PATH 0
#define WALL 1
#define VISITED 2
#define FINAL 3
#define EDGE 4
int maze[MAX+2][MAX+2]={
{4,4,4,4,4,4,4,4,4,4},
{4,0,0,0,0,0,0,0,1,4},
{4,0,1,1,0,1,1,0,1,4},
{4,0,0,0,1,0,0,0,1,4},
{4,0,1,0,0,1,1,0,0,4},
{4,0,1,1,1,0,0,1,1,4},
{4,0,1,0,0,0,1,0,1,4},
{4,0,0,0,1,0,0,0,1,4},
{4,0,1,1,1,0,1,0,0,4},
{4,4,4,4,4,4,4,4,4,4}
};
int parent[100];
int end, start;
void print_maze(int x, int y);
typedef struct node{
int dest; //๋ชฉ์ ๋
ธ๋
int weight; //๊ฐ์ค์น
struct node * next;
} Node;
typedef struct list{
Node * head;
}List;
typedef struct graph{
int V;
List * array;
}Graph;
Node * new_node(int dest, int weight){
Node * new = (Node*)malloc(sizeof(Node));
new->dest=dest;
new->weight=weight;
new->next=NULL;
return new;
}
Graph * create_graph(int V){
Graph * g = (Graph*)malloc(sizeof(Graph));
g->V = V;
g->array = (List*)malloc(V*sizeof(List));
for(int i=0;i<V;i++){
g->array[i].head=NULL;
}
return g;
}
void add_edge(Graph *g,int src, int dest, int weight){
Node * new = new_node(dest, weight);
new->next=g->array[src].head;
g->array[src].head=new;
new=new_node(src, weight);
new->next = g->array[dest].head;
g->array[dest].head = new;
}
typedef struct hnode{
int v;
int dis;
}HNode;
typedef struct heap{
int size;
int capacity;
int *pos; //decrease key()์ ํ์ํ๋ค.
HNode **array;
}Heap;
HNode * new_hnode(int v, int dis){
HNode * new = (HNode*)malloc(sizeof(HNode));
new->v=v;
new->dis=dis;
return new;
}
Heap * create_heap(int capacity){
Heap * heap = (Heap*)malloc(sizeof(Heap));
heap->pos=(int*)malloc(capacity*sizeof(int));
heap->size=0;
heap->capacity=capacity;
heap->array=(HNode**)malloc(capacity*sizeof(HNode*));
return heap;
}
void swap_node(HNode ** a, HNode **b){
HNode * tmp =*a;
*a=*b;
*b=tmp;
}
void heapify(Heap* heap,int i){
int min,left,right;
min=i;
left = i*2+1;
right = i*2+2;
if(left < heap->size && (heap->array[left]->dis < heap->array[min]->dis))min=left;
if(right<heap->size && heap->array[right]->dis<heap->array[min]->dis)min=right;
if(min!=i){
HNode * smallest = heap->array[min];
HNode * inode = heap->array[i];
heap->pos[smallest->v]=i;
heap->pos[inode->v]=min;
swap_node(&heap->array[min], &heap->array[i]);
heapify(heap,min);
}
}
int is_empty(Heap * h){
return h->size==0;
}
HNode * delete(Heap * h){
if(is_empty(h))return NULL;
HNode * root = h->array[0];
HNode * last = h->array[h->size - 1];
h->array[0]=last;
h->pos[root->v]=h->size-1;
h->pos[last->v]=0;
--h->size;
heapify(h, 0);
return root;
}
void decrease_key(Heap * h, int v, int dis){
// heap array์ ์ ์ v์ ๋ํ index
int i = h->pos[v];
h->array[i]->dis = dis; //distance update
while(i && ( h->array[i]->dis < h->array[(i-1)/2]->dis)){
h->pos[h->array[i]->v] = (i-1)/2;
h->pos[h->array[(i-1)/2]->v] = i;
swap_node(&h->array[i], &h->array[(i-1)/2]);
i=(i-1)/2;
}
}
int is_min(Heap * h, int v){
if(h->pos[v] < h->size) return 1;
else return 0;
}
void backtracking(int end){
int i, j, back;
int m = MAX+2;
back = end;
i = end / m;
j = end % m;
while( parent[back] != -1)
{
back = parent[back];
maze[i][j] = FINAL;
i = back / 10;
j = back % 10;
}
maze[1][1] = FINAL;
}
void print_array(int dis[],int n){
printf("์ ์ \t\t์์๋
ธ๋๋ก๋ถํฐ๊ฑฐ๋ฆฌ\n");
int e = 88;
for(int i=0;i<n;i++){
if(i==e)printf("๋์ฐฉ์ง!!\n");
printf("%d\t\t\t%d\n",i,dis[i]);
}
}
void dijkstra(Graph * g,int src){
int V= g->V;
int dis[V];
Heap * heap = create_heap(V);
for(int i=0;i<V;i++){
dis[i]=INT_MAX;
heap->array[i]=new_hnode(i, dis[i]);
heap->pos[i]=i;
}
// ์ถ๋ฐ์ ์ ๊ฑฐ๋ฆฌ๋ฅผ 0์ผ๋ก ๋ง๋ฆ
heap->array[src]=new_hnode(src, dis[src]);
heap->pos[src]=src;
dis[src]=0;
decrease_key(heap,src,dis[src]);
heap->size=V;
while(!is_empty(heap)){
HNode * min = delete(heap);
int u = min->v;
Node * trav = g->array[u].head;
while(trav!=NULL){
int v = trav->dest;
if(is_min(heap, v)&&dis[u]!=INT_MAX && trav->weight+dis[u]<dis[v]){
dis[v] = dis[u] + trav->weight;
parent[v]=u;
maze[u/(MAX+2)][u%(MAX+2)]=VISITED;
print_maze(u/(MAX+2), u%(MAX+2));
decrease_key(heap,v,dis[v]);
}
trav=trav->next;
}
}
print_array(dis, V);
}
void print_maze(int x,int y){
// sleep(1);
// clear();
for(int i=0;i<MAX+2;i++){
for(int j=0;j<MAX+2;j++){
switch (maze[i][j]) {
case 0:
printf(BLACK);
if(i==x&&j==y){
printf(BOLDRED);
}
printf("[]");
printf(RESET);
break;
case 1:
if(i==x&&j==y){
printf(BOLDRED);
}
printf("[]");
break;
case 3:
printf(BOLDGREEN);
printf("[]");
printf(RESET);
break;
case 4:
printf(BOLDBLUE);
if(i==x&&j==y){
printf(BOLDRED);
printf("[]");
}else
printf("[]");
printf(RESET);
break;
default:
printf(BOLDYELLOW);
if(i==x&&j==y){
printf(BOLDRED);
}
printf("[]");
printf(RESET);
break;
break;
}
printf(RESET);
if(j==MAX+1)printf("\n");
}
}
printf(RESET);
}
int main()
{
// create the graph given in above fugure
int m = MAX+2, s;
Graph * graph = create_graph(m*m);
start = m*1+1;
end = m*8+8;
parent[start] = -1;
for(int i=1;i<m-1;i++){
for(int j=1;j<m-1;j++){
s=i*m+j;
if(maze[i][j]==PATH){
if(i==1){
if(maze[i+1][j]==PATH)add_edge(graph, s, s+m, 1);
if(j==1){
if(maze[i][j+1]==PATH)add_edge(graph, s, s+1, 1);
}else if(j==m-1){
if(maze[i][j+1]==PATH)add_edge(graph, s, s-1, 1);
}else{
if(maze[i][j+1]==PATH)add_edge(graph, s, s-1, 1);
if(maze[i][j+1]==PATH)add_edge(graph, s, s+1, 1);
}
}else if(i==m-2){
if(maze[i-1][j]==PATH)add_edge(graph, s, s-m, 1);
if(j==1){
if(maze[i][j+1]==PATH)add_edge(graph, s, s+1, 1);
}else if(j==m-1){
if(maze[i][j+1]==PATH)add_edge(graph, s, s-1, 1);
}else{
if(maze[i][j+1]==PATH)add_edge(graph, s, s-1, 1);
if(maze[i][j+1]==PATH)add_edge(graph, s, s+1, 1);
}
}else if(j==1){
if(maze[i][j+1]==PATH)add_edge(graph, s, s+1, 1);
if(i!=1&&i!=m-2){
if(maze[i+1][j]==PATH)add_edge(graph, s, s+m, 1);
if(maze[i-1][j]==PATH)add_edge(graph, s, s-m, 1);
}
}else if(j==m-2){
if(maze[i][j-1]==PATH)add_edge(graph, s, s-1, 1);
if(i!=1&&i!=m-2){
if(maze[i+1][j]==PATH)add_edge(graph, s, s+m, 1);
if(maze[i-1][j]==PATH)add_edge(graph, s, s-m, 1);
}
}else{
if(maze[i+1][j]==PATH)add_edge(graph, s, s+m, 1);
if(maze[i-1][j]==PATH)add_edge(graph, s, s-m, 1);
if(maze[i][j+1]==PATH)add_edge(graph, s, s+1, 1);
if(maze[i][j-1]==PATH)add_edge(graph, s, s-1, 1);
}
}
}
}
print_maze(start/m, start%m);
dijkstra(graph, 11);
backtracking(end);
print_maze(end/m, end%m);
return 0;
}
A*
A* ์๊ณ ๋ฆฌ์ฆ ์ ์๊ณ ๋ฆฌ์ฆ์ ๋ํด์ ์์ธํ ์ค๋ช ๋์ด์๋ค.
queue
enQueueํ ๋, ์ฝ์ ์ ๋ ฌ์ ํด์ ๊ฐ์ ๋ฃ์ด์ค๋ค. (๊ฐ์ค์น๊ฐ ๋ฎ์ ๊ฐ์ ๋จผ์ ๊บผ๋ด๊ธฐ ์ํด์!)
typedef struct vertex{
int x,y;
int g_x;
}Vertex;
typedef struct node{
Vertex ver;
struct node * next;
}QNode;
typedef struct que{
QNode *front, *rear;
}Queue;
QNode * new_node(Vertex v){
QNode * new = (QNode *)malloc(sizeof(QNode));
new->ver.x = v.x;
new->ver.y = v.y;
new->ver.g_x = v.g_x;
new->next=NULL;
return new;
}
Queue * creat_queue(void){
Queue * new = (Queue *)malloc(sizeof(Queue));
new->front = new->rear= NULL;
return new;
}
Vertex front(Queue *q){
return q->front->ver;
}
Vertex rear(Queue *q){
return q->rear->ver;
}
int is_empty(Queue * q){
return (q->front==NULL && q->rear==NULL);
}
//front ํฌ์ธํฐ๋ ์ญ์ , rear ํฌ์ธํฐ๋ ์ฝ์
ํ ๋ ์ฌ์ฉ
void enQueue(Queue * q,Vertex v){
QNode * new = new_node(v);
QNode * tq =q->front;
Vertex tmp;
int key;
if(is_empty(q)){
q->front = q->rear = new;
return;
}
//์ฐ์ ์์ํ
// with insertion-sort, begin sorting process.
while( tq!= NULL){
key = weight[v.x][v.y];
if( key < weight[tq->ver.x][tq->ver.y]){
tmp = tq->ver;
tq->ver = v;
v = tmp;
}
tq = tq->next;
}
new->ver = v;
q->rear->next= new;
q->rear=new;
}
void deQueue(Queue * q){
if(q->front==NULL){
return;
}
q->front = q->front->next;
if(q->front==NULL) q->rear=NULL;
}
heuristic
// heuristicํจ์๋ก ๊ฐ์ค์น๋ฅผ ๊ณ์ฐํ๋ ํจ์
// ์ฌ๊ธฐ์ pre๋ ์ด์ ์ ์ ์ gx๊ฐ์ ๋ฐ์์จ๋ค.
int heuristic(Vertex v, int x,int y, int *pre){
int res;
// h(x)ํจ์ ์ฆ, ์ถ๊ตฌ์์ ์ผ๋ง๋ ๊ฑธ๋ฆฌ๋์ง ๊ณ์ฐํ๋ค.(๋งจํํ)
res = ((abs(end.x-x)+abs(end.y-y))*10);
*pre = v.g_x;
// ๋๊ฐ์ ์ธ ๊ฒฝ์ฐ
if(abs(v.x-x)==abs(v.y-y)){
*pre = *pre +14;
}else{
*pre = *pre +10;
}
// f(x) = g(x) + h(x)
return res+(*pre);
}
open list
// ์ธ์ ๋
ธ๋๋ฅผ queue์ ์ถ๊ฐํ๊ธฐ
void add_openlist(Queue * q,Vertex v){
Vertex tmp;
// pw๋ ์ด์ weigt
int i,j,w,pre;
// ์ธ์ ํ ์ ์ ํ์ธ
for(i=v.x-1;i<=v.x+1;i++){
if(i<1||i>MAX)continue; // ๋ฒ์๋ฅผ ๋ฒ์ด๋๋ฉด ํต๊ณผํ๋ค.
for(j=v.y-1;j<=v.y+1;j++){
if(j<1||j>MAX)continue; // ๋ฒ์๋ฅผ ๋ฒ์ด๋๋ฉด ํต๊ณผํ๋ค.
if(i==v.x&&j==v.y)continue; // i์ j๊ฐ ํ์ฌ ๋
ธ๋๋ ๊ฐ์ผ๋ฉด ํต๊ณผ
if(maze[i][j]!=0)continue; // ๊ธธ์ด ์๋๋ฉด ํต๊ณผ
// ๊ฐ์ค์น f(x)
w = heuristic(v, i, j, &pre);
// ๊ฐ์ค์น๊ฐ ํ์ฌ๋ณด๋ค ๋ฎ๊ฑฐ๋ ๊ธฐ๋ก์ด ์๋์ด์์ผ๋ฉด ๊ฐฑ์
if(w<weight[i][j]||weight[i][j]==0){
weight[i][j]=w;
// ๋ถ๋ชจ ๋
ธ๋์ ์ ๋ณด๋ฅผ ์ ์ฅํ๋ค.
parent[i][j] = (v.x*MAX+2)+v.y;
// ์ถ๊ตฌ๋ฅผ ์ฐพ์ผ๋ฉด ์ข
๋ฃ
if(end.x == i && end.y ==j)return;
}
tmp.x = i;
tmp.y = j;
tmp.g_x = pre;
enQueue(q, tmp);
}
}
}
astar
void astar(Vertex s,Vertex e){
Queue * q = creat_queue();
Vertex v;
// ์์์ ์ weight๋ 0์ด๋ค.
weight[s.x][s.y] = 0;
// ์์์ ์ ๋ถ๋ชจ๋
ธ๋๋ฅผ ๊ฐ๊ณ ์์ง ์๋๋ค.
parent[s.x][s.y]=-1;
// ์์์ ์์ ์์ง์ธ ๊ฑฐ๋ฆฌ(gx)๋ 0์ด๋ค.
s.g_x = 0;
v = s;
add_openlist(q,v);
while(!is_empty(q)){
// ํ์ฌ ์ ์ Closed list์ ์ถ๊ฐ >> maze์ ๋ฐ๋กํ์
maze[v.x][v.y]=CLOSED;
v = front(q);
deQueue(q);
if(v.x==end.x && v.y==end.y)return;
// ์๋ก์ด ์ธ์ ๋
ธ๋๋ฅผ ์ถ๊ฐํด์ค๋ค.
add_openlist(q, v);
}
}
backtracking
void backtracking(){
int i, j, back;
if(parent[end.x][end.y]==0){
printf("๊ฒฝ๋ก๊ฐ ์์ต๋๋ค.\n");
return;
}
i = parent[end.x][end.y] / MAX+2;
j = parent[end.x][end.y] % MAX+2;
while( parent[i][j] != -1)
{
back = parent[i][j];
maze[i][j] = FINAL;
i = back / MAX+2;
j = back % MAX+2;
}
maze[start.x][start.y] = FINAL;
}
print
void print_weight(){
int i,j;
for(i=0;i<MAX+2;i++){
for(j=0;j<MAX+2;j++)
printf("%6d",weight[i][j]);
printf("\n");
}
}
void print_maze(int x,int y){
for(int i=0;i<MAX+2;i++){
for(int j=0;j<MAX+2;j++){
switch (maze[i][j]) {
case 0:
printf(BLACK);
if(i==x&&j==y){
printf(BOLDRED);
}
printf("[]");
printf(RESET);
break;
case 1:
if(i==x&&j==y){
printf(BOLDRED);
}
printf("[]");
break;
case 3:
printf(BOLDGREEN);
printf("[]");
printf(RESET);
break;
case 4:
printf(BOLDBLUE);
if(i==x&&j==y){
printf(BOLDRED);
printf("[]");
}else
printf("[]");
printf(RESET);
break;
default:
printf(BOLDYELLOW);
if(i==x&&j==y){
printf(BOLDRED);
}
printf("[]");
printf(RESET);
break;
break;
}
printf(RESET);
if(j==MAX+1)printf("\n");
}
}
printf(RESET);
}
main
int main(){
start.x=1;start.y=1;
end.x=MAX;end.y=MAX;
astar(start, end);
print_weight();
print_maze(end.x,end.y);
backtracking();
print_maze(end.x,end.y);
}
Last updated