6 Array and Function Practice: Minesweeper Game

6. Array and function practice: Minesweeper game

Original address: https://beryl-licorice-3a8.notion.site/5421ccb8a34c4ebbb185b6b70e0ba9b9?pvs=4

  • Introduction to rules
    1. After the player clicks on a square, the square will display the following situations: a number, indicating the number of mines hidden in the eight surrounding squares; a blank, indicating that there are no mines in the surrounding eight squares; or a mine, indicating that the player The mine is triggered and the game fails.

    2. Players need to interpret the clues of the numbers to deduce which squares are safe (non-mine areas) and which squares may contain mines. Clicking on a safe square will reveal more information, helping players find other safe squares.

    3. If the player successfully finds all safe squares without triggering any mines, the game is won.

1. Game analysis and design

During the process of mine clearing, information about the mines deployed and the mines detected need to be stored, so we need a certain data structure to store this information: we use 1 to store mines and 0 to store normal blocks.

1.1Analysis of data structure:

First, we use known knowledge for analysis. Both the mines deployed and the mines investigated need to be stored, so we need a certain data structure to store this information. React quickly – array!

How to implement the demining algorithm? According to the rules, when we click on a block, its actual number tells us how many mines are around it, so we need to get the information centered on it:

This leads to a new question: How to prevent array out-of-bounds access? Based on the existing knowledge, I think that adding a layer of shells with all 0s will perfectly solve the problem 1

Continuing with the analysis, we arrange mines on the chessboard. The information of mines on the chessboard (1) and the information of mines (0). Suppose that after we check a certain position, this coordinate is not a mine, and there are 1 around this coordinate. If there are mines, then we need to record and store the number of mines detected and print them out as important reference information for mine clearance. So where is the information about the number of mines stored? The answer is an array

Solution: We use two arrays to store information, one to access the mine, and one to access the information found out.

1.2File structure design

Putting so many lines of code in the same file is definitely very bloated. We use three files to implement the program. The multi-file organization format is explained along with the actual code.

1.3Notes:

 There are too many types of data stored, which can easily lead to ambiguity.

When counting the number of mines around a coordinate, it may cross the boundary.

Use two arrays, one to store mine information and one to store mine troubleshooting information.

char show[11][11];store 0’

char mine[11][11];store *’

2. Code practice:

2.1Create files: < /strong>

  • Quickly add multi-file knowledge

    Under normal circumstances, the function declaration and type declaration are placed in the header file (.h), and the implementation of the function is placed in the source file (.c) file. as follows:

    add.c

    int Add(int x,int y)
    {<!-- --> return x + y:
    }//Define function
    

    add.h puts this file in the header file, and the rest are source files

    int Add(int x,int y);//Declaration of function
    

    test.c

    #include<stdio.h>
    #include"add.h"//Special writing method for self-defined header files
    int main(){<!-- -->
        int a=10; int b=20;
    int c = Add(a,b)//Function call
    

    operation result:

  1. test.c–Write the test logic of the game in the file
  2. game.c – file to write the implementation of functions in the game, etc.
  3. game.h – file to write the data types and function declarations required by the game, etc.

2.2Encapsulation interface

void menu() {<!-- -->
printf("************************");
printf("************1go************");
printf("************2out*******");
printf("************************");
}
void game() {<!-- -->
}

int main()
{<!-- -->
int input = 0;
do {<!-- -->//The reason for using do-while loop is to enter first and then loop to avoid inputting 0 without operation.
menu();
printf("Please enter");
scanf("%d", & amp;input);
switch (input) {<!-- -->
case 1:
printf("Minesweeper");
game();//encapsulation function
break;
case 0:
printf("Exit the game\\
");
break;
default:
printf("Illegal input, please choose again");
break;
}
} while (input);
\t
return 0;
}

Initialize the chessboard: One of the benefits of using macro definitions is to simplify and understand the code

From the above, we need:

#define ROW 9 #define COL 9

#define ROWS ROW + 2 #define COLS COL + 2

#include<stdio.h>
#include"game.h"
void InitBoard(char arr[ROWS][COLS], int rows, int cols,char set) {<!-- -->
int i = 0;//line
for(i=0;i<rows;i + + ){<!-- -->
int j = 0;
for (j = 0; j < cols; j + + ) {<!-- -->
arr[i][j] = set;
}
}
}
void DisplayBoard(char arr[ROWS][COLS],int row,int col) {<!-- -->
int i = 1;
for (i = 1; i <= row; i + + ) {<!-- -->
int j = 0;
for (j = 1; j < col; j + + ) {<!-- -->
printf("%c ", arr[i][j]);
}
printf("\\
");
}
printf("\\
");
}

We have solved the problem of array access out of bounds. At the same time, we must pay attention to saving code and trying to make a function more useful.

Header file:

#pragma once

#define ROW 9
#define COL 9

#define ROWS ROW + 2
#define COLS COL + 2

void InitBoard(char arr[ROWS][COLS], int rows, int cols,char set);
void DisplayBoard(char arr[ROWS][COLS],int row,int col);

Function construction:

void game() {<!-- -->
char mine[ROWS][COLS];
char show[ROWS][COLS];
//Initialize the chessboard
InitBoard(mine, ROWS, COLS,'0');//'0'
InitBoard(show, ROWS, COLS,'*');//'*'
//Print the chessboard
DisplayBoard(show,ROW,COL);
}
 Rendering:

2.3Establishing a coordinate system< /strong>

How can we obtain the legitimate data entered by the user? We can establish a coordinate system and let users enter column coordinates and row coordinates to obtain information.

void DisplayBoard(char arr[ROWS][COLS],int row,int col) {<!-- -->
int i = 1;
//Print the row coordinates first:
for (i = 0; i <= row; i + + ) {<!-- -->//Start with i=0 to make the chessboard conform to the actual situation
printf("%d ", i);
}
printf("\\
");

for (i = 1; i <= row; i + + ) {<!-- -->
int j = 0;
for (j = 1; j <= col; j + + ) {<!-- -->
if (1 == j) printf("%d ", i);//Print column coordinates
printf("%c ", arr[i][j]);
}
printf("\\
");
}
printf("\\
");
}

Why do we need to print the row coordinates first? Because according to the printing order, if the column coordinates are printed first, the row coordinates will be below.

I have listed the code for printing coordinates separately. For the sake of code alignment and beauty, we pay attention to:

  • Space handling for line coordinate printing and i starting from 0
  • Space handling for column coordinate printing and i starting from 1
for (i = 0; i <= row; i + + ) {<!-- -->//Start with i=0 to make the chessboard conform to the actual situation
printf("%d ", i);
}
for (j = 1; j <= col; j + + ) {<!-- -->
if (1 == j) printf("%d ", i);//Print column coordinates

2.4Implementing game operations

2.4.1Deploying mines

setmine(mine, ROW, COL);//Use the function in the void game in test.c
void setmine(char arr[ROWS][COLS], int row, int col); function declaration
void setmine(char arr[ROWS][COLS], int row, int col) {<!-- -->
//Randomly arrange 10 mines
int count = 10;
while (count) {<!-- -->
int x = rand() % COL + 1;
int y = rand() % ROW + 1;

if (arr[x][y] == '0') {<!-- -->
arr[x][y] = '1';
}
else count + + ;
count--;
}
}//Note on function implementation

!

We store 1 as a mine in the table of 0.

Here I would like to remind you of a few points:

  • Pay attention to the printing order, set mine first and then print the array of mine
  • When using rand(), the stdlib.h and time.h header files are required
  • Pay attention to the conditional judgment in the if statement to ensure that we place 10 mines
  • Be sure to rotate the camera view at any time:

Now set up a function in test.c and place it in the game() function

Then complete the function declaration in game.h

Finally, complete the function implementation in the game.c file

2.4.2Disposal of mines

Verify the information in the show array and complete demining in the mine array.

finedmind(mine, show, ROW, COL); Create a function from this.

void finemine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col); Create function declaration

Create function implementation:

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 < row * col - 10) {<!-- -->//Because it was checked 71 times!
printf("Please enter the coordinates to be checked\\
");
scanf("%d %d", & amp;x, & amp;y);
if (x >= 1 & amp; & amp; x <= ROW & amp; & amp; y >= 1 & amp; & amp; y <= COL)
{<!-- -->
if (mine[x][y] == '1')
{<!-- -->
printf("you lose!");
}
else
{<!-- -->
int n = getminecount(mine, x, y);
show[x][y] = n + '0';
DisplayBoard(show, ROW, COL);
win++;
}

}
else printf("Illegal coordinates, please re-enter\\
");
}
}
//Nested sub-function form:
int getminecount(char arr[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';}

At this point our program is complete.

3. Summary-review again

  1. We first studied the gameplay and rules of “Mine Sweeper”. We learned that two arrays were constructed for processing, one for Show and one for Mine. At the same time, we also know how to deal with out-of-bounds array access – constructing a code shell.
  2. Then we dismantle the game: lobby interface → display minesweeper operation module → general command execution module of the minesweeper game → preprocessing array and display module → coordinate axis positioning module → mine generation module → mine clearance module and end processing module.
  3. Review of several difficulties:
  • How to establish coordinates to align coordinates with elements, and how coordinates correspond to elements one-to-one
  • How to arrange mines randomly, and the number is exactly 10
  • I admit that demining is too difficult. How to feedback the results and how to limit the scope during demining is critical!

game.c

game.h

test.c