迷宫:
#############
##I@@@#@#@@@#
###@#@@@#@#@#
#@##@@#@@@#@#
###@@@#@#@#@#
#@@@#@@@#@#@#
#@#@#####@#@#
#@#@@@@@@@@##
#@####@#@#@@#
#@#@@#@@#@#@#
###@#@###@@@#
#@@##@###@###
########O@###
MAIN.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mazeSolution.h"
/**主函数(仅限测试)---程序入口**/
int main(void)
{
Maze *M = new Maze("D:\\DataStructures\\maze\\MazeStack\\MazeStack\\Maze.txt");
//迷宫图的设定文件,路径可以自定义
M->DisplayMazeGraphic();
if(M->FindMazePath())
{
cout<<"You can find the route!"<<endl;
M->Format();
M->DisplayMazeGraphic();
}
else//没有发现可以走出迷宫的方法
cout<<"No solution!"<<endl;
delete M;
system("pause");
return 0;
}
mazeStack.h
#ifndef MAZESTACK_H
#define MAZESTACK_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define UPON 0
#define RIGHT 1
#define DOWN 2
#define LEFT 3
#define TRIED 4
#define MALLOC_JUDGE(E) if(!E){fprintf(stderr,"内存分配失败……");\
system("pause");\
exit(EXIT_FAILURE);\
}
///========================struct===============================
struct coordinate
{
int x,y;
};
struct position
{
char sign[20];//做标记,看是墙还是路---(走出迷宫的方向)
int dir;//下一个可以走的方向
struct coordinate pos;//记录所处的坐标位置
};
///====================stack class====================
typedef struct position SElemType;
class SqStack
{
private:
SElemType *base;
SElemType *top;
int stackSize;
public:
SqStack(); //InitStack
bool ClearStack(); //clear stack
bool StackEmpty(); //judge empty
bool DestoryStack(); //destory stack
bool GetTop(SElemType &e);//get the top of the stack
bool Push(SElemType e); //入栈push
bool Pop(SElemType &e); //出栈pop
bool StackTraverse(void(*visit)());//Traverse
int StackLength(); //get the length of the stack
protected:
};
SqStack::SqStack()
{
base = (SElemType*)calloc(STACK_INIT_SIZE,sizeof(SElemType));
MALLOC_JUDGE(base);//";"可以省略
top = base;
stackSize = STACK_INIT_SIZE;
}
bool SqStack::GetTop(SElemType &e)
{
if(base == top)
return false;
else
e = *(top - 1);
return true;
}
bool SqStack::Push(SElemType e)//入栈
{
if(top - base >= stackSize)
{//栈满,追加存储空间
base = (SElemType*)realloc(base,
(STACK_INIT_SIZE + STACKINCREMENT)*sizeof(SElemType));
MALLOC_JUDGE(base);
top = base + stackSize;
stackSize += STACKINCREMENT;
}
*top++ = e;
return true;
}
bool SqStack::Pop(SElemType &e)//出栈
{
if(top == base)//空栈
return false;
else
e = *--top;
return true;
}
bool SqStack::StackEmpty()
{
if(base == top)
return true;
else
return false;
}
bool SqStack::DestoryStack()
{
if(base == NULL)
return false;
free(base);
base = top = NULL;
stackSize = 0;
return true;
}
#endif MAZESTACK
#ifndef MAZESOLUTION_H
#define MAZESOLUTION_H
#include <iostream>
#include <fstream>
#include <iomanip>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
#include "mazeStack.h"
#define MAX_SIZE 18//迷宫的长宽值(length,width)不大于18
class Maze: public SqStack
{
private:
int length,width;
struct position mazeGraphic[MAX_SIZE][MAX_SIZE];
struct coordinate inlet,outlet;
public:
Maze(char *Maze);
void DisplayMazeGraphic();
bool NextPos(struct position &e1,struct position &e2);
bool CanPass(struct position e1,struct position &e2);
bool FindMazePath();
void Format();
protected:
};
Maze::Maze(char *Maze)
{
fstream fin;
fin.open(Maze,ios::in);
if(!fin)
{
fprintf(stderr,"打开文件操作失败……");
system("pause");
exit(EXIT_FAILURE);
}
else
{
int i = 0,j = 0;
char cTemp;
length = width = 0;
while((cTemp = fin.get()) != EOF)
{
mazeGraphic[i][j].dir = UPON;
mazeGraphic[i][j].pos.x = j;
mazeGraphic[i][j].pos.y = i;
switch(cTemp)
{
case '#':
strcpy(mazeGraphic[i][j++].sign,"■");//墙
break;
case '@':
strcpy(mazeGraphic[i][j++].sign,"□");//路
break;
case 'I':
inlet = mazeGraphic[i][j].pos;
strcpy(mazeGraphic[i][j++].sign,"★");//入口
break;
case 'O':
outlet = mazeGraphic[i][j].pos;
strcpy(mazeGraphic[i][j++].sign,"☆");//出口
break;
case '\n':
j = 0,i++;
length++;
break;
default:
fprintf(stderr,"未知错误!操作失败……\n");
system("pause");
exit(EXIT_FAILURE);
}
if(width < j)
width = j;
}
}
fin.close();
}
//打印迷宫布局
void Maze::DisplayMazeGraphic()
{
for(int i = 0;i < length;++i)
{
for(int j = 0;j < width;++j)
cout<<mazeGraphic[i][j].sign;
cout<<endl;
}
}
bool Maze::CanPass(struct position e1,struct position &e2)
{
bool _bool = true;
int i = e1.pos.x;//right & left
int j = e1.pos.y;//upon & down
int _dir = e1.dir;
switch(_dir)
{
case UPON:
if(j > 0 && strcmp(mazeGraphic[j - 1][i].sign,"■") != 0)
e2 = mazeGraphic[j - 1][i];
else
_bool = false;
break;
case RIGHT:
if(i + 1 < width && strcmp(mazeGraphic[j][i + 1].sign,"■") != 0)
e2 = mazeGraphic[j][i + 1];
else
_bool = false;
break;
case DOWN:
if(j + 1 < length && strcmp(mazeGraphic[j + 1][i].sign,"■") != 0)
e2 = mazeGraphic[j + 1][i];
else
_bool = false;
break;
case LEFT:
if(i > 0 && strcmp(mazeGraphic[j][i - 1].sign,"■") != 0)
e2 = mazeGraphic[j][i - 1];
else
_bool = false;
break;
default:
fprintf(stderr,"未知错误!操作失败……\n");
system("pause");
exit(EXIT_FAILURE);
}
return _bool;
}
//寻找下一个可以通过的路口
bool Maze::NextPos(struct position &e1,struct position &e2)
{
while(e1.dir != TRIED)
{
e1.dir++;
mazeGraphic[e1.pos.y][e1.pos.x].dir = e1.dir;
if(CanPass(e1,e2))
return true;
}
return false;
}
//寻找走出迷宫的路径
bool Maze::FindMazePath()
{
strcpy(mazeGraphic[inlet.y][inlet.x].sign,"■");
Push(mazeGraphic[inlet.y][inlet.x]);
struct position e1,e2;
while(!StackEmpty())
{
GetTop(e1);
if(NextPos(e1,e2))//找到一个可以走的路口
{
strcpy(mazeGraphic[e2.pos.y][e2.pos.x].sign,"■");
Push(e2);
if(!strcmp(e2.sign,"☆"))
break;
}
else
{
Pop(e1);
strcpy(mazeGraphic[e1.pos.y][e1.pos.x].sign,"□");
}
}
if(!StackEmpty())
return true;
else
return false;
}
//格式化---提供一种输出迷宫路径的方式
//销毁栈
void Maze::Format()
{
struct position e;
Pop(e);
while(Pop(e))
{
int i = e.pos.x,j = e.pos.y;
switch(mazeGraphic[j][i].dir)
{
case UPON:
strcpy(mazeGraphic[j][i].sign,"↑");
break;
case RIGHT:
strcpy(mazeGraphic[j][i].sign,"→");
break;
case DOWN:
strcpy(mazeGraphic[j][i].sign,"↓");
break;
case LEFT:
strcpy(mazeGraphic[j][i].sign,"←");
break;
default:
fprintf(stderr,"未知错误!操作失败……\n");
system("pause");
exit(EXIT_FAILURE);
}
}
strcpy(mazeGraphic[inlet.y][inlet.x].sign,"★");
strcpy(mazeGraphic[outlet.y][outlet.x].sign,"☆");
DestoryStack();
}
#endif MAZESOLUTION_H