扫雷游戏的实现

还记得那艘旧扫雷舰吗? 我们在一个正方形的棋盘上玩,我们必须在没有地雷的格子上点击棋盘。显然,我们不知道地雷在哪里。如果点击了一个有地雷的单元格,我们就输了,否则我们仍在游戏中。 这个游戏有三个关卡-

null
  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()函数选择他的动作。

还有两块板- realBoard 我的董事会 .我们玩游戏 我的董事会 realBoard 存储矿山的位置。在整个比赛中, realBoard 保持不变,而 我的董事会 根据用户的移动可以看到许多变化。 我们可以在初级、中级和高级中选择任何级别。这是通过在函数中传递上述其中一项来实现的—— 选择困难级别() [但是,在用户输入游戏中,在玩游戏之前会向用户询问此选项]。 一旦选择了级别,则 realBoard 我的董事会 相应地初始化,我们将地雷放置在 realBoard 随机我们还使用函数指定移动 移动() 在玩游戏之前[但是在用户输入游戏中,用户自己在整个游戏中分配动作,直到游戏结束]。 我们可以在玩游戏前作弊(通过知道地雷的位置),使用该功能—— 扫雷工 .在代码中,此函数被注释。因此,如果你害怕失败,那么取消对该函数的注释,然后播放! 然后玩游戏,直到用户要么赢(当用户从未踏步/点击包含地雷的单元格时),要么输(当用户踏步/点击包含地雷的单元格时)。这在while()循环中表示。当用户赢或输时,while()循环终止。 这个 makeMove() while循环中的函数从随机分配的移动中随机获得移动。[但是在用户输入游戏中,此功能会提示用户输入自己的移动]。 此外,为了确保用户的第一步始终是安全的(因为用户在第一步中可能会因为踩/点击一个有地雷的单元格而失败,这将非常不公平),我们使用if语句进行了检查——if( 当前移动索引 == 0) 这个程序的生命线是递归函数—— 扫雷 如果用户踩下/点击一枚地雷,则此函数返回一个true,如果他踩下/点击一个安全单元,则会丢失else,然后我们得到该单元周围地雷的计数。我们使用这个函数 countAdjacentMines() 计算相邻的矿井。因为最多可以有8个周围细胞,所以我们检查所有8个周围细胞。 如果这个单元没有相邻的地雷,那么我们会递归地点击/步进所有安全的相邻单元(从而减少游戏时间)。如果这个单元至少有一个相邻的地雷,那么这个计数就会显示在当前单元上。这是给玩家的一个提示,这样他就可以避免按逻辑步进/点击有地雷的单元格。 此外,如果你点击一个没有相邻地雷的单元(在周围八个单元中的任何一个),那么所有相邻单元都会自动清除,从而节省我们的时间。 所以我们可以看到,我们不必总是点击所有没有地雷的单元格(单元格总数–地雷数量)来获胜。如果我们幸运的话,我们可以在很短的时间内通过点击没有任何相邻单元格的单元格来获胜。 用户继续玩游戏,直到他踩下/点击一个有地雷的单元格(在这种情况下,用户输了),或者如果他已经点击/踩下了所有安全单元格(在这种情况下,用户赢了)。

CPP

// A C++ Program to Implement and Play Minesweeper
#include<bits/stdc++.h>
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; i<SIDE; i++)
printf ( "%d " , i);
printf ( "" );
for (i=0; i<SIDE; i++)
{
printf ( "%d   " , i);
for (j=0; j<SIDE; j++)
printf ( "%c " , myBoard[i][j]);
printf ( "" );
}
return ;
}
// A Function to count the number of
// mines in the adjacent cells
int countAdjacentMines( int row, int col, int mines[][2],
char realBoard[][MAXSIDE])
{
int i;
int count = 0;
/*
Count all the mines in the 8 adjacent
cells
N.W   N   N.E
|   /
|  /
W----Cell----E
/ |
/   |
S.W    S   S.E
Cell-->Current 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; i<MINES; i++)
myBoard[mines[i][0]][mines[i][1]]= '*' ;
printBoard (myBoard);
printf ( "You lost!" );
return ( true ) ;
}
else
{
// Calculate the number of adjacent mines and put it
// on the board
int count = countAdjacentMines(row, col, mines, realBoard);
(*movesLeft)--;
myBoard[row][col] = count + '0' ;
if (!count)
{
/*
Recur for all 8 adjacent cells
N.W   N   N.E
|   /
|  /
W----Cell----E
/ |
/   |
S.W    S   S.E
Cell-->Current 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<MINES; )
{
int random = rand () % (SIDE*SIDE);
int x = random / SIDE;
int y = random % SIDE;
// Add the mine if no mine is placed at this
// position on the board
if (mark[random] == false )
{
// Row Index of the Mine
mines[i][0]= x;
// Column Index of the Mine
mines[i][1] = y;
// Place the mine
realBoard[mines[i][0]][mines[i][1]] = '*' ;
mark[random] = true ;
i++;
}
}
return ;
}
// A Function to initialise the game
void initialise( char realBoard[][MAXSIDE], char myBoard[][MAXSIDE])
{
// Initiate the random number generator so that
// the same configuration doesn't arises
srand ( time (NULL));
// Assign all the cells as mine-free
for ( int i=0; i<SIDE; i++)
{
for ( int j=0; j<SIDE; j++)
{
myBoard[i][j] = realBoard[i][j] = '-' ;
}
}
return ;
}
// A Function to cheat by revealing where the mines are
// placed.
void cheatMinesweeper ( char realBoard[][MAXSIDE])
{
printf ( "The mines locations are-" );
printBoard (realBoard);
return ;
}
// A function to replace the mine from (row, col) and put
// it to a vacant space
void replaceMine ( int row, int col, char board[][MAXSIDE])
{
for ( int i=0; i<SIDE; i++)
{
for ( int j=0; j<SIDE; j++)
{
// Find the first location in the board
// which is not having a mine and put a mine
// there.
if (board[i][j] != '*' )
{
board[i][j] = '*' ;
board[row][col] = '-' ;
return ;
}
}
}
return ;
}
// A Function to play Minesweeper game
void playMinesweeper ()
{
// Initially the game is not over
bool gameOver = false ;
// Actual Board and My Board
char realBoard[MAXSIDE][MAXSIDE], myBoard[MAXSIDE][MAXSIDE];
int movesLeft = SIDE * SIDE - MINES, x, y;
int mines[MAXMINES][2]; // stores (x,y) coordinates of all mines.
initialise (realBoard, myBoard);
// Place the Mines randomly
placeMines (mines, realBoard);
/*
If you want to cheat and know
where mines are before playing the game
then uncomment this part
cheatMinesweeper(realBoard);
*/
// You are in the game until you have not opened a mine
// So keep playing
int currentMoveIndex = 0;
while (gameOver == false )
{
printf ( "Current Status of Board : " );
printBoard (myBoard);
makeMove (&x, &y);
// This is to guarantee that the first move is
// always safe
// If it is the first move of the game
if (currentMoveIndex == 0)
{
// If the first move itself is a mine
// then we remove the mine from that location
if (isMine (x, y, realBoard) == true )
replaceMine (x, y, realBoard);
}
currentMoveIndex ++;
gameOver = playMinesweeperUtil (myBoard, realBoard, mines, x, y, &movesLeft);
if ((gameOver == false ) && (movesLeft == 0))
{
printf ( "You won !" );
gameOver = true ;
}
}
return ;
}
// A Function to choose the difficulty level
// of the game
void chooseDifficultyLevel ()
{
/*
--> 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" );
printf ( "Press 0 for BEGINNER (9 * 9 Cells and 10 Mines)" );
printf ( "Press 1 for INTERMEDIATE (16 * 16 Cells and 40 Mines)" );
printf ( "Press 2 for ADVANCED (24 * 24 Cells and 99 Mines)" );
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);
}


输入:

01 22 33 44 5

输出:

Enter the Difficulty LevelPress 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<bits/stdc++.h>
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 ( "My move is (%d, %d)" , *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; i<movesLeft; )
{
int random = rand () % (SIDE*SIDE);
int x = random / SIDE;
int y = random % SIDE;
// Add the mine if no mine is placed at this
// position on the board
if (mark[random] == false )
{
// Row Index of the Mine
moves[i][0]= x;
// Column Index of the Mine
moves[i][1] = y;
mark[random] = true ;
i++;
}
}
return ;
}
// A Function to print the current gameplay board
void printBoard( char myBoard[][MAXSIDE])
{
int i,j;
printf ( "    " );
for (i=0; i<SIDE; i++)
printf ( "%d " , i);
printf ( "" );
for (i=0; i<SIDE; i++)
{
printf ( "%d   " , i);
for (j=0; j<SIDE; j++)
printf ( "%c " , myBoard[i][j]);
printf ( "" );
}
return ;
}
// A Function to count the number of
// mines in the adjacent cells
int countAdjacentMines( int row , int col , int mines[][2], char realBoard[][MAXSIDE])
{
int i;
int count = 0;
/*
Count all the mines in the 8 adjacent
cells
N.W   N   N.E
|   /
|  /
W----Cell----E
/ |
/   |
S.W    S   S.E
Cell-->Current 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; i<MINES; i++)
myBoard[mines[i][0]][mines[i][1]]= '*' ;
printBoard (myBoard);
printf ( "You lost!" );
return ( true ) ;
}
else
{
// Calculate the number of adjacent mines and put it
// on the board.
int count = countAdjacentMines(row, col, mines, realBoard);
(*movesLeft)--;
myBoard[row][col] = count + '0' ;
if (!count)
{
/*
Recur for all 8 adjacent cells
N.W   N   N.E
|   /
|  /
W----Cell----E
/ |
/   |
S.W    S   S.E
Cell-->Current 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<MINES; )
{
int random = rand () % (SIDE*SIDE);
int x = random / SIDE;
int y = random % SIDE;
// Add the mine if no mine is placed at this
// position on the board
if (mark[random] == false )
{
// Row Index of the Mine
mines[i][0]= x;
// Column Index of the Mine
mines[i][1] = y;
// Place the mine
realBoard[mines[i][0]][mines[i][1]] = '*' ;
mark[random] = true ;
i++;
}
}
return ;
}
// A Function to initialise the game
void initialise ( char realBoard[][MAXSIDE], char myBoard[][MAXSIDE])
{
// Initiate the random number generator so that
// the same configuration doesn't arises
srand ( time (NULL));
// Assign all the cells as mine-free
for ( int i=0; i<SIDE; i++)
{
for ( int j=0; j<SIDE; j++)
{
myBoard[i][j] = realBoard[i][j] = '-' ;
}
}
return ;
}
// A Function to cheat by revealing where the mines are
// placed.
void cheatMinesweeper ( char realBoard[][MAXSIDE])
{
printf ( "The mines locations are-" );
printBoard (realBoard);
return ;
}
// A function to replace the mine from (row, col) and put
// it to a vacant space
void replaceMine ( int row, int col, char board[][MAXSIDE])
{
for ( int i=0; i<SIDE; i++)
{
for ( int j=0; j<SIDE; j++)
{
// Find the first location in the board
// which is not having a mine and put a mine
// there.
if (board[i][j] != '*' )
{
board[i][j] = '*' ;
board[row][col] = '-' ;
return ;
}
}
}
return ;
}
// A Function to play Minesweeper game
void playMinesweeper ()
{
// Initially the game is not over
bool gameOver = false ;
// Actual Board and My Board
char realBoard[MAXSIDE][MAXSIDE], myBoard[MAXSIDE][MAXSIDE];
int movesLeft = SIDE * SIDE - MINES, x, y;
int mines[MAXMINES][2]; // Stores (x, y) coordinates of all mines.
int moves[MOVESIZE][2]; // Stores (x, y) coordinates of the moves
// Initialise the Game
initialise (realBoard, myBoard);
// Place the Mines randomly
placeMines (mines, realBoard);
// Assign Moves
// If you want to make your own input move,
// then the below function should be commnented
assignMoves (moves, movesLeft);
/*
//If you want to cheat and know
//where mines are before playing the game
//then uncomment this part
cheatMinesweeper(realBoard);
*/
// You are in the game until you have not opened a mine
// So keep playing
int currentMoveIndex = 0;
while (gameOver == false )
{
printf ( "Current Status of Board : " );
printBoard (myBoard);
makeMove (&x, &y, moves, currentMoveIndex);
// This is to guarantee that the first move is
// always safe
// If it is the first move of the game
if (currentMoveIndex == 0)
{
// If the first move itself is a mine
// then we remove the mine from that location
if (isMine (x, y, realBoard) == true )
replaceMine (x, y, realBoard);
}
currentMoveIndex ++;
gameOver = playMinesweeperUtil (myBoard, realBoard, mines, x, y, &movesLeft);
if ((gameOver == false ) && (movesLeft == 0))
{
printf ( "You won !" );
gameOver = true ;
}
}
return ;
}
// A Function to choose the difficulty level
// of the game
void chooseDifficultyLevel ( int level)
{
/*
--> 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!

本文由 拉希特·贝尔瓦里亚 .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以写一篇文章,然后将文章邮寄给评论-team@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。 如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写评论

© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享