g. knowledge summary (knowledge required for independently writing games):
1. Basic implementation of function;
2. Two dimensional array;
catalogue
1. Implementation of basic interface
2. Initialize the chessboard (two-dimensional array)
mine clearance
design sketch:
As can be seen from the above renderings, the functions we need to realize are:
1. Random mine burial
2. Display mine number
3. Deployment
4. Marking
5. Determine the winner or loser
It is unrealistic to put thunder, numbers and * in an array at the same time, because if thunder has been placed in a grid, it is impossible to turn it into an asterisk display, so we get a general idea that we should use two arrays, one buried thunder and one display.
As usual, create three files
game.h first references and defines the necessary data
# define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <time.h> #define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2 #define EASY_COUNT 10
This time we use '*' as unknown quantity, '#' as mark, '1' as thunder and '0' as non thunder (here is a foreshadowing)
1. Implementation of basic interface
This part is relatively simple, so just mention it briefly
void menu() { printf("*********************************\n"); printf("********* 1. Play *********\n"); printf("********* 0. Exit *********\n"); printf("*********************************\n"); } void game() { char mine[ROWS][COLS] = { 0 };//Store mine information char show[ROWS][COLS] = { 0 };//A chessboard displayed to players intialize(mine,ROWS ,COLS,'0'); intialize(show,ROWS ,COLS,'*'); //Display chessboard print(show, ROW, COL); //Lay thunder setmine(mine, ROW, COL); //Check search(mine, show, ROW, COL,0); } int main() { int input = 0; srand((unsigned int)time(NULL)); do { menu(); printf("Please select>:"); scanf("%d", &input); switch (input) { case 1: printf("game start\n"); game(); break; case 0: printf("Quit the game\n"); break; default: printf("Selection error, please re select\n"); break; } } while (input); return 0; }
Here someone may ask, why create an 11 * 11 array?
If we want to find the number of mines in the 9 * 9 chessboard, we have to find the surrounding 8 elements, but if we want to find the number of lattice attachment mines in the corners, it involves the problem of array crossing, which is not easy to do. So we make the array bigger to ensure that the array access will not cross the boundary
2. Initialize the chessboard (two-dimensional array)
Now we have to consider a problem. This time we have two two two-dimensional arrays to initialize, and the contents are different. What should we do?
In fact, it is also relatively simple. You only need to let the initialization function accept an additional amount that needs to be initialized
void intialize(char board[ROWS][COLS], int row, int col, char target) { int i = 0; for (i = 0; i < row; i++) { int j = 0; for (j = 0; j < col; j++) { board[i][j] = target; } } }
In this way, different initialization can be completed
3. Printing of chessboard
As the checkerboard required for mine clearance is relatively large, in order to facilitate play, the row and column number needs to be printed this time
void print(char board[ROWS][COLS], int row, int col) { int i = 0; for (i = 0; i <= row; i++)//Print column number { printf("%d ", i); } printf("\n"); for (i = 1; i <= row; i++) { int j = 0; printf("%d ", i);//Print line number for (j = 1; j <= col; j++) { printf("%c ", board[i][j]); } printf("\n"); } }
design sketch:
4. Lay lightning
The arrangement of Mines involves the problem of random numbers. It is necessary to ensure that mines will not be arranged repeatedly and will only be arranged in a 9 * 9 chessboard
void setmine(char board[ROWS][COLS], int row, int col) { int x = 0; int y = 0; int count = 0; while (1)//Cycle without full arrangement { x = rand() % row + 1;//Make x and y between 1 and 9 to ensure that the array does not cross the boundary y = rand() % col + 1; if (board[x][y] != '1')//Ensure that the arranged lightning is not repeated { board[x][y] = '1'; count++; } if (count == EASY_COUNT)//Jump out of the cycle only after all non repeating mines are arranged break; } }
5. Safety protection
In order to prevent sudden death in the first investigation and improve the game experience, we need to design it so that if players step on Thunder for the first time, the chessboard will reset until there is no thunder here
first_die++; if (first_die == 1 && mine[x][y] == '1')//first_die is created in test, and 0 is passed in by default { while (mine[x][y] == '1') { intialize(mine, ROWS, COLS, '0');//The chessboard must be initialized first, otherwise the original thunder will still be there setmine(mine, ROW, COL); } }
6. Mine number display
int search_show(char mine[ROWS][COLS], int x, int y) { return (mine[x - 1][y] + mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] + mine[x][y + 1] + mine[x - 1][y + 1] - 8 * '0'); }
The ASCII value of '0' is 48. We design the mine as' 1 'to facilitate adding and subtracting 8' 0 'to directly obtain the number of mines
7. Mine detection
The following is one of the key points of this article. In fact, the implementation idea of Lei's investigation is relatively simple. If you step on Lei, the game ends; If not, continue the game and display the number of nearby mines
int x = 0; int y = 0; while (1) { printf("Please enter the coordinates to be checked, such as: 1\n"); scanf("%d%d", &x, &y); first_die++; if (x >= 1 && x <= row && y >= 1 && y <= col)//Judge whether the input line number is within the specified range { if (mine[x][y] == '1') { printf("You're dead. Please keep up your efforts\n"); print(mine, ROW, COL); break; } else { show[x][y] = search_show(mine, ROW, COL)+'0';//Displays the number of mines around open(mine,show, x, y,row,col); print(show, ROW, COL); } } else { printf("Input error, please re-enter\n"); }
8. Marking mine
We can add a marking function after troubleshooting. We specify to mark with '#' and only unknown quantities can be marked at the same time
//Mark mine int input1 = 0; int input2 = 0; if (x >= 1 && x <= row && y >= 1 && y <= col) { do//Run at least once { printf("Please enter the marker coordinates,Enter 0 to exit the tag\n"); scanf("%d%d", &input1, &input2); if (input1 >= 1 && input1 <= row && input2 >= 1 && input2 <= col) { if (show[input1][input2] == '*')//Mark only unknowns { show[input1][input2] = '#'; print(show, ROW, COL); } else { printf("Marking failed, please mark again\n"); } } else if (input1 == 0 && input2 == 0)//Enter 0 to exit the tag break; else { printf("Marking error, please mark again\n"); } } while (input1&&input2); printf("Tag exited\n"); }
9. Deployment
This should be the hardest part to implement. Here we use the idea of recursion
void open(char mine[ROWS][COLS],char show[ROWS][COLS], int x, int y,int row ,int col) { int ret = 0; ret =search_show(mine,x,y); if (ret == 0)//If there is no thunder around, judge to expand { show[x][y] = ' ';//Prevent dead recursion. If show[x][y] is not changed to '', the next detection may be *. Enter recursion again until it is stuck. if (x - 1 > 0 && y > 0 && show[x - 1][y] == '*'|| show[x - 1][y] == '#') open(mine, show, x - 1, y, row, col); if (x - 1 > 0 && y + 1 <= col && show[x - 1][y + 1] == '*'|| show[x - 1][y + 1] == '#') open(mine, show, x - 1, y + 1, row, col); if (x > 0 && y + 1 <= col && show[x][y + 1] == '*'|| show[x][y + 1] == '#') open(mine, show, x, y + 1, row, col); if (x + 1 <= row && y + 1 <= col && show[x + 1][y + 1] == '*'|| show[x + 1][y + 1] == '#') open(mine, show, x + 1, y + 1, row, col); if (x + 1 <= row && y > 0 && show[x + 1][y] == '*'|| show[x + 1][y] == '#') open(mine, show, x + 1, y, row, col); if (x + 1 <= row && y - 1 > 0 && show[x + 1][y - 1] == '*'|| show[x + 1][y - 1] == '#') open(mine, show, x + 1, y - 1, row, col); if (x > 0 && y - 1 > 0 && show[x][y - 1] == '*'|| show[x][y - 1] == '#') open(mine, show, x, y - 1, row, col); if (x - 1 > 0 && y - 1 > 0 && show[x - 1][y - 1] == '*'|| show[x - 1][y - 1] == '#') open(mine, show, x - 1, y - 1, row, col); } else//If there is thunder, the number of thunder is returned { return show[x][y]=search_show(mine, x, y)+'0'; } }
10. Difficulty setting
In fact, the implementation idea is relatively simple. You can set middle again_ Count and HARD_COUNT.
When transferring parameters, you can also pass in the difficulty number
It's not difficult to leave it to everyone to realize it by themselves
11. Global code
game.h # define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <time.h> #define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2 #define EASY_COUNT 10 //initialization void intialize(char board[ROWS][COLS], int row, int col, char target); //Print chessboard void print(char board[ROWS][COLS], int row, int col); //Lay thunder void setmine(char board[ROWS][COLS], int row, int col); //Check thunder void search(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col,int game.c # define _CRT_SECURE_NO_WARNINGS # include "game.h" void intialize(char board[ROWS][COLS], int row, int col, char target) { int i = 0; for (i = 0; i < row; i++) { int j = 0; for (j = 0; j < col; j++) { board[i][j] = target; } } } void print(char board[ROWS][COLS], int row, int col) { int i = 0; for (i = 0; i <= row; i++) { printf("%d ", i); } printf("\n"); for (i = 1; i <= row; i++) { int j = 0; printf("%d ", i); for (j = 1; j <= col; j++) { printf("%c ", board[i][j]); } printf("\n"); } } void setmine(char board[ROWS][COLS], int row, int col) { int x = 0; int y = 0; int count = 0; while (1) { x = rand() % row + 1; y = rand() % col + 1; if (board[x][y] != '1') { board[x][y] = '1'; count++; } if (count == EASY_COUNT) break; } } int search_show(char mine[ROWS][COLS], int x, int y) { return (mine[x - 1][y] + mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] + mine[x][y + 1] + mine[x - 1][y + 1] - 8 * '0'); } void open(char mine[ROWS][COLS],char show[ROWS][COLS], int x, int y,int row ,int col) { int ret = 0; ret =search_show(mine,x,y); if (ret == 0)//If there is no thunder around, judge to expand { show[x][y] = ' ';//Prevent dead recursion. If show[x][y] is not changed to '', the next detection may be *. Enter recursion again until it is stuck. if (x - 1 > 0 && y > 0 && show[x - 1][y] == '*'|| show[x - 1][y] == '#') open(mine, show, x - 1, y, row, col); if (x - 1 > 0 && y + 1 <= col && show[x - 1][y + 1] == '*'|| show[x - 1][y + 1] == '#') open(mine, show, x - 1, y + 1, row, col); if (x > 0 && y + 1 <= col && show[x][y + 1] == '*'|| show[x][y + 1] == '#') open(mine, show, x, y + 1, row, col); if (x + 1 <= row && y + 1 <= col && show[x + 1][y + 1] == '*'|| show[x + 1][y + 1] == '#') open(mine, show, x + 1, y + 1, row, col); if (x + 1 <= row && y > 0 && show[x + 1][y] == '*'|| show[x + 1][y] == '#') open(mine, show, x + 1, y, row, col); if (x + 1 <= row && y - 1 > 0 && show[x + 1][y - 1] == '*'|| show[x + 1][y - 1] == '#') open(mine, show, x + 1, y - 1, row, col); if (x > 0 && y - 1 > 0 && show[x][y - 1] == '*'|| show[x][y - 1] == '#') open(mine, show, x, y - 1, row, col); if (x - 1 > 0 && y - 1 > 0 && show[x - 1][y - 1] == '*'|| show[x - 1][y - 1] == '#') open(mine, show, x - 1, y - 1, row, col); } else { return show[x][y]=search_show(mine, x, y)+'0'; } } int win(char show[ROWS][COLS], int row, int col) { int i = 0; int j = 0; int count = 0; for (i = 1; i <= row; i++) { for (j = 1; j <= col; j++) { if (show[i][j] == '*'||show[i][j]=='#') count++; } } if (count == EASY_COUNT) return 1; else return 0; } void search(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int first_die) { int x = 0; int y = 0; while (1) { printf("Please enter the coordinates to be checked, such as: 1\n"); scanf("%d%d", &x, &y); first_die++; //Prevent the first sudden death if (first_die == 1 && mine[x][y] == '1') { while (mine[x][y] == '1') { intialize(mine, ROWS, COLS, '0'); setmine(mine, ROW, COL); } } if (x >= 1 && x <= row && y >= 1 && y <= col) { if (mine[x][y] == '1') { printf("You're dead. Please keep up your efforts\n"); print(mine, ROW, COL); break; } else { show[x][y] = search_show(mine, ROW, COL)+'0';//Displays the number of mines around open(mine,show, x, y,row,col); print(show, ROW, COL); } } else { printf("Input error, please re-enter\n"); } //Judge whether to win or lose int Win = win(show, row, col); if (Win == 1) { printf("Congratulations, victory\n"); break; } //Mark mine int input1 = 0; int input2 = 0; if (x >= 1 && x <= row && y >= 1 && y <= col) { do { printf("Please enter the marker coordinates,Enter 0 to exit the tag\n"); scanf("%d%d", &input1, &input2); if (input1 >= 1 && input1 <= row && input2 >= 1 && input2 <= col) { if (show[input1][input2] == '*') { show[input1][input2] = '#'; print(show, ROW, COL); } else { printf("Marking failed, please mark again\n"); } } else if (input1 == 0 && input2 == 0) break; else { printf("Marking error, please mark again\n"); } } while (input1&&input2); printf("Tag exited\n"); } } } test.c # define _CRT_SECURE_NO_WARNINGS # include "game.h" void menu() { printf("*********************************\n"); printf("********* 1. Play *********\n"); printf("********* 0. Exit *********\n"); printf("*********************************\n"); } void game() { char mine[ROWS][COLS] = { 0 };//Store mine information char show[ROWS][COLS] = { 0 };//Store the information of the detected mine intialize(mine,ROWS ,COLS,'0'); intialize(show,ROWS ,COLS,'*'); //Display chessboard print(show, ROW, COL); //Lay thunder setmine(mine, ROW, COL); //Check search(mine, show, ROW, COL,0); } int main() { int input = 0; srand((unsigned int)time(NULL)); do { menu(); printf("Please select>:"); scanf("%d", &input); switch (input) { case 1: printf("game start\n"); game(); break; case 0: printf("Quit the game\n"); break; default: printf("Selection error, please re select\n"); break; } } while (input); return 0; }
The above is the content of this sharing. If you like my sharing, don't forget to praise and pay attention!
If you have any comments on my article, please comment below or send me a private letter!
I'm Bai Chen. I'll see you next time!!