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 ...
随机推荐
- Linux之硬件管理(不断更新中)
1 查看CPU信息 [root@limt01 .ssh]# lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64- ...
- BZOJ4546: codechef XRQRS
Description 给定一个初始时为空的整数序列(元素由1开始标号)以及一些询问: 类型1:在数组后面就加入数字x. 类型2:在区间L…R中找到y,最大化(x xor y). 类型3:删除数组最后 ...
- 关于Nodejs的多进程模块Cluster
关于Nodejs的多进程模块Cluster 前述 我们都知道nodejs最大的特点就是单进程.无阻塞运行,并且是异步事件驱动的.Nodejs的这些特性能够很好的解决一些问题,例如在服务器开发中,并 ...
- javascrit2.0完全参考手册(第二版) 第2章第2节 语言特性
脚本执行顺序 js代码是按照它们在html中出现的顺序一行一行被解释的.这表明把函数定义和变量声明放到<head>中会很好.这保证了函数的代码和事件相关的处理程序不会立即执行. 大 ...
- 清除BOM头源码
BOM: Byte Order Mark UTF-8 BOM又叫UTF-8 签名,其实UTF-8 的BOM对UFT-8没有作用,是为了支援UTF-16,UTF-32才加上的BOM,BOM签名的意思就是 ...
- [LintCode] Ugly Number 丑陋数
Write a program to check whether a given number is an ugly number`. Ugly numbers are positive number ...
- c#语句 随堂练习1
1.请输入两个整数a,b,若a²+b²>100,则打印出a²+b²的结果,否则打印出a+b的结果. 2.有一组函数,y=x(x<1),y=2x-1(1<=x<10),y=3x- ...
- 第 13 章 剖析el表达式
13.1. 再谈el(Expression Language) 我们已经知道el是jsp-2.0规范的一部分,tomcat-5.x版本以上都已经能够支持jsp-2.0规范,但在更低版本的tomcat和 ...
- CSS3初学篇章_5(背景样式/列表样式/过渡动画)
背景样式 1.背景颜色语法:background-color : transparent | color body { background-color:#CCCCCC;} 2.渐变色彩语法:back ...
- Android中layout_gravity和gravity的区别
安卓中的 layout_gravity 属性和 gravity属性 有啥区别? LinearLayout有两个非常相似的属性: android:gravity与android:layout_gravi ...