国庆小长假,当大家都去看人山人海的时候,我独自一人狂码代码。这两天想要实现的内容是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. 【BZOJ3207】花神的嘲讽计划I 可持久化线段树/莫队

    看到题目就可以想到hash 然后很自然的联想到可持久化权值线段树 WA:base取了偶数 这道题还可以用莫队做,比线段树快一些 可持久化线段树: #include<bits/stdc++.h&g ...

  2. BZOJ4499: 线性函数

    Description 小C最近在学习线性函数,线性函数可以表示为:f(x) = kx + b.现在小C面前有n个线性函数fi(x)=kix+bi ,他对这n个线性函数执行m次操作,每次可以: 1.M ...

  3. mysql 存储过程,搞死人的语法

    MySQL 真心不如sqlserver灵活 存储过程注意事项: 1.declare 依次声明 DECLARE MyAccountID VARCHAR (36); DECLARE Balance DEC ...

  4. Windows Phone 8 Sync

    A lot of the below depends on the types of data, how often it is changing, and how often it is likel ...

  5. How to pull Android database to local file system

    >adb shell# ls /data/data/PACKAGE_NAME/databases# exit// pull it>adb pull /data/data/PACKAGE_N ...

  6. Oracle 部分函数使用说明

    oracle有些函数可能我知道是什么作用,但是具体其实说不清楚,这里是我这几天看到的函数使用方法及说明,记录一下,以后看看 --1.replace('str',oldVal,newVal)替换功能方法 ...

  7. 8点需要注意的Web编程小细节

  8. PowerDesigner的使用二

    PowerDesigner是一款功能非常强大的建模工具软件,足以与Rose比肩,同样是当今 最著名的建模软件之一.Rose是专攻UML对象模型的建模工具,之后才向数据库建模发展,而PowerDesig ...

  9. NFS服务器搭建

    1. 安装nfs-kernel-server,然后编辑/etc/exports. /sambadata/nfsserver    10.0.0.0/255.255.255.0(fsid=0,all_s ...

  10. Mysql5.5命令行修改密码

    今天下载了mysql5.5.45免安装版,配置好之后发现mysql默认是没有设置密码的,也就是密码为空. 如果是本机作开发测试用,有无密码倒也无所谓,不过发布在服务器上没有密码肯定是不行的,那就需要设 ...