国庆小长假,当大家都去看人山人海的时候,我独自一人狂码代码。这两天想要实现的内容是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++复现经典游戏——扫雷的更多相关文章

  1. C language 模拟 win的经典游戏——扫雷

    让我们在terminal下愉快的...扫雷 昨天跟奇葩霖聊起"雷区"这个敏感词汇,然后非常荣幸的... 应该轰炸不到我.. . 后来百无聊赖的去玩了把扫雷.然后发现我之前都是乱扫的 ...

  2. JY游戏之毁经典《扫雷》

    JY游戏之毁经典<扫雷> 这是一个经典的pc端游戏,一定的运气加一点数学常识,讲的是一个速度,这次,我利用js JY库重做了这款游戏,加了三次生命,过关难度,也兼容了移动端的触摸事件. 它 ...

  3. Javascript版经典游戏之《扫雷》

    翻出年初写的游戏贴上来,扫雷相信大家都玩过,先上图: 源码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN ...

  4. FC经典游戏还原之:松鼠大作战2

    版权声明:本文原创发布于博客园"优梦创客"的博客空间(id:raymondking123) 原帖地址:http://www.cnblogs.com/raymondking123/p ...

  5. Unity2017 经典游戏开发教程 算法分析与实现 (张帆 著)

    https://meta.box.lenovo.com/link/view/82c451b41ce34e81a4b34cb46747d3d5 第1章 熟悉Unity软件的操作 第2章 打地鼠 (已看) ...

  6. c++小游戏——扫雷

    #include<cstdio> #include<cstring> #include<algorithm> #include<conio.h> #in ...

  7. c语言小游戏-扫雷的完成

    C语言-扫雷游戏 本文将对此游戏做一个大致的概述,此代码适合初学者,编写软件使用了vs2017. 该代码可以实现如下功能: 1.用户可以选择3个难度,分别布置不同个数的雷. 2.随机数设置雷的位置. ...

  8. 经典游戏--24点--c++代码实现和总体思路(简单暴力向)

    24点 24点是一个非常经典的游戏,从扑克牌里抽4张牌,其中J=11,Q=12,K=13,然后经过+,-,*,/,(),的计算后,使得计算得值为24,例如抽到1,2,2,5四张牌,那么 (1+5)*( ...

  9. 技术分享:RxJS实战练习-经典游戏Breakout

    效果图 数据流分析 1.ticker$ 数据流 interval配合scheduler/animationFrame 作为游戏随时间变化的控制数据流 ticker$ = interval(this.T ...

随机推荐

  1. Java_解密ThreadLocal

    概述 相信读者在网上也看了很多关于ThreadLocal的资料,很多博客都这样说:ThreadLocal为解决多线程程序的并发问题提供了一种新的思路:ThreadLocal的目的是为了解决多线程访问资 ...

  2. nodejs之async异步编程

    1.什么是异步编程? 异步编程是指由于异步I/O等因素,无法同步获得执行结果时, 在回调函数中进行下一步操作的代码编写风格,常见的如setTimeout函数.ajax请求等等. 示例:  for (v ...

  3. 李洪强漫谈iOS开发[C语言-046]-统计输入字符个数

  4. jQuery获取cookie

    之前一直以为获取cookie的方法封装在了jQuery包中...没想到还得单独下jquery.cookie.js插件,不太好找,备份一份: /*! * jQuery Cookie Plugin v1. ...

  5. HTML静态网页 Window.document对象

    一.找到元素: docunment.getElementById("id"):根据id找,最多找一个:    var a =docunment.getElementById(&qu ...

  6. MarkMan – 马克鳗,让设计更有爱!

    scavin(Google+) on 2010.11.16. MarkMan – 马克鳗 是一款方便高效的标注工具,极大节省设计师在设计稿上添加和修改标注的时间,让设计更有爱.Adobe AIR 平台 ...

  7. redis虚拟机模拟集群,节点,增加多端口命令

    Redis启动多端口,运行多实例 使用redis在同一台机器上,启用多个端口,实现多个实例,完成集群的模拟实现. 启动多实例 redis默认启动端口为6379,我们可以使用 --port 来指定多个端 ...

  8. 执行JDBC的executeUpdate()方法时,报错:数据类型不一致,应为number,但却为binary

    该原因是因为,在拼写update语句的时候将一个number类型的字段的值赋为了null导致的,如果想将一个number类型的字清空,不能使用null,可以使用“”来替代.

  9. 2016HUAS暑假集训训练2 K - Hero

    题目链接:http://acm.hust.edu.cn/vjudge/contest/121192#problem/K 这也是一道贪心题,刚开始写时以为只要对每一敌人的攻击和血的乘积进行从小到大排序即 ...

  10. Chrome开发,debug的使用方法。

    怎样打开Chrome的开发者工具? 你可以直接在页面上点击右键,然后选择审查元素: 或者在Chrome的工具中找到: 或者,你直接记住这个快捷方式: Ctrl+Shift+I (或者Ctrl+Shif ...