前言:
现时朋友们对“扫雷递归算法java”大体比较注重,咱们都想要了解一些“扫雷递归算法java”的相关知识。那么小编同时在网络上网罗了一些关于“扫雷递归算法java””的相关文章,希望同学们能喜欢,兄弟们快快来学习一下吧!最近搞了一个qt的小游戏,现在在这里分享给大家,一起来学习一下。
一、功能简介:
1、鼠标左键翻开格子。若周围没有雷,则会爆出一大片,效果如图1所示。
2、右键插上红旗,表示有雷,效果如图2所示。
3、左上角的数字表示剩余雷数。当点击右键给格子插上红旗时,数字会自动减1。当减少到零时,游戏会自动提示扫雷成功或失败,效果如图3所示。
4、顶部的笑脸表示游戏继续,伤心表示游戏结束。当鼠标左键点击该位置时,表示重新开始游戏。
5、右上角的数字表示扫雷的时间(s)。当时间大于999s时,游戏会自动弹出超时提示框,并结束游戏。
二、原理描述:
1、每个格子都保存一位数字。0~8表示这一格周围8格子中的雷数;50~58表示格子插上红旗;99表示该格子为雷;当左键翻开后,将格子中的数加上100,保存新的数值,即——100~108表示该格子已翻开,并且不是雷(0~8加上100);150~158表示插有红旗的格子翻开(10~58+100);199表示埋雷的格子被翻开。。。
2、当左键翻开一个格子时,程序会自动检测其周围格子,并将不是雷的翻开。当遇到格子周围都没有雷的时候,程序会递归点击周围的8个格子。
3、当确定格子埋有雷的时候,可右键点击插上红旗作标注。
接下来教大家如何创建工程并用代码实现该游戏。
三、实现过程
1、创建工程
打开qt creator软件,然后点击New Project。
2、选择模板
模板选择Application -> Qt Widget Application,之后点击“Choose”。
3、项目名称和位置
给项目添加名称,并可以修改项目保存的位置,然后点击“下一步”。
3、类名
可修改类名。删掉“创建界面”的沟。
4、完成创建
直接点击“完成”即可。
之后可看到如下界面。
5、初始化界面
初始化窗口大小以及标题,在mainwindow.h文件中添加以下信息。
#define GRID_X 20 //行 多少行地雷
#define GRID_Y 15 //列 多少列地雷
#define GAME_NAME "扫雷" //标题
在mainwindow.cpp中的构造函数MainWindow添加如下代码——
setWindowTitle("扫雷"); //设置标题
setFixedSize(GRID_X*20,GRID_Y*20+40); //设置窗口大小 20表示格子大小,40是留给另外部件的
运行效果如下图:
6、添加资源
为了美化游戏界面,我们需要添加一些图片资源。步骤如下——
6.1 右键点击项目,然后点击“添加新文件”,如图:
选择Qt -> Qt Resourse File;
设置资源文件名,如:res
生成资源文件res.qrc
在项目的同级目录下创建文件夹res,并将准备好的图片文件粘贴进去
然后鼠标右键点击res.qrc文件,选中Open in Editor
添加前缀" / "
添加res文件夹下的图片资源。直接选中所有图片文件,然后“打开”即可。保存所有文件
7、添加图标
在mainWindow.cpp的构造函数追加如下代码,即可给界面添加图标
setWindowIcon(QIcon(":/res/mine.ico"));
运行测试:
8、实现顶部界面
在界面顶部实现地雷数目、表情以及游戏时间的展示。
首先在mainwindow.h的类中添加以下代码——
int nMine; //地雷数目
int rtime; //游戏时间
int m_face; //表情包
void paintEvent(QPaintEvent *); //绘画事件
此外还要添加两个头文件
#include <QPixmap>
#include <QPainter>
对于mainwindow.cpp文件,先在构造函数中添加以下代码,初始化变量——
nMine = 50; //50个地雷
rtime = 0; //时间 0s
m_face = 1; //笑脸
然后重写绘画事件paintEvent——
void MainWindow::paintEvent(QPaintEvent *)
{
QPixmap num(":/res/item1.bmp");
QPixmap mine(":/res/item2.bmp");
QPixmap top(":/res/item3.bmp");
QPixmap face(":/res/item4.bmp");
QPainter painters(this);
//顶部框架
painters.drawPixmap(0, 0, top, 0, 0, 70, 40);
painters.drawPixmap(180, 0, top, 80, 0, 40, 40);
painters.drawPixmap(330, 0, top, 130, 0, 70, 40);
painters.drawPixmap(70, 0, 110, 40, top, 70, 0, 10, 40);
painters.drawPixmap(220, 0, 110, 40, top, 70, 0, 10, 40);
painters.drawPixmap(180+7, 7, face, m_face * 24, 0, 24, 24);
//剩余雷数目
painters.drawPixmap(27, 7, num, nMine/10 * 20, 0, 20, 27);
painters.drawPixmap(7, 7, num, 0, 0, 20, 27);
painters.drawPixmap(47, 7, num, nMine%10 * 20, 0, 20, 27);
//时间
painters.drawPixmap(337, 7, num, rtime/100 *20, 0, 20, 27);
painters.drawPixmap(357, 7, num, rtime%100/10 *20, 0, 20, 27);
painters.drawPixmap(377, 7, num, rtime%10 *20, 0, 20, 27);
}
运行调试:
9、实现游戏时间跳转
实现界面右上角的时间跳转
在mainwindow.h文件中添加头文件
#include <QTimer>
在类中添加如下代码
QTimer m_timer; //定时器
public slots:
void updateTime(); //槽函数 更新时间
对于mainwindow.cpp文件,在构造函数添加如下代码,建立信号与槽,并启动定时器
connect(&m_timer, SIGNAL(timeout()), this, SLOT(updateTime()));
m_timer.start(1000); //超时时间为1s
再实现槽函数updateTime
void MainWindow::updateTime()
{
rtime++;
update();
}
测试运行,可看到右上角时间的变化
10、埋地雷
初始化界面下方的格子,并埋下50个地雷。
在mainwindow.h头文件中添加一头文件,
#include <ctime>
在类中添加以下代码
int grid[GRID_Y][GRID_X]; //表示格子
void restart(); //重新开始
对于mainwindow.cpp文件,在构造函数中调用restart函数
restart();
然后实现restart函数
void MainWindow::restart()
{
for(int j=0; j<GRID_X; j++)
{
for(int i=0; i<GRID_Y; i++)
{
grid[j][i] = 0;
}
}
qsrand(time(NULL));
for(int i=0; i<50; i++) //埋50个地雷
{
int x = rand() % GRID_X;
int y = rand() % GRID_Y;
if(grid[x][y] != 99)
{
grid[x][y] = 99;
}
else
{
i--;
}
}
for(int x=0; x<GRID_X; x++) //计算每个格子周围的地雷
{
for(int y=0; y<GRID_Y; y++)
{
if(grid[x][y] == 99) //当检测到地雷时,将周围格子中的数加1
{
for(int i=-1; i<=1; i++)
{
for(int j=-1; j<=1; j++)
{
if(x+i<0 || x+i>=GRID_X || y+j<0 || y+j>=GRID_Y || grid[x+i][y+j]==99)
continue;
grid[x+i][y+j]++;
}
}
}
}
}
}
这里还需要将刚才的以下一些变量初始化代码剪切到restart函数里,这是因为重新开始游戏时,这些变量需要重新被初始化。
nMine = 50;
rtime = 0;
m_face = 1;
connect(&m_timer, SIGNAL(timeout()), this, SLOT(updateTime()));
m_timer.start(1000);
运行测试,效果如图
由于篇幅过长,剩余的功能留待下回讲解!!!
标签: #扫雷递归算法java