📜  扫雷游戏的实现

📅  最后修改于: 2022-05-13 01:57:40.842000             🧑  作者: Mango

扫雷游戏的实现

还记得旧的扫雷吗?
我们在一块方板上玩,我们必须点击没有地雷的单元格上的板。显然我们不知道地雷在哪里。如果单击存在地雷的单元格,则我们输了,否则我们仍在游戏中。
这个游戏分为三个级别-

  1. 初学者- 9 * 9 板和 10 地雷
  2. 中级- 16 * 16 板和 40 地雷
  3. 高级– 24 * 24 板和 99 地雷

找到地雷的概率——

  • 初级水平 - 10/81 (0.12)
  • 中级 - 40/256 (0.15)
  • 高级 - 99 / 576 (0.17)

瓷砖数量的增加提高了难度。因此,随着我们进入下一个级别,复杂性级别会增加。
它可能看起来像是一个完全基于运气的游戏(如果你在整个游戏中没有踩到任何地雷,那么你很幸运,如果你踩到了一个地雷,那么你会很不幸)。但这不是一个完全基于运气的游戏。相反,如果您遵循游戏本身给出的提示,您几乎每次都可以获胜。

赢得比赛的提示

  • 当我们点击一个在周围八个单元格中的一个或多个中具有相邻地雷的单元格时,我们就会知道有多少相邻单元格中有地雷。所以我们可以做一些合乎逻辑的猜测来找出哪些细胞有地雷。
  • 如果您单击没有相邻地雷的单元格(在周围八个单元格中的任何一个单元格中),则所有相邻单元格都会自动清除,从而节省了我们的时间。
  • 所以我们可以看到,我们不必总是点击所有没有地雷的单元格(单元格总数 - 地雷数)才能获胜。如果我们幸运的话,我们可以在很短的时间内通过点击没有任何相邻单元格有地雷的单元格来获胜。

执行

这里给出了游戏的两种实现:

  1. 在第一个实现中,用户的移动是使用 rand()函数随机选择的。
  2. 在第二个实现中,用户自己使用 scanf()函数选择他的动作。

还有两个板 - realBoardmyBoard 。我们在myBoard中玩我们的游戏, realBoard存储地雷的位置。在整个游戏过程中, realBoard保持不变,而myBoard会根据用户的移动看到许多变化。
我们可以选择任何级别——初级、中级和高级。这是通过在函数中传递上述之一来完成的——chooseDifficultyLevel() [但是在用户输入游戏中,在玩游戏之前会向用户询问此选项]。
一旦选择了关卡, realBoardmyBoard 就会相应地初始化,我们将地雷随机放置在realBoard中。我们还在玩游戏之前使用函数assignMoves()分配移动[但是在用户输入游戏中,用户自己在整个游戏期间分配移动直到游戏结束]。
我们可以在玩之前作弊(通过知道地雷的位置)使用函数——cheatMinesweepeer() 。在代码中这个函数被注释掉了。因此,如果您害怕输,请取消注释此函数,然后玩!
然后玩游戏直到用户获胜(当用户从不踩/点击包含地雷的单元格时)或失败(当用户踩到/点击包含地雷的单元格时)。这在 while() 循环中表示。当用户赢或输时,while() 循环终止。
while 循环中的makeMove()函数从随机分配的移动中随机获取移动。 [但在用户输入游戏中,此函数提示用户输入自己的动作]。
另外为了保证用户的第一步始终是安全的(因为用户可能会在第一步中通过踩/单击有地雷的单元格本身失败,这将非常不公平),我们通过使用进行检查if 语句 – if ( currentMoveIndex == 0)
这个程序的生命线是递归函数——playMinesweeperUtil()
如果用户踩到/单击地雷,则此函数返回 true,因此如果他踩到/单击安全单元格,则他会丢失,然后我们会获得该单元格周围的地雷计数。我们使用函数countAdjacentMines()来计算相邻的地雷。由于最多可以有 8 个周围的单元格,因此我们检查所有 8 个周围的单元格。
如果该单元格没有相邻的地雷,则我们递归地单击/踩到所有安全的相邻单元格(从而减少游戏时间)。如果该单元格至少有一个相邻的地雷,则该计数将显示在当前单元格上。这是给玩家的一个提示,以便他可以避免踩/点击有地雷的单元格。
此外,如果您单击没有相邻地雷的单元格(在周围八个单元格中的任何一个单元格中),则所有相邻单元格都会自动清除,从而节省了我们的时间。
所以我们可以看到,我们不必总是点击所有没有地雷的单元格(单元格总数 - 地雷数)才能获胜。如果我们幸运的话,我们可以在很短的时间内通过点击没有任何相邻单元格有地雷的单元格来获胜。
用户继续玩,直到他踩到/点击了一个有地雷的单元格(在这种情况下用户输了)或者如果他点击/踩到了所有安全单元格(在这种情况下用户赢了)。

CPP
// A C++ Program to Implement and Play Minesweeper
 
#include
using namespace std;
 
#define BEGINNER 0
#define INTERMEDIATE 1
#define ADVANCED 2
#define MAXSIDE 25
#define MAXMINES 99
#define MOVESIZE 526 // (25 * 25 - 99)
 
int SIDE ; // side length of the board
int MINES ; // number of mines on the board
 
// A Utility Function to check whether given cell (row, col)
// is a valid cell or not
bool isValid(int row, int col)
{
    // Returns true if row number and column number
    // is in range
    return (row >= 0) && (row < SIDE) &&
           (col >= 0) && (col < SIDE);
}
 
// A Utility Function to check whether given cell (row, col)
// has a mine or not.
bool isMine (int row, int col, char board[][MAXSIDE])
{
    if (board[row][col] == '*')
        return (true);
    else
        return (false);
}
 
// A Function to get the user's move
void makeMove(int *x, int *y)
{
    // Take the input move
    printf("Enter your move, (row, column) -> ");
    scanf("%d %d", x, y);
    return;
}
 
// A Function to print the current gameplay board
void printBoard(char myBoard[][MAXSIDE])
{
    int i, j;
 
    printf ("    ");
 
    for (i=0; iCurrent Cell (row, col)
        N -->  North        (row-1, col)
        S -->  South        (row+1, col)
        E -->  East         (row, col+1)
        W -->  West            (row, col-1)
        N.E--> North-East   (row-1, col+1)
        N.W--> North-West   (row-1, col-1)
        S.E--> South-East   (row+1, col+1)
        S.W--> South-West   (row+1, col-1)
    */
 
    //----------- 1st Neighbour (North) ------------
 
        // Only process this cell if this is a valid one
        if (isValid (row-1, col) == true)
        {
               if (isMine (row-1, col, realBoard) == true)
               count++;
        }
 
    //----------- 2nd Neighbour (South) ------------
 
        // Only process this cell if this is a valid one
        if (isValid (row+1, col) == true)
        {
               if (isMine (row+1, col, realBoard) == true)
               count++;
        }
 
    //----------- 3rd Neighbour (East) ------------
 
        // Only process this cell if this is a valid one
        if (isValid (row, col+1) == true)
        {
            if (isMine (row, col+1, realBoard) == true)
               count++;
        }
 
    //----------- 4th Neighbour (West) ------------
 
        // Only process this cell if this is a valid one
        if (isValid (row, col-1) == true)
        {
               if (isMine (row, col-1, realBoard) == true)
               count++;
        }
 
    //----------- 5th Neighbour (North-East) ------------
 
        // Only process this cell if this is a valid one
        if (isValid (row-1, col+1) == true)
        {
            if (isMine (row-1, col+1, realBoard) == true)
               count++;
        }
 
     //----------- 6th Neighbour (North-West) ------------
 
        // Only process this cell if this is a valid one
        if (isValid (row-1, col-1) == true)
        {
             if (isMine (row-1, col-1, realBoard) == true)
               count++;
        }
 
     //----------- 7th Neighbour (South-East) ------------
 
        // Only process this cell if this is a valid one
        if (isValid (row+1, col+1) == true)
        {
               if (isMine (row+1, col+1, realBoard) == true)
               count++;
        }
 
    //----------- 8th Neighbour (South-West) ------------
 
        // Only process this cell if this is a valid one
        if (isValid (row+1, col-1) == true)
        {
            if (isMine (row+1, col-1, realBoard) == true)
               count++;
        }
 
    return (count);
}
 
// A Recursive Function to play the Minesweeper Game
bool playMinesweeperUtil(char myBoard[][MAXSIDE], char realBoard[][MAXSIDE],
            int mines[][2], int row, int col, int *movesLeft)
{
 
    // Base Case of Recursion
    if (myBoard[row][col] != '-')
        return (false);
 
    int i, j;
 
    // You opened a mine
    // You are going to lose
    if (realBoard[row][col] == '*')
    {
        myBoard[row][col]='*';
 
        for (i=0; iCurrent Cell (row, col)
            N -->  North        (row-1, col)
            S -->  South        (row+1, col)
            E -->  East         (row, col+1)
            W -->  West            (row, col-1)
            N.E--> North-East   (row-1, col+1)
            N.W--> North-West   (row-1, col-1)
            S.E--> South-East   (row+1, col+1)
            S.W--> South-West   (row+1, col-1)
            */
 
                //----------- 1st Neighbour (North) ------------
 
            // Only process this cell if this is a valid one
            if (isValid (row-1, col) == true)
            {
                   if (isMine (row-1, col, realBoard) == false)
                   playMinesweeperUtil(myBoard, realBoard, mines, row-1, col, movesLeft);
            }
 
            //----------- 2nd Neighbour (South) ------------
 
            // Only process this cell if this is a valid one
            if (isValid (row+1, col) == true)
            {
                   if (isMine (row+1, col, realBoard) == false)
                    playMinesweeperUtil(myBoard, realBoard, mines, row+1, col, movesLeft);
            }
 
            //----------- 3rd Neighbour (East) ------------
 
            // Only process this cell if this is a valid one
            if (isValid (row, col+1) == true)
            {
                if (isMine (row, col+1, realBoard) == false)
                    playMinesweeperUtil(myBoard, realBoard, mines, row, col+1, movesLeft);
            }
 
            //----------- 4th Neighbour (West) ------------
 
            // Only process this cell if this is a valid one
            if (isValid (row, col-1) == true)
            {
                   if (isMine (row, col-1, realBoard) == false)
                    playMinesweeperUtil(myBoard, realBoard, mines, row, col-1, movesLeft);
            }
 
            //----------- 5th Neighbour (North-East) ------------
 
            // Only process this cell if this is a valid one
            if (isValid (row-1, col+1) == true)
            {
                if (isMine (row-1, col+1, realBoard) == false)
                    playMinesweeperUtil(myBoard, realBoard, mines, row-1, col+1, movesLeft);
            }
 
             //----------- 6th Neighbour (North-West) ------------
 
            // Only process this cell if this is a valid one
            if (isValid (row-1, col-1) == true)
            {
                 if (isMine (row-1, col-1, realBoard) == false)
                    playMinesweeperUtil(myBoard, realBoard, mines, row-1, col-1, movesLeft);
            }
 
             //----------- 7th Neighbour (South-East) ------------
 
            // Only process this cell if this is a valid one
            if (isValid (row+1, col+1) == true)
            {
                 if (isMine (row+1, col+1, realBoard) == false)
                    playMinesweeperUtil(myBoard, realBoard, mines, row+1, col+1, movesLeft);
            }
 
            //----------- 8th Neighbour (South-West) ------------
 
            // Only process this cell if this is a valid one
            if (isValid (row+1, col-1) == true)
            {
                if (isMine (row+1, col-1, realBoard) == false)
                    playMinesweeperUtil(myBoard, realBoard, mines, row+1, col-1, movesLeft);
            }
        }
 
        return (false);
    }
}
 
// A Function to place the mines randomly
// on the board
void placeMines(int mines[][2], char realBoard[][MAXSIDE])
{
    bool mark[MAXSIDE*MAXSIDE];
 
    memset (mark, false, sizeof (mark));
 
    // Continue until all random mines have been created.
    for (int i=0; i BEGINNER = 9 * 9 Cells and 10 Mines
    --> INTERMEDIATE = 16 * 16 Cells and 40 Mines
    --> ADVANCED = 24 * 24 Cells and 99 Mines
    */
 
    int level;
 
    printf ("Enter the Difficulty Level\n");
    printf ("Press 0 for BEGINNER (9 * 9 Cells and 10 Mines)\n");
    printf ("Press 1 for INTERMEDIATE (16 * 16 Cells and 40 Mines)\n");
    printf ("Press 2 for ADVANCED (24 * 24 Cells and 99 Mines)\n");
 
    scanf ("%d", &level);
 
    if (level == BEGINNER)
    {
        SIDE = 9;
        MINES = 10;
    }
 
    if (level == INTERMEDIATE)
    {
        SIDE = 16;
        MINES = 40;
    }
 
    if (level == ADVANCED)
    {
        SIDE = 24;
        MINES = 99;
    }
 
    return;
}
 
// Driver Program to test above functions
int main()
{
    /* Choose a level between
    --> BEGINNER = 9 * 9 Cells and 10 Mines
    --> INTERMEDIATE = 16 * 16 Cells and 40 Mines
    --> ADVANCED = 24 * 24 Cells and 99 Mines
    */
    chooseDifficultyLevel ();
 
    playMinesweeper ();
 
    return (0);
}


CPP
// A C++ Program to Implement and Play Minesweeper
// without taking input from user
 
#include
using namespace std;
 
#define BEGINNER 0
#define INTERMEDIATE 1
#define ADVANCED 2
#define MAXSIDE 25
#define MAXMINES 99
#define MOVESIZE 526 // (25 * 25 - 99)
 
int SIDE ; // side length of the board
int MINES ; // number of mines on the board
 
// A Utility Function to check whether given cell (row, col)
// is a valid cell or not
bool isValid(int row, int col)
{
    // Returns true if row number and column number
    // is in range
    return (row >= 0) && (row < SIDE) &&
           (col >= 0) && (col < SIDE);
}
 
// A Utility Function to check whether given cell (row, col)
// has a mine or not.
bool isMine (int row, int col, char board[][MAXSIDE])
{
    if (board[row][col] == '*')
        return (true);
    else
        return (false);
}
 
// A Function to get the user's move and print it
// All the moves are assumed to be distinct and valid.
void makeMove (int *x, int *y, int moves[][2], int currentMoveIndex)
{
    *x = moves[currentMoveIndex][0];
    *y = moves[currentMoveIndex][1];
 
    printf ("\nMy move is (%d, %d)\n", *x, *y);
 
    /*
    // The above moves are pre-defined
    // If you want to make your own move
    // then uncomment this section and comment
    // the above section
 
      scanf("%d %d", x, y);
    */
 
    return;
}
 
// A Function to randomly assign moves
void assignMoves (int moves[][2], int movesLeft)
{
    bool mark[MAXSIDE*MAXSIDE];
 
    memset(mark, false, sizeof(mark));
 
    // Continue until all moves are assigned.
    for (int i=0; iCurrent Cell (row, col)
        N -->  North        (row-1, col)
        S -->  South        (row+1, col)
        E -->  East         (row, col+1)
        W -->  West            (row, col-1)
        N.E--> North-East   (row-1, col+1)
        N.W--> North-West   (row-1, col-1)
        S.E--> South-East   (row+1, col+1)
        S.W--> South-West   (row+1, col-1)
    */
 
    //----------- 1st Neighbour (North) ------------
 
        // Only process this cell if this is a valid one
        if (isValid (row-1, col) == true)
        {
               if (isMine (row-1, col, realBoard) == true)
               count++;
        }
 
    //----------- 2nd Neighbour (South) ------------
 
        // Only process this cell if this is a valid one
        if (isValid (row+1, col) == true)
        {
               if (isMine (row+1, col, realBoard) == true)
               count++;
        }
 
    //----------- 3rd Neighbour (East) ------------
 
        // Only process this cell if this is a valid one
        if (isValid (row, col+1) == true)
        {
            if (isMine (row, col+1, realBoard) == true)
               count++;
        }
 
    //----------- 4th Neighbour (West) ------------
 
        // Only process this cell if this is a valid one
        if (isValid (row, col-1) == true)
        {
               if (isMine (row, col-1, realBoard) == true)
               count++;
        }
 
    //----------- 5th Neighbour (North-East) ------------
 
        // Only process this cell if this is a valid one
        if (isValid (row-1, col+1) == true)
        {
            if (isMine (row-1, col+1, realBoard) == true)
               count++;
        }
 
     //----------- 6th Neighbour (North-West) ------------
 
        // Only process this cell if this is a valid one
        if (isValid (row-1, col-1) == true)
        {
             if (isMine (row-1, col-1, realBoard) == true)
               count++;
        }
 
     //----------- 7th Neighbour (South-East) ------------
 
        // Only process this cell if this is a valid one
        if (isValid (row+1, col+1) == true)
        {
               if (isMine (row+1, col+1, realBoard) == true)
               count++;
        }
 
    //----------- 8th Neighbour (South-West) ------------
 
        // Only process this cell if this is a valid one
        if (isValid (row+1, col-1) == true)
        {
            if (isMine (row+1, col-1, realBoard) == true)
               count++;
        }
 
    return (count);
}
 
// A Recursive Function to play the Minesweeper Game
bool playMinesweeperUtil(char myBoard[][MAXSIDE], char realBoard[][MAXSIDE],
            int mines[][2], int row, int col, int *movesLeft)
{
 
    // Base Case of Recursion
    if (myBoard[row][col]!='-')
        return (false);
 
    int i, j;
 
    // You opened a mine
    // You are going to lose
    if (realBoard[row][col] == '*')
    {
        myBoard[row][col]='*';
 
        for (i=0; iCurrent Cell (row, col)
            N -->  North        (row-1, col)
            S -->  South        (row+1, col)
            E -->  East         (row, col+1)
            W -->  West            (row, col-1)
            N.E--> North-East   (row-1, col+1)
            N.W--> North-West   (row-1, col-1)
            S.E--> South-East   (row+1, col+1)
            S.W--> South-West   (row+1, col-1)
            */
 
                //----------- 1st Neighbour (North) ------------
 
            // Only process this cell if this is a valid one
            if (isValid (row-1, col) == true)
            {
                   if (isMine (row-1, col, realBoard) == false)
                   playMinesweeperUtil(myBoard, realBoard, mines, row-1, col, movesLeft);
            }
 
            //----------- 2nd Neighbour (South) ------------
 
            // Only process this cell if this is a valid one
            if (isValid (row+1, col) == true)
            {
                   if (isMine (row+1, col, realBoard) == false)
                    playMinesweeperUtil(myBoard, realBoard, mines, row+1, col, movesLeft);
            }
 
            //----------- 3rd Neighbour (East) ------------
 
            // Only process this cell if this is a valid one
            if (isValid (row, col+1) == true)
            {
                if (isMine (row, col+1, realBoard) == false)
                    playMinesweeperUtil(myBoard, realBoard, mines, row, col+1, movesLeft);
            }
 
            //----------- 4th Neighbour (West) ------------
 
            // Only process this cell if this is a valid one
            if (isValid (row, col-1) == true)
            {
                   if (isMine (row, col-1, realBoard) == false)
                    playMinesweeperUtil(myBoard, realBoard, mines, row, col-1, movesLeft);
            }
 
            //----------- 5th Neighbour (North-East) ------------
 
            // Only process this cell if this is a valid one
            if (isValid (row-1, col+1) == true)
            {
                if (isMine (row-1, col+1, realBoard) == false)
                    playMinesweeperUtil(myBoard, realBoard, mines, row-1, col+1, movesLeft);
            }
 
             //----------- 6th Neighbour (North-West) ------------
 
            // Only process this cell if this is a valid one
            if (isValid (row-1, col-1) == true)
            {
                 if (isMine (row-1, col-1, realBoard) == false)
                    playMinesweeperUtil(myBoard, realBoard, mines, row-1, col-1, movesLeft);
            }
 
             //----------- 7th Neighbour (South-East) ------------
 
            // Only process this cell if this is a valid one
            if (isValid (row+1, col+1) == true)
            {
                   if (isMine (row+1, col+1, realBoard) == false)
                    playMinesweeperUtil(myBoard, realBoard, mines, row+1, col+1, movesLeft);
            }
 
            //----------- 8th Neighbour (South-West) ------------
 
            // Only process this cell if this is a valid one
            if (isValid (row+1, col-1) == true)
            {
                if (isMine (row+1, col-1, realBoard) == false)
                    playMinesweeperUtil(myBoard, realBoard, mines, row+1, col-1, movesLeft);
            }
        }
 
        return (false);
    }
}
 
// A Function to place the mines randomly
// on the board
void placeMines(int mines[][2], char realBoard[][MAXSIDE])
{
    bool mark[MAXSIDE*MAXSIDE];
 
    memset (mark, false, sizeof (mark));
 
    // Continue until all random mines have been created.
    for (int i=0; i BEGINNER = 9 * 9 Cells and 10 Mines
    --> INTERMEDIATE = 16 * 16 Cells and 40 Mines
    --> ADVANCED = 24 * 24 Cells and 99 Mines
    */
 
    if (level == BEGINNER)
    {
        SIDE = 9;
        MINES = 10;
    }
 
    if (level == INTERMEDIATE)
    {
        SIDE = 16;
        MINES = 40;
    }
 
    if (level == ADVANCED)
    {
        SIDE = 24;
        MINES = 99;
    }
 
    return;
}
 
// Driver Program to test above functions
int main()
{
    /* Choose a level between
    --> BEGINNER = 9 * 9 Cells and 10 Mines
    --> INTERMEDIATE = 16 * 16 Cells and 40 Mines
    --> ADVANCED = 24 * 24 Cells and 99 Mines
    */
    chooseDifficultyLevel (BEGINNER);
 
    playMinesweeper ();
    return (0);
}


输入:

0
1 2
2 3
3 4
4 5

输出:

Enter the Difficulty Level
Press 0 for BEGINNER (9 * 9 Cells and 10 Mines)
Press 1 for INTERMEDIATE (16 * 16 Cells and 40 Mines)
Press 2 for ADVANCED (24 * 24 Cells and 99 Mines)
Current Status of Board : 
    0 1 2 3 4 5 6 7 8 

0   - - - - - - - - - 
1   - - - - - - - - - 
2   - - - - - - - - - 
3   - - - - - - - - - 
4   - - - - - - - - - 
5   - - - - - - - - - 
6   - - - - - - - - - 
7   - - - - - - - - - 
8   - - - - - - - - - 
Enter your move, (row, column) -> Current Status of Board : 
    0 1 2 3 4 5 6 7 8 

0   - - - - - - - - - 
1   - - 2 - - - - - - 
2   - - - - - - - - - 
3   - - - - - - - - - 
4   - - - - - - - - - 
5   - - - - - - - - - 
6   - - - - - - - - - 
7   - - - - - - - - - 
8   - - - - - - - - - 
Enter your move, (row, column) ->     0 1 2 3 4 5 6 7 8 

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

You lost!

随机选择用户输入时的C程序实现

CPP

// A C++ Program to Implement and Play Minesweeper
// without taking input from user
 
#include
using namespace std;
 
#define BEGINNER 0
#define INTERMEDIATE 1
#define ADVANCED 2
#define MAXSIDE 25
#define MAXMINES 99
#define MOVESIZE 526 // (25 * 25 - 99)
 
int SIDE ; // side length of the board
int MINES ; // number of mines on the board
 
// A Utility Function to check whether given cell (row, col)
// is a valid cell or not
bool isValid(int row, int col)
{
    // Returns true if row number and column number
    // is in range
    return (row >= 0) && (row < SIDE) &&
           (col >= 0) && (col < SIDE);
}
 
// A Utility Function to check whether given cell (row, col)
// has a mine or not.
bool isMine (int row, int col, char board[][MAXSIDE])
{
    if (board[row][col] == '*')
        return (true);
    else
        return (false);
}
 
// A Function to get the user's move and print it
// All the moves are assumed to be distinct and valid.
void makeMove (int *x, int *y, int moves[][2], int currentMoveIndex)
{
    *x = moves[currentMoveIndex][0];
    *y = moves[currentMoveIndex][1];
 
    printf ("\nMy move is (%d, %d)\n", *x, *y);
 
    /*
    // The above moves are pre-defined
    // If you want to make your own move
    // then uncomment this section and comment
    // the above section
 
      scanf("%d %d", x, y);
    */
 
    return;
}
 
// A Function to randomly assign moves
void assignMoves (int moves[][2], int movesLeft)
{
    bool mark[MAXSIDE*MAXSIDE];
 
    memset(mark, false, sizeof(mark));
 
    // Continue until all moves are assigned.
    for (int i=0; iCurrent Cell (row, col)
        N -->  North        (row-1, col)
        S -->  South        (row+1, col)
        E -->  East         (row, col+1)
        W -->  West            (row, col-1)
        N.E--> North-East   (row-1, col+1)
        N.W--> North-West   (row-1, col-1)
        S.E--> South-East   (row+1, col+1)
        S.W--> South-West   (row+1, col-1)
    */
 
    //----------- 1st Neighbour (North) ------------
 
        // Only process this cell if this is a valid one
        if (isValid (row-1, col) == true)
        {
               if (isMine (row-1, col, realBoard) == true)
               count++;
        }
 
    //----------- 2nd Neighbour (South) ------------
 
        // Only process this cell if this is a valid one
        if (isValid (row+1, col) == true)
        {
               if (isMine (row+1, col, realBoard) == true)
               count++;
        }
 
    //----------- 3rd Neighbour (East) ------------
 
        // Only process this cell if this is a valid one
        if (isValid (row, col+1) == true)
        {
            if (isMine (row, col+1, realBoard) == true)
               count++;
        }
 
    //----------- 4th Neighbour (West) ------------
 
        // Only process this cell if this is a valid one
        if (isValid (row, col-1) == true)
        {
               if (isMine (row, col-1, realBoard) == true)
               count++;
        }
 
    //----------- 5th Neighbour (North-East) ------------
 
        // Only process this cell if this is a valid one
        if (isValid (row-1, col+1) == true)
        {
            if (isMine (row-1, col+1, realBoard) == true)
               count++;
        }
 
     //----------- 6th Neighbour (North-West) ------------
 
        // Only process this cell if this is a valid one
        if (isValid (row-1, col-1) == true)
        {
             if (isMine (row-1, col-1, realBoard) == true)
               count++;
        }
 
     //----------- 7th Neighbour (South-East) ------------
 
        // Only process this cell if this is a valid one
        if (isValid (row+1, col+1) == true)
        {
               if (isMine (row+1, col+1, realBoard) == true)
               count++;
        }
 
    //----------- 8th Neighbour (South-West) ------------
 
        // Only process this cell if this is a valid one
        if (isValid (row+1, col-1) == true)
        {
            if (isMine (row+1, col-1, realBoard) == true)
               count++;
        }
 
    return (count);
}
 
// A Recursive Function to play the Minesweeper Game
bool playMinesweeperUtil(char myBoard[][MAXSIDE], char realBoard[][MAXSIDE],
            int mines[][2], int row, int col, int *movesLeft)
{
 
    // Base Case of Recursion
    if (myBoard[row][col]!='-')
        return (false);
 
    int i, j;
 
    // You opened a mine
    // You are going to lose
    if (realBoard[row][col] == '*')
    {
        myBoard[row][col]='*';
 
        for (i=0; iCurrent Cell (row, col)
            N -->  North        (row-1, col)
            S -->  South        (row+1, col)
            E -->  East         (row, col+1)
            W -->  West            (row, col-1)
            N.E--> North-East   (row-1, col+1)
            N.W--> North-West   (row-1, col-1)
            S.E--> South-East   (row+1, col+1)
            S.W--> South-West   (row+1, col-1)
            */
 
                //----------- 1st Neighbour (North) ------------
 
            // Only process this cell if this is a valid one
            if (isValid (row-1, col) == true)
            {
                   if (isMine (row-1, col, realBoard) == false)
                   playMinesweeperUtil(myBoard, realBoard, mines, row-1, col, movesLeft);
            }
 
            //----------- 2nd Neighbour (South) ------------
 
            // Only process this cell if this is a valid one
            if (isValid (row+1, col) == true)
            {
                   if (isMine (row+1, col, realBoard) == false)
                    playMinesweeperUtil(myBoard, realBoard, mines, row+1, col, movesLeft);
            }
 
            //----------- 3rd Neighbour (East) ------------
 
            // Only process this cell if this is a valid one
            if (isValid (row, col+1) == true)
            {
                if (isMine (row, col+1, realBoard) == false)
                    playMinesweeperUtil(myBoard, realBoard, mines, row, col+1, movesLeft);
            }
 
            //----------- 4th Neighbour (West) ------------
 
            // Only process this cell if this is a valid one
            if (isValid (row, col-1) == true)
            {
                   if (isMine (row, col-1, realBoard) == false)
                    playMinesweeperUtil(myBoard, realBoard, mines, row, col-1, movesLeft);
            }
 
            //----------- 5th Neighbour (North-East) ------------
 
            // Only process this cell if this is a valid one
            if (isValid (row-1, col+1) == true)
            {
                if (isMine (row-1, col+1, realBoard) == false)
                    playMinesweeperUtil(myBoard, realBoard, mines, row-1, col+1, movesLeft);
            }
 
             //----------- 6th Neighbour (North-West) ------------
 
            // Only process this cell if this is a valid one
            if (isValid (row-1, col-1) == true)
            {
                 if (isMine (row-1, col-1, realBoard) == false)
                    playMinesweeperUtil(myBoard, realBoard, mines, row-1, col-1, movesLeft);
            }
 
             //----------- 7th Neighbour (South-East) ------------
 
            // Only process this cell if this is a valid one
            if (isValid (row+1, col+1) == true)
            {
                   if (isMine (row+1, col+1, realBoard) == false)
                    playMinesweeperUtil(myBoard, realBoard, mines, row+1, col+1, movesLeft);
            }
 
            //----------- 8th Neighbour (South-West) ------------
 
            // Only process this cell if this is a valid one
            if (isValid (row+1, col-1) == true)
            {
                if (isMine (row+1, col-1, realBoard) == false)
                    playMinesweeperUtil(myBoard, realBoard, mines, row+1, col-1, movesLeft);
            }
        }
 
        return (false);
    }
}
 
// A Function to place the mines randomly
// on the board
void placeMines(int mines[][2], char realBoard[][MAXSIDE])
{
    bool mark[MAXSIDE*MAXSIDE];
 
    memset (mark, false, sizeof (mark));
 
    // Continue until all random mines have been created.
    for (int i=0; i BEGINNER = 9 * 9 Cells and 10 Mines
    --> INTERMEDIATE = 16 * 16 Cells and 40 Mines
    --> ADVANCED = 24 * 24 Cells and 99 Mines
    */
 
    if (level == BEGINNER)
    {
        SIDE = 9;
        MINES = 10;
    }
 
    if (level == INTERMEDIATE)
    {
        SIDE = 16;
        MINES = 40;
    }
 
    if (level == ADVANCED)
    {
        SIDE = 24;
        MINES = 99;
    }
 
    return;
}
 
// Driver Program to test above functions
int main()
{
    /* Choose a level between
    --> BEGINNER = 9 * 9 Cells and 10 Mines
    --> INTERMEDIATE = 16 * 16 Cells and 40 Mines
    --> ADVANCED = 24 * 24 Cells and 99 Mines
    */
    chooseDifficultyLevel (BEGINNER);
 
    playMinesweeper ();
    return (0);
}

输出:

Current Status of Board : 
    0 1 2 3 4 5 6 7 8 

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

My move is (4, 7)
Current Status of Board : 
    0 1 2 3 4 5 6 7 8 

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

My move is (3, 7)
Current Status of Board : 
    0 1 2 3 4 5 6 7 8 

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

My move is (7, 3)
    0 1 2 3 4 5 6 7 8 

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

You lost!