Minesweeping is a classic game. Now use c language to realize minesweeping, the most important of which is the use of arrays.
File creation
Creating different modules can make the code more logical and concise, and can also hide some programs.
test.c: as a test file, it is mainly used to test the whole project; game.c: game file, which is mainly used to store and write the program about the realization of the game - mine burying, mine sweeping, etc; game.h: as a game header file, it is mainly used to store header files, declaration and definition characters of game functions, etc.
First write the program before the game starts:
void game() { } void menu() { printf("----------------------\n"); printf("------1. play--------\n"); printf("------0. exit--------\n"); printf("----------------------\n"); } void test() { int input = 0; do { menu(); printf("Please select>"); scanf("%d", &input); switch (input) { case 1: game(); break; case 0: printf("Leave the game\n"); break; default: printf("Input error, please re-enter\n"); break; } }while(input); } int main() { test(); return 0; }
General idea
1. Mine sweeping requires mines. Mines should be stored in a two-dimensional array to create a two-dimensional array with nine rows and nine columns. It is used to make a minesweeping interface of nine rows and nine columns. Use 0 to indicate that there is no thunder and 1 to indicate that there is thunder, so it should be an integer array. However, in the process of mine clearance, if there is no mine, the number of surrounding mines should be displayed. If there is just one mine around, it may be confused with the one with mine. Then the problem comes again. If you use other characters, it will be very chaotic, so you choose to create two arrays, one to bury mines and the other to show mine clearance. At this time, the two arrays should be strictly the same for operation. The displayed array needs' * 'to initialize the interface, so the type of array should be character array.
2. The second step is to initialize the array. Those used to bury mines are initialized to all '0' first, and those used to display minesweeping are initialized to all '*'.
3. The third step is to bury the mine. This requires the subscript operation array to randomly generate numbers to be used as the subscript of the mine element. Here, pay attention not to cross the boundary (overflow the array).
4. The fourth step of demining is still demining through subscript. Considering here, when demining, if there are no mines, you need to know how many mines are around. If the checked elements are right in the middle, it's OK to check eight elements around. If they are on the border, they will cross the border. In order to avoid this situation, create two more rows when creating an array to prevent the array access from crossing the boundary. As long as there is no thunder, the two more rows are '0', but don't print them when printing. Defining symbols in game.h
#define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2
1. Initialize array
//Write under test.c file void game() { //Create array char mine[ROWS][COLS] = { 0 };//Special for buried mine char show[ROWS][COLS] = { 0 };//Show mine //initialization InitBoard(mine, ROWS, COLS, '0'); InitBoard(show, ROWS, COLS, '*'); }
//game.c write down function //Initialize array void InitBoard(char board[ROWS][COLS], int rows, int cols, char set) { int i = 0; int j = 0; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { board[i][j] = set; } } }
2. Print interface
//Print void Display_board(char board[ROWS][COLS], int row, int col) { //It should be 1 ~ 9 int i = 0; int j = 0; //Print column number for (i = 0; i <= col; i++) { printf("%d ", i); if (i == 0) printf("|"); } printf("\n"); //Print split lines for (i = 0; i <= col; i++) { printf("—"); } printf("\n"); for (i = 1; i <= row; i++) { printf("%d |", i);//Print line number for (j = 1; j <= col; j++) { printf("%c ", board[i][j]); } printf("\n"); } }
When printing the interface, you must remember that there are 1 ~ 9 rows and 1 ~ 9 columns. Here, you should pay special attention to transferring parameters and assigning values to variables.
3. Mine burial
//Writing code under game.c //Buried mine void Setmine(char mine[ROWS][COLS], int row, int col) { int count = MINE_COUNT;//Small details while (count) { int x = rand() % row + 1; int y = rand() % col + 1; if (mine[x][y] == '0') { mine[x][y] = '1'; count--; } } }
There is a small detail here, that is, the number of buried mines. The characters defined by the macro are still used, which should be defined in game.h, so that it is convenient to change the number of buried mines (game difficulty) in the future .
And if you want to get a random number that is less than a certain number, take the remainder of the maximum number, which must be less than the maximum number and less than 1.
4. Mine clearance
The implementation of logic is still relatively clear. Input coordinates and re input beyond the range; Enter the cycle within the range to see whether the selected thunder is mine. If it is mine, the game ends, and print the array of Mines stored. The cycle ends. If it is not mine, print the array excluding thunder. Here, print the number of surrounding thunder. If you can play all the time, the condition for winning the game is to find all the elements without mines. You need to design the condition for the end of the cycle.
//Calculate the number of surrounding mines static int Get_mine_count(char board[ROWS][COLS], int x, int y) { return board[x - 1][y - 1] + board[x - 1][y] + board[x - 1][y + 1] + board[x][y - 1] + board[x][y + 1] + board[x + 1][y - 1] + board[x + 1][y] + board[x + 1][y + 1] - 8 * '0'; } //mine clearance void Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) { int x = 0; int y = 0; int win = 0; while (win < col * row - MINE_COUNT) { printf("Please enter coordinates>"); scanf("%d %d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col) { if (mine[x][y] != '1') { int a = Get_mine_count(mine, x, y); //calculation show[x][y] = a + '0'; Display_board(show, row, col); win++; if (win == col * row - MINE_COUNT) printf("Congratulations, you eliminated all thunder\n"); } else { printf("I'm sorry you were killed"); Display_board(mine, row, col); break; } } else { printf("Illegal coordinates, please re-enter"); } } }
A trick here is to print the number of mines around the coordinates. It is very ingenious in the design. Thunder is' 1 ', not thunder is' 0', but the type of array is character type, so simple addition must not work. We know that the integer number of 0 ~ 9 plus' 0 'is the character's' 0' ~ '9'. Then the sum of 8 characters minus 8 '0' should be the number of shaped thunder. However, it is still necessary to add '0' when printing, because the array itself is of character type and cannot be printed and shaped.
ASCII values are essentially integer numbers. So 0 + 48 ='0 '= = 0 +'0' ='0 '.
5. Complete code
//game.h #define ROWS ROW+2 #define COLS COL+2 #define MINE_COUNT 78 //Initialize array void InitBoard(char board[ROWS][COLS], int rows, int cols, char set); //Print thunder disk void Display_board(char board[ROWS][COLS], int row, int col); //Buried mine void Setmine(char board[ROWS][COLS], int rows, int cols); //mine clearance void Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
//test.c #include"game.h" void game() { //Create array char mine[ROWS][COLS] = { 0 };//Special for buried mine char show[ROWS][COLS] = { 0 };//Show mine //initialization InitBoard(mine, ROWS, COLS, '0'); InitBoard(show, ROWS, COLS, '*'); //Buried mine Setmine(mine, ROW, COL); //Print thunder disk Display_board(mine, ROW, COL); //mine clearance Findmine(mine,show, ROW, COL); } void menu() { printf("----------------------\n"); printf("------1. play--------\n"); printf("------0. exit--------\n"); printf("----------------------\n"); } void test() { srand((unsigned int)time(NULL)); int input = 0; do { menu(); printf("Please select>"); scanf("%d", &input); switch (input) { case 1: game(); break; case 0: printf("Leave the game\n"); break; default: printf("Input error, please re-enter\n"); break; } }while(input); } int main() { test(); return 0; }
//game.c #include"game.h" //Initialize array void InitBoard(char board[ROWS][COLS], int rows, int cols, char set) { int i = 0; int j = 0; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { board[i][j] = set; } } } //Print thunder disk void Display_board(char board[ROWS][COLS], int row, int col) { //It should be 1 ~ 9 int i = 0; int j = 0; //Print column number for (i = 0; i <= col; i++) { printf("%d ", i); if (i == 0) printf("|"); } printf("\n"); //Print split lines for (i = 0; i <= col; i++) { printf("—"); } printf("\n"); for (i = 1; i <= row; i++) { printf("%d |", i);//Print line number for (j = 1; j <= col; j++) { printf("%c ", board[i][j]); } printf("\n"); } } //Buried mine void Setmine(char mine[ROWS][COLS], int row, int col) { int count = MINE_COUNT; while (count) { int x = rand() % row + 1; int y = rand() % col + 1; if (mine[x][y] == '0') { mine[x][y] = '1'; count--; } } } //Calculate the number of surrounding mines static int Get_mine_count(char board[ROWS][COLS], int x, int y) { return board[x - 1][y - 1] + board[x - 1][y] + board[x - 1][y + 1] + board[x][y - 1] + board[x][y + 1] + board[x + 1][y - 1] + board[x + 1][y] + board[x + 1][y + 1] - 8 * '0'; } //mine clearance void Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) { int x = 0; int y = 0; int win = 0; while (win < col * row - MINE_COUNT) { printf("Please enter coordinates>"); scanf("%d %d", &x, &y);//error if (x >= 1 && x <= row && y >= 1 && y <= col) { if (mine[x][y] != '1') { int a = Get_mine_count(mine, x, y); //calculation show[x][y] = a + '0'; Display_board(show, row, col); win++; if (win == col * row - MINE_COUNT) printf("Congratulations, you eliminated all thunder\n"); } else { printf("I'm sorry you were killed"); Display_board(mine, row, col); break; } } else { printf("Illegal coordinates, please re-enter"); } } }