C++实现扫雷、排雷小游戏

本文实例为大家分享了C++实现扫雷、排雷小游戏的具体代码,供大家参考,具体内容如下

界面:

游戏思想: 

扫雷游戏:

1.随机给定雷点坐标

2.判断每个点的雷情况

3.由用户根据上下左右键到达指定位置,点击enter,翻开该点
        如果该点是雷点,此时翻开所有雷点,告知游戏结束
        非雷点,翻开该点坐标

代码:

#include<iostream>
#include<vector>
#include<sstream>
#include<algorithm>
#include<graphics.h>
#include<ctime>
#include<conio.h>

using namespace std;

#define WIDTH 500
#define HEIGHT 500
#define SIDE 50
#define THUNDERNUM 10
#define TOTALSCORE 100
#define EVERY_OF_DESC 5

int score = TOTALSCORE;
class Point {
public:
 int x;
 int y;
 Point() {}
 Point(int _x, int _y)
 :x(_x), y(_y)
 {}
 void setPoint(int x, int y) {
 this->x = x;
 this->y = y;
 }
 Point(const Point& xy)
 :x(xy.x), y(xy.y)
 {}
 bool operator<(const Point& xy)const {
 if (x <= xy.x)
 return true;
 return y <= xy.y;
 }
 Point& operator=(const Point& xy) {
 if (this != &xy) {
 x = xy.x;
 y = xy.y;
 }
 return *this;
 }
 bool operator==(const Point& xy) {
 return ((x == xy.x) && (y = xy.y));
 }
 bool operator!=(const Point& xy) {
 return !(*this == xy);
 }
};

class ThunderPoint {
private:
 vector<Point> storage;
 int num;
public:
 ThunderPoint(int _num = THUNDERNUM)
 :num(_num) {
 //初始化雷点位置
 int count = 0;
 while (count != num) {
 int x = (rand() % (WIDTH / SIDE)) * SIDE;//随机生成数据,使之在图形界面之中
 int y = (rand() % (HEIGHT / SIDE)) * SIDE;
 Point tem(x, y);
 int i = -1;
 bool flag = false;
 for (i = 0; i < storage.size(); i++) {
 if (tem == storage[i]) {
  flag = true;
  break;
 }
 }
 if (flag==false) {
 //说明没有重复
 storage.push_back(tem);
 count++;
 }
 }
 }
 vector<Point>& getThunderPoint() {
 //获得雷点位置
 return storage;
 }
 void drawThunderPoint() {
 auto it = storage.begin();
 while (it != storage.end()) {
 setfillcolor(RED);
 fillcircle((*it).x, (*it).y, SIDE / 2);
 ++it;
 }
 }
};

class Grid {
private:
 vector<vector<int>> nearbythunder;
 vector<vector<bool>> isopen;
 ThunderPoint thunder;
 Point currposition;
 Point preposition;
 vector<COLORREF> color;
public:
 bool isOver;
public:
 Grid()
 :thunder(10),currposition()
 {
 preposition.setPoint(0, 0);
 for (int i = 0; i < 10; ++i) {
 color.push_back(RGB(rand() % 256, rand() % 256, rand() % 256));
 }
 isOver = false;
 isopen.resize(HEIGHT / SIDE, vector<bool>(WIDTH / SIDE, false));
  nearbythunder.resize(HEIGHT/SIDE,vector<int>(WIDTH/SIDE,0));
 currposition.setPoint(0, 0);
 //先将雷点的位置标出来,标为数字 9
 //  任何一个点,他附近的雷点最多8个
 auto it = thunder.getThunderPoint().begin();
 while (it != thunder.getThunderPoint().end()) {
 int x = ((*it).x)/SIDE;
 int y = ((*it).y)/SIDE;
 nearbythunder[x][y] = 9;
 if (((y - SIDE/SIDE) >= 0) && (nearbythunder[x][y - SIDE/SIDE] != 9)) {
 nearbythunder[x][y - SIDE/SIDE]++;
 }
 if (((y - SIDE/SIDE) >= 0) && ((x - SIDE/SIDE) >= 0) && (nearbythunder[x - SIDE/SIDE][y - SIDE/SIDE] != 9)) {
 nearbythunder[x - SIDE/SIDE][y - SIDE/SIDE]++;
 }
 if (((y - SIDE/SIDE) >= 0) && ((x + SIDE/SIDE) < WIDTH/SIDE) && (nearbythunder[x + SIDE/SIDE][y - SIDE/SIDE] != 9)) {
 nearbythunder[x + SIDE/SIDE][y - SIDE/SIDE]++;
 }
 if (((x - SIDE/SIDE) >= 0) && (nearbythunder[x - SIDE/SIDE][y] != 9)) {
 nearbythunder[x - SIDE/SIDE][y]++;
 }
 if (((x + SIDE/SIDE) < WIDTH/SIDE) && (nearbythunder[x + SIDE/SIDE][y] != 9)) {
 nearbythunder[x + SIDE/SIDE][y]++;
 }
 if (((y + SIDE/SIDE) < HEIGHT/SIDE) && (nearbythunder[x][y + SIDE/SIDE] != 9)) {
 nearbythunder[x][y + SIDE/SIDE]++;
 }
 if (((y + SIDE/SIDE) < HEIGHT/SIDE) && ((x - SIDE/SIDE) >= 0) && (nearbythunder[x - SIDE/SIDE][y + SIDE/SIDE] != 9)) {
 nearbythunder[x - SIDE/SIDE][y + SIDE/SIDE]++;
 }
 if (((y + SIDE / SIDE) < HEIGHT / SIDE) && ((x + SIDE / SIDE) < WIDTH / SIDE) && (nearbythunder[x + SIDE / SIDE][y + SIDE / SIDE] != 9)) {
 nearbythunder[x + SIDE / SIDE][y + SIDE / SIDE]++;
 }
 ++it;
 }
 for (int i = 0; i < HEIGHT; i = i + SIDE) {
 setlinecolor(YELLOW);
 line(0, i, WIDTH, i);
 line(i, 0, i, HEIGHT);
 }
 }
 void keyDown()
 {
 char userKey = _getch();
 if (userKey == -32) // 表明这是方向键
 userKey = -_getch(); // 获取具体方向,并避免与其他字母的 ASCII 冲突
 setfillcolor(GREEN);
 preposition = currposition;
 switch (userKey)
 {
 case 'w':
 case 'W':
 case -72: //上
 {
 if (currposition.y - SIDE >= 0) {
 currposition.y -= SIDE;
 }
 }
 break;
 case 's':
 case 'S':
 case -80://下
 {
 if (currposition.y + SIDE < HEIGHT)
 currposition.y += SIDE;
 }
 break;
 case 'a':
 case 'A':
 case -75://左
 {
 if (currposition.x - SIDE >= 0)
 currposition.x -= SIDE;
 }
 break;
 case 'd':
 case 'D':
 case -77://右
 {
 if (currposition.x + SIDE < WIDTH) {
 currposition.x += SIDE;
 }
 }
 break;
 case '\r':
 {
 score -= EVERY_OF_DESC;
 settextstyle(10, 10, "楷体");
 settextcolor(GREEN);
 RECT rect;
 rect.left = WIDTH-100; rect.top = 100; rect.right = WIDTH; rect.bottom = 200;
 string ll = to_string(score);
 const char* str = ll.c_str();
 //drawtext(str, &rect, 1);

 //现在开始翻
 openOne(currposition);
 }
 break;
 }
 setlinecolor(BLACK);
 setlinestyle(1, 0);
 line(preposition.x, preposition.y, preposition.x + SIDE, preposition.y);
 setfillcolor(GREEN);
 setlinecolor(WHITE);
 setlinestyle(1, 2);
 line(currposition.x, currposition.y, currposition.x + SIDE, currposition.y );
 }
private:
 bool pred(bool x) {
 return x == true;
 }
 void openOne(const Point& cur) {
 //说明此时翻一个
 isopen[cur.x / SIDE][cur.y / SIDE] = true;
 //此时应该着色
 settextcolor(color[nearbythunder[cur.x/SIDE][cur.y/SIDE]]);
 RECT rect;
 settextstyle(SIDE, SIDE, "楷体");
 rect.left = cur.x; rect.top = cur.y; rect.right = cur.x + SIDE; rect.bottom = cur.y + SIDE;
 drawtext((to_string(nearbythunder[cur.x / SIDE][cur.y / SIDE])).c_str(), &rect, 1);
 int count = 0;
 for (int i = 0; i < HEIGHT / SIDE; ++i) {
 for (int j = 0; j < WIDTH / SIDE; ++j) {
 if (isopen[i][j] == true) {
  count++;
 }
 }
 }
 cout << count << endl;
 if (nearbythunder[cur.x / SIDE][cur.y / SIDE] == 9 || count==((WIDTH/SIDE)*(HEIGHT/SIDE)- THUNDERNUM)) {
 //说明游戏结束
 setfillcolor(RED);
 for (int i = 0; i < thunder.getThunderPoint().size(); i++) {
 fillcircle((thunder.getThunderPoint()[i]).x + SIDE / 2, (thunder.getThunderPoint()[i]).y + SIDE / 2, SIDE / 2);
 }
 settextcolor(WHITE);
 settextstyle(SIDE, SIDE, "楷体");
 rect.left = 0; rect.top = 4*SIDE; rect.right = WIDTH; rect.bottom = HEIGHT;
 drawtext("GAMEOVER!", &rect, 2);
 isOver = true;
 return;
 }
 }
};

int main() {
 initgraph(WIDTH, HEIGHT);//初始化界面
 srand((unsigned)time(NULL));//设置随机数据种子,以当前的时间戳为种子
 setbkcolor(RED);
 srand((unsigned)time(NULL));
 settextcolor(BLUE);
 setbkmode(TRANSPARENT); // 设置文字输出模式为透明c
 setbkcolor(HSLtoRGB(100, 0.3, 7.5f));
 Grid gr;
 while (gr.isOver==false) {
 gr.keyDown();
 }
 system("pause");
 clearcliprgn();
}

代码解读:

1.类之间的联系

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

(0)

相关推荐

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

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

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

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

  • 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

  • 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实现简单扫雷游戏

    本文实例为大家分享了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++实现扫雷小游戏的具体代码,供大家参考,具体内容如下 目前的版本是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++和easyx图形库做一个低配版扫雷游戏

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

  • 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++实现扫雷游戏(控制台版)

    本文实例为大家分享了C++实现扫雷游戏的具体代码,供大家参考,具体内容如下 需要开一个map.txt  写入地图 地图中 *表示空地   ; x表示地雷 ********** ********** **x******* ********** ********** ********** ********** ********** ********** 然后就是扫雷的控制台代码了,只简单的检测了一下 #include <stdio.h> #include <string.h> #def

  • C++实现扫雷游戏

    本文实例为大家分享了C++实现扫雷游戏的具体代码,供大家参考,具体内容如下 直接上代码 #include<stdio.h> #include<windows.h> #include<stdlib.h> #include<time.h> #include<conio.h> #include<queue> #include<ctype.h> #define A 17 //地图的高 #define B 17 //地图的宽 #de

随机推荐