C++实现控制台版扫雷程序

本文实例为大家分享了C++实现控制台版扫雷程序的具体代码,供大家参考,具体内容如下

测试平台: WIN7

工具: VC6.0 , VS2008都能编译得过。

花了两天时间写的,里面涉及的算法大都是自己想的,所以可能有些BUG。

#include <iostream>
#include <time.h>
#include <windows.h>
using namespace std;
 
#pragma comment (linker,"/subsystem:console")
 
#define BLACK 0        //空白
#define MINE 100    //地雷
#define NOSWEEP 0    //未扫过
#define SWEEP 1        //扫雷
#define FLAG 2        //标记
 
class WinMine
{
public:
 
    WinMine(int iRow, int iColumn);
    ~WinMine();
public:
    void InitMine(int iMineMax);
    void SetColor();
    void StatisticsMine();
    void Map();
    bool OpenWhites(int x, int y, int status);
    void GameStart(int iMineMax);
    void GameOver();
    bool GoodOver();
private:
    int **m_ppMine;
    int **m_ppSweep;
    bool m_bMineflag;
    bool m_bSweepflag;
    int m_row;
    int m_column;
    int m_minenum;
};
 
int main(void)
{
    system("color 0d");
    while (true)
    {
        int level;
        WinMine *Mine;
        cout << "请输入游戏等级:" <<endl;
        cout << "1.初级" <<endl;
        cout << "2.中级" <<endl;
        cout << "3.高级" <<endl;
        cout << "4.退出" <<endl;
        cin >> level;
        if (level == 1)
        {
            Mine = new WinMine(9,9);
            Mine->GameStart(10);
        }
        else if (level == 2)
        {
            Mine = new WinMine(16,16);
            Mine->GameStart(40);
        }
        else if (level == 3)
        {
            Mine = new WinMine(16,30);
            Mine->GameStart(70);
        }
        else if (level == 4)
        {
            return 0;
        }
        else 
        {
            cout << "输入错误!" <<endl;
            continue;
        }
        delete Mine;
    }
 
    return 0;
}
 
WinMine::WinMine(int iRow, int iColumn)
{
    int i;
    
    //储雷状态
    m_ppMine = (int **) new int[iRow]; if (!m_ppMine) return;
    m_ppMine[0] = new int[iRow * iColumn]; if (!*m_ppMine) { delete[] m_ppMine; m_ppMine = NULL; return;}
    m_bMineflag = true;
 
    //扫雷状态
    m_ppSweep = (int **) new int[iRow]; if (!m_ppSweep) return;
    m_ppSweep[0] = new int[iRow * iColumn]; if (!*m_ppSweep) { delete[] m_ppSweep; m_ppSweep = NULL; return;}
    m_bSweepflag = true;
 
    m_row = iRow; m_column = iColumn;
    
    for (i = 1; i < iRow; i++)
    {
        m_ppMine[i] = m_ppMine[0] + i * iRow;
    }
 
    for (i = 1; i < iRow; i++)
    {
        m_ppSweep[i] = m_ppSweep[0] + i * iRow;
    }
 
    memset(m_ppSweep[0], 0, iRow * iColumn * sizeof(int));
    memset(m_ppMine[0], 0, iRow * iColumn * sizeof(int));
    
}
 
WinMine::~WinMine()
{
    if (m_bMineflag)
    {
        if (m_ppMine[0]) delete[] m_ppMine[0];
        if (m_ppMine) delete[] m_ppMine;
    }
    if (m_bSweepflag)
    {
        if (m_ppSweep[0]) delete[] m_ppSweep[0];
        if (m_ppSweep) delete[] m_ppSweep;
    }
}
 
//设置颜色
void WinMine::SetColor()
{
    system("color 0a");
}
 
//初始化雷数
void WinMine::InitMine(int iMineMax)    
{
    int x, y,num = 0;
    srand( (unsigned)time(NULL) );
    for (int i = 0; num != iMineMax; i++)
    {
        x = rand()%m_row;
        y = rand()%m_column;
        if (MINE != m_ppMine[x][y])
        {
            m_ppMine[x][y] = MINE;
            num++;
        }
    }
    m_minenum = num;
 
}
 
//统计雷数
void WinMine::StatisticsMine()
{
    int i, j;
    int n, m;
    int num = 0; //保存雷数
 
    //中间
    for ( i = 1; i < m_row - 1; i++)
    {
        for ( j = 1; j < m_column - 1; j++)
        {
            if ( m_ppMine[i][j] == BLACK)
            {
                for (n = i - 1; n <= i + 1; n++)
                {
                    for (m = j - 1; m <= j + 1; m++)
                    {
                        if ( m_ppMine[n][m] == MINE )
                            num++;
 
                    }
                }
                m_ppMine[i][j] = num;
                num = 0;
            }
 
        }
    }
 
    //顶边
    for ( i = 1; i < m_column - 1; i++)
    {
        if (m_ppMine[0][i] == BLACK)
        {
            for (n = 0; n < 2; n++)
            {
                for (m = i - 1; m <= i + 1; m++)
                {
                    if (m_ppMine[n][m] == MINE)
                        num++;
                }
            }
            m_ppMine[0][i] = num;
            num = 0;
        }
    }
 
    //下边
    for ( i = 1; i < m_column - 1; i++)
    {
        if (m_ppMine[m_row - 1][i] == BLACK)
        {
            for (n = m_row - 2; n < m_row; n++)
            {
                for (m = i - 1; m <= i + 1; m++)
                {
                    if (m_ppMine[n][m] == MINE)
                        num++;
                }
            }
            m_ppMine[m_row - 1][i] = num;
            num = 0;
        }
    }
 
    //左边
 
    for ( i = 1; i < m_row - 1; i++ )
    {
        if (m_ppMine[i][0] == BLACK)
        {
            for (n = i - 1; n <= i + 1; n++)
            {
                for (m = 0; m < 2; m++)
                    if (m_ppMine[n][m] == MINE)
                        num++;    
            }
 
            m_ppMine[i][0] = num;
            num = 0;
        }
    }
 
    //右边
    for ( i = 1; i < m_row - 1; i++ )
    {
        if (m_ppMine[i][m_column - 1] == BLACK)
        {
            for (n = i - 1; n <= i + 1; n++)
            {
                for (m = m_column - 2; m < m_column; m++)
                {
                    if (m_ppMine[n][m] == MINE)
                        num++;
                }
            }
            m_ppMine[i][m_column - 1] = num;
            num = 0;
        }
    }
 
    //左上角
    if (m_ppMine[0][0] != MINE)
    {
        if (m_ppMine[0][1] == MINE)
            num++;
        if (m_ppMine[1][1] == MINE)
            num++;
        if (m_ppMine[1][0] == MINE)
            num++;
        m_ppMine[0][0] = num;
        num = 0;
    }
 
 
    //左下角
 
    if (m_ppMine[m_row - 1][0] != MINE)
    {
        if (m_ppMine[m_row - 2][0] == MINE)
            num++;
        if (m_ppMine[m_row - 2][1] == MINE)
            num++;
        if (m_ppMine[m_row - 1][1] == MINE)
            num++;
        m_ppMine[m_row - 1][0] = num;
        num = 0;
    }
 
    //右上角
    if (m_ppMine[0][m_column - 1] != MINE)
    {
        if (m_ppMine[1][m_column - 1] == MINE)
            num++;
        if (m_ppMine[1][m_column - 2] == MINE)
            num++;
        if (m_ppMine[0][m_column - 2] == MINE)
            num++;
        m_ppMine[0][m_column - 1] = num;
        num = 0;
    }
 
    //右下角
    if (m_ppMine[m_row - 1][m_column - 1] != MINE)
    {
        if (m_ppMine[m_row - 2][m_column - 1] == MINE)
            num++;
        if (m_ppMine[m_row - 2][m_column - 2] == MINE)
            num++;
        if (m_ppMine[m_row - 1][m_column - 2] == MINE)
            num++;
        m_ppMine[m_row - 1][m_column - 1] = num;
        num = 0;
    }
}
 
//展开空白
bool WinMine::OpenWhites(int row, int column, int status)
{
    if (row < 0 || row > (m_row - 1) || column < 0 || column > (m_column - 1))
        return true;
    if (status == SWEEP &&  m_ppMine[row][column] == MINE)
    {
        return false;
    }
 
    if (status == FLAG)
    {
        m_ppSweep[row][column] = FLAG;
        return true;
    }
 
    if (m_ppSweep[row][column] == NOSWEEP && m_ppMine[row][column] != MINE)
    {
 
        if (m_ppMine[row][column] > 0)
        {
            m_ppSweep[row][column] = SWEEP; 
            return true;
        }
        else
        {
            m_ppSweep[row][column] = SWEEP;
            OpenWhites(row-1, column, status);
            OpenWhites(row-1, column-1, status);
            OpenWhites(row-1, column+1, status);
            OpenWhites(row, column-1, status);
            OpenWhites(row, column+1, status);
            OpenWhites(row+1, column, status);
            OpenWhites(row+1, column-1, status);
            OpenWhites(row+1, column+1, status);
        }
    }
    return true;
}
 
//地图
void WinMine::Map()
{
    SetColor();
    int i, j;
    for ( i = 0; i < m_row; i++)
    {
        for (j = 0; j < m_column; j++)
        {
            if (m_ppSweep[i][j] == SWEEP)
            {
                if (m_ppMine[i][j] == 0)
                {
                    cout << "□";
                }
                else if (m_ppMine[i][j] == 1)
                {
                    cout << "①";
                }
                else if (m_ppMine[i][j] == 2)
                {
                    cout << "②";
                }
                else if (m_ppMine[i][j] == 3)
                {
                    cout << "③";
                }
                else if (m_ppMine[i][j] == 4)
                {
                    cout << "④";
                }
                else if (m_ppMine[i][j] == 5)
                {
                    cout << "⑤";
                }
                else if (m_ppMine[i][j] == 6)
                {
                    cout << "⑥";
                }
                else if (m_ppMine[i][j] == 7)
                {
                    cout << "⑦";
                }
                else if (m_ppMine[i][j] == 8)
                {
                    cout << "⑧";
                }    
 
            }
            else if (m_ppSweep[i][j] == FLAG)
            {
                cout << "⊙";
            }
            else
                cout << "▇";
        }
        cout << endl;
    }
}
 
//游戏结束
void WinMine::GameOver()
{
 
    int i, j;
    for ( i = 0; i < m_row; i++)
    {
        for (j = 0; j < m_column; j++)
        {
            if (m_ppMine[i][j] == MINE)
                cout << "★";
            else 
                cout << "□";
            
        }
        cout << endl;
    }
}
//检查是否雷标记正确。
bool WinMine::GoodOver()
{
    int i, j;
    int num = 0;
    for (i = 0; i < m_row; i++)
    {
        for (j = 0; j < m_column; j++)
        {
            if (m_ppSweep[i][j] == FLAG && m_ppMine[i][j] == MINE)
                num++;
 
        }
    }
    if (num == m_minenum)
        return true;
    else
        return false;
}
 
//开始游戏
void WinMine::GameStart(int iMineMax)
{
    int x, y;
    int flag;
begin:
    memset(m_ppSweep[0], 0, m_row * m_column * sizeof(int));
    memset(m_ppMine[0], 0, m_row * m_column * sizeof(int));
    InitMine(iMineMax);
    StatisticsMine();
 
    while (true)
    {
        system("cls");
 
        Map();
        cout << "请输入要扫的区域的坐标:" <<endl;
        cout << "请输入纵坐标:";cin>>x;
        cout << "请输入横坐标:";cin>>y;
        if (x <= 0 || x > m_row || y <= 0 || y > m_column)
        {
            cout <<"输入错误请重新输入" <<endl;
            Sleep(1000);
            continue;
        }
 
        cout << "请输入是要做标记还是扫雷,扫雷请按1,标记请按2:" <<endl;
        cin >> flag;
        if ( false == OpenWhites(x-1, y-1, flag) )
        {
            int i;
            system("cls");
            GameOver();
            cout << "游戏结束!" <<endl;
            cout << "继续游戏请按1,退出游戏请按0:"<<endl;
            cin >> i;
            if (i == 1)
                goto begin;
            else 
                goto end;
        }
        else
        {
            if (GoodOver() == true)
            {
                int i;
                cout << "扫雷成功!" <<endl;
                cout << "继续游戏请按1,退出游戏请按0:"<<endl;
                cin >> i;
                if (i == 1)
                    goto begin;
                else 
                    goto end;
            }
        }
    }
end:
    return;
}

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

(0)

相关推荐

  • C++实现扫雷小游戏(控制台版)

    本文为大家分享了C++实现扫雷小游戏的具体代码,供大家参考,具体内容如下 程序功能: 提供三种模式:初级.中级.高级 操作模式:wsad控制光标移动,空格键打开方块 提供扫雷地图的类 map.h #ifndef MAP_H_ #define MAP_H_ #define MAX_LENGTH 32 //可以提供的地图最大长度 #define MAX_WIDTH 18 //可以提供的地图最大宽度 #define UP_EDGE 1 //上边界 #define DOWN_EDGE _wid //下边

  • C++学习心得之扫雷游戏

    本文实例为大家分享了C++实现扫雷游戏的具体代码,供大家参考,具体内容如下 一.序言 创建一个9*9有10个雷的扫雷游戏 文章的顺序是按照我当时的编程顺序写的,顺便写下我当初的一点思路,总的代码在文章最后,前面的都是分散的函数,有需要的朋友直接复制最后的 二.创建 创建一个头文件,一个放游戏的程序,一个放运行测试的程序 #define _CRT_SECURE_NO_WARNINGS 1 #include<stdlib.h>//生成随机数 #include<stdio.h> #inc

  • C++实现一个扫雷小游戏

    本文实例为大家分享了C++实现扫雷小游戏的具体代码,供大家参考,具体内容如下 目前的版本是0.98版本,可以提出增加新功能意见哦 代码如下: #include<bits/stdc++.h> #include<windows.h> using namespace std; long long int c,dev,m,k,cnt,d,e,jie=10,z,abc,n,b[1000][1000],a[1000][1000],cc,cd,ce,def; //c是随机行,k是随机列 bool

  • C++实现扫雷游戏(控制台不闪屏版)

    之前写了一个C++ 的控制台扫雷小游戏,但由于过度使用system("cls")刷屏,导致闪屏,因此重写了一个改善的不闪屏版本,并把逻辑重新捋了一遍. map.h #ifndef MAP_H_ #define MAP_H_ #define MAX_WID 18 #define MAX_LEN 32 #define UP_EDGE 1 //上边界 #define LEFT_EDGE 1 //左边界 #define RIGHT_EDGE _len //右边界 #define DOWN_ED

  • C++实现扫雷经典小游戏

    用C++复现经典扫雷,供大家参考,具体内容如下 主要是dfs实现打开一片的操作,数字带有颜色,很真实. windows扫雷中鼠标左右键同时按也实现了,即试探. 先上图,详见下面代码: 代码中有详细注释,编译无任何错误警告. Ps.有bug请评论指出,谢谢啦~ 另外我觉得代码比较臃肿,有什么可以优化的也请提出~ #include<cstdio> #include<cstring> #include<algorithm> #include<conio.h> #i

  • C++扫雷游戏的简单制作

    本文实例为大家分享了C++实现扫雷游戏的具体代码,供大家参考,具体内容如下 #ifndef SAOLEI_H #define SAOLEI_H class Block { friend class Saoleigame; public: Block(); bool isShown(); void setnum(int); int getnum(); bool isbomb(); protected: int num; bool flag_show; int x; int y; }; class

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

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

  • 利用c++和easyx图形库做一个低配版扫雷游戏

    游戏界面 由于这个游戏是我抱着玩一玩的心态做出来的,所以没有过多的去设计界面,也没有去找游戏的资源(图片.游戏音效等).仅使用了不同颜色的方块来表示游戏中方块的状态和种类.(绿色为初始状态(未翻转的状态),黄色为翻转后的背景颜色,蓝色表示已插旗的方块,红色代表地雷) 图1 游戏主菜单界面 图二 模式一的游戏界面(20*20 40个雷) 图三 模式二的游戏界面(10*10 20个雷) 图四 游戏成功界面 图五 游戏失败界面 2.全部代码 #include<graphics.h> #include

  • C++代码实现扫雷游戏

    前言 提示:本文是基于easyX图形库实现的,还有部分功能可以添加,仅适合新手参考. 提示:以下是本篇文章正文内容,下面案例可供参考 一.扫雷游戏模式 在确定大小的矩形雷区中随机布置一定数量的地雷,玩家需要尽快找出雷区中的所有不是地雷的方块,而不许踩到地雷. 游戏的基本操作包括左键单击和右键单击.其中左键用于打开安全的格子,推进游戏进度:右键用于标记地雷,以辅助判断. 左键单击:在判断出不是雷的方块上按下左键,可以打开该方块.如果方块上出现数字,则该数字表示其周围3×3区域中的地雷数(一般为8个

  • C++实现简单扫雷游戏

    扫雷是一个经典的电脑小游戏,用C++来编一下,效果自己试一下 #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 |

随机推荐