C++复现经典游戏——扫雷
国庆小长假,当大家都去看人山人海的时候,我独自一人狂码代码。这两天想要实现的内容是Windows上的一个经典游戏——扫雷。相信90后和一些上班族对此并不陌生。然而,从win8开始,扫雷就不再是Windows上的默认自带游戏了,但是可以通过微软的应用商店进行下载安装(界面更酷炫,游戏模式更丰富)。目前在win10上也暂时没有找到这款游戏。
这两天再次用Qt基本图形界面框架,来实现扫雷游戏的功能。本想做得酷炫酷炫再酷炫的,但是真正动手写起来的时候,才发现还是有很多技术关没有通过,因此界面写得丑了。这次扫雷程序实现了基本的游戏功能,包含随机布雷、空白块自动扩展、输赢判断等。
程序界面如下:

游戏界面
整个扫雷游戏,最主要的一部分是当点击到空白块的时候,如何扩展开来。我在写程序前,也上网查了扫雷相关的东西,发现扫雷程序已经被写烂了,很多人都复现过,毕业设计、课程设计等等。说起来,扫雷程序确实适合用来练手,整个程序功能并不是特别的复杂。
下面说说我认为的点到空白块的自动扩展算法。
(1)点击到空白块
(2)计算该空白块周围一圈雷的个数。若为零,翻开该块并跳至(3)。若不为零,则翻开并显示雷的个数,跳至(4)。
(3)对周围八个块,重复第二步。
(4)结束
以上四步便是空白块自动扩展算法,是不是很简单。但是我刚开始的时候这个东西还是想了很长一段时间。当写程序实现该算法的时候,有一点需要注意的地方,就是翻开的块需要做个标记。对于第三步中,已经翻开的块不需要再执行第(2)步,不然就可能进入死循环。此外,该算法可以使用递归实现或非递归实现。
下面是我的具体实现代码:
/*
*统计(x,y)周围一圈雷的个数
*/
int MainWindow::sumMine(int x, int y)
{
int mineNum=;
if(x->=&&y->=&&map[x-][y-]==) mineNum++;
if(x->=&&map[x-][y]==) mineNum++;
if(x->=&&y+<mapCols&&map[x-][y+]==) mineNum++;
if(y->=&&map[x][y-]==) mineNum++;
if(y+<mapCols&&map[x][y+]==) mineNum++;
if(x+<mapRows&&y->=&&map[x+][y-]==) mineNum++;
if(x+<mapRows&&map[x+][y]==) mineNum++;
if(x+<mapRows&&y+<mapCols&&map[x+][y+]==) mineNum++;
return mineNum; } /*
*从(x,y)开始进行扩展
*/
void MainWindow::expendBlock(int x, int y)
{
int mineAround=sumMine(x,y);
if(mineAround!=){
//在(x,y)显示雷的个数,然后结束递归
QTableWidgetItem * temp=new QTableWidgetItem;
temp->setText(QString::number(mineAround,));
temp->setTextAlignment(Qt::AlignCenter);
temp->setBackgroundColor(QColor(,,));
mapUI->setItem(x,y,temp);
mapFlag[x][y]=;
return ;
}
//翻开(x,y),并从周围八个方向递归,要判断越界 list<POINT> expendList;
POINT point;
point.x=x;
point.y=y;
expendList.push_back(point);
while (!expendList.empty()) {
point=expendList.front();
expendList.pop_front();
x=point.x;
y=point.y;
mineAround=sumMine(x,y);
if(mineAround!=){
QTableWidgetItem * temp=new QTableWidgetItem;
temp->setText(QString::number(mineAround,));
temp->setTextAlignment(Qt::AlignCenter);
temp->setBackgroundColor(QColor(,,));
mapUI->setItem(x,y,temp);
mapFlag[x][y]=;
continue;
}
QTableWidgetItem * temp1=new QTableWidgetItem;
temp1->setBackgroundColor(QColor(,,));
temp1->setTextAlignment(Qt::AlignCenter);
mapUI->setItem(x,y,temp1);
mapFlag[x][y]=;
if(x->=&&y->=&&mapFlag[x-][y-]==){
point.x=x-;
point.y=y-; expendList.push_back(point);
}
if(x->=&&mapFlag[x-][y]==){
point.x=x-;
point.y=y; expendList.push_back(point);
}
if(x->=&&y+<mapCols&&mapFlag[x-][y+]==){
point.x=x-;
point.y=y+; expendList.push_back(point);
}
if(y->=&&mapFlag[x][y-]==){
point.x=x;
point.y=y-; expendList.push_back(point);
}
if(y+<mapCols&&mapFlag[x][y+]==){
point.x=x;
point.y=y+; expendList.push_back(point);
}
if(x+<mapRows&&y->=&&mapFlag[x+][y-]==){
point.x=x+;
point.y=y-; expendList.push_back(point);
}
if(x+<mapRows&&mapFlag[x+][y]==){
point.x=x+;
point.y=y; expendList.push_back(point);
}
if(x+<mapRows&&y+<mapCols&&mapFlag[x+][y+]==){
point.x=x+;
point.y=y+;
expendList.push_back(point);
}
} }
其中map[][]保存着地图信息。mapFlag[][]是地图标志,当该块已经翻开是设置为1,否则为0。
C++复现经典游戏——扫雷的更多相关文章
- C language 模拟 win的经典游戏——扫雷
让我们在terminal下愉快的...扫雷 昨天跟奇葩霖聊起"雷区"这个敏感词汇,然后非常荣幸的... 应该轰炸不到我.. . 后来百无聊赖的去玩了把扫雷.然后发现我之前都是乱扫的 ...
- JY游戏之毁经典《扫雷》
JY游戏之毁经典<扫雷> 这是一个经典的pc端游戏,一定的运气加一点数学常识,讲的是一个速度,这次,我利用js JY库重做了这款游戏,加了三次生命,过关难度,也兼容了移动端的触摸事件. 它 ...
- Javascript版经典游戏之《扫雷》
翻出年初写的游戏贴上来,扫雷相信大家都玩过,先上图: 源码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN ...
- FC经典游戏还原之:松鼠大作战2
版权声明:本文原创发布于博客园"优梦创客"的博客空间(id:raymondking123) 原帖地址:http://www.cnblogs.com/raymondking123/p ...
- Unity2017 经典游戏开发教程 算法分析与实现 (张帆 著)
https://meta.box.lenovo.com/link/view/82c451b41ce34e81a4b34cb46747d3d5 第1章 熟悉Unity软件的操作 第2章 打地鼠 (已看) ...
- c++小游戏——扫雷
#include<cstdio> #include<cstring> #include<algorithm> #include<conio.h> #in ...
- c语言小游戏-扫雷的完成
C语言-扫雷游戏 本文将对此游戏做一个大致的概述,此代码适合初学者,编写软件使用了vs2017. 该代码可以实现如下功能: 1.用户可以选择3个难度,分别布置不同个数的雷. 2.随机数设置雷的位置. ...
- 经典游戏--24点--c++代码实现和总体思路(简单暴力向)
24点 24点是一个非常经典的游戏,从扑克牌里抽4张牌,其中J=11,Q=12,K=13,然后经过+,-,*,/,(),的计算后,使得计算得值为24,例如抽到1,2,2,5四张牌,那么 (1+5)*( ...
- 技术分享:RxJS实战练习-经典游戏Breakout
效果图 数据流分析 1.ticker$ 数据流 interval配合scheduler/animationFrame 作为游戏随时间变化的控制数据流 ticker$ = interval(this.T ...
随机推荐
- Poj 3250 单调栈
1.Poj 3250 Bad Hair Day 2.链接:http://poj.org/problem?id=3250 3.总结:单调栈 题意:n头牛,当i>j,j在i的右边并且i与j之间的所 ...
- IOS中NSUserDefaults的用法(轻量级本地数据存储)
NSUserDefaults适合存储轻量级的本地数据,比如要保存一个登陆界面的数据,用户名.密码之类的,个人觉得使用NSUserDefaults是首选.下次再登陆的时候就可以直接从NSUserDefa ...
- 深入浅出 - Android系统移植与平台开发(八)- HAL Stub框架分析
作者:唐老师,华清远见嵌入式学院讲师. 1. HAL Stub框架分析 HAL stub的框架比较简单,三个结构体.两个常量.一个函数,简称321架构,它的定义在:@hardware/libhardw ...
- e.Handled的理解
private void textBox1_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e) { ...
- 附件上传 使用javascript
<html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1" runat=&quo ...
- C#向文本文件中写入日志
今天看了一篇文章,说的是使用微软自带的日志类写日志,然后晚上我就花了2个多小时自己动手试了一下,然后模仿者自己封装了一个类库. 下面是自己封转的类: /***** * 创建人:金河 * 创建日期:20 ...
- Curl参数一览
* 目录 1. 介绍 2. curl扩展的安装 3. curl_init 4. curl_setopt 5. curl_exec 6. curl_close 7. curl_version * 介绍 ...
- JDBC的事务处理
JDBC的事务处理 事务,也是数据库事务,指的是作为单个逻辑工作单元执行的一系列操作.正常的情况下,操作应该顺利进行,与操作相关的所有数据库信息也成功地更新: 但是,如果在这一系列过程中任何一个环节出 ...
- Maven3下的java web项目
咱们使用Maven3构建一个j2ee项目,项目的成果是一个war包,只需把它部署在服务器上,就可以使用浏览器访问. 具体详细信息 参考 http://www.mossle.com/docs/mave ...
- bzoj1857: [Scoi2010]传送带--三分套三分
三分套三分模板 貌似只要是单峰函数就可以用三分求解 #include<stdio.h> #include<string.h> #include<algorithm> ...