preface
Mine sweeping game is to place a certain number of mines in a chessboard. Players can constantly eliminate mines to realize mine sweeping. If there is no mine nearby, they can eliminate a piece of chess pieces without mine nearby. If they encounter mine, the game will fail. If there is only mine left on the chessboard, mine clearing will succeed.
If you haven't played mine sweeping, you can click here to experience it: mine clearance
Achieve goals
The final implementation style is as follows (which can be further improved according to their own needs):
Minesweeping video demonstration
Implementation steps
Print menu
Provides options for players to choose whether to start or exit the game
void menu(void) { printf("***********************\n"); printf("***** 1,Start the game *****\n"); printf("***** 0,Exit the game *****\n"); printf("***********************\n"); }
Initialize chessboard
When arranging the chessboard, we need to create two chessboards, that is, two-dimensional arrays. Because we need to hide the thunder when sweeping the thunder, we can't let the players see it, and we can't change the position of the thunder, so we create two chessboards, one for storing the thunder (Thunder board for short) and the other for displaying it. We can print the chessboard according to the information of the thunder board. First, you need to initialize the chessboard, initialize all thunder boards to the character '0', and initialize all chessboards to '*'.
void init_board(char board[ROWS][COLS], int row, int col, char ch) //ch is used to control the style of chess pieces { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { board[i][j] = ch; //Initializes all elements in a two-dimensional array to } } }
Lay thunder
The random number function Rand needs to be used to realize the random arrangement of mines when arranging mines. The function srand needs to be called before using rand function, and the timestamp function time needs to be used when using srand. This with tic-tac-toe Chinese computer chess is the same.
void init_mine(char board[ROWS][COLS], int row, int col) { int count = COUNT_MINE; //Custom mine number do { int x = (rand() % 9) + 1; //Control the generation position of mine int y = (rand() % 9) + 1; if (board[x][y] == '0') //Judge whether the current position is a mine. If it is a mine, arrange a mine { board[x][y] = '1'; count--; } } while (count); }
Print chessboard
Print out all the checkerboards, and use some symbols to separate them, so as to facilitate the division of branches and columns. This step needs to be carried out after each minesweeping
void print(char board[ROWS][COLS], int row, int col) { for (int i = 0; i <= ROW; i++) //Number of print columns { printf("%d ", i); } printf("\n"); printf("----------\n"); //Split between rows for (int i = 1; i <= row; i++) { printf("%d ", i); //Number of print columns for (int j = 1; j <= col; j++) { printf("| %c ", board[i][j]); //Split between columns } putchar('|'); printf("\n"); printf("----------\n"); } }
Determine whether to continue the game
If the current position is Lei, end the game immediately.
char is_continue(char board[ROWS][COLS], int row, int col) { if (board[row][col] == '1') //Judge whether the current position is mine return '1'; else return '0'; }
Calculate the number of nearby mines
If the current position is not mine, the number of nearby mines will be displayed.
char count_mine(char board[ROWS][COLS], int row, int col) { char count = '0'; for (int i = row - 1; i <= row + 1; i++) { for (int j = col - 1; j <= col + 1; j++) { if (board[i][j] == '1') //Judge whether the current position is thunder count++; //count } } return count; }
Recursive expansion [key and difficult points]
If there are no mines in the current position and there are no mines in the nearby positions, you can use recursion to expand these positions. When recursing, you should pay attention to: it cannot exceed the boundary of the chessboard, and this position cannot be thunder. When recursing, you need to judge these two conditions first, and then recurse after meeting these two conditions.
void spread_board(char put_board[ROWS][COLS], char show_board[ROWS][COLS], int row, int col) { if (row == 0 || col == 0 || row > ROW || col > COL) //Judge whether the boundary is exceeded return; if (show_board[row][col] != '*') //Judge whether the current position is thunder return; char count = count_mine(put_board, row, col); //Calculate the number of mines near the current position show_board[row][col] = count; //open if (count == '0') { for (int i = row - 1; i <= row + 1; i++) { for (int j = col - 1; j <= col + 1; j++) { spread_board(put_board, show_board, i, j); //Recursive expansion } } } }
Judge whether minesweeping is successful
If the number of unchecked on the chessboard is greater than the number of thunder, then continue the game. If it is equal to the number of thunder, then the minesweeping is successful!!! (this step can also be used to verify the correctness of the code) so at this time, you only need to traverse the chessboard and calculate the number that has not been checked.
int is_discion(char board[ROWS][COLS], int row, int col) { int count = 0; for (int i = 1; i <= row; i++) { for (int j = 1; j <= col; j++) { if (board[i][j] == '*') //Judge whether the current location has been checked { count++; //count } } } return count; }
source code
If you don't know anything about mine sweeping, you can refer to the code here: mine clearance