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

1. Menu interface

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
			printf("Illegal coordinates, please re-enter\n");
	}
	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
	{
		menu();
		scanf("%d", &ch);
		switch (ch)
		{
		case 1:printf("Start the game\n"); system("cls"); game(); break;
		case 0:printf("Exit the game\n"); break;
		default:printf("Input error, please re-enter\n"); break;
		}
	} while (ch);
	return 0;
}