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();
}

效果图:

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

(0)

相关推荐

  • C++基于控制台实现的贪吃蛇小游戏

    本文实例讲述了C++基于控制台实现的贪吃蛇小游戏.分享给大家供大家参考.具体实现方法如下: #include <windows.h> #include <time.h> #include <stdio.h> #define MAX 100 #define UP 1 #define DOWN 2 #define LEFT 3 #define RIGHT 4 #define MOVING 5 #define STOP 0 HANDLE hMain_Out = NULL; H

  • VC++中的字体设置方法详解

    VC++中static text字体改变 窗口都有2个和字体有关的函数:CWnd::GetFont()和SetFont(CFont*, BOOL);1)CFont* pFont = m_static.GetFont(); 2)LOGFONT LogFont;pFont->GetLogFont(&LogFont); 3)对LogFont直接操纵修改里面的字体选项 //如LogFont.lfUnderline = 1;设置下划线 LogFont.lfHeight=30;       //字体大小

  • C语言控制台版2048小游戏

    效果不好,见谅,没事就写了一个!!! /** * @author Routh * @main.c * @date 2014, 4, 26 */ #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <windows.h> // console width #define CONSOLE_WIDTH 80 #define BOX_WIDTH 10 int BOX[4][4] = {

  • C/C++实现控制台输出不同颜色字体的方法

    本文实例讲述了C/C++实现控制台输出不同颜色字体的方法.分享给大家供大家参考,具体如下: 在控制台输出不同颜色的字 效果 代码: #include "stdio.h" #include "windows.h" int main(int argn, char **argv) { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN); printf("Hello&q

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

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

  • c语言在控制台判定鼠标左键的小例子

    复制代码 代码如下: // temp1.cpp : Defines the entry point for the console application. // //#include <stdafx.h> #include <windows.h> #include <conio.h> #include <stdlib.h> #include<stdio.h> int main(int argc, char* argv[]) {  SetCons

  • 原创的C语言控制台小游戏

    最开始左上色块被感染,通过切换颜色,不断感染同色色块.亮点是可以切换图案,设置方块个数和最大限制次数.整体还是比较满意,希望大神指教. #include <stdio.h> #include <windows.h> #include <conio.h> #include <time.h> #include <stdlib.h> int DIFFICULT=44; int count=0 ; int TYPE_SHAPE=2 ; int flag=

  • C++实现基于控制台界面的吃豆子游戏

    本文实例讲述了C++实现基于控制台界面的吃豆子游戏.分享给大家供大家参考.具体分析如下: 程序运行界面如下所示: ESC键可退出游戏. main.cpp源文件如下: #include "lib.h" #pragma once extern int level; int main() { FOOD food; WALL wall; BODY CurPos; HALL hall; int iExit = 0; while(1) { if(iExit) break; Init(&fo

  • java实现扫雷游戏控制台版

    本文实例为大家分享了java实现扫雷游戏控制台版,供大家参考,具体内容如下 扫雷游戏 a.游戏的分析 在游戏中需要存在对象包含哪些. 格子对象(Grid): 属性:内容(content).状态(type) b.工程架构 设计工程包结构 bean:存放实体类 core:游戏核心类(游戏操作) test:扫雷玩的测试类 c.编写类 Grid(属性:content.type) Core类–游戏核心类(雷区创建.显示雷区.布雷.踩雷) Test类–测试类 d.核心类设计 1.格子对象创建方法定义 2.显

  • Java实现五子棋游戏(控制台版)

    本项目为大家分享了Java实现五子棋游戏的具体代码,供大家参考,具体内容如下 该项目为Java编程语言编写的五子棋游戏(控制台版),用到二维数组.for循环.if语句.while()语句.Scanner Until包,此项目主要是对数组的使用.该项目的功能有落子.输出棋盘.判断输赢. 代码条: package edu.qizi.gam; import java.util.Scanner; public class GobangTest { public static void main(Stri

  • C语言实现一个简单的扫雷游戏

    前言 扫雷跟上一篇文章的三子棋一样,是C语言基础知识的综合运用的实例,对于巩固我们的基础知识非常重要,同时扫雷作为C语言的一个小项目,锻炼我们的编程思维,也是一个不可多得的实践. 提示:以下是本篇文章正文内容 一.扫雷的基本思路 1.用C语言实现简单的扫雷,我们需要创建两个数组,一个数组存放雷的信息,另外一个数组存放排雷后结果的信息. 2.在创建数组时候,需要注意的是数组需要大一圈,什么意思?举个例子,比如说我们实现的是9 ×9的扫雷,那么我们的数组就得创建10×10.为什么呢? 原因如下: 因

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

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

  • C语言实现扫雷游戏简易版

    本文实例为大家分享了C语言实现扫雷游戏的简易版,供大家参考,具体内容如下 game.h #pragma once #include <stdio.h> #include <string.h> #include <time.h> #include <windows.h> #define ROW 12 #define COL 12 #define NUMS 20 #pragma warning(disable:4996) void Menu(); void Ga

  • C语言实现简单的扫雷游戏

    本文实例为大家分享了C语言实现简单扫雷游戏的具体代码,供大家参考,具体内容如下 前言 扫雷游戏规则: 1.踩过所有非雷格子即扫雷成功,踩到雷即游戏结束. 2.点击方格,如果出现数字,数字表示这个格子周围八个格子的雷的个数. 一.如何实现? 1.如何实现雷与雷周围的信息不冲突? 如果采用一个二维数组,1表示雷,0表示非雷,那么某一坐标周围如果雷的个数是1,就会与前面冲突,所以设定两个字符型(char)数组,数组mine用来存储雷的信息,数组show用来存放排查出来的雷的信息(周围八个格子中雷的个数

  • python实现简易五子棋游戏(控制台版)

    本文实例为大家分享了python实现简易五子棋游戏的具体代码,供大家参考,具体内容如下 运行效果: 完整代码+注释: finish = False # 游戏是否结束 flagNum = 1  # 当前下棋者标记 flagch = '*'  # 当前下棋者棋子 x = 0    # 当前棋子的横坐标 y = 0    # 当前棋子的纵坐标 print('---------五子棋游戏(控制台版)---------') # 棋盘初始化 checkerboard=[] for i in range(10

  • C语言实现简单的扫雷游戏操作

    扫雷小游戏的代码实现,供大家参考,具体内容如下 编译器使用的为VS2013 代码分为三个部分 1.头文件 game.h 2.源文件 game.c 用来存放游戏中所有的函数 3.源文件 test.c 用来存放游戏的主题部分 代码如下: game.h部分 #include<stdio.h> #include<time.h> #include<stdlib.h> #define EASY_COUNT 5 //存放雷的个数,此处为5,可任意改变 #define ROW 5 //

  • 基于C语言实现简单的扫雷游戏

    扫雷游戏的实现,必须要考虑其中包含的功能. 首先是在游戏开始时的初始界面,规定用户输入1则游戏开始,输入2则游戏结束,再去创建两个二维数组,一个存放用户看到的界面,一个存放埋雷的雷盘,在进行初始化两个二维数组,用户界面展示为一个10*10的界面,首行和首列存储'0'-'9',给用户直观的可以寻找想要搜索的元素,雷区初始化为' 0 ',用户界面初始化为'?'. 在进行雷位置的初始化,使用数字帧表示,用  数字帧%9+1  得到一个1-9的数字,可以取得一个[1-9][1-9]的坐标,建立一个 i

  • C语言实现自定义扫雷游戏(递归版)

    本文实例为大家分享了C语言自定义扫雷游戏的具体代码,供大家参考,具体内容如下 实现过程 对于用C语言实现扫雷游戏得实现,可将游戏过程分为两个板块. 实现游戏关键功能得函数 搭建合理得游戏过程 实现游戏关键功能 为了将游戏功能方便管理和键入,首先我们创建一个头文件,mine.h对游戏功能进行声明.然后创建对应的源文件mine.c对这些函数进行定义. 对于游戏功能,我们首先想到的是构建一个目标规格的雷盘,也就是二维数组.为了使游戏更具可玩性,所以雷盘的规格应可以自定义.所以在mine.h头文件中,应

随机推荐