#include "stdafx.h"
typedef struct{
int x;
int y;
}COORDINATE;
typedef struct {
int no;
COORDINATE loc;
int direction;
}ITEM;
#define maze_line 10
#define maze_row 9
int a[maze_row][maze_line] =
{
1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 0, 0, 0, 0, 0,
0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
0, 0, 1, 1, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
};
int mark[maze_row][maze_line] = {0};
#define SELEMTYPE ITEM
#define STACK_INIT_LEN 10
#define STACK_INCR_LEN 10
typedef struct stack
{
SELEMTYPE *base;
SELEMTYPE *top;
int stack_size;
}SQSTACK;
int init_stack(SQSTACK **ptr)
{
*ptr = (SQSTACK *)calloc(1, sizeof(SQSTACK));
if(NULL == *ptr)
{
printf("init stack error\n");
exit(-1);
}
(*ptr)->base = (SELEMTYPE *)calloc(STACK_INIT_LEN, sizeof(SELEMTYPE));
if(NULL == (*ptr)->base)
{
printf("init stack.base error\n");
exit(-1);
}
(*ptr)->top = (*ptr)->base;
(*ptr)->stack_size = STACK_INIT_LEN;
return true;
}
int push_stack(SQSTACK *ptr, SELEMTYPE elem)
{
if(ptr->top - ptr->base >= ptr->stack_size)
{
ptr->base = (SELEMTYPE *)realloc(ptr->base, (ptr->stack_size+STACK_INCR_LEN) * sizeof(SELEMTYPE));
if(NULL == ptr->base)
{
printf("realloc the stack error\n");
exit(-1);
}
ptr->top = ptr->base + ptr->stack_size;
ptr->stack_size += STACK_INCR_LEN;
}
*ptr->top= elem;
ptr->top++;
return true;
}
int pop_stack(SQSTACK *ptr, SELEMTYPE *elem)
{
if(ptr->top == ptr->base)
{
printf("no need pop, the stack is empty.\n");
return true;
}
else
{
*elem = *--ptr->top;
}
return true;
}
int get_top(SQSTACK *ptr, SELEMTYPE *elem)
{
if(true == is_empty(ptr))
{
printf("no elem in stack \n");
return false;
}
else
{
*elem = *(ptr->top - 1);
}
return true;
}
void clear_stack(SQSTACK * ptr)
{
if(NULL != ptr)
{
if(NULL != ptr->base)
{
free(ptr->base);
ptr->base = ptr->top = NULL;
ptr->stack_size = 0;
}
free(ptr);
}
return;
}
int is_empty(SQSTACK *ptr)
{
if((NULL == ptr) || (NULL == ptr->base) || ptr->base == ptr->top )
{
return true;
}
else
{
return false;
}
}
int is_passed(ITEM *ptr)
{
if(NULL == ptr)
{
return false;
}
if(0 != ptr->no || (0 == a[ptr->loc.y][ptr->loc.x]) || 0 != mark[ptr->loc.y][ptr->loc.x])
{
return false;
}
else
{
return true;
}
}
int is_end(ITEM *ptr)
{
if(ptr->loc.x == (maze_line - 1) && ptr->loc.y == (maze_row -1))
{
return true;
}
else
{
return false;
}
}
int get_next(ITEM *ptr, ITEM *next)
{
int result = true;
next->loc.x = ptr->loc.x;
next->loc.y = ptr->loc.y;
next->direction = 0;
next->no = 0;
switch(ptr->direction)
{
case 0:
(ptr->loc.x ==0)?result = false:next->loc.x = ptr->loc.x - 1;
break;
case 1:
(ptr->loc.y ==maze_row -1)?result = false:next->loc.y = ptr->loc.y + 1;
break;
case 2:
(ptr->loc.x ==maze_line -1)?result = false:next->loc.x= ptr->loc.x + 1;
break;
case 3:
(ptr->loc.y ==0)?result = false:next->loc.y= ptr->loc.y - 1;
break;
}
if(false == result)
{
next->no = -1;
}
return result;
}
void mark_pos(ITEM *ptr, int value)
{
mark[ptr->loc.y][ptr->loc.x] = value;
return;
}
int maze_find_path(SQSTACK *head)
{
ITEM start = {0};
ITEM current = {0};
ITEM *ptr = ¤t;
ITEM next = {0};
int no = 0;
*ptr = start;
do{
if(true == is_passed(ptr))
{
ptr->no = ++no;
push_stack(head, *ptr);
mark_pos(ptr, 1);
if(true == is_end(ptr))
{
return true;
}
get_next(ptr, &next);
*ptr = next;
}
else
{
pop_stack(head, ptr);
while(ptr->direction == 3 && false == is_empty(head))
{
mark_pos(ptr, -1);
pop_stack(head, ptr);
}
if(ptr->direction < 3)
{
ptr->direction++;
get_next(ptr, &next);
push_stack(head, *ptr);
*ptr = next;
}
}
} while(false == is_empty(head));
return false;
}
void print_path(SQSTACK *ptr)
{
if(true == is_empty(ptr))
{
printf("print_path: stack is empty\n");
return;
}
while(ptr->top !=ptr->base)
{
ptr->top--;
printf("no:%d, x:%d, y:%d\n", (ptr->top)->no, (ptr->top)->loc.x, (ptr->top)->loc.y);
}
return;
}
int mazepath()
{
SQSTACK *head = NULL;
init_stack(&head);
if(true == maze_find_path(head))
{
print_path(head);
}
else
{
printf("no path!\n");
}
clear_stack(head);
return true;
}