Minesweeping games

Posted by mrmom on Tue, 04 Jan 2022 15:54:28 +0100

1, Game design requirements

1. Enter coordinates to display the number of surrounding mines

2. All positions without mines nearby shall be deployed

3. If the player steps on thunder in the first move of chess, it is determined that the player is not dead and the thunder is redistributed

2, Code function

Select 1 to start the game and 0 to exit the game

```void menu()
{
printf("***************************\n");
printf("*********1.Start the game********\n");
printf("*********0.Exit the game********\n");
printf("***************************\n");
}```

2. Create two arrays, one for setting mines, and the other for storing the number of mines during demining

```char board[LINES][ROWS] = { 0 };  // Storage mine
char show[LINES][ROWS] = { 0 };//The number of mines after storage. In order to facilitate the investigation of the most peripheral mines, expand the square by one circle

#define LINE 9
#define ROW 9
#define LINES 11
#define ROWS 11```

Use the macro definition to set the array size for easy change

When checking mines, it is necessary to count the number of mines with a total of 8 coordinates around. In the 9 * 9 grid, for example, the coordinates of the upper left corner will be out of bounds during access, so expand the 9 * 9 array by one circle and change it to the 11 * 11 array, but the mine information is still stored in the 9 * 9 grid.

3. Initialization of two arrays

The board array is used to store future mines and is initialized to '0'

The show array is used to store the checked information and is initialized to '*'

Use char set to pass in '0' and '*'

```void Initboard(char board[LINES][ROWS], int lines, int rows, char set)
{
int i = 0; int j = 0;
for (i = 0; i < lines; i++)
{
for (j = 0; j < rows; j++)
{
board[i][j] = set;
}
}
}```

4. Print array

In order to facilitate the input of coordinates, the rows and columns are printed

```void Displayboard(char board[LINES][ROWS], int line, int row)
{
int i = 0; int j = 0;
for (i = 1; i <= line; i++)
{
if (i == 1)
{
for (j = 0; j <= row; j++)
printf("%d ", j);
printf("\n");
}
printf("%d ", i);
for (j = 1; j <= row; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
}```

5. Start setting mine

Use the macro definition to set the number of mines

It is required that the coordinates of thunder cannot exceed the boundary and cannot be repeated

Because the rows and columns are printed, the array coordinates start with 1

```void Setboard(char board[LINES][ROWS], int line, int row)
{//9 * 9 grid range 1 ~ 9
srand((unsigned int)time(NULL));
int count = COUNT;
while (count)
{
int x = rand() % line + 1;
int y = rand() % row + 1;
if (board[x][y] != '1')
{
board[x][y] = '1';
count--;
}
}
}```

6. Mine Troubleshooting: Findboard () realizes overall control

```int Time = 1;
void Findboard(char board[LINES][ROWS], char show[LINES][ROWS], int line, int row)
{
int x; int y;
int count = Countset(show, LINES, ROW);//show the total number of coordinates not expanded in the array
while (count>COUNT)//Loop condition: the number of unexpanded in the show array is more than the total number of Lei
{
printf("Game sharing%d A ray\n", COUNT);
printf("Please enter coordinates,Abscissa range 1~%d，Ordinate range 1~%d\n",line,row);
scanf("%d%d", &x, &y);
if (x >= 1 && x <= line && y >= 1 && y <= row) //Coordinates cannot be out of bounds
{
if (show[x][y] != '*')// Enter the expanded coordinates and re-enter the loop
{
printf("This position has been arranged, please re-enter the coordinates!\n");
}
else if (board[x][y] == '1')//The coordinates entered are ray
{
if (Time == 1)//The first step is to redistribute thunder in chess
{
printf("At the beginning of the game, I stepped on ray, and ray has been redistributed\n");
Safe(board, LINES, ROWS, x, y);
Findboard(board, show, line, row);
}
else //The coordinates entered are thunder, not the first step of chess, death
{
Sleep(100);
system("cls");
printf("I stepped on thunder\n");
printf("The distribution of lightning is shown in the figure:\n");
Displayboard(board, LINE, ROW);
break;// The thunder jumped out of the loop
}
}
else //If the coordinates entered are not thunder, the game does not meet the requirements of redistributing thunder, and the Time value is changed to 0
{
Time = 0;
int   s = Countboard(board, LINES, ROWS, x, y);//Record the number of thunder in a week
show[x][y] = s+'0';// Using the characteristics of ASCII code value, 1 + '0' ='1 ', so that the show array can store the number of mines
Openboard(board ,show, LINES, ROWS, x, y);//Where there are no mines around the expansion coordinates
count = Countset(show, LINES, ROW);//Record the number of coordinates of the remaining show array that have not been expanded, and change the comparison value of the loop condition
Sleep(100);
system("cls");
Displayboard(show, LINE, ROW);//Print show array
}
}
else//Coordinates out of bounds, re-enter
}
if (count == COUNT)//When the non expanded coordinates of the show array are equal to the total number of thunder, the game wins
printf("Successful demining\n");
}
```

Setboard() function generates thunder in the 9 * 9 array. It is required that the number is sufficient and the position is not repeated

```void Setboard(char board[LINES][ROWS], int line, int row)
{//9 * 9 grid range 1 ~ 9
srand((unsigned int)time(NULL));
int count = COUNT;
while (count)
{
int x = rand() % line + 1;
int y = rand() % row + 1;
if (board[x][y] != '1')
{
board[x][y] = '1';
count--;
}
}
}```

The Safe() function removes the thunder of this coordinate and regenerates the thunder of another position when the coordinate is entered for the first time. It is required that the thunder position cannot be repeated

```void Safe(char board[LINES][ROWS], int line, int row, int x, int y) //Avoid stepping on thunder the first time
{
board[x][y] = '0';
int b = 1;
while (b)
{
int x = rand() % line + 1;
int y = rand() % row + 1;
if (board[x][y] == '0')
{
board[x][y] = '1';
b = 0;
}
}```

Countboard(): counts the number of mines around the coordinates

Characters - characters get numbers

```int Countboard(char board[LINES][ROWS], int lines, int rows,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');
}
```

Openboard(): expand the position without thunder around, recursion

```void Openboard(char board[LINES][ROWS], char show[LINES][ROWS], int lines, int rows, int x, int y)
{
int ret = Countboard(board, LINES, ROWS, x, y);//ret number of Mines stored around
if (ret == 0)//If there is no thunder around, judge whether there is thunder in the surrounding coordinates
{
show[x][y] = '0';//Save show
if (x - 1 >= 1 && x - 1 <= LINE && y - 1 >= 1 && y - 1 <= ROW && show[x - 1][y - 1] == '*')//Coordinate range
Openboard(board, show, LINES, ROWS, x - 1, y - 1);
if (x - 1 >= 1 && x - 1 <= LINE && y + 1 >= 1 && y + 1 <= ROW && show[x - 1][y + 1] == '*')
Openboard(board, show, LINES, ROWS, x - 1, y + 1);
if (x - 1 >= 1 && x - 1 <= LINE && y >= 1 && y <= ROW && show[x - 1][y] == '*')
Openboard(board, show, LINES, ROWS, x - 1, y);
if (x >= 1 && x <= LINE && y - 1 >= 1 && y - 1 <= ROW && show[x][y - 1] == '*')
Openboard(board, show, LINES, ROWS, x, y - 1);
if (x >= 1 && x <= LINE && y + 1 >= 1 && y + 1 <= ROW && show[x][y + 1] == '*')
Openboard(board, show, LINES, ROWS, x, y + 1);
if (x + 1 >= 1 && x + 1 <= LINE && y - 1 >= 1 && y - 1 <= ROW && show[x + 1][y - 1] == '*')
Openboard(board, show, LINES, ROWS, x + 1, y - 1);
if (x + 1 >= 1 && x + 1 <= LINE && y >= 1 && y <= ROW && show[x + 1][y] == '*')
Openboard(board, show, LINES, ROWS, x + 1, y);
if (x + 1 >= 1 && x + 1 <= LINE && y + 1 >= 1 && y + 1 <= ROW && show[x + 1][y + 1] == '*')
Openboard(board, show, LINES, ROWS, x + 1, y + 1);
}
else//When there is thunder around the coordinates
show[x][y] = ret + '0';
}```

Countset(): counts the number of coordinates without expanded positions

```int Countset(char show[LINES][ROWS], int lines, int rows)
{
int i, j;
int count = 0;
for (i = 1; i <= LINE; i++)
{
for (j = 1; j <= ROW; j++)
{
if (show[i][j] == '*')
count++;
}
}
return count;
}```

3, Code

We put the definition of the above function in game C in the document

game.h declaration

```#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<windows.h>
#define LINE 9
#define ROW 9
#define LINES 11
#define ROWS 11
#define COUNT 10
void Initboard(char board[LINES][ROWS], int lines, int rows,char set);
void Displayboard(char board[LINES][ROWS], int line, int row);
void Setboard(char board[LINES][ROWS], int line, int row);
void Findboard(char board[LINES][ROWS], char show[LINES][ROWS], int line, int row);
int Countboard(char show[LINES][ROWS], int lines, int rows, int x, int y);
void Openboard(char board[LINES][ROWS], char show[LINES][ROWS], int lines, int rows, int x, int y);
void Safe(char board[LINES][ROWS], int lines, int rows,int x,int y);
int Countset(char show[LINES][ROWS], int lines, int rows);```

Set game c,  game.h put test C implementation

```#define _CRT_SECURE_NO_WARNINGS
#include "game.h"

void game()
{
char board[LINES][ROWS] = { 0 };  // Storage mine
char show[LINES][ROWS] = { 0 };//The number of mines after storage. In order to facilitate the investigation of the most peripheral mines, expand the square by one circle
Initboard(board, LINES, ROWS, '0');
Initboard(show, LINES, ROWS, '*');
printf("\n");
Displayboard(show, LINE, ROW);
Setboard(board, LINE, ROW);// Generate thunder in the 9 * 9 grid in the middle
Findboard(board,show ,LINE, ROW);//The number of mines near the coordinates is passed into the show array
}

int main()
{
int ch = 0;
do
{