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:

https://gitee.com/living-amethyst/code2021/tree/master/test_11_09_mine%20clearance 

  Let's start!

catalogue

1, The overall idea of the game

2, Create game menu  

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

 

2, Create game menu  

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
	{
		menu();
		printf("Please select");
		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
		{
			printf("Illegal coordinates, please re-enter\n");
		}
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("Congratulations on your success!");
		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
		{
			printf("Illegal coordinates, please re-enter\n");
		}
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("Congratulations on your success!");
		DisplayBoard(mine, row, col);
	}
	

}

  test.c    —— Test game  

#define _CRT_SECURE_NO_WARNINGS

#include"game.h"
void menu()
{
	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
	{
		menu();
		printf("Please select:\n");
			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