catalogue
Introduction to mine clearance
Initialize checkerboard init_board()
Returns the count of mines with 8 coordinates around this coordinate_ mine()
Recursive expansion super_open_mine()
Judge how many "thunder" counts are left on the chessboard_ show_ mine()
Game implementation function (game)
Introduction to mine clearance
The minesweeping game is to uncover all non mine grids and win. Stepping on mine grids is even a failure. The main area of the game consists of many squares, Click a grid randomly with the left mouse button, the grid will be opened and the numbers in the grid will be displayed. The numbers in the grid mean that several mines are hidden in the eight grids around it.
In C language, we use the way of inputting coordinates instead of mouse clicking.
The function is not introduced in this article: (I don't want to introduce it, but the blogger hasn't mastered the ability, mainly because he is lazy)
- Interactive difficulty selection function
- Marking mine function
- Select coordinate expansion function after marking mine
Realization idea
First, we use three files to contain the whole program
- Mine.h
- Mine.c
- test.c
Mine.h header file contains all header files and global variables required for code implementation
Mine.c source file contains the main functions implemented by the code
The test.c source file is responsible for testing the code
Implementation process
- Print interactive menu
- Initialize chessboard
- Lay thunder
- Minesweeping (recursive expansion)
- Judge victory
- Victory game is over, otherwise cycle step 4
When defining the two-dimensional array of chessboard, we need to define two arrays; An array mine is used to place the thunder position (not shown), and another array show is used to show the chess face!
Code decomposition
-
Chessboard definition
//Global variable rows and columns #define ROW 3 #define COL 3 //Avoid array out of bounds, and add more rows and columns around the original chessboard #define ROWS ROW+2 #define COLS COL+2
-
Interactive menu()
//Interactive menu void menu() { printf("-----------------------\n"); printf("------ [Mine clearance] ------\n"); printf("------ 1.start ------\n"); printf("------ 0.sign out ------\n"); printf("-----------------------\n"); }
-
Initialize checkerboard init_board()
Here, we initialize the show chessboard to '*'
Initialize the mine chessboard to '0'
//Initialize chessboard void init_board(char board[ROWS][COLS], int row, int col, char ch) { int i = 0; int j = 0; for (i = 0; i < ROWS; i++) { for (j = 0; j < COLS; j++) { board[i][j] = ch; } } }
-
Print checkerboard display()
//Print chessboard void display(char show[ROWS][COLS], int row, int col) { int i = 0; int j = 0; for (i = 0; i <= col; i++) { //Print column coordinates printf("%d ", i); } printf("\n"); for (i = 1; i <= row; i++) { //Print line coordinates printf("%d ", i); for (j = 1; j <= col; j++) { printf("%c ", show[i][j]); } printf("\n"); } printf("\n"); }
-
Layout thunder set_mine()
//Number of Mines #define COUNT 1 //Lay thunder void set_mine(char mine[ROWS][COLS], int row, int col) { int x = 0; int y = 0; int count = COUNT; while (count) { //Obtain random numbers and generate thunder ('1 ') on the chessboard x = rand() % row + 1; y = rand() % col + 1; if (mine[x][y] == '0') { mine[x][y] = '1'; count--; } } }
-
Returns the count of mines with 8 coordinates around this coordinate_ mine()
Note that the return type of the function here is static
//Returns the number of mines in a circle around this coordinate static count_mine(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';//ASCII value differs from numeric character by '0' }
-
Recursive expansion super_open_mine()
Recursive expansion condition:
- It's not ray at this coordinate, != ' 1'
- There is no thunder in the eight coordinates around this coordinate, count = 0
- This coordinate has not been expanded,! = '"
//Recursive expansion void super_open_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y) { //Obtain the mine number of eight coordinates around the coordinate int count = count_mine(mine, x, y); if (count == 0 && show[x][y] != ' ') { show[x][y] = ' '; if (x - 1 >= 0 && x <= ROW && y >= 0 && y <= COL && show[x - 1][y] == '*') { super_open_mine(mine, show, x - 1, y); } if (x + 1 >= 0 && x + 1 <= ROW && y >= 0 && y <= COL && show[x + 1][y] == '*') { super_open_mine(mine, show, x + 1, y); } if (x >= 0 && x <= ROW && y - 1 >= 0 && y - 1 <= COL && show[x][y - 1] == '*') { super_open_mine(mine, show, x, y - 1); } if (x >= 0 && x <= ROW && y + 1 >= 0 && y + 1 <= COL && show[x][y + 1] == '*') { super_open_mine(mine, show, x, y + 1); } } else { show[x][y] = count + '0'; } }
-
Mine sweep_mine()
//Check thunder int sweep_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) { int x = 0; int y = 0; int count = 0; printf("Please enter minesweeping coordinates(that 's ok.column):>"); scanf("%d.%d", &x, &y); if ((x >= 1 && x <= row) && (y >= 1 && y <= col)) { if (mine[x][y] == '1') { return 1; } else { super_open_mine(mine, show, x, y); display(show, ROW, COL); return 0; } } else { printf("The coordinates entered are illegal, please re-enter!\a\n\n"); } return 0; }
-
Judge how many "thunder" counts are left on the chessboard_ show_ mine()
//Judge how many "thunder" there are on the chessboard int count_show_mine(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] == '*') { count++; } } } return count; }
-
Game implementation function (game)
//Game implementation function void game() { char mine[ROWS][COLS] = { 0 }; char show[ROWS][COLS] = { 0 }; init_board(mine, ROWS, COLS, '0');//mine initialized to '0' init_board(show, ROWS, COLS, '*');//show is initialized to '*' set_mine(mine, ROW, COL); //display(mine, ROW, COL); display(show, ROW, COL); while (1) { int ret = sweep_mine(mine, show, ROW, COL); if (ret) { printf("\n You're blown up. The game's over!\n\a"); display(mine, ROW, COL); break; } int key = count_show_mine(show, ROW, COL); if (key == COUNT) { printf("WIN!\a\n"); break; } } }
-
Test function test()
//Test function void test() { srand((unsigned int)time(NULL)); int choose = -1; do { menu(); scanf("%d", &choose); switch (choose) { case 1: printf("\n Game start:\n"); game(); break; case 0: printf("game over...\n\a"); break; default: printf("Input error, please re-enter!\n\a"); break; } } while (choose); }
-
Main function ()
//calling function int main(void) { test(); return 0; }
Code overview
- Mine.h
#pragma once #Include < stdio. H > / / printf(), scanf() function header file #Include < stdlib. H > / / get the timestamp header file #Include < time. H > / / time header file //Global variable rows and columns #define ROW 3 #define COL 3 //Avoid array out of bounds, and add more rows and columns around the original chessboard #define ROWS ROW+2 #define COLS COL+2 //Number of Mines #define COUNT 1 //Function declaration void menu(); void init_board(); void display(); void set_mine(); int sweep_mine();
- Mine.c
#define _CRT_SECURE_NO_WARNINGS 1 #include "Mine.h" //Interactive menu void menu() { printf("-----------------------\n"); printf("------ [Mine clearance] ------\n"); printf("------ 1.start ------\n"); printf("------ 0.sign out ------\n"); printf("-----------------------\n"); } //Initialize chessboard void init_board(char board[ROWS][COLS], int row, int col, char ch) { int i = 0; int j = 0; for (i = 0; i < ROWS; i++) { for (j = 0; j < COLS; j++) { board[i][j] = ch; } } } //Print chessboard void display(char show[ROWS][COLS], int row, int col) { int i = 0; int j = 0; for (i = 0; i <= col; i++) { //Print column coordinates printf("%d ", i); } printf("\n"); for (i = 1; i <= row; i++) { //Print line coordinates printf("%d ", i); for (j = 1; j <= col; j++) { printf("%c ", show[i][j]); } printf("\n"); } printf("\n"); } //Lay thunder void set_mine(char mine[ROWS][COLS], int row, int col) { int x = 0; int y = 0; int count = COUNT; while (count) { //Obtain random numbers and generate thunder ('1 ') on the chessboard x = rand() % row + 1; y = rand() % col + 1; if (mine[x][y] == '0') { mine[x][y] = '1'; count--; } } } //Returns the number of mines in a circle around this coordinate static count_mine(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';//ASCII value differs from numeric character by '0' } //Recursive expansion void super_open_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y) { int count = count_mine(mine, x, y); if (count == 0 && show[x][y] != ' ') { show[x][y] = ' '; if (x - 1 >= 0 && x <= ROW && y >= 0 && y <= COL && show[x - 1][y] == '*') { super_open_mine(mine, show, x - 1, y); } if (x + 1 >= 0 && x + 1 <= ROW && y >= 0 && y <= COL && show[x + 1][y] == '*') { super_open_mine(mine, show, x + 1, y); } if (x >= 0 && x <= ROW && y - 1 >= 0 && y - 1 <= COL && show[x][y - 1] == '*') { super_open_mine(mine, show, x, y - 1); } if (x >= 0 && x <= ROW && y + 1 >= 0 && y + 1 <= COL && show[x][y + 1] == '*') { super_open_mine(mine, show, x, y + 1); } } else { show[x][y] = count + '0'; } } //Check thunder int sweep_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) { int x = 0; int y = 0; int count = 0; printf("Please enter minesweeping coordinates(that 's ok.column):>"); scanf("%d.%d", &x, &y); if ((x >= 1 && x <= row) && (y >= 1 && y <= col)) { if (mine[x][y] == '1') { return 1; } else { super_open_mine(mine, show, x, y); display(show, ROW, COL); return 0; } } else { printf("The coordinates entered are illegal, please re-enter!\a\n\n"); } return 0; } //Judge how many "thunder" there are on the chessboard int count_show_mine(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] == '*') { count++; } } } return count; }
- test.c
#define _CRT_SECURE_NO_WARNINGS 1 #include "Mine.h" //Game implementation function void game() { char mine[ROWS][COLS] = { 0 }; char show[ROWS][COLS] = { 0 }; init_board(mine, ROWS, COLS, '0'); init_board(show, ROWS, COLS, '*'); set_mine(mine, ROW, COL); //display(mine, ROW, COL); display(show, ROW, COL); while (1) { int ret = sweep_mine(mine, show, ROW, COL); if (ret) { printf("\n You're blown up. The game's over!\n\a"); display(mine, ROW, COL); break; } int key = count_show_mine(show, ROW, COL); if (key == COUNT) { printf("WIN!\a\n"); break; } } } //Test function void test() { srand((unsigned int)time(NULL)); int choose = -1; do { menu(); scanf("%d", &choose); switch (choose) { case 1: printf("\n Game start:\n"); game(); break; case 0: printf("game over...\n\a"); break; default: printf("Input error, please re-enter!\n\a"); break; } } while (choose); } //calling function int main(void) { test(); return 0; }