C language entry-level game - minesweeping

Keywords: C Back-end

In the last issue, we realized the small game of Sanzi chess in C language   C language implementation of Sanzi chess

Today, let's write a minesweeping game. When it comes to minesweeping, I believe everyone is familiar. Maybe many friends are still experts in minesweeping.

In fact, minesweeping and Sanzi chess have many similarities, and both need the knowledge of arrays.

Today's minesweeping is also quite interesting

As the blogger is a programming learning Xiaobai, this is only the primary version of mine sweeping. Some functions of this version can not be realized. In the follow-up study, I will continue to update and optimize this little game. I look forward to your attention. In addition, if there are errors or improper places in this article, you are welcome to correct!

For the code of this mine clearance project, welcome to my gitee code warehouse:

Let's start!

catalogue

1, The overall idea of the game

3, Realization of game subject

1. Create a chessboard (array)

2. Initialize the chessboard

3. Print chessboard

4. Lay lightning

4. Mine detection

4, All codes

5, Thoughts on the improvement of games

1, The overall idea of the game

In order to make the code more readable and thoughtful, we need to create three files to complete the project

1. test.c    —— Test game
2. game.h -- Declaration of game functions
3. game.c -- implementation of game function

Then we need to build two chessboards. Why?

Let's first think about the rules of the game of mine clearance, as shown in the figure. If the box I selected is not mine, a number will be displayed on it. This number represents the number of mines in the 3 * 3 area (red box) centered on it. Its range is 0 ~ 8. Our initial assumption is: the number of mines without mine is 0, and the number of mines with mine is 1

But if my box is not a mine and the format of the mine around it is displayed, if there is a mine around it, it needs to be displayed

Digital 1 hour  ， We won't know if this 1 is ray? Or the number of surrounding mines? So we need to build two chessboards

A chessboard is used to store the information of the arranged thunder (which is not visible to the player before the end of the game)

Another chessboard stores the information of the checked thunder (this is what the player sees during the game)

One more question

If the chessboard we set is 9 * 9

When we choose to check the number of thunder around this position, there is no next to it, so we need to expand the chessboard to 11 * 11

(but only 9 * 9 chessboard is printed)

As shown in the picture, we can check the number of mines around this grid

This is how we operate

Like the previous Gobang games, we first need to set up a game menu

As soon as we enter the game, we first need to see the menu, so here we use the do...while loop

The functions of our menu include:

1. Game entry
2. Game exit
3.   Illegal input return prompt and description
```void menu()
{
printf("************************\n");
printf("*****   1.play   *******\n");
printf("*****   0.exit   *******\n");
printf("************************\n");

}
void test()
{
int input = 0;
do
{
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("Exit the game\n");
break;
default:
printf("Selection error\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
```

Here, we have created the test function and menu function to make the logic clearer. Now we have completed the menu part

For this game menu, we can realize the following game functions:

• Enter 1 to enter the game
• Enter 0 to exit the game
• If you enter other numbers, you will be prompted that the selection is wrong and will be re entered

This is how the menu works

3, Realization of game subject

1. Create a chessboard (array)

```//Create array
char mine[ROWS][COLS] = { 0 };//Store the information of the arranged mine
char show[ROWS][COLS] = { 0 };//Store the information of the checked mine```

2. Initialize the chessboard

We use the mine array as a chessboard to store the information of the arranged thunder

Use the show array as a checkerboard for storing the checked mine information

We use an InitBoard function to initialize the two checkerboards

Look at the code:

```//Declaration of function
void InitBoard(char board[ROWS][COLS], int rows,int cols,char set);

//Definition of function
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;
}
}

}

//Function call
//Initialize mine array to full character '0'
InitBoard(mine,ROWS,COLS,'0');
//Initialize the show array to all '*'
InitBoard(show,ROWS,COLS,'*');```

We initialize the mine array to the character '0'

The show array is initially recognized as the character '*'

3. Print chessboard

We play with two chessboards

among   The chessboard represented by the mine array can only be seen after the game is over or by the game tester

Another show array represents a chessboard that players can see when playing the game

Let's write the code

```//Definition of function
void DisplayBoard(char board[ROWS][COLS], int row, int col);

//Definition of function
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
//1-9
int i = 0;
int j = 0;
printf("\n");
printf("---The Minesweeper game---\n");
//Print column number
for (i = 0;i <= col;i++)
{
printf("%d ", i);
}
printf("\n");
for (i = 1;i <= row;i++)
{
printf("%d ", i);
for (j = 1;j <= col;j++)
{

printf("%c ", board[i][j]);
}
printf("\n");
}

}

//Function call
DisplayBoard(show, ROW, COL);//Print only 9 * 9 content```

4. Lay lightning

Now we can arrange the thunder. Because the thunder is arranged randomly, we need to use the rand function

srand((unsigned int)time(NULL));      // Initialize
x = rand() % row+1;           // X ranges from 1 to 9
y = rand() %   col+1;           // Y ranges from 1 to 9

Here's the code:

```//Declaration of function
void SetMine(char mine[ROWS][COLS],int row,int col);

//Definition of function
void SetMine(char mine[ROWS][COLS], int row, int col)
{
//Arrange 10 mines
int count = EASY_COUNT;
while (count)
{
//Production random subscript
int x = rand() % row + 1;//Range 1 to 9
int y = rand() % col + 1;
if (mine[x][y] == '0')
{
mine[x][y] = '1';
count--;
}
}
}

//Function call
SetMine(mine, ROW, COL);```

We add the printing of the mine chessboard and comment it out, which is convenient for us to test the game or check the problems in the game

Here, EASY_COUNT is the number of thunder. We define it with define

4. Mine detection

For mine detection, we implement it as follows:

1. Enter the coordinates of the mine
2. Check whether the coordinate is thunder
•     (1) It's ray    --> I'm sorry it blew up
•     (0) is not mine  --> There are several mines around the statistical coordinates -- > store the information of mine troubleshooting in the show array, and the game continues

We use it here   get_mine_count   and   FindMine    Two functions

The get_mine_count function is used to count how many mines are around the coordinates

Look at the code

```//statement
void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS], int row, int col);//From mine to show

//Check thunder
int get_mine_count(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+1] +
mine[x + 1][y] +
mine[x][y + 1] +
mine[x - 1][y + 1] - 8 * '0';
}

void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
//1. Enter the coordinates of the mine
//2. Check whether the coordinate is thunder
//(1) It's ray -- > I'm sorry it blew up
//(0) not thunder -- > there are several thunder -- > around the statistical coordinates to store the information of checking thunder into the show array. The game continues
int x = 0;
int y = 0;
int win = 0;
while (win<row*col- EASY_COUNT)
{
printf("Please enter the coordinates to check: ");
scanf("%d %d", &x, &y);//x ranges from 1 to 9 and y ranges from 1 to 9
//Judge the legitimacy of coordinates
if (x >= 1 && x <= col && y >= 1 && y <= row)
{
if (mine[x][y] == '1')
{
printf("I'm sorry you were killed\n");
DisplayBoard(mine, row, col);//Show me how he was killed
break;
}
else
{
//If it's not thunder, how many thunder are there around the (x,y) coordinate
int count = get_mine_count(mine, x, y);
show[x][y] = count+'0';
//Display the troubleshooting information
DisplayBoard(show, row, col);
win++;
}
}
else
{
}
}
if (win == row * col - EASY_COUNT)
{
DisplayBoard(mine, row, col);
}

}

//call
FindMine(mine,show,ROW,COL);```

Here are a few points to note:

1.

Here, the function has two formal parameters to check from mine and put them into show

2.

These represent the coordinates of other grids around the coordinates found

3. Because we store the characters' 0 'and' 1 'in the chessboard

Let's take a look first   ASCII code table

We can find that the ASCII code values of '0', '1', '2' characters are continuous. To display the number of mines around the grid, we need to convert the characters' 0 ',' 1 ',' 2 '... Into numbers 0, 1, 2, 3

We only need to subtract a '0' from each character, and its ASCII code value is 48. Let's see how we operate:

Then it is converted into characters and stored in the array

4. We also need to judge the legitimacy of the coordinates entered by the player:

4, All codes

game.h -- Declaration of game functions

```#pragma once
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#define ROW 9
#define COL 9
#define EASY_COUNT 10

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

//Initialize chessboard
void InitBoard(char board[ROWS][COLS], int rows,int cols,char set);
//Print chessboard
void DisplayBoard(char board[ROWS][COLS], int row, int col);
//Lay thunder
void SetMine(char mine[ROWS][COLS],int row,int col);
//Check thunder
void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS], int row, int col);```

game.c -- implementation of game function

```#define _CRT_SECURE_NO_WARNINGS
#include"game.h"
//initialization
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 chessboard
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
//1-9
int i = 0;
int j = 0;
printf("\n");
printf("---The Minesweeper game---\n");
//Print column number
for (i = 0;i <= col;i++)
{
printf("%d ", i);
}
printf("\n");
for (i = 1;i <= row;i++)
{
printf("%d ", i);
for (j = 1;j <= col;j++)
{

printf("%c ", board[i][j]);
}
printf("\n");
}

}

//Lay thunder
void SetMine(char mine[ROWS][COLS], int row, int col)
{
//Arrange 10 mines
int count = EASY_COUNT;
while (count)
{
//Production random subscript
int x = rand() % row + 1;//Range 1 to 9
int y = rand() % col + 1;
if (mine[x][y] == '0')
{
mine[x][y] = '1';
count--;
}
}
}

int get_mine_count(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+1] +
mine[x + 1][y] +
mine[x][y + 1] +
mine[x - 1][y + 1] - 8 * '0';
}
//Check thunder
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
//1. Enter the coordinates of the mine
//2. Check whether the coordinate is thunder
//(1) It's ray -- > I'm sorry it blew up
//(0) not thunder -- > there are several thunder -- > around the statistical coordinates to store the information of checking thunder into the show array. The game continues
int x = 0;
int y = 0;
int win = 0;
while (win<row*col- EASY_COUNT)
{
printf("Please enter the coordinates to check: ");
scanf("%d %d", &x, &y);//x ranges from 1 to 9 and y ranges from 1 to 9
//Judge the legitimacy of coordinates
if (x >= 1 && x <= col && y >= 1 && y <= row)
{
if (mine[x][y] == '1')
{
printf("I'm sorry you were killed\n");
DisplayBoard(mine, row, col);//Show me how he was killed
break;
}
else
{
//If it's not thunder, how many thunder are there around the (x,y) coordinate
int count = get_mine_count(mine, x, y);
show[x][y] = count+'0';
//Display the troubleshooting information
DisplayBoard(show, row, col);
win++;
}
}
else
{
}
}
if (win == row * col - EASY_COUNT)
{
DisplayBoard(mine, row, col);
}

}```

test.c    —— Test game

```#define _CRT_SECURE_NO_WARNINGS

#include"game.h"
{
printf("**********************\n");
printf("*****  1.play  *******\n");
printf("*****  0.exit  *******\n");
printf("**********************\n");
}
void game()
{
//Create array
char mine[ROWS][COLS] = { 0 };//Store the information of the arranged mine
char show[ROWS][COLS] = { 0 };//Store the information of the checked mine

//Initialize mine array to full character '0'
InitBoard(mine,ROWS,COLS,'0');
//Initialize the show array to all '*'
InitBoard(show,ROWS,COLS,'*');
//Print chessboard

DisplayBoard(show, ROW, COL);//Print only 9 * 9 content

//Lay thunder
SetMine(mine, ROW, COL);
/*DisplayBoard(mine, ROW, COL);*/
//This is not for players to see

//Check thunder
FindMine(mine,show,ROW,COL);//From mine to show
}

void test()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
scanf("%d", &input);
switch (input)
{
case 1:
//mine clearance
game();
break;
case 0:
break;
default:
printf("Selection error");
break;

}
} while (input);

}

int main()
{
test();
return 0;
}```

OK, so we have finished the minesweeping game

5, Thoughts on the improvement of games

If you have played authentic minesweeping games, you must know that minesweeping games also have two functions:

1. If it's not thunder and there's no thunder around -- > spread out
2. If we determine which location, we can mark ray

This is the optimization scheme we will give to the game in the future

The first of these functions we need to implement recursively

These will be updated later. Welcome to continue to pay attention!

Posted by agent_smith_sp on Wed, 10 Nov 2021 12:04:48 -0800