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

 更新时间:2022年05月07日 11:55:04   作者:AillMe  
这篇文章主要为大家详细介绍了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;
}

再为大家分享一位作者的文章:控制台版扫雷(支持鼠标操作)

//说明: 左键双击对应windows自带扫雷中的双键点击
 
#include <windows.h>
#include <cstdlib>
#include <ctime>
#include <list>
 
using namespace std;
//数组索引转成坐标
#define X(v) (v) % WIDTH
#define Y(v) (v) / WIDTH
//坐标系统转换
#define BOARDX(x) ((x) - OFFSETX) / 2
#define BOARDY(y) (y) - OFFSETY
#define SCREENX(x) 2 * (x) + OFFSETX
#define SCREENY(y) (y) + OFFSETY
#define BACKGROUND_WHITE (BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED)
#define FOREGROUND_WHITE (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED)
 
typedef enum {
    UNKNOWN,
    DISPLAY,
    MARKED
} State;
 
typedef enum {
    NUMBER,
    EMPTY,
    MINE
} MType;
 
typedef struct {
    State state;
    MType mtype;
    int val;
} Cell;
 
typedef bool (* CmpProc)(Cell& cell, void* pData);
 
int HEIGHT   = 16;
int WIDTH    = 16;
int MINE_CNT = 40;    //地雷数
int CELL_CNT;
//第一个格子的x, y偏移
int OFFSETX = 3;
int OFFSETY = 3;
int flagCnt;        //标记数
int mineLeft;        //地雷剩余
int unkwLeft;        //未知剩余
int liveLeft;        //生命剩余
COORD tmPos;        //计时坐标
COORD mnPos;        //地雷(剩余)坐标
COORD lvPos;        //生命坐标
bool bGameStart, bGameStop;        //游戏开始.结束标记
DWORD dwStart;
HANDLE hOut, hIn;
Cell cells[16][30];
 
void writeChar(LPCSTR pChar, COORD wrtCrd)
{
    DWORD wtn;
    WriteConsoleOutputCharacter(hOut, pChar, strlen(pChar), wrtCrd, &wtn);
}
 
void fillChar(TCHAR cChar, DWORD len, COORD wrtCrd)
{
    DWORD wtn;
    FillConsoleOutputCharacter(hOut, cChar, len, wrtCrd, &wtn);
}
 
void fillAttr(WORD attr, DWORD len, COORD wrtCrd)
{
    DWORD wtn;
    FillConsoleOutputAttribute(hOut, attr, len, wrtCrd, &wtn);
}
 
bool isCell(int x, int y)
{
    return x >= 0 && x < WIDTH && y >= 0 && y < HEIGHT;
}
 
bool isMine(int x, int y)
{
    return isCell(x, y) && cells[y][x].mtype == MINE;
}
 
bool cmpState(Cell& cell, void* pData)
{
    return cell.state == *(State*)pData;
}
 
bool cmpMtype(Cell& cell, void* pData)
{
    return cell.mtype == *(MType*)pData;
}
//四周格子作比较
int aroundCmp(int x, int y, CmpProc cmp, void* pData)
{
    int nRet = 0;
    for (int y0=y-1; y0<=y+1; y0++)
    {
        for (int x0=x-1; x0<=x+1; x0++)
        {
            if (isCell(x0, y0) 
                && !(x0 == x && y0 == y))        //not self
            {
                nRet += cmp(cells[y0][x0], pData);
            }
        }
    }
    return nRet;
}
 
int aroundMines(int x, int y)
{
    int val = MINE;
    return aroundCmp(x, y, cmpMtype, &val);
}
 
int aroundMarks(int x, int y)
{
    int val = MARKED;
    return aroundCmp(x, y, cmpState, &val);
}
//扰乱数组的前n个元素
void ruffle(int* arr, int len, int n)
{
    for (int i=0; i<n; i++)
    {
        int j = rand() % len;
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }
}
//计时
void setElapsedTime()
{
    if (bGameStart && !bGameStop)
    {
        DWORD dwDelt = (GetTickCount() - dwStart) / 1000;
        if (dwDelt < 1000)
        {
            char buf[5] = {0};
            sprintf(buf, "%.3d\0", dwDelt);
            writeChar(buf, tmPos);
        }    
    }
}
//剩余雷数(仅显示, 非实际)
void setMinesLeft()
{
    char buf[5] = {0};
    sprintf(buf, "%2d\0", MINE_CNT - flagCnt);
    writeChar(buf, mnPos);
}
//剩余生命
void setLivesLeft(int delt = 0)
{
    char buf[5] = {0};
    liveLeft += delt;
    sprintf(buf, "%2d\0", liveLeft);
    writeChar(buf, lvPos);
}
 
void drawCell(int x, int y)
{
    Cell* pCell = &cells[y][x];
    COORD cellCrd = {SCREENX(x), SCREENY(y)};
    char buf[3] = {0};
    switch (pCell->state)
    {
    case UNKNOWN:
        sprintf(buf, "□\0");
        break;
    case MARKED:
        sprintf(buf, " P\0");    
        break;
    case DISPLAY:
        switch (pCell->mtype)
        {
        case MINE:
            sprintf(buf, " *\0");
            break;
        case EMPTY:
            sprintf(buf, "  \0");
            break;
        case NUMBER:
            sprintf(buf, " %d\0", pCell->val);
            fillAttr((WORD)pCell->val, 2, cellCrd);    //数字着色
            break;
        }
        break;
    }
    writeChar(buf, cellCrd);
}
//初始化信息栏
void initInfoBar()
{
    char buf[50] = {0};
    sprintf(buf, "生命: %2d   地雷: %2d   用时: 000\0", liveLeft, MINE_CNT);
    COORD crd = {(80 - strlen(buf)) / 2, SCREENY(HEIGHT) + 1};        //水平居中
    writeChar(buf, crd);
    crd.X += 6;        lvPos = crd;
    crd.X += 11;    mnPos = crd;
    crd.X += 11;    tmPos = crd;
}
 
void clearScreen()
{
    COORD crd = {0, 0};
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    GetConsoleScreenBufferInfo(hOut, &csbi);
    fillChar(' ', csbi.dwSize.X * csbi.dwSize.Y, crd);
    fillAttr(FOREGROUND_WHITE, csbi.dwSize.X * csbi.dwSize.Y, crd);
}
 
void initGame()
{
    srand((unsigned)time(NULL));
    SetConsoleTitle("扫雷控制台版   F2: 初级; F3: 中级; F4: 高级");
    clearScreen();
    CELL_CNT = HEIGHT * WIDTH;
    OFFSETX = (80 - WIDTH * 2) / 2;    //水平居中
    int* idxs = new int[CELL_CNT];    //地雷索引
    int i, x, y;
    //init cells and indexs
    for (i=0; i<CELL_CNT; i++)
    {
        cells[Y(i)][X(i)].mtype = EMPTY;
        cells[Y(i)][X(i)].state = UNKNOWN;
        idxs[i] = i;
    }
    ruffle(idxs, CELL_CNT, MINE_CNT);
    //fill mines
    for (i=0; i<MINE_CNT; i++)
    {
        cells[Y(idxs[i])][X(idxs[i])].mtype = MINE;
    }
    //fill nums && print the game
    for (y=0; y<HEIGHT; y++)
    {
        for (x=0; x<WIDTH; x++)
        {
            if (!isMine(x, y))
            {
                cells[y][x].val = aroundMines(x, y);
                cells[y][x].mtype = cells[y][x].val > 0 ? NUMBER : EMPTY;
            }
            drawCell(x, y);
        }
    }
    delete[] idxs;
 
    bGameStart = false;
    bGameStop  = false;
    mineLeft = MINE_CNT;
    unkwLeft = CELL_CNT;
    liveLeft = MINE_CNT / 20 + 1;    //每二十个雷加一条命
    flagCnt  = 0;
    initInfoBar();
}
 
void showAll()
{
    for (int i=0; i<CELL_CNT; i++)
    {
        cells[Y(i)][X(i)].state = DISPLAY;
        drawCell(X(i), Y(i));
    }
}
 
void showTip(const char* tipMsg, WORD attr = FOREGROUND_WHITE)
{
    COORD tipCrd = {(80 - strlen(tipMsg)) / 2, 1};
    writeChar(tipMsg, tipCrd);
    fillAttr(attr, strlen(tipMsg), tipCrd);
}
 
void gameWin()
{
    if (!bGameStop)
    {
        showTip("恭喜你, 你赢了! ", FOREGROUND_GREEN | FOREGROUND_INTENSITY);
        bGameStop = true;
    }
}
 
void gameOver(int x, int y)
{
    setLivesLeft(-1);
    if (liveLeft == 0)
    {
        showAll();
        showTip("游戏结束, 请重新来过!", FOREGROUND_RED | FOREGROUND_INTENSITY);
        bGameStop = true;
    }
    else
    {
        COORD crd = {SCREENX(x), SCREENY(y)};
        WORD attr = FOREGROUND_WHITE;
        for (int i=0; i<6; i++)        //触雷闪烁
        {
            attr = FOREGROUND_WHITE ^ FOREGROUND_RED ^ attr;
            fillAttr(attr, 2, crd);
            Sleep(100);
        }
    }
}
 
void showAround(int x, int y)
{    
    list<COORD> lst;
    COORD crd = {x, y};
    lst.push_back(crd);
    while (!lst.empty())
    {
        crd = lst.front();
        lst.pop_front();
        x = crd.X;
        y = crd.Y;
        for (int x0=x-1; x0<=x+1; x0++)
        {
            for (int y0=y-1; y0<=y+1; y0++)
            {
                if (!isCell(x0, y0)    || (x0 == x && y0 == y))
                {
                    continue;
                }
                Cell* pCell = &cells[y0][x0];
                if (pCell->state == UNKNOWN)
                {
                    if (pCell->mtype == MINE)
                    {
                        gameOver(x0, y0);
                        break;
                    }
                    else if (pCell->mtype == EMPTY)
                    {
                        crd.X = x0;
                        crd.Y = y0;
                        lst.push_back(crd);
                    }
                    unkwLeft--;
                    pCell->state = DISPLAY;
                    drawCell(x0, y0);
                }
            }    //end for
        }    //end for
    }
}
 
void onCellLDBLClick(int x, int y)
{
    Cell* pCell = &cells[y][x];
    //左双击对显示的数字格子起作用, 且该格子周围的标记数等于该数字
    if (pCell->mtype == NUMBER && pCell->state == DISPLAY 
        && aroundMarks(x, y) == pCell->val)
    {
        showAround(x, y);
    }
}
 
void onCellLClick(int x, int y)
{
    Cell* pCell = &cells[y][x];
    //左击只对未知格子起作用
    if (pCell->state == UNKNOWN)
    {
        if (pCell->mtype == MINE)
        {
            gameOver(x, y);
        }
        else
        {
            pCell->state = DISPLAY;
            unkwLeft--;
            drawCell(x, y);
            if (pCell->mtype == EMPTY)
            {
                showAround(x, y);
            }
        }
    }    
}
 
void onCellRClick(int x, int y)
{
    Cell* pCell = &cells[y][x];
    //右击对未知, 标记格子起作用
    if (pCell->state != DISPLAY)
    {
        if (pCell->state == UNKNOWN)
        {
            pCell->state = MARKED;
            mineLeft -= pCell->mtype == MINE ? 1 : 0;
            unkwLeft--;
            flagCnt++;
        }
        else
        {
            pCell->state = UNKNOWN;
            mineLeft += pCell->mtype == MINE ? 1 : 0;
            unkwLeft++;
            flagCnt--;
        }
        drawCell(x, y);
        setMinesLeft();
    }
}
 
void onKeyDown(WORD keyCode)
{
    switch (keyCode)
    {
    case VK_F2:        //初级
        HEIGHT   = 9;
        WIDTH    = 9;
        MINE_CNT = 10;
        initGame();
        break;
    case VK_F3:        //中级
        HEIGHT   = 16;
        WIDTH    = 16;
        MINE_CNT = 40;
        initGame();
        break;
    case VK_F4:        //高级
        HEIGHT   = 16;
        WIDTH    = 30;
        MINE_CNT = 99;
        initGame();
        break;
    case VK_F12:
        if (liveLeft < 99)
        {
            setLivesLeft(1);
        }
        break;
    default:
        break;
    }
}
 
void afterMouseEvent()
{
    if (!bGameStart)
    {
        bGameStart = true;
        dwStart = GetTickCount();
    }
    if (mineLeft == 0 && unkwLeft == 0)
    {
        gameWin();
    }
}
 
int main(int argc, char* argv[])
{
    hIn  = GetStdHandle(STD_INPUT_HANDLE);
    hOut = CreateConsoleScreenBuffer(
            GENERIC_WRITE,
            0,
            NULL,
            CONSOLE_TEXTMODE_BUFFER,
            NULL
            );
    CONSOLE_CURSOR_INFO cci;
    cci.dwSize = 1;
    cci.bVisible = FALSE;
    SetConsoleCursorInfo(hOut, &cci);    //隐藏光标
    SetConsoleActiveScreenBuffer(hOut);
    initGame();
    //监听事件
    for (;;)
    {
        DWORD nEvts;
        GetNumberOfConsoleInputEvents(hIn, &nEvts);
        if (nEvts > 0)
        {
            INPUT_RECORD inpRec;
            ReadConsoleInput(hIn, &inpRec, 1, &nEvts);
            bool bClked = false;    //是否有合法鼠标事件发生
            if (!bGameStop && inpRec.EventType == MOUSE_EVENT)
            {
                int x = BOARDX(inpRec.Event.MouseEvent.dwMousePosition.X);
                int y = BOARDY(inpRec.Event.MouseEvent.dwMousePosition.Y);
                if (!isCell(x, y))
                {
                    continue;
                }
                bClked = true;
                switch (inpRec.Event.MouseEvent.dwButtonState)
                {
                case FROM_LEFT_1ST_BUTTON_PRESSED:
                    if (inpRec.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK)
                    {
                        onCellLDBLClick(x, y);
                        break;    //处理过双击不再处理单击
                    }
                    onCellLClick(x, y);
                    break;
                case RIGHTMOST_BUTTON_PRESSED:
                    onCellRClick(x, y);
                    break;
                default:
                    bClked = false;
                    break;
                }
                if (bClked)
                {
                    afterMouseEvent();
                }
            }
            if (inpRec.EventType == KEY_EVENT)    //按键事件
            {
                onKeyDown(inpRec.Event.KeyEvent.wVirtualKeyCode);
                Sleep(100);
            }
            FlushConsoleInputBuffer(hIn);
        }
        setElapsedTime();
        Sleep(50);
    }
    return 0;
}

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

相关文章

  • C++构建函数使用介绍

    C++构建函数使用介绍

    构造函数主要作用在于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无须手动调用;析构函数主要作用在于对象销毁前系统自动调用,执行一 些清理工作
    2022-08-08
  • C++文件IO流及stringstream流读写文件和字符串操作详解

    C++文件IO流及stringstream流读写文件和字符串操作详解

    本文详细介绍C++中的文件IO流和stringstream流的使用方法,包括文件的打开、读写操作,以及字符串的输入输出、转换等操作。同时提供实用的示例代码和技巧,帮助读者更好地掌握这两种流的使用
    2023-04-04
  • 详解C语言#define预处理宏定义

    详解C语言#define预处理宏定义

    本文主要介绍了C语言#define预处理宏定义,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • 详解C++ 引用

    详解C++ 引用

    这篇文章主要介绍了C++ 引用的相关资料,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-07-07
  • 纯C语言实现五子棋

    纯C语言实现五子棋

    本文给大家分享的是去年制作的一个纯C语言实现的五子棋的代码,虽然没有带漂亮的界面,还是推荐给大家,有需要的小伙伴可以参考下。
    2015-03-03
  • vs2022 qt环境搭建调试的方法步骤

    vs2022 qt环境搭建调试的方法步骤

    最近net6和vs2022发布,本文就详细的介绍一下vs2022 qt环境搭建调试的方法步骤,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • C语言简明讲解操作符++和--的使用方法

    C语言简明讲解操作符++和--的使用方法

    ++和--运算符分别是+=1和-=1的简写。设计这样两个运算符的本意是⽅便程序员,但i++和++i使⽤不恰当有时候会造成混淆,反倒令刚入门的C程序员有点混乱
    2022-04-04
  • C语言中进制知识汇总

    C语言中进制知识汇总

    在C语言里,整数有三种表示形式:十进制,八进制,十六进制。 其中以数字0开头,由0~7组成的数是八进制。以0X或0x开头,由0~9,A~F或a~f 组成是十六进制。除表示正负的符号外,以1~9开头,由0~9组成是十进制。
    2016-05-05
  • C++对cin输入字符的判断及分段函数处理方法示例

    C++对cin输入字符的判断及分段函数处理方法示例

    这篇文章主要介绍了C++对cin输入字符的判断及分段函数处理方法,结合实例形式分析了C++输入判断及处理相关操作技巧,需要的朋友可以参考下
    2017-09-09
  • C++ 如何判断四个点是否构成正方形

    C++ 如何判断四个点是否构成正方形

    这篇文章主要介绍了C++ 如何判断四个点是否构成正方形的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03

最新评论