C++代码实现扫雷游戏

前言

提示:本文是基于easyX图形库实现的,还有部分功能可以添加,仅适合新手参考。

提示:以下是本篇文章正文内容,下面案例可供参考

一、扫雷游戏模式

在确定大小的矩形雷区中随机布置一定数量的地雷,玩家需要尽快找出雷区中的所有不是地雷的方块,而不许踩到地雷。
游戏的基本操作包括左键单击和右键单击。其中左键用于打开安全的格子,推进游戏进度;右键用于标记地雷,以辅助判断。
左键单击:在判断出不是雷的方块上按下左键,可以打开该方块。如果方块上出现数字,则该数字表示其周围3×3区域中的地雷数(一般为8个格子,对于边块为5个格子,对于角块为3个格子。所以扫雷中最大的数字为8);如果方块上为空(相当于0),则可以递归地打开与空相邻的方块;如果不幸触雷,则游戏结束。
右键单击:在判断为地雷的方块上按下右键,可以标记地雷(显示为小红旗)。重复一次或两次操作可取消标记。

二、代码实现

1.绘制地图场景

根据每一块地区的数据进行图形输出。

代码如下(示例):

void drawmap(int map[][12],IMAGE *img)
{
 int i, j;
 for (i = 1; i <= 10; i++)
 {
 for (j = 0; j <= 10; j++)
 {
 int x = 50 * (i - 1);//得到位置
 int y = 50 * (j - 1);
 if (map[i][j]>25)
 {
 putimage(x, y, &img[9]);//标记flag
 }
 else
 {
 switch (map[i][j])
 {
 case 9:
  putimage(x, y, &img[11]);//输出图片雷
  break;
 case 10:
  putimage(x, y, &img[0]);//0
  break;
 case 11:
  putimage(x, y, &img[1]);//1
  break;
 case 12:
  putimage(x, y, &img[2]);//2
  break;
 case 13:
  putimage(x, y, &img[3]);//3
  break;
 case 14:
  putimage(x, y, &img[4]);//4
  break;
 case 15:
  putimage(x, y, &img[5]);//5
  break;
 case 16:
  putimage(x, y, &img[6]);//6
  break;
 case 17:
  putimage(x, y, &img[7]);//7
  break;
 case 18:
  putimage(x, y, &img[8]);//8
  break;
 default:
  putimage(x, y, &img[10]);//地图
  break;
 }
 }
 }
 }
}

2.鼠标点击

鼠标左键点击翻开格子,右键点击标记flag,再次点击可以进行取消。
sum记录翻开格子的数量,点击后对每个位置的数据进行加减操作。

代码如下(示例):

int mousedown(int map[][12])
{
 MOUSEMSG m; //定义鼠标消息变量
 while (1)
 {
 //获取鼠标消息
 m = GetMouseMsg();
 int mi = m.x / 50 + 1;
 int mj = m.y / 50 + 1;

 //判断鼠标消息
 switch (m.uMsg)
 {
 case WM_LBUTTONDOWN:
 if (map[mi][mj] > 9) //已翻开的情况
 {
 continue;
 }
 if (map[mi][mj] == 0) //如果点击为0,则翻开一片。
 {
 //使用递归函数
 swap(map, mi, mj);
 }
 else
 {
 map[mi][mj] += 10;
 sum += 1;
 }
 return map[mi][mj];
 break;
 case WM_RBUTTONDOWN:
 if (map[mi][mj] > 9&& map[mi][mj] < 25) //已翻开的情况
 {
 continue;
 }
 if (map[mi][mj] > 25) //再次点击取消flag
 {
 map[mi][mj] -= 30;
 }
 else
 {
 map[mi][mj] += 30;
 }
 return map[mi][mj];
 break;
 }
 }
}

3.递归

当我们点到为0的地区时,将会打开周围的部分地区,外围为非0数或到达边界,内部为0.
如图:

代码如下(示例):

void swap(int map[][12],int mi,int mj)
{
 map[mi][mj] = 10;
 sum += 1;
 for (int i = mi - 1; i <= mi + 1; i++)
 {
 for (int j = mj - 1; j <= mj + 1; j++)
 {
 //数组下标不能越界
 if (i >= 1 && i <= 10 && j >= 1 && j <= 10)
 {
 //翻开的只能是数字
 if (map[i][j] < 9)
 {
  //如果为0,则进行递归。
  if (map[i][j] == 0)
  {
  swap(map, i, j);
  }
  else
  {
  map[i][j] += 10;
  sum += 1;
  }
 }
 }
 }
 }
}

4.初始化游戏

代码如下(示例):

void startgame()
{
 initgraph(500, 500); //初始化地图500x500
 int map[12][12] = { 0 };
 int i,j,m,n;
 //随机函数种子
 srand((unsigned int)time(NULL));
 //随机生成10个雷
 for (n = 0; n < 10;)
 {
 i = rand() % 10 + 1; //[1,10]
 j = rand() % 10 + 1;
 if (map[i][j] == 0) //排除本来就有雷的情况
 {
 map[i][j] = -1; //-1表示有雷
 n++;
 }
 }
 //产生数字
 for (i = 1; i <= 10; i++)
 {
 for (j = 1; j <= 10; j++)
 {
 //排除是雷的情况
 if (map[i][j] != -1)
 {
 for (m = i - 1; m <= i + 1; m++) //判断周围是否有雷
 {
  for (n = j - 1; n <= j + 1; n++)
  {
  if (map[m][n] == -1)
  {
  map[i][j]++;
  }
  }
 }
 }
 }
 }
 IMAGE img[12]; //定义图片变量
 loadimage(&img[0], "E:\\C++ project\\minesweeping\\0.jpg", 50, 50);
 loadimage(&img[1], "E:\\C++ project\\minesweeping\\1.gif", 50, 50);//加载图片
 loadimage(&img[2], "E:\\C++ project\\minesweeping\\2.gif", 50, 50);
 loadimage(&img[3], "E:\\C++ project\\minesweeping\\3.gif", 50, 50);
 loadimage(&img[4], "E:\\C++ project\\minesweeping\\4.gif", 50, 50);
 loadimage(&img[5], "E:\\C++ project\\minesweeping\\5.gif", 50, 50);
 loadimage(&img[6], "E:\\C++ project\\minesweeping\\6.gif", 50, 50);
 loadimage(&img[7], "E:\\C++ project\\minesweeping\\7.gif", 50, 50);
 loadimage(&img[8], "E:\\C++ project\\minesweeping\\8.gif", 50, 50);
 loadimage(&img[9], "E:\\C++ project\\minesweeping\\flag.gif", 50, 50);
 loadimage(&img[10], "E:\\C++ project\\minesweeping\\地图.gif", 50, 50);
 loadimage(&img[11], "E:\\C++ project\\minesweeping\\雷.gif", 50, 50);
 while (1)
 {
 drawmap(map, img);
 //点到地雷
 if (mousedown(map)==9)
 {
 sum = 0; //重置判断变量
 drawmap(map, img);
 MessageBox(hwnd,"你踩到雷了!","Game Over",MB_OK);
 return;
 }
 //成功完成游戏
 if (sum == 90)
 {
 sum = 0; //重置判断变量
 drawmap(map, img);
 MessageBox(hwnd, "你成功完成了游戏!", "Game Over", MB_OK);
 return;
 }
 }
}

5.main

代码如下(示例):

#include<iostream>
#include<time.h>
#include<graphics.h> //图形库头文件 easyx
#include <conio.h> //调用_getch函数
using namespace std;
HWND hwnd;
int sum = 0;//用于表示目前已经点开的格子数
//声明函数
void drawmap(int map[][12], IMAGE* img);
int mousedown(int map[][12]);
void swap(int map[][12], int mi, int mj);
//初始化游戏

//绘制地图

//鼠标点击

//递归函数

int main()
{
 while (1)
 {
 startgame();
 if (MessageBox(hwnd, "再来一次", "结束游戏", MB_YESNO)==IDNO)
 break;
 }
 //_getch(); //防止闪屏
 closegraph();
 return 0;
}

总结及运行

提示:本代码仅供参考,编译器为visual studio
图片资源可以在网上找找,将其放到对应的目录即可。

运行结果如图:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C++实现简单的扫雷游戏(控制台版)

    C++新手的代码,请各位多包涵. 用C++写的一个简单的控制台版扫雷游戏.玩家通过输入方块的坐标来翻开方块. 只是一个雏形,能够让玩家执行翻开方块的操作并且判断输赢,还未添加标记方块.游戏菜单.记录游戏时间.重新开一局等等的功能. 玩家输入坐标的方式来翻开方块只适用于小型的"雷区",若"雷区"大了,用坐标会变得很不方便. 代码片段扫雷V1.1 #include<stdio.h> #include<Windows.h> #define YELL

  • C++实现简单扫雷游戏

    扫雷是一个经典的电脑小游戏,用C++来编一下,效果自己试一下 #include<stdio.h> #include<Windows.h> #define YELLOW FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY #define CYAN FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY #define ORANGE FOREGROUND_RED |

  • 利用c++和easyx图形库做一个低配版扫雷游戏

    游戏界面 由于这个游戏是我抱着玩一玩的心态做出来的,所以没有过多的去设计界面,也没有去找游戏的资源(图片.游戏音效等).仅使用了不同颜色的方块来表示游戏中方块的状态和种类.(绿色为初始状态(未翻转的状态),黄色为翻转后的背景颜色,蓝色表示已插旗的方块,红色代表地雷) 图1 游戏主菜单界面 图二 模式一的游戏界面(20*20 40个雷) 图三 模式二的游戏界面(10*10 20个雷) 图四 游戏成功界面 图五 游戏失败界面 2.全部代码 #include<graphics.h> #include

  • C++实现一个扫雷小游戏

    本文实例为大家分享了C++实现扫雷小游戏的具体代码,供大家参考,具体内容如下 目前的版本是0.98版本,可以提出增加新功能意见哦 代码如下: #include<bits/stdc++.h> #include<windows.h> using namespace std; long long int c,dev,m,k,cnt,d,e,jie=10,z,abc,n,b[1000][1000],a[1000][1000],cc,cd,ce,def; //c是随机行,k是随机列 bool

  • C++实现扫雷小游戏(控制台版)

    本文为大家分享了C++实现扫雷小游戏的具体代码,供大家参考,具体内容如下 程序功能: 提供三种模式:初级.中级.高级 操作模式:wsad控制光标移动,空格键打开方块 提供扫雷地图的类 map.h #ifndef MAP_H_ #define MAP_H_ #define MAX_LENGTH 32 //可以提供的地图最大长度 #define MAX_WIDTH 18 //可以提供的地图最大宽度 #define UP_EDGE 1 //上边界 #define DOWN_EDGE _wid //下边

  • C++基于EasyX实现简单扫雷游戏

    本文实例为大家分享了C++ EasyX实现简单扫雷游戏的具体代码,供大家参考,具体内容如下 [实现代码] #include <cmath> #include <time.h> #include <easyx.h> #include <conio.h> using namespace std; #define Size 500 //定义窗口大小 #define SquareSize 50 //定义格子大小 #define BackGroundColor LIG

  • C++扫雷游戏的简单制作

    本文实例为大家分享了C++实现扫雷游戏的具体代码,供大家参考,具体内容如下 #ifndef SAOLEI_H #define SAOLEI_H class Block { friend class Saoleigame; public: Block(); bool isShown(); void setnum(int); int getnum(); bool isbomb(); protected: int num; bool flag_show; int x; int y; }; class

  • C++学习心得之扫雷游戏

    本文实例为大家分享了C++实现扫雷游戏的具体代码,供大家参考,具体内容如下 一.序言 创建一个9*9有10个雷的扫雷游戏 文章的顺序是按照我当时的编程顺序写的,顺便写下我当初的一点思路,总的代码在文章最后,前面的都是分散的函数,有需要的朋友直接复制最后的 二.创建 创建一个头文件,一个放游戏的程序,一个放运行测试的程序 #define _CRT_SECURE_NO_WARNINGS 1 #include<stdlib.h>//生成随机数 #include<stdio.h> #inc

  • C++实现扫雷经典小游戏

    用C++复现经典扫雷,供大家参考,具体内容如下 主要是dfs实现打开一片的操作,数字带有颜色,很真实. windows扫雷中鼠标左右键同时按也实现了,即试探. 先上图,详见下面代码: 代码中有详细注释,编译无任何错误警告. Ps.有bug请评论指出,谢谢啦~ 另外我觉得代码比较臃肿,有什么可以优化的也请提出~ #include<cstdio> #include<cstring> #include<algorithm> #include<conio.h> #i

  • C++实现扫雷游戏(控制台不闪屏版)

    之前写了一个C++ 的控制台扫雷小游戏,但由于过度使用system("cls")刷屏,导致闪屏,因此重写了一个改善的不闪屏版本,并把逻辑重新捋了一遍. map.h #ifndef MAP_H_ #define MAP_H_ #define MAX_WID 18 #define MAX_LEN 32 #define UP_EDGE 1 //上边界 #define LEFT_EDGE 1 //左边界 #define RIGHT_EDGE _len //右边界 #define DOWN_ED

随机推荐