自制c++扫雷(可以标记和去掉标记)自己测试无bug

#include <iostream>
#include <conio.h>
#include<time.h>
#include<fstream>//这里采用c++的文件输入输出试一下。c语言的我也不太会以后写写
using namespace std;

//定义一个10*10的扫雷地图
int GameMap[12][12] = {
    {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
    {-1,0,0,0,0,0,0,0,0,0,0,-1},
{-1,0,0,0,0,0,0,0,0,0,0,-1},
{-1,0,0,0,0,0,0,0,0,0,0,-1},
{-1,0,0,0,0,0,0,0,0,0,0,-1},
{-1,0,0,0,0,0,0,0,0,0,0,-1},
{-1,0,0,0,0,0,0,0,0,0,0,-1},
{-1,0,0,0,0,0,0,0,0,0,0,-1},
{-1,0,0,0,0,0,0,0,0,0,0,-1},
{-1,0,0,0,0,0,0,0,0,0,0,-1},
{-1,0,0,0,0,0,0,0,0,0,0,-1},
{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, };

int Boomnum = 0;//存在的已探测地区数量
int safe=0;
void printmap()//打印地图
{
    cout << "地雷数:" << Boomnum << "已探测格子数:" << safe<<" (当全部非地雷格子已经探测时胜利)" << endl;
    for (int i = 0; i < 12; i++)
    {
        cout <<"                " << endl;
        for (int j = 0; j < 12; j++)
            switch (GameMap[i][j])
            {
            case -1:cout << "墙"; break;
            
            case 0:cout << "  "; break;
            case -2:case -3:cout << "雷"; break;//-2是没有揭开的地雷,-3是揭开的地雷
            case -4:case-5:case-6:case-7:cout << "0 "; break;
            case -10:case-11:cout << "标"; break;
            default:
                cout << GameMap[i][j]<<" ";
                break;
            }
    }
    
}

fstream range;//定义一个文件对象range


void BoomEmerger()//地雷生成
{
    cout << "输入要生成的地雷数" << endl;
    cin >> Boomnum;
    int i;
    int j;
    for (int k = 0; k < Boomnum; k++)//生成输入个数个雷
    {
        i = 1+rand()%10;
        j = 1+rand()%10;
        if (GameMap[i][j] != -2)
            GameMap[i][j] = -2;
        else
            k--;
    }
}



void scanboomnum(int input1,int input2)//扫描周围雷的数量
{
    if(GameMap[input1][input2]==0)
    {
        for (int i = input1 - 1; i <= input1 + 1; i++)//探测本格周围雷的数量
            for (int j = input2 - 1; j <= input2 + 1; j++)
                if (GameMap[i][j] == -2)
                    GameMap[input1][input2]++;//有一个就+1
        safe++;//探测一次,已探测格子+1
    }
            if (GameMap[input1][input2] == 0)
                GameMap[input1][input2] = -4;//-4表示该格周围没有地雷
            

} 


void scanzero(int input1,int input2)//扫描0的数量
{
    for (int i = input1 - 1; i <= input1 + 1; i++)//探测本格周围雷的数量
        
        for (int j = input2 - 1; j <= input2 + 1; j++)
        {
            if(GameMap[i][j]==0)//只对没有探测过的格子探测,减少操作
            scanboomnum(i, j);
        }
    if (GameMap[input1 + 1][input2] == -4)//如果本格的上面周围也没有雷
    {
        GameMap[input1][input2]--;//为本格做一个标记防止下一个空白格又探测本格,互相探测形成死循环
        scanzero(input1 + 1, input2);//对上面的周围进行探测,后面同理
        
    }

    if (GameMap[input1 - 1][input2] == -4)
    {
        GameMap[input1][input2]--;scanzero(input1 - 1, input2);
        
    }

    if (GameMap[input1][input2+1] == -4)
    {
        GameMap[input1][input2]--;scanzero(input1, input2 + 1);
        
    }

    if (GameMap[input1 ][input2-1] == -4)
    {
        GameMap[input1][input2]--;scanzero(input1, input2 - 1);
        
    }
}
int main()
{
    cout << "   欢迎来到周恺祺扫雷游戏:按任意键开始:" << endl;
    srand(time(nullptr));
    bool startgame = 1;//控制游戏开始还是结束

    int op=0;//用来判断是做标记还是扫雷

    int input1=0;//用于选择的行和列
    int input2=0;
    cin >> input1;//没作用,就是给个看主页的作用
    BoomEmerger();//生成地雷
    
    while (startgame)
    {
        system("CLS");
        printmap();
        if ( safe == (100 - Boomnum))//判断胜利触发器
                {

                    cout <<endl<< "游戏胜利!!" << endl;
                    startgame = 0;
                    cout << "请输入你的名字";
                    char name[100];
                    cin >> name;
                    
                    range.open("C:\\Users\\24060\\Desktop\\c++项目算法训练\\ScanBoom\\Range.txt", ios_base::app);//追加到文件尾 注:这里我写的绝对路径!!!你们自己改一下就好!!
                    if (!range.is_open())
                    {
                        cout << "查看失败1" << endl;
                    }
                    range << name <<" 地雷数:"<<Boomnum<<"  " << endl ;
                    range.close();
                    range.open("C:\\Users\\24060\\Desktop\\c++项目算法训练\\ScanBoom\\Range.txt", ios_base::in);//读取
                    if (!range.is_open())
                    {
                        cout << "查看失败" << endl;
                    }
                    else
                    {
                        char ch;
                        while (range.good())
                        {
                            range >> ch;
                            cout << ch;
                        }
                        
                    }
                    range.close();
                    break;
                }
        
        cout << endl << "请输入要进行的操作" << endl << "1、探测格子" << endl << "2、排雷(对已经排雷格子使用会取消排雷)" << endl << "" << endl;
        cin >> op;
        switch (op)
        {
        case 1:
            cout<< "行数和列数:(空格隔开,回车确定)" << endl;
            cin >> input1 >> input2;
            
            if (GameMap[input1][input2] == -2)//踩到雷了
            //因为地雷在没点开之前是空白,我原本还想着两个地图,一个是展示地图一个是实际数据地图
            //但是我后来想了一个,只有踩雷的时候显示出所有的雷不就好了吗。
        {
            system("CLS");
            cout << "                 踩到雷了!!游戏失败!!!" << endl;
            for (int i = 1; i < 12; i++)
            {
                for (int j = 1; j < 12; j++)
                    if (GameMap[i][j] == -2)
                        GameMap[i][j] = -3;

            }
            printmap();
            startgame = 0;
            break;
        }
            scanboomnum(input1, input2);
            if (GameMap[input1][input2] == -4)//如果还是0的话,就将周围8格的内容都展示出来
                scanzero(input1, input2);
            break;


        case 2://标记地雷操作
        {
            cout << "行数和列数:(空格隔开,回车确定)" << endl;
            cin >> input1 >> input2;
            if (GameMap[input1][input2] == -2)//如果是地雷则为正确标记-10
                GameMap[input1][input2] = -10;

            else if (GameMap[input1][input2] == 0)
                GameMap[input1][input2] = -11;//错误标记-11

            else if (GameMap[input1][input2] == -10)//标记还原操作
                GameMap[input1][input2] = -2;//标记正确还原地雷

            else if (GameMap[input1][input2] == -11)
                GameMap[input1][input2] = 0;//标记错误还原为未探测状态
            else//如果是已探测目标就报错
                cout << "无法标记!" << endl;
        }

        default://查看排行榜操作
            
            break;
        }
        if (input1 == 27)
            startgame = 0; 
        //没有踩到雷,就显示周围雷的数量 
    }
    
}

//这个项目写扫雷

有问题可以随时问我,代码中的注释写的算是很清楚了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值