【Qt编程】3D迷宫游戏
说起迷宫想必大家都很熟悉,个人感觉迷宫对人的方向感是很大的考验,至少我的方向感是不好的,尤其是在三维空间中。由于这段时间帮导师做项目用到了三维作图,便心血来潮想做个三维迷宫玩玩。要想画出三维的迷宫游戏,我们需要先从二维开始。
二维迷宫:
1.最开始时,只有初始点处的墙被拆掉
2、随机数randnum=2,开始向左边拆墙,由于(4,2)为0(有墙),可以拆,于是拆掉(4,2)、(4,3)位置的墙,则结果如下:
3、接着产生随机数randnum=1,开始向下拆墙,由于(6,2)为0(有墙),可以拆,于是拆掉(5,2)、(6,2)位置的墙,结果如下:
4、继续产生随机数randnum=0,开始向上拆墙,由于(4,2)为1没有墙,不可以拆,于是重新产生随机数,结果与上一张图一样:
5、继续产生随机数randnum=3,开始向右拆墙,由于(6,4)为0有墙,可以拆,于是拆掉(6,3)、(6,4)位置的墙,结果如下:
按照上述步骤重复下去,最终得到一个可能的迷宫矩阵如下:
#include<iostream>
#include<ctime>
#include<vector>
#define M 9//迷宫的行
#define N 9//迷宫的列
//构造迷宫类型//
using namespace std;
class MazeStack;//申明该类
class Maze//定义迷宫节点信息。
{
public:
int i;
int j;
int state;
};
class MazeMat
{
Maze matrix[M][N];//迷宫矩阵
vector<Maze> EntryPath;//从初始点到入口的路径
vector<Maze> ExitPath;//从初始点到出口的路径
vector<Maze> FinalPath;//从入口到出口的路径
MazeStack *mazeStack;//定义栈
public:
void initMaze();//初始化迷宫矩阵
void createMaze();//产生迷宫矩阵
void displayMaze();//显示迷宫矩阵
void FindWay();//寻找入口到出口的路径
};
//////////////////
2、Maze.cpp
#include"MazeStack.h"
using namespace std;
void MazeMat::initMaze()//初始化迷宫矩阵
{
for(int i=0;i<M;i++)
for(int j=0;j<N;j++)
{
matrix[i][j].i=i;
matrix[i][j].j=j;
matrix[i][j].state=0;//初始化迷宫矩阵元素为0,即全为墙
}
mazeStack=new MazeStack();
EntryPath.clear();//初始化各个路径
ExitPath.clear();
FinalPath.clear();
}
void MazeMat::createMaze()//产生迷宫矩阵,中间也记录了从初始点到入口、出口的路径
{
int i=4;//初始点设定,注意i,j必须为偶数
int j=4;
bool Left=false;//初始化四个方向,false代表可以朝这个方向搜索
bool Right=false;
bool Up=false;
bool Down=false;
matrix[i][j].state=1;//设置初始点是空的,即不是墙
srand((int)time(0));//产生随机数种子,使得每次运行情况不同
Maze temp;
temp.i=i;
temp.j=j;
temp.state=0;
int count1=0;
int num1=0;
mazeStack->Push(temp);//将初始点进栈
while(1)//不断循环搜索可行方向,形成迷宫
{
temp.i=i;
temp.j=j;
int randNum=0;
randNum=rand()%4;//0,1,2,3
//我们假设迷宫矩阵的第一个元素(0,0)为入口,最后一个元素(M-1,N-2)为出口
if(temp.i==0&&temp.j==0)
{
EntryPath.clear();
while(mazeStack->isEmpty() == false)
{
EntryPath.push_back(mazeStack->GetTop());//获得从初始点到入口的路径
mazeStack->Pop();
}
for(int ii=EntryPath.size()-1;ii>=0;ii--)
{
mazeStack->Push(EntryPath[ii]);//还原栈
}
}
if(temp.i==M-1&&temp.j==N-1)
{
ExitPath.clear();
while(mazeStack->isEmpty() == false)
{
ExitPath.push_back(mazeStack->GetTop());//获得从初始点到出口的路径
mazeStack->Pop();
}
for(int i=ExitPath.size()-1;i>=0;i--)
{
mazeStack->Push(ExitPath[i]);//还原栈
}
}
switch(randNum)
{
case 0://向上搜索
if(Up==false&&i>1&&matrix[i-2][j].state!=1)
{
mazeStack->Push(temp);
matrix[i-1][j].state=1;
matrix[i-2][j].state=1;
i=i-2;
Left=false;
Right=false;
Up=false;
Down=false;
}
else
Up=true;
break;
case 1://向下搜索
if(Down==false&&i<M-2&&matrix[i+2][j].state!=1)
{
mazeStack->Push(temp);
matrix[i+1][j].state=1;
matrix[i+2][j].state=1;
i=i+2;
Left=false;
Right=false;
Up=false;
Down=false;
}
else
Down=true;
break;
case 2://向左搜索
if(Left==false&&j>1&&matrix[i][j-2].state!=1)
{
mazeStack->Push(temp);
matrix[i][j-1].state=1;
matrix[i][j-2].state=1;
j=j-2;
Left=false;
Right=false;
Up=false;
Down=false;
}
else
Left=true;
break;
case 3://向右搜索
if(Right==false&&j<N-2&&matrix[i][j+2].state!=1)
{
mazeStack->Push(temp);
matrix[i][j+1].state=1;
matrix[i][j+2].state=1;
j=j+2;
Left=false;
Right=false;
Up=false;
Down=false;
}
else
Right=true;
break;
}//end switch
if(Left&&Right&&Up&&Down) //当上下左右都不可行时,进行回溯
{
if(mazeStack->isEmpty()) //回溯完毕,生成迷宫
{
return ;
}
else //进行出栈操作
{
i = mazeStack->GetTop().i;
j = mazeStack->GetTop().j;
mazeStack->Pop();
Left=false;
Right=false;
Up=false;
Down=false;
}
}
}//end while
}
void MazeMat::displayMaze()//显示迷宫
{
matrix[0][0].state = matrix[M-1][N-1].state = 2;//2表示入口和出口
for(int i=0;i<FinalPath.size();i++)
{
matrix[FinalPath.at(i).i][FinalPath.at(i).j].state=3;//3表示可达路径点
}
cout<<"左上角为入口,右下角为出口,oo代表可达路径."<<endl;
for(int k=0;k<N+2;k++)//在迷宫矩阵的外围墙
cout<<"■";
cout<<endl;
for (int i = 0; i < M; i++)
{
cout<<"■";
for (int j = 0; j <N; j++)
{
switch ( matrix[i][j].state )
{
case 0:cout<<"■";break;// 显示墙
case 1:cout<<" ";break;//显示空
case 2:cout<<"↘";break;//显示入口和出口
case 3:cout<<"oo";break;//显示可达路径
}
}
cout<<"■";
cout<<endl;
}
for(int k=0;k<N+2;k++)
cout<<"■";
cout<<endl;
}
void MazeMat::FindWay()//寻找可达路径
{
FinalPath.clear();//清零
int i=0,j=0;
for(i=EntryPath.size()-1,j=ExitPath.size()-1;i>=0&&j>=0;i--,j--)
{
if(EntryPath.at(i).i!=ExitPath.at(j).i||EntryPath.at(i).j!=ExitPath.at(j).j)
{
break;
}
}
if(i<0)//初始点到出口的路径中经过入口
{
for(int k=ExitPath.size()-EntryPath.size()-1;k>=0;k--)
{
FinalPath.push_back(ExitPath.at(k));
}
}
else if(j<0)//初始点到入口的路径中经过出口
{
for(int k=EntryPath.size()-ExitPath.size()-1;k>=0;k--)
{
FinalPath.push_back(EntryPath.at(k));
}
}
else//初始点到入口、出口的路径有部分重叠或则没有重叠
{
for(int k=0;k<=i+1;k++)
{
FinalPath.push_back(EntryPath.at(k));
}
for(int k=j;k>=0;k--)
{
FinalPath.push_back(ExitPath.at(k));
}
}
}
3、MazeStack.h
#include"Maze.h"
typedef Maze ElementType;
//这里是栈的定义
typedef struct node
{
ElementType data;
struct node *next;
}Node;
class MazeStack
{
public:
MazeStack():bottom(NULL),top(NULL),Size(NULL){}
~MazeStack(){}
bool isEmpty();
bool Push(ElementType e);
ElementType GetTop();
ElementType Pop();
private:
Node *bottom;
Node *top;
int Size;
};
4、MazeStack.cpp
#include"MazeStack.h"
bool MazeStack::isEmpty()//判断栈是否为空
{
if(top==bottom)
return true;
return false;
}
bool MazeStack::Push(Maze m)//进栈
{
Node *temp;
temp=top;
top=new Node();
if(!top)
return false;
top->data=m;
top->next=temp;
Size++;
return true;
}
Maze MazeStack::Pop()//出栈
{
Node temp;
temp.data=top->data;
temp.next=top->next;
delete top;
top=temp.next;
Size--;
return temp.data;
}
Maze MazeStack::GetTop()//取栈顶元素
{
return top->data;
}
5、main.cpp
#include"MazeStack.h"
void main()
{
MazeMat matrix;
matrix.initMaze();
matrix.createMaze();
matrix.FindWay();
matrix.displayMaze();
}
具体的程序截图如下:
2维到3维的转化
原文:http://blog.csdn.net/tengweitw/article/details/40213317
作者:nineheadedbird
【Qt编程】3D迷宫游戏的更多相关文章
- 用webgl打造自己的3D迷宫游戏
用webgl打造自己的3D迷宫游戏 2016/09/19 · JavaScript · WebGL 原文出处: AlloyTeam 背景:前段时间自己居然迷路了,有感而发就想到写一个可以让人迷路 ...
- 【Qt编程】基于Qt的词典开发系列--后序
从去年八月份到现在,总算完成了词典的编写以及相关技术文档的编辑工作.从整个过程来说,文档的编写比程序的实现耗费的时间更多.基于Qt的词典开发系列文章,大致包含了在编写词典软件过程中遇到的技术重点与难点 ...
- Qt编程学习网站
http://blog.csdn.net/k122769836/article/details/8637677 QT - little_su - 博客频道 - CSDN.NET Qt - 1+1=2 ...
- 3D单机游戏《天鹰教》源码发布(二)
3D单机游戏<天鹰教>源码发布 作者 作者: 游蓝海 博客: http://blog.csdn.net/you_lan_hai mail: you_lan_hai@foxmail. ...
- POJ 2251 Dungeon Master(3D迷宫 bfs)
传送门 Dungeon Master Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 28416 Accepted: 11 ...
- c语言迷宫游戏的实现
// // main.c // 迷宫游戏代码实现 // #include <stdio.h> #define ROW 6 //宏定义行 #define COL 6 //宏定义列 /** * ...
- 51nod 1459 迷宫游戏(dij)
题目链接:51nod 1459 迷宫游戏 dij裸题. #include<cstdio> #include<cstring> #include<algorithm> ...
- qt编程入门
面对qt编程,必须先知道qt中常用的类: QPushButton按钮类.QLabel标签类.QMessageBox对话框类.QCheckBox.QAction.QMenu.QStatusBar.QTo ...
- 3D跑酷游戏《月影忍者之疾风狂逃》
<月影忍者之疾风狂逃>是一款3D跑酷游戏,也是我实习的时候参与的一个项目,在那个公司我学到了很多东西,谢谢他们.大家可以去玩玩这个游戏啊,还是不错的哦.
随机推荐
- python 如何优雅地退出子进程
python 如何优雅地退出子进程 主进程产生子进程,子进程进入永久循环模式.当主进程要求子进程退出时,如何能安全地退出子进程呢? 参考一些代码,我写了这个例子.运行之后,用kill pid试试.pi ...
- emysql add_poop() 超时出错
emysql add_poop() 超时出错(金庆的专栏)sample/a_hello.erl 连接本机更改为连接局域网内的MySql服务器: emysql:add_pool(hello_poo ...
- 20 ViewPager demo5,6:FragmentAdapter 导航数据
Demo5 文件结构: MainActivity.java package com.qf.day20_viewpager_demo5; import java.util.ArrayList; impo ...
- Linux--DNS服务器
DNS是Internet上使用最普遍,也是最重要的服务之一,通过DNS我们才可以访 问丰富多彩的网络,而DNS服务器就是为了实现域名解析功能而搭建的. 域名系统采用层次结构,按地理区域或机构区域 ...
- EBS库存(INV)模块常用表
select * from org_organization_definitions库存组织 select * from mtl_parameters组织参数 select * from mtl ...
- (一二四)tableView的多组数据展示和手动排序
最近在写一个轻量级的网络游戏,遇到了技能优先顺序手动排序的需求,我就想到了iOS自带的tableView编辑功能,对其进行了初步探索,最后做出的效果如下图所示: 点击左边可以删除,拖住右边可以手动排序 ...
- UNIX网络编程——非阻塞connect
当在一个非阻塞的TCP套接字上调用connect时,connect将立即返回一个EINPROGRESS错误,不过已经发起的TCP三次握手继续进行.我们接着使用select检测这个连接或成功或失败的已建 ...
- Android读取网络图片到本地的简约的实现
今天在网上看到了一个关于读取网络文件的小视频,觉得不错,拿来与大家分享 思路 具体的思路比较的简单,但是思想非常的单纯.那就是输入一个网址,点击按钮,将从网络上获取的一张图片显示到一个ImageVie ...
- ElGamal密码
ElGamal也是一种基于离散对数的公钥体制,与Diffie-Hellman密钥体制密切相关.ElGamal密码体系用于数字签名标准(DSS)和S/MIME电子邮件标准等一些技术标准中. 算法描述: ...
- Linux信号实践(1) --Linux信号编程概述
中断 中断是系统对于异步事件的响应, 进程执行代码的过程中可以随时被打断,然后去执行异常处理程序; 计算机系统的中断场景:中断源发出中断信号 -> CPU判断中断是否屏蔽屏蔽以及保护现场 -&g ...