#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#include <conio.h>
#define MAZE_SIZE 19
#define ROBOT 2
#define delay(n) Sleep(n) // n/1000초만큼 시간 지연
void gotoxy(int, int);
void clrscr(void);
int get_shape(int [][MAZE_SIZE], int, int);
void draw_maze(int [][MAZE_SIZE]);
void record(int, int);
void forward(int *, int *, int);
void right(int *);
void left(int *);
int still_in_maze(int, int);
int wall_ahead(int [][MAZE_SIZE], int, int, int);
void right_hand(int [][MAZE_SIZE], int , int , int);
void del_path(int, int);
void shortest_path(void);
int maze[MAZE_SIZE][MAZE_SIZE] = {
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1},
{1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1},
{1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1},
{1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
};
int sx = MAZE_SIZE - 1;
int sy = MAZE_SIZE - 2; // 생쥐 출발 위치
int *rec; // 최단 경로 계산을 위한 생쥐가 움직인 경로를 저장
#define UP 1
#define RIGHT 2
#define DOWN 4
#define LEFT 8
void main(void)
{
rec = (int *)malloc(MAZE_SIZE * MAZE_SIZE); // 생쥐 움직임 저장
if(rec == NULL)
{
cputs("\r\nMemory allocation error! ");
exit(1);
}
clrscr();
draw_maze(maze);
gotoxy(40, 5);
cputs("Simulation of Micro Mouse");
gotoxy(40, 10);
cputs(" Press any key to start ... ");
//bioskey(0);
right_hand(maze, sx, sy, LEFT);
gotoxy(40, 10);
cputs(" Press any key to see shortest path.. ");
//bioskey(0);
shortest_path();
gotoxy(40, 10);
cputs(" Press any key to end program ... ");
// bioskey(0);
}
//
// Dos상에서의 gotoxy 를 Visual Studio에서 사용하게끔 SetConsoleCursorPosition을 이용한다.
//
void gotoxy(int x, int y)
{
COORD Cur;
Cur.X=x;
Cur.Y=y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),Cur);
}
//
// 도스상의 cls를 사용하기 위해서
//
void clrscr(void)
{
system("cls");
}
//
// 미로를 화면에 그려주기
//
void draw_maze(int m[][MAZE_SIZE])
{
int i,j;
for(j=0; j<MAZE_SIZE; j++)
for(i=0; i<MAZE_SIZE; i++)
{
gotoxy(i+1, j+1);
/* switch(get_shape(m, i, j))
{
case 32:
putch(" ");
break;
case 179:
putch("│");
break;
case 196:
putch("─");
break;
case 192:
putch("└");
break;
case 218:
putch("┌");
break;
case 195:
putch("├");
break;
case 217:
putch("┘");
break;
case 193:
putch("┴");
break;
case 191:
putch("┐");
break;
case 180:
putch("┤");
break;
case 194:
putch("┬");
break;
case 197:
putch("┼");
break;
}*/
putch(get_shape(m, i, j));
}
}
//
// 벽 배치에 따른 중앙벽의 모양을 리턴
//
int get_shape(int m[][MAZE_SIZE], int x, int y)
{
static shape[] = {
32, 179, 196, 192, 179, 179, 218, 195, 196, 217, 196, 193, 191, 180, 194, 197
};
//
// ' ', │, ─, └, │, │, ┌, ├, ─, ┘, ─, ┴, ┐, ┤. ┬, ┼
//
int s = 0;
if(m[y][x])
{
if(y > 0 && m[y-1][x]) s |= UP;
if(y < MAZE_SIZE - 2 && m[y+1][x]) s |= DOWN;
if(x > 0 && m[y][x-1]) s |= LEFT;
if(x < MAZE_SIZE -2 && m[y][x+1]) s |= RIGHT;
}
return shape[s];
}
//
// 생쥐의 이동 경로를 저장
//
void record(int x, int y)
{
static int index = 0;
rec[index++] = x;
rec[index++] = y;
}
//
// 생쥐를 한 칸 앞으로 이동
//
void forward(int *x, int *y, int dir)
{
gotoxy(*x + 1, *y + 1);
putch(' ');
*x = (dir == LEFT) ? --(*x) :
(dir == RIGHT) ? ++(*x) : *x;
*y = (dir == UP) ? --(*y) :
(dir == DOWN) ? ++(*y) : *y;
record(*x, *y);
gotoxy(*x + 1, *y + 1);
putch(ROBOT);
}
//
// 생쥐를 시계방향으로
//
void right(int *dir)
{
*dir <<= 1;
*dir = (*dir > LEFT) ? UP : *dir;
}
//
// 생쥐를 반시계 방향으로
//
void left(int *dir)
{
*dir >>= 1;
*dir = (*dir == 0) ? LEFT : *dir;
}
//
// 아직 미로에 들어 있는가?
//
int still_in_maze(int x, int y)
{
if(x > 0 && x < MAZE_SIZE - 1 && y > 0 && y < MAZE_SIZE -1)
return 1;
else
return 0;
}
//
// 벽이 앞에 있는가?
//
int wall_ahead(int m[][MAZE_SIZE], int x, int y, int dir)
{
x = (dir == LEFT) ? --x :
(dir == RIGHT) ? ++x : x;
y = (dir == UP) ? --y :
(dir == DOWN) ? ++y : y;
return m[x][y];
}
//
// 우선법 알고리즘
//
void right_hand(int m[][MAZE_SIZE], int x, int y, int dir)
{
gotoxy(x+1, y+1);
putch(ROBOT);
record(x, y);
forward(&x, &y, dir);
while(still_in_maze(x, y))
{
delay(100);
right(&dir);
while(wall_ahead(m, x, y, dir))
left(&dir);
forward(&x, &y, dir);
}
record(-1, -1);
}
//
// 중복경로 삭제 알고리즘
//
void del_path(int i, int j)
{
while(rec[j] >= 0)
rec[i++] = rec[j++];
rec[i] = -1;
}
//
// 중복경로 제거 알고리즘
//
void shortest_path(void)
{
int i = 0;
int x, y;
int j;
int x1, y1;
while(rec[i] >= 0)
{
x = rec[i];
y = rec[i + 1];
j = i + 2;
while(rec[j] >= 0)
{
x1 = rec[j];
y1 = rec[j + 1];
if(x == x1 && y == y1)
{
del_path(i, j);
}
j+=2;
}
i+=2;
}
i=0; // 최단거리 생쥐 에니메이션
while(rec[i] >= 0)
{
x = rec[i++];
y = rec[i++];
gotoxy(x + 1, y + 1);
putch(ROBOT);
delay(100);
gotoxy(x + 1, y + 1);
putch(' ');
}
}
#include <windows.h>
#include <stdlib.h>
#include <conio.h>
#define MAZE_SIZE 19
#define ROBOT 2
#define delay(n) Sleep(n) // n/1000초만큼 시간 지연
void gotoxy(int, int);
void clrscr(void);
int get_shape(int [][MAZE_SIZE], int, int);
void draw_maze(int [][MAZE_SIZE]);
void record(int, int);
void forward(int *, int *, int);
void right(int *);
void left(int *);
int still_in_maze(int, int);
int wall_ahead(int [][MAZE_SIZE], int, int, int);
void right_hand(int [][MAZE_SIZE], int , int , int);
void del_path(int, int);
void shortest_path(void);
int maze[MAZE_SIZE][MAZE_SIZE] = {
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1},
{1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1},
{1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1},
{1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
};
int sx = MAZE_SIZE - 1;
int sy = MAZE_SIZE - 2; // 생쥐 출발 위치
int *rec; // 최단 경로 계산을 위한 생쥐가 움직인 경로를 저장
#define UP 1
#define RIGHT 2
#define DOWN 4
#define LEFT 8
void main(void)
{
rec = (int *)malloc(MAZE_SIZE * MAZE_SIZE); // 생쥐 움직임 저장
if(rec == NULL)
{
cputs("\r\nMemory allocation error! ");
exit(1);
}
clrscr();
draw_maze(maze);
gotoxy(40, 5);
cputs("Simulation of Micro Mouse");
gotoxy(40, 10);
cputs(" Press any key to start ... ");
//bioskey(0);
right_hand(maze, sx, sy, LEFT);
gotoxy(40, 10);
cputs(" Press any key to see shortest path.. ");
//bioskey(0);
shortest_path();
gotoxy(40, 10);
cputs(" Press any key to end program ... ");
// bioskey(0);
}
//
// Dos상에서의 gotoxy 를 Visual Studio에서 사용하게끔 SetConsoleCursorPosition을 이용한다.
//
void gotoxy(int x, int y)
{
COORD Cur;
Cur.X=x;
Cur.Y=y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),Cur);
}
//
// 도스상의 cls를 사용하기 위해서
//
void clrscr(void)
{
system("cls");
}
//
// 미로를 화면에 그려주기
//
void draw_maze(int m[][MAZE_SIZE])
{
int i,j;
for(j=0; j<MAZE_SIZE; j++)
for(i=0; i<MAZE_SIZE; i++)
{
gotoxy(i+1, j+1);
/* switch(get_shape(m, i, j))
{
case 32:
putch(" ");
break;
case 179:
putch("│");
break;
case 196:
putch("─");
break;
case 192:
putch("└");
break;
case 218:
putch("┌");
break;
case 195:
putch("├");
break;
case 217:
putch("┘");
break;
case 193:
putch("┴");
break;
case 191:
putch("┐");
break;
case 180:
putch("┤");
break;
case 194:
putch("┬");
break;
case 197:
putch("┼");
break;
}*/
putch(get_shape(m, i, j));
}
}
//
// 벽 배치에 따른 중앙벽의 모양을 리턴
//
int get_shape(int m[][MAZE_SIZE], int x, int y)
{
static shape[] = {
32, 179, 196, 192, 179, 179, 218, 195, 196, 217, 196, 193, 191, 180, 194, 197
};
//
// ' ', │, ─, └, │, │, ┌, ├, ─, ┘, ─, ┴, ┐, ┤. ┬, ┼
//
int s = 0;
if(m[y][x])
{
if(y > 0 && m[y-1][x]) s |= UP;
if(y < MAZE_SIZE - 2 && m[y+1][x]) s |= DOWN;
if(x > 0 && m[y][x-1]) s |= LEFT;
if(x < MAZE_SIZE -2 && m[y][x+1]) s |= RIGHT;
}
return shape[s];
}
//
// 생쥐의 이동 경로를 저장
//
void record(int x, int y)
{
static int index = 0;
rec[index++] = x;
rec[index++] = y;
}
//
// 생쥐를 한 칸 앞으로 이동
//
void forward(int *x, int *y, int dir)
{
gotoxy(*x + 1, *y + 1);
putch(' ');
*x = (dir == LEFT) ? --(*x) :
(dir == RIGHT) ? ++(*x) : *x;
*y = (dir == UP) ? --(*y) :
(dir == DOWN) ? ++(*y) : *y;
record(*x, *y);
gotoxy(*x + 1, *y + 1);
putch(ROBOT);
}
//
// 생쥐를 시계방향으로
//
void right(int *dir)
{
*dir <<= 1;
*dir = (*dir > LEFT) ? UP : *dir;
}
//
// 생쥐를 반시계 방향으로
//
void left(int *dir)
{
*dir >>= 1;
*dir = (*dir == 0) ? LEFT : *dir;
}
//
// 아직 미로에 들어 있는가?
//
int still_in_maze(int x, int y)
{
if(x > 0 && x < MAZE_SIZE - 1 && y > 0 && y < MAZE_SIZE -1)
return 1;
else
return 0;
}
//
// 벽이 앞에 있는가?
//
int wall_ahead(int m[][MAZE_SIZE], int x, int y, int dir)
{
x = (dir == LEFT) ? --x :
(dir == RIGHT) ? ++x : x;
y = (dir == UP) ? --y :
(dir == DOWN) ? ++y : y;
return m[x][y];
}
//
// 우선법 알고리즘
//
void right_hand(int m[][MAZE_SIZE], int x, int y, int dir)
{
gotoxy(x+1, y+1);
putch(ROBOT);
record(x, y);
forward(&x, &y, dir);
while(still_in_maze(x, y))
{
delay(100);
right(&dir);
while(wall_ahead(m, x, y, dir))
left(&dir);
forward(&x, &y, dir);
}
record(-1, -1);
}
//
// 중복경로 삭제 알고리즘
//
void del_path(int i, int j)
{
while(rec[j] >= 0)
rec[i++] = rec[j++];
rec[i] = -1;
}
//
// 중복경로 제거 알고리즘
//
void shortest_path(void)
{
int i = 0;
int x, y;
int j;
int x1, y1;
while(rec[i] >= 0)
{
x = rec[i];
y = rec[i + 1];
j = i + 2;
while(rec[j] >= 0)
{
x1 = rec[j];
y1 = rec[j + 1];
if(x == x1 && y == y1)
{
del_path(i, j);
}
j+=2;
}
i+=2;
}
i=0; // 최단거리 생쥐 에니메이션
while(rec[i] >= 0)
{
x = rec[i++];
y = rec[i++];
gotoxy(x + 1, y + 1);
putch(ROBOT);
delay(100);
gotoxy(x + 1, y + 1);
putch(' ');
}
}
'Native > C' 카테고리의 다른 글
마이크로 마우스(Micro mouse) save history ver (0) | 2013.10.02 |
---|---|
트리(tree) (0) | 2013.10.02 |
[myfun] void strtoupper(char *); 소문자를 대문자로 (0) | 2013.10.02 |
[myfun] void strtolower(char *); 대문자를소문자로 (0) | 2013.10.02 |
4-22 mystrstrUpper (0) | 2013.10.02 |