目录

1.扫雷游戏的分析与设计

2.扫雷游戏的代码实现


1.扫雷游戏的分析与设计

1.1扫雷游戏的功能说明

(1)通过控制台来实现游戏

(2)通过菜单选择继续游戏或结束

(3)在9*9的棋盘上实现

(4)随机布置10个雷

(5)排查雷,若位置不是雷,则显示周围有几个雷;若已排查了71个位置,则剩下的都是雷,排查成功;若排查到雷,游戏结束。

如图:

初始界面

       

扫雷过程

游戏结束

1.2.1扫雷游戏的设计

扫雷的过程中,布置的雷的信息和排查出雷的信息(即该位置周围有几颗雷)都需要储存,因为我们需要在9*9的棋盘上进行游戏,所以可以想到使用一个9*9的数组来分别储存。

0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
2 0 0 0 0 0 0 0 0 0
3 0 0 0 0 0 0 0 0 0
4 0 0 0 0 0 0 0 0 0
5 0 0 0 0 0 0 0 0 0
6 0 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 0

0

0
8 0 0 0 0 0 0 0 0 0

                                                                     9*9棋盘

如果这个地方有雷,则设为1,否则设为0。

如果随机布置10个雷

0 1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 1 0 0 0 0
2 0 0 1 0 0 0 1 0 0
3 0 0 0 0 0 0 0 0 0
4 0 0 0 1 0 0 1 0 0
5 0 1 0 0 0 0 1 0 0
6 0 0 0 1 0 0 0 0 0
7 1 0 0 0 0 0 0 0 0
8 0 1 0 0 0 0 0 1 0

假设我们排查(2,1),因为它周围有1个雷,则该位置显示1。

那如果我们排查(8,2),则会发生一些问题,因为它没有第9行,所以会发生“越界”,因此若想防止这种情况,可以将数组设置成11*11 。

0 1 2 3

4

5 6 7 8 9 10
0
1 0 0 0 0 0 0 0 0 0
2 0 0 0 1 0 0 0 0 0
3 0 0 1 0 0 0 1 0 0
4 0 0 0 0 0 0 0 0 0
5 0 0 0 1 0 0 1 0 0
6 0 0 0 0 0 1 0 0 0
7 0 0 0 1 0 0 0 0 0
8 1 0 0 0 0 0 0 0 0
9 0 1 0 0 0 0 0 1 0
10

周围加上一圈棋盘

继续分析,我们在棋盘上布置了雷,棋盘上雷的信息(1)和非雷的信息(0),假设我们排查了某个位置后,此坐标不是雷,周围有1个雷,那我们需要将排查出来的雷的数量信息记录储存,并打印出来,作为排雷的一个参考依据。那关于雷的个数我们应该存放在哪里?还是之前的布置雷的数组中吗?但这样可能雷的信息和雷的个数可能会产生混淆。

我们此时可能已经想到,既然有两个信息,那我们设置两个棋盘不就好了。对此,我们可以用一个棋盘(我给数组取名mine)存放布置好雷的信息,给另一个棋盘(我给数组取名show)存放排查出雷的信息。此时两数组互不干扰,将雷布置到mine数组,在mine数组中排查雷,将排查出的数据存放在show数组中,打印show数组供排查参考。

同时为保持神秘,show数组开始时初始化为‘*’,mine数组开始时初始化为字符‘0’,当设置成雷时,改成‘0’。

0 1 2 3

4

5 6 7 8 9 10
0
1 ‘0’ ‘0’ ‘0’ ‘0’ ‘0’ ‘0’ ‘0’ ‘0’ ‘0’
2 ‘0’ ‘0’ ‘0’ ‘1’ ‘0’ ‘0’ ‘0’ ‘0’ ‘0’
3 ‘0’ ‘0’ ‘1’ ‘0’ ‘0’ ‘0’ ‘1’ ‘0’ ‘0’
4 ‘0’ ‘0’ ‘0’ ‘0’ ‘0’ ‘0’ ‘0’ ‘0’ ‘0’
5 ‘0’ ‘0’ ‘0’ ‘1’ ‘0’ ‘0’ ‘1’ ‘0’ ‘0’
6 ‘0’ ‘0’ ‘0’ ‘0’ ‘0’ ‘1’ ‘0’ ‘0’ ‘0’
7 ‘0’ ‘0’ ‘0’ ‘1’ ‘0’ ‘0’ ‘0’ ‘0’ ‘0’
8 ‘1’ ‘0’ ‘0’ ‘0’ ‘0’ ‘0’ ‘0’ ‘0’ ‘0’
9 ‘0’ ‘1’ ‘0’ ‘0’ ‘0’ ‘0’ ‘0’ ‘1’ ‘0’
10

mine数组布置雷后的状态

0 1 2 3

4

5 6 7 8 9 10
0
1 ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’
2 ‘*’ ‘*’ *’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’
3 ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’
4 ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’
5 ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’
6 ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’
7 ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’
8 ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’
9 ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’ ‘*’
10

show数组初始化状态

对应的数组应该是:

vector<vector<char>> show(ROWS,vector<char>(COLS,'0'));

vector<vector<char>> mine(ROWS,vector<char>(COLS,'*'));

1.2.2文件结构设计

为了方便实现对文件的管理,这里我们使用3个文件:

mine_clearance_test.cpp    //此文件用于游戏逻辑的实现

mine_clearance.h                //此文件用于游戏中函数的实现

mine_clearance.cpp            //此文件用于游戏数据类型的定义和函数的定义

2.扫雷游戏的代码实现

mine_clearance.h 

#pragma once //防止头文件被多次包含包含

#include <iostream>

#include <vector>

#include <ctime>

#include <cstdlib>

#define ROW 9

#define COL 9

#define ROWS ROW+2

#define COLS COL+2

#define EASY_COUNT 10;

using namespace std;

//布置雷

void SetMine(vector<vector<char>> &show,int row,int col);

//打印棋盘

void Display(vector<vector<char>> &show,int row,int col);

//扫雷

void FindMine(vector<vector<char>> &show,vector<vector<char>> &mine,int row,int col);

//显示旁边有几个雷

int CountMine(vector<vector<char>> &show,int row,int col,int x,int y);

mine_clearance.cpp 

#include "mine_clearance.h"

//布置雷

void SetMine(vector<vector<char>> &show,int row,int col){

    int flag=EASY_COUNT;

    srand((unsigned int)time(NULL));

    while(flag){

        int x=rand()%row+1,y=rand()%col+1;

        if(show[x][y]=='0'){

            show[x][y]='1';

            flag--;

        }

    }

}

//打印棋盘

void Display(vector<vector<char>> &show,int row,int col){

    cout<<"****---扫雷游戏---****"<<endl;

    for(int i=0;i<=col;i++) cout<<i<<' ';

    cout<<endl;

    for(int i=1;i<=row;i++){

        cout<<i<<' ';

        for(int j=1;j<=col;j++){

            cout<<show[i][j]<<' ';

        }

        cout<<endl;

    }

}

//显示旁边有几个雷

int CountMine(vector<vector<char>> &show,int row,int col,int x,int y){

    int cnt;

    cnt=show[x-1][y-1]+show[x-1][y]+show[x-1][y+1]+show[x][y-1]+show[x][y+1]+show[x+1][y-1]+show[x+1][y]+show[x+1][y+1]-8*'0';

    return cnt;

}

//扫雷

void FindMine(vector<vector<char>> &show,vector<vector<char>> &mine,int row,int col){

    int cnt=row*col-EASY_COUNT;

    int cnt_mine=0;

    while(cnt){

        int x,y;

        cout<<"请输入要排查的行列号"<<endl;

        cin>>x>>y;

        if(x>=1&&x<=9&&y>=1&&y<=9){//排查坐标的有效性

            if(mine[x][y]=='*'){

                if(show[x][y]!='1'){

                    cnt--;

                    cnt_mine=CountMine(show,row,col,x,y);

                    mine[x][y]=cnt_mine+'0';

                    Display(mine,row,col);

                }

                else{

                    cout<<"很遗憾,游戏结束"<<endl;

                    Display(show,row,col);

                    break;

                }

            }

        }

       

    }

    if(cnt==0) cout<<"恭喜你,雷已被排完";

}

mine_clearance_test.cpp

#include "mine_clearance.h"

void Menu(){//打印菜单

    cout<<"******************************"<<endl;

    cout<<"******      0.exit       *****"<<endl;

    cout<<"******      1.game       *****"<<endl;

    cout<<"******************************"<<endl;

    cout<<"请选择:";

}

void Game(){

    //声明并初始化

    vector<vector<char>> show(ROWS,vector<char>(COLS,'0')),mine(ROWS,vector<char>(COLS,'*'));

    SetMine(show,ROW,COL);//布置雷

    Display(mine,ROW,COL);

    FindMine(show,mine,ROW,COL);

}

void test(){

    Menu();

    int flag;

    do{

        cin>>flag;

        switch(flag){

            case 0:

                cout<<"游戏结束";

                break;

            case 1:

                cout<<"开始游戏"<<endl;

                Game();

                break;

            default:

                cout<<"请输入0或1";

        }

    }while(flag);

}

int main(){

    test();

    return 0;

}

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐