当前位置:   article > 正文

C++完成扫雷代码(初步)_c++扫雷游戏代码和代码讲解

c++扫雷游戏代码和代码讲解

      这篇文章是用C++来简单讲解扫雷代码怎么实现。首先我们就得先理清代码思路,先看这张图片。

扫雷相似游戏下载预约_豌豆荚

       可以看到,游戏中的棋盘(我没实际看到的),没有被排除的地方就是灰白色方块,被掩盖,排查之后出现的数字,是代表这个地方周围一圈(八个位置)总共有多少个雷(随机位置),而旗帜是用来标记雷的(暂时不做实现)。那么在代码实现过程中,我们就需要做到扫雷棋盘的创建,随机放置雷,排查雷以及棋盘的打印。仅用C++,我们肯定暂时做不到正常游戏那样,所以我们就需要两个棋盘,一个棋盘给玩家看假设刚开始全是字符  *  ,每当我们选择排查的坐标时,就会进入到另一个隐藏的棋盘,同坐标下排查,与游戏的棋盘同呼应,这样说肯定会有点抽象,先看图

       至于为什么行列都加二,后面会说。当玩家输入坐标时,假如2 3,反应的其实是隐藏的棋盘,假如隐藏的棋盘2 3坐标布置了雷,游戏就结束了,假如没有雷,那么就会根据隐藏的棋盘的坐标2 3计算周围一圈有几个雷,再返回一个数据,输出到玩家看到的棋盘上。

 

一丶框架建设

#include<iostream>
using namespace std;
void menu()    //打印菜单
{
    cout << "***************************" << endl;
    cout << "***********1.play**********" << endl;
    cout << "***********0.exit**********" << endl;
    cout << "***************************" << endl;
}
int main()
{
    int n = 0;
    do 
    {
        menu();
        cout << "请输入:";
        cin >> n;
        switch (n)
        {
        case 1: break;
        case 0:cout << "游戏结束" << endl; break;
        default:cout << "输入错误,请重新输入" << endl; break;
        }
    } while (n);
    return 0;
}

       这里我们使用do while循环和switch来控制游戏的开始和结束,while循环的条件是n,1表示游戏开始并且循环继续,0表示结束,循环也会结束,执行效果如下,menu()函数随便写写就是了。

 二丶自定义头文件,函数的实现

       框架完成那就该写这个游戏需要的函数了,首先需要在源文件添加两个新项,鼠标右击源文件添加新建项,一个项名字写   头文件名称.h   , 另一个项名字写为   头文件名称.cpp

game.h项用来存放需要函数的声明以及一些定义的常量,game.cpp就是用来实现game.h声明后的函数。

1.棋盘的创建

 

       我们现在game.h里声明函数,在此之前,先定义一些常变量,表示棋盘矩阵的行和列,可以看到,这里的EasyNumber可以理解为简单模式(实际上就是雷的个数),我还定义了ROWS和COLS总是比ROW和COL多2,还是待会儿解释。再来看game()函数,是定义在  扫雷实现 的项里,它会调用已经实现的game.h里的函数。接下来就请看棋盘创建的代码

void Create(char chessboard[ROWS][COLS], int rows, int cols, char ch)  //创建棋盘
{
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            chessboard[i][j] = ch;
        }
    }
}

       在geme()函数中,我们已经事先定义了两个二维矩阵,我们可以看到Create()函数有四个变量,分别是数组,行,列,数组元素,而我们这里数组元素都用的char类型字符,这样可以做到创建几个数据类型相同的棋盘,用字符’0‘来表示隐藏棋盘没有雷的情况,所以等下我们布置雷就要用到字符’1‘。

2.布置雷

void MinePlace(char chessboard[ROWS][COLS])    
{
    int num = EasyNumber;
    int x, y;
    srand(time(NULL));
    while (num)
    {
        x = rand() % 10 + 1;
        y = rand() % 10 + 1;
        if (chessboard[x][y] == '0')
        {
            chessboard[x][y] = '1';
            num--;
        }
    }
}

       这个函数的实现还是很简单,但是这里用到了srand(),time()和rand()【资料来源于百度百科】,srand和rand的头文件都是<cstdlib>(C语言是<stdlib.h>),time()的头文件是<ctime>,然后rand()产生的随机数模上10+1就将产生的数字控制在1-10之间,分别赋值给x和y

再根据坐标将字符’0‘改成字符’1‘,只能原来是’0‘才会成功修改,并且使应该布置的雷个数减一,避免重复。

 3.打印棋盘

void Print(char chessboard[ROWS][COLS], int rows, int cols)   
{
    for (int i = 0; i <= rows; i++) {
        cout << i << " ";
    }
    cout << endl;
    for (int i = 1; i <= rows; i++) {
        cout << i << " ";
        for (int j = 1; j <= cols; j++) {
            cout << chessboard[i][j] << " ";
        }
        cout << endl;
    }
}

     三个变量,依次是数组,行,列,第一个for循环打印的第一行数字是让棋盘打印更加直观且美观,第二个for循环从1行1列开始打印,看打印效果就知道了。这个函数对所以棋盘都有效。

 4.排查雷

int MarkerMine(char chessboard[ROWS][COLS], int x, int y)
{
    return chessboard[x - 1][y - 1]
        + chessboard[x - 1][y]
        + chessboard[x - 1][y + 1]
        + chessboard[x][y - 1]
        + chessboard[x][y + 1]
        + chessboard[x + 1][y - 1]
        + chessboard[x + 1][y]
        + chessboard[x + 1][y + 1] - 8 * '0';
}
void FindMine(char gamemode[ROWS][COLS], char actualmode[ROWS][COLS], int row, int col)
{
    int x, y;
    int count = 0;
    int win = 0;
    while (win < row * col - EasyNumber)
    {
        cout << "请输入你要排查的坐标:";
        cin >> x >> y;
        if (x >= 1 && x <= row && y >= 1 && y <= col)
        {
            if (actualmode[x][y] == '1')
            {
                cout << "你被炸死了,游戏结束" << endl;
                Print(actualmode, ROW, COL); break;
            }
            else
            {
                count = MarkerMine(actualmode, x, y);
                gamemode[x][y] = count + '0';
                Print(gamemode, ROW, COL);
                win++;
            }
        }
        else
        {
            cout << "坐标非法,请重新输入" << endl;
        }
        if (win == row * col - EasyNumber)
            cout << "恭喜你,排查成功!" << endl;
    }
}

       这排查雷会讲到之前的疑惑,先看第二个函数,四个变量,依次是游戏棋盘,隐藏棋盘,行和列,变量count是用来存输入一个坐标后,如果该坐标不是雷,周围有多少个雷。变量win用来存储我们排查了多个次,如果等于   棋盘数-雷的个数(win == row * col - EasyNumber),那我们就排查成功。while循环我们没输入一个坐标,就会往隐藏棋盘反应,踩雷游戏就结束,没踩雷,就计算周围雷的个数,接下来就看第一个函数int MarkerMine(char chessboard[ROWS][COLS], int x, int y),进入到函数,我们发现就一个return函数还要一堆加法。

      假如我输入  4   5 (实际输入是 3  4)  坐标,看周围就两个1,此时我们知道ASCII码表知道字符’0‘是48,’1‘是49,’2‘是50,我们将周围每个坐标减去一个’0‘,就能得到一个整型数据,再相加,就能得到周围雷的个数,但这是整型,之后我们再将count加上一个’0‘,这样就变成ASCII值的雷的个数,然后在将这个值赋值给玩家看到的游戏棋盘再打印出来,再看坐标 7   3(实际输入是 6  2 ),此坐标周围多出来一行,实际上我们创建棋盘的时候都赋值为'0',所以依旧适用我们写的int MarkerMine(char chessboard[ROWS][COLS], int x, int y)函数

       这实际上是我们使用的棋盘,最外层是有字符'0'的,这里我写的数字代表行列,也是打印出来我们看见的,这也就是为什么我们要把行列都加二的原因

三丶代码展示

1.minesweeper.cpp

 

 2.game.h

 3.game.cpp

 

 

 

 

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/90882
推荐阅读
相关标签
  

闽ICP备14008679号