国庆小长假,当大家都去看人山人海的时候,我独自一人狂码代码。这两天想要实现的内容是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. tornado 学习笔记1 引言

    从事软件开发这行业也快5年啦,其实从事的工作也不完全是软件开发,软件开发只是我工作中的一部分.其中包括课题研究.信息化方案设计.软件开发.信息系统监理.项目管理等工作,比较杂乱.开发的软件比较多,但是 ...

  2. SQL中union运算操作的理解

    在SQL中,对于并运算,可以使用union关键字. 例如: SELECT column_name(s) FROM table_name1 UNION SELECT column_name(s) FRO ...

  3. node.js开发中使用Node Supervisor实现监测文件修改并自动重启应用提高nodejs调试效率

    在开发或调试Node.js应用程序的时候,当你修改js文件后,总是要按下CTRL+C终止程序,然后再重新启动,即使是修改一点小小的参数,也 总是要不断地重复这几个很烦人的操作.这是因为Node.js ...

  4. Weka使用介绍

    (转) http://baidutech.blog.51cto.com/4114344/1033714/ 1.简介 数据挖掘.机器学习这些字眼,在一些人看来,是门槛很高的东西.诚然,如果做算法实现甚至 ...

  5. 用c#实现$.now()(1437813924915)的时间效果

    Convert.ToInt64((DateTime.UtcNow - Convert.ToDateTime("1970-01-01")).TotalMilliseconds)

  6. Handler消息传递机制

    引言: 出于性能优化考虑,Android的UI操作并不是线程安全的,这意味着如果有多个线程并发操作UI组件,可能导致线程安全问题. 为了解决这个问题,Android制定了一条简单的规则:只允许UI线程 ...

  7. 关于android端的json传输

    比较通用的传输方法 import java.util.ArrayList; import java.util.List; import org.apache.http.HttpEntity; impo ...

  8. PHP filesystem attack vectors

    http://www.ush.it/2009/02/08/php-filesystem-attack-vectors/ On Apr 07, 2008 I spoke with Kuza55 and ...

  9. 汇编基础知识之二debug的使用

    DEBUG的使用 (要在win32位习题下进行,win7 64位需要安装DosBox和debug这2个软件): 1:win64位下debug的使用教程: 下载debug.exe,这里我把debug放在 ...

  10. 对Oracle数据库坏块的理解

    1.物理坏块和逻辑坏块 在数据库中有一个概念叫做数据块的一致性,Oracle的数据块的一致性包括了两个层次:物理一致性和逻辑一致性,如果一个数据块在这两个层次上存在不一致性,那就对应到了我们今天要要说 ...