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

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

代码片段扫雷V1.1

#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 | FOREGROUND_GREEN | FOREGROUND_INTENSITY
#define PURPLE FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY

using namespace std;

const int STARTX = 30;
const int STARTY = 6;
const int MAXX = 9;//雷区的宽
const int MAXY = 9;//雷区的高
const int BOMBNUMBER = 10;//地雷数量

class Cube{
private:
  bool ifHaveBomb;//该方块是否含有炸弹
  bool ifOpen;//该方块有无被玩家翻开
  int nearBombNumber;//该区块周围8格的含有炸弹的方块的数量
public:
  void setOpen() {
    //将Open的值改为true
    ifOpen = true;
  }
  bool getOpen() {
    //获取ifOpen的值
    return ifOpen;
  }
  void setNearBombNumber(int number) {
    //给nearBombNumber赋值
    nearBombNumber = number;
  }
  void haveBomb() {
    //给方块放置地雷
    ifHaveBomb = true;
  }
  bool getIfHaveBomb() {
    //获取ifHaveBomb的值
    return ifHaveBomb;
  }
  int getNearBombNumber() {
    //获取nearBombNumber的值
    return nearBombNumber;
  }
  void resetCube(bool ifhavebomb = false, bool ifopen = false, int nearbombnumber = 0){
    //初始化成员数据
    ifHaveBomb = ifhavebomb;
    ifOpen = ifopen;
    nearBombNumber = nearbombnumber;
  }
};
Cube cube[MAXX][MAXY];

void GoTo(int x, int y);//定位光标
void setBomb(int bombNumber);//生成bombNumber个炸弹并且放进随机的方块中
void show();//显示地雷阵
int checkAndSetNearBombNumber(int x, int y);//检查当前方块周围的雷数量
void gameStart();//初始化游戏
void showXY();//显示雷区坐标
bool player(bool &life);//玩家输入坐标翻开方块
void message(bool life);//玩家游戏结束后输出的信息
void autoOpen(int x,int y);//玩家翻开的方块为不含雷且周围无雷的方块时,自动翻开周围无雷的方块
bool ifWin();//判断玩家是否扫雷成功
void showBomb();//游戏结束后显示地雷位置

int main() {

  gameStart();
  show();
  bool life = true, win = true;
  while (player(life) && !ifWin()) {
  }
  message(life && ifWin());
  return 0;
}

void GoTo(int x, int y) {
  //定位光标
  COORD coord = { x,y };
  SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}

void setBomb(int bombNumber = BOMBNUMBER) {
  //生成bombNumber个炸弹并且放进随机的方块中
  srand((unsigned)GetCurrentTime());
  while (bombNumber--) {
    int x = MAXX + 1, y = MAXY + 1;
    while ((x >= MAXX || y >= MAXY) || cube[x][y].getIfHaveBomb() == true) {
      x = rand() % MAXX;
      y = rand() % MAXY;
    }
    cube[x][y].haveBomb();
  }
}

void show() {
  //显示地雷阵
  system("cls");
  showXY();
  SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), CYAN);
  for (int i = 0;i < MAXY;i++) {
    GoTo(STARTX, STARTY + i);
    for (int j = 0;j < MAXX;j++) {
      if (cube[j][i].getOpen() == true) {
        if (cube[j][i].getIfHaveBomb() == false) {
          if (cube[j][i].getNearBombNumber() == 0) { //挖开无雷的方块显示该方块周围多少个方块含雷,若为0则显示空格
            printf(" ");
          } else {
            printf(" %d", cube[j][i].getNearBombNumber());
          }
        } else {
          printf("×");//有雷的方块被挖开后显示×
        }
      } else {
        printf("■");//未翻开的方块用■显示
      }
    }
  }
}

void showXY() {
  //显示坐标轴
  SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), CYAN);
  GoTo(STARTX - 3, STARTY + MAXY / 2);
  printf("Y");
  GoTo(STARTX + MAXX, STARTY - 2);
  printf("X");
  SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), YELLOW);
  for (int i = 0;i < MAXY;i++) {
    GoTo(STARTX - 1, STARTY + i);
    printf("%d ", i);
  }
  for (int i = 0;i < 2 * MAXX;i += 2) {
    GoTo(STARTX + i + 1, STARTY - 1);
    printf("%d ", i / 2);
  }
}

int checkAndSetNearBombNumber(int x, int y) {
  //检查当前方块周围的雷数量
  int num = 0;

  if (cube[x][y].getIfHaveBomb() == true) {
    //若该方块有地雷,则不用判断它周围有几个雷
    return 0;
  } else {
    //用两个循环当前方块周围8格扫一遍
    for (int i = -1; i <= 1; i++) {
      for (int j = -1; j <= 1; j++) {
        int nx = x + i;
        int ny = y + j;
        if (!(ny == y && nx == x) && (nx >= 0 && nx <= MAXX - 1) &&
          (ny >= 0 && ny <= MAXY - 1)) {
          if (cube[nx][ny].getIfHaveBomb()) {
            num++;
          }
        }
      }
    }
    cube[x][y].setNearBombNumber(num);//设置该方块附近的地雷的数量
    return 0;
  }
}

void gameStart() {
  //初始化游戏
  for (int i = 0;i < MAXY;i++) {
    for (int j = 0;j < MAXX;j++) {
      cube[j][i].resetCube();
    }
  }
  setBomb();
  for (int i = 0;i < MAXY;i++) {
    for (int j = 0;j < MAXX;j++) {
      checkAndSetNearBombNumber(j, i);
    }
  }
}

bool player(bool &life) {
  //玩家输入坐标翻开方块
  int x, y;
  GoTo(STARTX - 3, STARTY + MAXY + 1);
  printf("请输入坐标(x,y),x和y用空格隔开");
  GoTo(STARTX + MAXX / 2, STARTY + MAXY + 2);
  scanf("%d%d", &x, &y);
  if ((x < 0) || (x > MAXX - 1) || (y < 0) || (y > MAXY - 1)) {
    //当玩家输入的坐标超出范围时
    show();
    GoTo(STARTX - 3, STARTY + MAXY + 3);
    printf("该坐标不存在,请重新输入坐标");
    GoTo(STARTX + MAXX / 2, STARTY + MAXY + 2);
  } else if (cube[x][y].getIfHaveBomb() == true) {
    //当玩家翻开的方块有地雷时
    cube[x][y].setOpen();
    show();
    life = false;
    return false;
  } else if (cube[x][y].getOpen() == false) {
    //当玩家翻开的方块无雷时
    if (cube[x][y].getNearBombNumber() == 0) {
      autoOpen(x, y);
      cube[x][y].setOpen();
      show();
    } else {
      cube[x][y].setOpen();
      show();
    }
  } else if (cube[x][y].getOpen() == true) {
    //当玩家输入已翻开方块的坐标时
    show();
    GoTo(STARTX, STARTY + MAXY + 3);
    printf("该方块已被挖开,请再次输入坐标");
    GoTo(STARTX + MAXX / 2, STARTY + MAXY + 2);
  }
  ifWin();
  return true;
}

void message(bool result) {
  if (result == true) {
    //玩家胜利时输出的信息
    showBomb();
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), YELLOW);
    GoTo(STARTX - 1, STARTY + MAXY + 1);
    printf("祝贺你,你胜利了!");
    GoTo(STARTX, STARTY + MAXY + 2);
  } else {
    //玩家失败时输出的信息
    showBomb();
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), PURPLE);
    GoTo(STARTX - 1, STARTY + MAXY + 1);
    printf("××你踩中地雷了××");
    GoTo(STARTX, STARTY + MAXY + 2);
  }
}

void autoOpen(int x, int y) {
  //玩家翻开的方块为不含雷且周围无雷的方块时,自动翻开周围无雷的方块
  for (int i = -1; i <= 1; i++) {
    for (int j = -1; j <= 1; j++) {
      int nx = x + i;
      int ny = y + j;
      if (!(ny == y && nx == x) && (nx >= 0 && nx <= MAXX - 1) &&
        (ny >= 0 && ny <= MAXY - 1) && cube[nx][ny].getOpen() == false) {
        if (cube[nx][ny].getNearBombNumber() == 0) {
          cube[nx][ny].setOpen();
          autoOpen(nx, ny);
        } else {
          cube[nx][ny].setOpen();
        }
      }
    }
  }
}

bool ifWin() {
  //判断玩家是否扫雷成功达到游戏结束条件
  int num = 0;
  for (int i = 0;i < MAXX;i++) {
    for (int j = 0;j < MAXY;j++) {
      if (cube[j][i].getOpen() == false) {
        num++;
      }
    }
  }
  if (num == BOMBNUMBER) {
    return true;
  } else {
    return false;
  }
}

void showBomb() {
  //游戏结束后显示地雷位置
  for (int i = 0;i < MAXY;i++) {
    for (int j = 0;j < MAXX;j++) {
      if (cube[j][i].getIfHaveBomb() == true) {
        cube[j][i].setOpen();
      }
    }
  }
  show();
}

效果图:

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

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索c++
, 游戏
扫雷
java扫雷代码简单实现、扫雷c语言最简单代码、控制台扫雷、c语言实现简单数据库、链表c语言实现 简单,以便于您获取更多的相关知识。

时间: 2024-08-22 17:01:16

C++实现简单的扫雷游戏(控制台版)_C 语言的相关文章

C语言实现的猜拳游戏代码分享_C 语言

这是一个简单的猜拳游戏(剪子包子锤),让你与电脑对决.你出的拳头由你自己决定,电脑则随机出拳,最后判断胜负. 下面的代码会实现一个猜拳游戏,让你与电脑对决.你出的拳头由你自己决定,电脑则随机出拳,最后判断胜负. 启动程序后,让用户出拳,截图: 用户出拳,显示对决结果:截图: 代码实现: #include <stdio.h> #include <stdlib.h> #include <time.h> int main() { char gamer; // 玩家出拳 int

C语言借助EasyX实现的生命游戏源码_C 语言

本文讲述C语言借助EasyX实现的生命游戏,具体操作流程如下: 1.生命游戏内容: 该游戏包括一个二维矩形世界,这个世界中的每个方格居住着一个活着的或死了的细胞.一个细胞在下一个时刻生死取决于相邻八个方格中活着的细胞的数量.如果一个细胞周围的活细胞数量多于 3 个,这个细胞会因为资源匮乏而在下一个时刻死去:如果一个位置周围有 3 个活细胞,则该位置在下一个时刻将诞生一个新的细胞:如果一个位置周围有 2 个活细胞,则该位置的细胞生死状态保持不变:如果一个细胞周围的活细胞少于 2 个,那么这个细胞会

经典扫雷游戏Web版

在网页上扫雷 GameMode: Beginner 初级设置 Width:7 Height:7 Mine:10. Intermediate 中级设置 Width:15 Height:15 Mine:40. Expert 高级设置 Width:30 Height:15 Mine:99. Random 随机模式. CustomerSetting: 用户自定义扫雷的 Width Height Mine. Performance Test: 测试游戏在浏览器上的反应. Game Record: 游戏记录

用VC++6.0的控制台实现2048小游戏的程序_C 语言

首先感谢这位大侠的无私分享,仔细学习这个程序以后收获很多,试着添加一些注释 源程序是从开源中国看到的,原作者是 刘地(sir?) 地址为http://www.oschina.net/code/snippet_593413_46040 geek_monkey于2015年3月5日为拜读该程序,受益匪浅 为了方便自己,以及更多初学者阅读,我试着写了写了注释供参考 我是C语言初学者,如有错误希望指正.轻喷 复制代码 代码如下: #include <stdlib.h> #include <stdi

C++简单输出钻石菱形图效果_C 语言

本文实例讲述了C++简单输出钻石菱形图效果的方法.分享给大家供大家参考,具体如下: /* * 作 者: 刘同宾 * 完成日期:2012 年 11 月 25 日 * 版 本 号:v1.0 * 输入描述: * 问题描述: 设计和输出钻石图形. * 程序输出: * 问题分析:略 * 算法设计:略 */ #include<iostream> using namespace std; int main() { char a[][5]={{' ',' ','*'},{' ','*',' ','*'},{'

简单的socket编程入门示例_C 语言

功能简单实现client输入内容发送到server端输出 复制代码 代码如下: #include <stdio.h>#include <iostream>#include <winsock2.h>#pragma comment(lib, "ws2_32.lib")using namespace std;int main() { // 初始化 Winsock. WSADATA wsaData; int iResult = WSAStartup( MAK

C语言kmp算法简单示例和实现原理探究_C 语言

以前看过kmp算法,当时接触后总感觉好深奥啊,抱着数据结构的数啃了一中午,最终才大致看懂,后来提起kmp也只剩下"奥,它是做模式匹配的"这点干货.最近有空,翻出来算法导论看看,原来就是这么简单(下不说程序实现,思想很简单). 模式匹配的经典应用:从一个字符串中找到模式字串的位置.如"abcdef"中"cde"出现在原串第三个位置.从基础看起 朴素的模式匹配算法 A:abcdefg  B:cde 首先B从A的第一位开始比较,B++==A++,如果全

C++实现哈夫曼树简单创建与遍历的方法_C 语言

本文以实例形式讲述了C++实现哈夫曼树简单创建与遍历的方法,比较经典的C++算法. 本例实现的功能为:给定n个带权的节点,如何构造一棵n个带有给定权值的叶节点的二叉树,使其带全路径长度WPL最小. 据此构造出最优树算法如下: 哈夫曼算法: 1. 将n个权值分别为w1,w2,w3,....wn-1,wn的节点按权值递增排序,将每个权值作为一棵二叉树.构成n棵二叉树森林F={T1,T2,T3,T4,...Tn},其中每个二叉树都只有一个权值,其左右字数为空 2. 在森林F中选取根节点权值最小二叉树,

利用C语言实现2048小游戏的方法_C 语言

准备工作 首先上一张图,因为这里只是在用C语言验证算法,所以没有对界面做很好的优化,丑是理所应当的. 了解了游戏的工作原理,实际上可以将游戏描述为四个带有方向的同一操作:     1.将所有数字向一个方向移动至中间没有空位     2.将相邻的两个相同的数字加和然后放在更靠近移动方向前部的一个位置上 另外需要判断一下玩家当前输入的内容是否可以执行,如果不可以执行等待用户下一条记录. 同时需要对游戏的进程进行控制,如果可以继续游戏,那么运行玩家继续输入下一条指令,而如果不可以进行,那么提示无法继续