通过C++设计了一个迷宫游戏,涉及到链表,C++基本操作,终端字符处理,深度优先遍历算法。下面开始吧!
- 在全局变量中定义地图,包括地图的长和高(30*20),同时还需定义一些标记。
- flag 用于创建地图,true代表地图传创建成功。
- slow用于更换游戏速度,true代表游戏慢速。
- autogame用于更换游戏模式,true代表自动游戏。
#define MAX_X 20
#define MAX_Y 30
bool flag = false;
bool slow = false;
bool autogame = true;
int maze[MAX_X][MAX_Y]; //迷宫
2.路线栈
路线栈设计来记录移动路径。路径栈是一个类,它可以记录地图的坐标和移动轨迹。
class stack_of_maze{
private:
//code
public:
//code
};
- 成员变量
在成员变量中定义一个数据结构来包括地图坐标和移动信息。
//记录迷宫坐标
struct node
{
int x;
int y;
char direction; //上一步路径(如何来的)
node* next;
};
node* head;
- 成员函数
构造和析构
stack_of_maze(){
//初始化
head = NULL;
}
~stack_of_maze(){
node* p = head;
//逐个删除
while(head!=NULL){
head = head->next;
delete p;
p = head;
}
}
压栈
设置一个新节点用于插入,首先将信息记录到新节点中,再把新节点插入到栈顶。这个函数的功能用于添加新的移动信息。
void push(int xx,int yy,char ddirection){
//定义一个新节点
node* new_node = new node;
//赋值
if(new_node!=NULL){
new_node->x = xx;
new_node->y = yy;
new_node->direction = ddirection;
new_node->next = NULL;
//判断栈是否为空,如果为空则直接把新节点赋值给栈,否则添加到栈顶
if(head==NULL)
head = new_node;
else{
new_node->next = head;
head = new_node;
}
}
else
cout<<"内存分配失败"<<endl;
}
出栈
推出栈顶元素,用于判断路径是否正确,如果下一个节点为空则说明路径错误,前方不能通行。
node* pop(int& xx,int& yy){
if(head!=NULL){
node* p = head;
head = head->next;
xx = p->x;
yy = p->y;
delete p;
}
return head;
}
打印
打印路径信息。
void print(){
if(head!=NULL){
node* p = head;
while(p!=NULL){
cout<<" "<<p->x<<" "<<p->y<<" "<<p->direction<<endl;
p = p->next;
}
}
else
cout<<"栈为空,打印失败"<<endl;
}
3.创建地图
首先把地图全设置为1,即死路,然后除了出入口和最外一层墙壁保持不变,其他位置采用随机函数来初始化通路为0。纵坐标为x,横坐标为y.
void createMaze(){
int maxway = MAX_X * MAX_Y; //最大通路
int x,y;
//先填充迷宫
for(x=0;x<MAX_X;x++)
for(y=0;y<MAX_Y;y++)
maze[x][y] = 1;
//随机函数种子,以时间为参数
srand((unsigned)time(NULL));
//随机构建迷宫通路
for(int i=0;i<maxway;i++)
{
x = rand() % (MAX_X-2) + 1;
y = rand() % (MAX_Y-2) + 1;
maze[x][y] = 0;
}
maze[1][1] = 0; //入口
maze[MAX_X-2][MAX_Y-2] = 0; //出口
maze[0][1] = 3;
maze[MAX_X-1][MAX_Y-2] = 0;
}
4. 打印地图
根据标记列表对应符号来打印地图。
void printMaze(){
int x,y;
//清屏,如果是windows环境使用system("cls")
system("clear");
//打印地图
for(x=0;x<MAX_X;x++)
{
for(y=0;y<MAX_Y;y++)
{
if(maze[x][y]==0){cout<<" ";continue;} //通路
if(maze[x][y]==1){cout<<"■ ";continue;} //墙
if(maze[x][y]==2){cout<<"× ";continue;} //死胡同
if(maze[x][y]==3){cout<<"↓ ";continue;} //向下走
if(maze[x][y]==4){cout<<"→ ";continue;}
if(maze[x][y]==5){cout<<"← ";continue;}
if(maze[x][y]==6){cout<<"↑ ";continue;}
if(maze[x][y]==7){cout<<"※ ";continue;} //当前站立位置
}
cout<<endl;
}
//是否慢速游戏
if(slow){
sleep(1); //延时函数
}
}
4.1检查地图
因为地图的创建是随机的,所以为了能正确的进行游戏,检查创建的地图是否正确,这里传递定义一条备用路径来检验,如果通路则flag标记为true,游戏使用这个地图。
void check(stack_of_maze &s){
//备份地图
int temp[MAX_X][MAX_Y];
for(int x=0;x<MAX_X;x++)
for(int y=0;y<MAX_Y;y++)
temp[x][y] = maze[x][y];
int x=1,y=1; //出发点
while(1){
temp[x][y] = 2;
//向下
if(temp[x+1][y]==0){
s.push(x,y,'D');
//在当前位置做一个向下的标志
temp[x][y] = 3;
x = x + 1;
temp[x][y] = 7; //当前位置
//判断是否到达出口,如果到达出口则flag标记为true,下同
if((x==MAX_X-1)&&(y==MAX_Y-2)){
flag = true;
return;
}
else
continue;
}
//向右
if(temp[x][y+1]==0){
s.push(x,y,'R');
//在当前位置做一个向右的标志
temp[x][y] = 4;
y = y + 1;
temp[x][y] = 7;
if((x==MAX_X-1)&&(y==MAX_Y-2)){
flag = true;
return;
}
else
continue;
}
//向上
if(temp[x-1][y]==0){
s.push(x,y,'U');
//在当前位置做一个向上的标志
temp[x][y] = 6;
x = x - 1;
temp[x][y] = 7;
if((x==MAX_X-1)&&(y==MAX_Y-2)){
flag = true;
return;
}
else
continue;
}
//向左
if(temp[x][y-1]==0){
s.push(x,y,'L');
//在当前位置做一个向右的标志
temp[x][y] = 5;
y = y - 1;
temp[x][y] = 7;
if((x==MAX_X-1)&&(y==MAX_Y-2)){
flag = true;
return;
}
else
continue;
}
//上下左右不通,则回退到起点
if(s.pop(x,y)==NULL && temp[x-1][y]!=0 && temp[x][y-1]!=0 && temp[x][y+1]!=0 && temp[x+1][y]!=0){
temp[0][1] = 7;
if(temp[1][1]!=1)
temp[1][1] = 2;
return;
}
}
}
4.2移动
移动的规则是已知的,在这里主要进行命令识别,得到正确的命令后,首先判断下一个地址是否通路,如果是则要清除当前信息再移动到下一步。
void move(){
int x=1,y=1; //出发点
//一直游戏,直到走出
while(1){
//判断输入的命令
switch(getch()){
case 's':
if(maze[x+1][y]==0){
//清空当前位置信息
maze[x][y] = 0;
x = x + 1;
//当前位置
maze[x][y] = 7;
printMaze();
if((x==MAX_X-1)&&(y==MAX_Y-2)){
cout<<"\n\n 成功走出"<<endl;
return;
}
}
break;
case 'd':
if(maze[x][y+1]==0){
if(maze[x][y+1]==0){
maze[x][y] = 0;
y = y + 1;
maze[x][y] = 7;
printMaze();
if((x==MAX_X-1)&&(y==MAX_Y-2)){
cout<<"\n\n 成功走出"<<endl;
return;
}
}
}
break;
case 'w':
if(maze[x-1][y]==0){
maze[x][y] = 0;
x = x - 1;
maze[x][y] = 7;
printMaze();
if((x==MAX_X-1)&&(y==MAX_Y-2)){
cout<<"\n\n 成功走出"<<endl;
return;
}
}
break;
case 'a':
if(maze[x][y-1]==0){
maze[x][y] = 0;
y = y - 1;
maze[x][y] = 7;
printMaze();
if((x==MAX_X-1)&&(y==MAX_Y-2)){
cout<<"\n\n 成功走出"<<endl;
return;
}
}
break;
}
}
}
4.3自动游戏
游戏会根据深度优先算法自动搜索路径,其中游戏会根据slow标志选择游戏速度。
void autoMove(stack_of_maze &s){
int x=1,y=1; //出发点
while(1){
maze[x][y] = 2;
//向下
if(maze[x+1][y]==0){
s.push(x,y,'D');
maze[x][y] = 3; //在当前位置做一个向下的标志
x = x + 1;
maze[x][y] = 7; //当前位置
if(slow)
printMaze();
if((x==MAX_X-1)&&(y==MAX_Y-2)){
s.push(x,y,'*');
cout<<"\n\n 成功走出"<<endl;
return;
}
else
continue;
}
//向右
if(maze[x][y+1]==0){
s.push(x,y,'R');
maze[x][y] = 4; //在当前位置做一个向右的标志
y = y + 1;
maze[x][y] = 7;
if(slow)
printMaze();
if((x==MAX_X-1)&&(y==MAX_Y-2)){
s.push(x,y,'*');
cout<<"\n\n 成功走出"<<endl;
return;
}
else
continue;
}
//向上
if(maze[x-1][y]==0){
s.push(x,y,'U');
maze[x][y] = 6; //在当前位置做一个向上的标志
x = x - 1;
maze[x][y] = 7;
if(slow)
printMaze();
if((x==MAX_X-1)&&(y==MAX_Y-2)){
s.push(x,y,'*');
cout<<"\n\n 成功走出"<<endl;
return;
}
else
continue;
}
//向左
if(maze[x][y-1]==0){
s.push(x,y,'L');
maze[x][y] = 5; //在当前位置做一个向右的标志
y = y - 1;
maze[x][y] = 7;
if(slow)
printMaze();
if((x==MAX_X-1)&&(y==MAX_Y-2)){
s.push(x,y,'*');
cout<<"\n\n 成功走出"<<endl;
return;
}
else
continue;
}
//上下左右不通,则回退
if(s.pop(x,y)==NULL && maze[x-1][y]!=0 && maze[x][y-1]!=0 && maze[x][y+1]!=0 && maze[x+1][y]!=0){
cout<<"\n\n 没有找到合适的路径"<<endl;
maze[0][1] = 7;
if(maze[1][1]!=1)
maze[1][1] = 2;
return;
}
}
}
4.4 开始游戏
首先会调用函数创建地图,然后根据标志位来进行游戏。因为会回调menu()函数,所以前面需要先声明一下。
void menu();
void gamestart(){
//初始化地图
flag = false;
while(!flag){
stack_of_maze stack;
//创建地图
createMaze();
//检查地图是否创建成功
check(stack);
//模仿进度条
system("clear");
cout<<"\t* loading. *"<<endl;
system("clear");
cout<<"\t* loading.. *"<<endl;
system("clear");
cout<<"\t* loading... *"<<endl;
}
//输出当前迷宫的初始状态
printMaze();
cout<<"\n\n 输入enter键继续"<<endl;
getchar();
//自行游戏
if(!autogame){
move();
cout<<"\n\n 输入enter键继续"<<endl;
getchar();
menu();
}
//自动游戏
else{
stack_of_maze stack1;
autoMove(stack1); //行走中……
}
printMaze(); //输出迷宫的最终状态
cout<<"\n\n 输入enter键继续"<<endl;
getchar();
menu();
}
4.5 菜单
定义一个简单的菜单来选择游戏模式。
void menu(){
system("clear");
int num;
cout<<"\t****************************************"<<endl;
cout<<"\t* *"<<endl;
cout<<"\t* 1.查看路径 *"<<endl;
cout<<"\t* *"<<endl;
cout<<"\t* 2.自动进行 *"<<endl;
cout<<"\t* *"<<endl;
cout<<"\t* 3.自行游戏 *"<<endl;
cout<<"\t* *"<<endl;
cout<<"\t* 4.退出游戏 *"<<endl;
cout<<"\t* *"<<endl;
cout<<"\t****************************************"<<endl;
slow = false;
//选择模式
switch(getch()){
case '1':
autogame = true;
gamestart();
break;
case '2':
autogame = true;
slow = true;
gamestart();
break;
case '3':
autogame = false;
gamestart();
break;
case '4':
exit(1);break;
default:
cout<<"\n\n 错误操作,输入enter返回!"<<endl;
getchar();
menu();
}
getchar();
}
4.6 主函数
int main(int argc,char** argv){
menu();
return 0;
}
5.界面截图