#pragma once
#include
#define FOR_MAZE
//#ifdef FOR_MAZE
//typedef struct Point{
// int row;
// int col;
//}Point;
typedef Point SeqStackType;
//#else
//typedef char SeqStackType;
//#endif
#define SEQ_STACK_SIZE 100
typedef struct SeqStck
{
SeqStackType data[SEQ_STACK_SIZE];
size_t size;
}SeqStack;
void SeqStackInit(SeqStack *stack);
void SeqStackDestory(SeqStack* stack);
void SeqStackPush(SeqStack* stack, SeqStackType value);
void SeqStackPop(SeqStack *stack);
SeqStackType SeqStackTop(SeqStack* stack);
size_t SeqStackSize(SeqStack *stack);
void SeqStackAssign(SeqStack *from, SeqStack *to);
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include"maze.h"
#include
//#include"seqstack.h"
#include
#define MAZE_COL 6
#define MAZE_ROM 6
#define SEQ_STACK_SIZE 100
#ifdef FOR_MAZE
typedef Point SeqStackType;
#else
typedef char SeqStackType;
#endif
typedef struct Maze{
int map[MAZE_COL][MAZE_ROM];
}Maze;
typedef struct Point{
int row;
int col;
}Point;
void SeqStackInit(SeqStack *stack)
{
if (stack == NULL)
{
return;
}
stack->size = 0;
}
void SeqStackDestory(SeqStack* stack)
{
if (stack == NULL)
{
return;
}
stack->size = 0;
}
void SeqStackPush(SeqStack* stack, SeqStackType value)
{
if (stack == NULL)
{
stack->data[stack->size++] = value;
return;
}
if (stack->size >= SEQ_STACK_SIZE)
{
return;
}
else
{
stack->data[stack->size++] = value;
}
}
void SeqStackPop(SeqStack *stack)
{
if (stack == NULL)
{
return;
}
if (stack->size == 0)
{
return;
}
else
{
stack->data[stack->size--] = 0;
}
}
//SeqStackType SeqStackTop(SeqStack* stack)
//{
// if (stack == NULL)
// {
// return 0;
// }
// if (stack->size == 0)
// {
// return 0;
// }
// SeqStackType value = stack->data[stack->size];
// return value;
//}
size_t SeqStackSize(SeqStack *stack)
{
if (stack == NULL)
{
return 0;
}
return stack->size;
}
//赋值操作
void SeqStackAssign(SeqStack *from, SeqStack *to)
{
if (from == NULL || to == NULL)
{
return;
}
/*size_t i = 0;
to->size = from->size;
for (; i < from->size; i++)
{
to->data[i] = from->data[i];
}*/
memcpy(to, from, sizeof(SeqStack));//malloc申请的空间不能使用该函数
}
void SeqStackPrintfChar(SeqStack *stack, const char* msg)
{
size_t i = 0;
printf("*++++++++*++++++++*++++++++*++++++++*++++++++*++++++++*");
if (stack == NULL)
{
printf("stack is NULL");
return;
}
printf("栈底[%s]:", msg);
SeqStack*cur = stack;
for (; isize; ++i)
{
printf("[%c]->", cur->data[i]);
}
printf("[栈顶]");
printf("\n");
}
void MazeInit(Maze* maze)
{
if (maze == NULL)
{
return;
}
int map[MAZE_COL][MAZE_ROM] = {
{ 0, 1, 0, 0, 0, 0 },
{ 0, 1, 1, 1, 0, 0 },
{ 0, 1, 0, 1, 1, 0 },
{ 0, 1, 1, 0, 0, 0 },
{ 0, 0, 1, 1, 0, 0 },
{ 0, 0, 0, 1, 0, 0 } };
size_t i = 0;
for (; i < MAZE_COL; i++)
{
size_t j = 0;
for (; j < MAZE_ROM; j++)
{
maze->map[i][j] = map[i][j];
}
}
}
void MazePrint(Maze*maze)
{
if (maze == NULL)
{
return;
}
size_t i = 0;
for (; i < MAZE_COL; i++)
{
size_t j = 0;
for (; j < MAZE_ROM; j++)
{
printf("%2d", maze->map[i][j]);//左右对齐问题
}
printf("\n");//每一行的所有列完成
}
printf("\n");
}
int PointInMap(Point cur)
{
if (cur.col < 0 || cur.col >= MAZE_COL || cur.row < 0 || cur.row >= MAZE_ROM)
return 0;
else
return 1;
}
int CanStay(Maze*maze, Point cur)
{
//1.点在地图上
if (!PointInMap(cur))
{
return 0;
}
//2.当前点对应的值为1
if (maze->map[cur.row][cur.col] == 1)
{
return 1;
}
return 0;
}
void Mark(Maze* maze, Point cur)//标记走过的点
{
//if (maze == NULL)//如果在其他场景下调用需要判断
//{
// return;
//}
maze->map[cur.row][cur.col] = 2;
}
int IsExit(Point cur, Point entry)//判定是否是出口
{
//点在地图边缘。不是入口
if (cur.col == 0 || cur.col == MAZE_COL - 1 || cur.row == 0 || cur.row == MAZE_ROM - 1)//在边缘
{
if (cur.row == entry.row&&cur.col == entry.col)//是入口
{
return 0;
}
return 1;
}
return 0;
}
void _HasPath(Maze* maze, Point cur, Point entry)
{
//1.判定当前点能否落脚(点在地图上,位置为一)
if (!CanStay(maze, cur))
{
return;
}
//2.标记走过的点
Mark(maze, cur);
//3.判断当前点是否是出口(落在边缘且不为入口)
if (IsExit(cur,entry))
{
printf("找到路了\n");
return;
}
//4.按照顺时针方向探测周围的临界点(递归调用haspath)
Point up = cur;
up.row -= 1;//根据地图来上下移动
_HasPath(maze, up,entry);
Point right = cur;
right.col += 1;
_HasPath(maze, right,entry);
Point down = cur;
down.row += 1;
_HasPath(maze, down,entry);
Point left = cur;
up.col -= 1;
_HasPath(maze, left,entry);
//5.如果是个方向都探测过了,就直接返回
return;
}
//使用递归方式查找迷宫是否有路径
void HasPath(Maze* maze, Point entry)//*maze用到地址是为了提高效率,还要修改地址
{
if (maze == NULL)
{
return;
}
_HasPath(maze,entry,entry);
return;
}
//非递归的解决简单迷宫
void HasPathByLoop(Maze* maze, Point entry)
{
if (maze == NULL)
{
return;
}
//1.判断入口点是否能落脚
if (!CanStay(maze, entry))
{
return;
}
//2.标记走过的入口点,并且将入口点入栈
Mark(maze, entry);
SeqStack stack;
SeqStackInit(&stack);
SeqStackPush(&stack,entry);
//3.进入循环,取栈顶元素为入口点
Point cur;
while (SeqStackTop(&stack, &cur))
{
//4.判定是不是出口
if (IsExit(cur, entry))
{
printf("找到路了\n");
return;
}
//5.按照一定的顺序判断当前点的临界点是否能落脚
Point up = cur;
up.row -= 1;
//6.如果某一个临界点能够落脚,标记此点并入栈,直接进入下一次循环
if (!CanStay(maze, up))
{
Mark(maze, up);
SeqStackPush(&stack, up);
continue;
}
Point right = cur;
right.col += 1;
if (!CanStay(maze, right))
{
Mark(maze, right);
SeqStackPush(&stack, right);
continue;
}
Point down = cur;
down.row += 1;
if (!CanStay(maze, down))
{
Mark(maze, down);
SeqStackPush(&stack, down);
continue;
}
Point left = cur;
up.col -= 1;
if (!CanStay(maze, left))
{
Mark(maze, left);
SeqStackPush(&stack, left);
continue;
}
//7.四个方向探测完毕,当前点入栈
SeqStackPop(&stack);
}
return;
}
void _GetShortPath(Maze* maze, Point cur, Point entry, SeqStack* short_path, SeqStack* cur_path)
{
//1.判断当前点能否落脚
if (!CanStay(maze, entry))
{
return;
}
//2.标记当前点,把当前点push到cur_path
Mark(maze, cur);
SeqStackPush(cur_path, cur);
//3.判断当前点是不是出口,如果是出口
if (IsExit(cur, entry))
{
//a)比较当前cur_path与short_path的长短
if (SeqStackSize(cur_path) < SeqStackSize(short_path) || SeqStackSize(short_path) == 0)
{//b)如果cur_path比较小或者short_path为空,用cur_path替换short_path
SeqStackAssign(cur_path, short_path);
}
//c)让cur_path出栈,同时返回到上一层栈帧
SeqStackPop(cur_path);
return;
}
//4.按照一定的顺序,递归的调用该函数完成临界点的判定
Point up = cur;
up.row -= 1;
_GetShortPath(maze, up, entry, &cur_path, &short_path);
Point right = cur;
right.col += 1;
_GetShortPath(maze, right, entry, &cur_path, &short_path);
Point down = cur;
down.row += 1;
_GetShortPath(maze, down, entry, &cur_path, &short_path);
Point left = cur;
left.col -= 1;
_GetShortPath(maze, left, entry, &cur_path, &short_path);
//5.回溯到上一个位置,先将cur_path出栈,再return
SeqStackPop(cur_path);
return;
}
int CanStayWithCycle(Maze*maze, Point cur, Point pre)
{
if (pre.row < 0)
{//初始情况,只判断cur
if (!PointInMap(cur))
{
return 0;
}
//2.当前点对应的值为1
int cur_value = maze->map[cur.row][cur.col];
if (cur_value == 1)
{
return 1;
}
return 0;
}
//1.点在地图上
if (!PointInMap(cur))
{
return 0;
}
//2.当前点对应的值为1
int cur_value = maze->map[cur.row][cur.col];
if (cur_value == 1)
{
return 1;
}
//3.判定当前点的值和前一个点的值的大小,满足cur_value-1>pre_value时才能落脚
int pre_value = maze->map[cur.row][cur.col];
if (cur_value - 1 > pre_value)
{
return 1;
}
return 0;
}
void MarkWithCycle(Maze* maze, Point cur, Point pre)
{
if (PointInMap(cur))
{
//pre非法
Mark(maze,cur);
return;
}
int pre_value = maze->map[cur.row][cur.col];
maze->map[cur.row][cur.col]=pre_value+1;
}
void _GetShortPathWithPath(Maze* maze, Point cur, Point pre, Point entry, SeqStack* short_path, SeqStack* cur_path)
{
//1.判断当前点能否落脚
if (!CanStayWithCycle(maze, cur,pre))
{
return;
}
//2.标记当前点,把当前点push到cur_path
MarkWithCycle(maze, cur,pre,entry);
SeqStackPush(cur_path, cur);
//3.判断当前点是不是出口,如果是出口
if (IsExit(cur, entry))
{
//a)比较当前cur_path与short_path的长短
SeqStackPrintfChar(&short_path, "最短路径是:");
if (SeqStackSize(cur_path) < SeqStackSize(short_path) || SeqStackSize(short_path) == 0)
{//b)如果cur_path比较小或者short_path为空,用cur_path替换short_path
SeqStackAssign(cur_path, short_path);
}
//c)让cur_path出栈,同时返回到上一层栈帧
SeqStackPop(cur_path);
return;
}
//4.按照一定的顺序,递归的调用该函数完成临界点的判定
Point up = cur;
up.row -= 1;
_GetShortPathWithPath(maze, up,cur, entry, &cur_path, &short_path);
Point right = cur;
right.col += 1;
_GetShortPathWithPath(maze, right, cur, entry, &cur_path, &short_path);
Point down = cur;
down.row += 1;
_GetShortPathWithPath(maze, down, cur, entry, &cur_path, &short_path);
Point left = cur;
left.col -= 1;
_GetShortPathWithPath(maze, left, cur, entry, &cur_path, &short_path);
//5.回溯到上一个位置,先将cur_path出栈,再return
SeqStackPop(cur_path);
return;
}
void GetShortPath(Maze* maze, Point entry)
{
SeqStack short_path;
SeqStack cur_path;
SeqStackInit(&short_path);
SeqStackInit(&cur_path);
_GetShortPath(maze, entry, entry, &cur_path, &short_path);
}
void test()
{
Maze maze;
Point entry= { 0, 1 };//常用表示方法
Point pre = { -1, -1 };//非法值
MazeInit(&maze);
MazePrint(&maze);
//HasPath(&maze, entry);
//MazePrint(&maze);
}
int main()
{
test();
system("pause");
return 0;
}