#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<windows.h>
 

#define MAX_SIZE 19
#define ROBOT1   38   // &
 

#define UP      1  
#define RIGHT   2
#define DOWN    4
#define LEFT    8
 

int get_shape(int, int);
void draw_maze(void);
void gotoxy(int , int);
void right_hand(int, int, int);
int wall_ahead(int, int, int);
void right(int*);
void left(int*);
int still_in_maze(int, int);
void foward(int*, int*, int);
void shortest_path(void);
void del_path(int, int);
void record(int, int);

int maze[MAX_SIZE][MAX_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, 1, 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* save;  // 이동경로 저장

void main()
{
    save = (int*)malloc(MAX_SIZE * MAX_SIZE);  // 배열 생성
    if(save==NULL)
    {
        printf("Memory allocation error !!!!\n");
        exit(1);
    }
    draw_maze();  // 미로 그리는 함수 호출
    gotoxy(40, 5);
    cputs("Simulation of Micro Mouse");
    gotoxy(40, 10);
    cputs("\t Press any key to start...");
    getche();

    right_hand(MAX_SIZE-2, MAX_SIZE-1, LEFT);  // 미로 이동 실행   
    gotoxy(40, 10);
    cputs("\t Press any key to see shortest path...");
    getche();

    shortest_path();  // 최단거리 함수 호출
    gotoxy(40, 20);
}
 

// 최단거리 함수 출력
void shortest_path(void)
{
    int init_x, init_y;
    int i, j;  
    for(i=0 ; save[i]>-1 ; i++)
    {
        init_x = save[i++];
        init_y = save[i];
        for(j=i+1 ; save[j]>-1 ; j++)
        {
            if(save[j++] == init_x && save[j] == init_y)
                del_path(i-1, j-1);
        }
    }

    // 출력
    i=0;
    while(save[i]>-1)
    {
        gotoxy(save[i+1]+1, save[i]+1);
        putchar(ROBOT1);
        Sleep(100);
        gotoxy(save[i+1]+1, save[i]+1);
        putchar(' ');
        i+=2;
    }
}
 

// 필요없는 경로 삭제 함수
void del_path(int x, int y)
{
    int i;
    for(i=0; save[y+i]>-1 ; i++)
        save[x+i] = save[y+i];
    save[x+i] = -1; // 배열의 끝을 선언
}

 // 이동경로 저장 함수
void record(int x, int y)
{
    static int i = 0;
    save[i++] = x;
    save[i++] = y;
}
 

// 미로 이동 함수
void right_hand(int x, int y, int dir)
{
    gotoxy(y + 1, x + 1);
    putchar(ROBOT1);
    Sleep(100);
    record(x, y);

    foward(&x, &y, dir);
    while(still_in_maze(x, y))
    {
        right(&dir);
        while(wall_ahead(x, y, dir)) // 앞에 벽이 1이 없을때 까지
        {          
            left(&dir);
        }
        foward(&x, &y, dir);
    }
    record(-1, -1); // 배열 마지막을 선언
}
 

//다음 경로값 1 확인 함수
int wall_ahead(int x, int y, int dir)
{
    switch(dir)
    {
        case UP     : --x; break;
        case RIGHT  : ++y; break;
        case DOWN   : ++x; break;
        case LEFT   : --y; break;
    }
    return maze[x][y];
}
 

// 오른쪽으로 회전
void right(int* dir)
{
    *dir = *dir << 1;
    if((*dir) > LEFT)
        *dir = UP;
}

//왼쪽으로 회전
void left(int* dir)
{
    *dir = *dir >> 1;
    if((*dir) < UP)
        *dir = LEFT;
}

//미로 안에 있는지 판별 함수
int still_in_maze(int x, int y)
{
    if(x>0 && x< MAX_SIZE-1 && y>0 && y<MAX_SIZE-1)
        return 1;
    else
        return 0;
}

//방향에 따라 전진 하는 함수
void foward(int* x, int* y, int dir)
{
    gotoxy((*y)+1, (*x)+1);
    putchar(' ');

    switch(dir)
    {
        case UP     : --(*x); break;
        case RIGHT  : ++(*y); break;
        case DOWN   : ++(*x); break;
        case LEFT   : --(*y); break;
    }
    gotoxy((*y)+1, (*x)+1);
    putchar(ROBOT1);
    Sleep(100);
    record(*x, *y);
}
 

// 미로글 그리는 함수
void draw_maze(void)
{
    int i, j;

    for(i=0 ; i<MAX_SIZE ; i++)
        for(j=0 ; j<MAX_SIZE ; j++)
        {
            gotoxy(j+1 , i+1);
            putchar(get_shape(i ,j));
        }
}

 //미로의 값에 따라 형태를 리턴하는 함수
int get_shape(int x, int y)
{
    static int shape[]= { 32, 5, 6, 3, 5, 5, 1, 25, 6, 4, 6, 21, 2, 23, 22, 16};
    int s=0;

    if(maze[x][y])
    {
        if(x>0 && maze[x-1][y])
            s = s | UP;
        if(x<MAX_SIZE-1 && maze[x+1][y])
            s = s | DOWN;
        if(y>0 && maze[x][y-1])
            s = s | LEFT;
        if(y<MAX_SIZE-1 && maze[x][y+1])
            s = s | RIGHT;
    }

    return shape[s];
}

 //VC 6.0 에서 사용할수 없는 gotoxy()함수 구현
void gotoxy(int x, int y)
{
    COORD Pos = {x-1,y-1};
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),Pos);
}


+ Recent posts