c language Gobang (including recursive clearing)

For the implementation of mine clearance, we can follow the following steps:

catalogue

1, Design ideas

2, Implementation mode

1. Menu printing

2.game function

3. Initialization and printing of chessboard

  4. Placement and number of Mines

5. Achieve a recursive effect

  6. Mine detection

  3, Complete code

1, Design ideas

Everyone must have played minesweeping

  This is a standard minesweeping. For code implementation, we need to consider the following points:

1. Design and initialization of chessboard

2. Put thunder in the chessboard

3. Statistics of mine number

4. How to achieve "one piece" effect

5. Judgment of winning or losing

Next, we will carry out specific operations.

 

 

2, Implementation mode

1. Menu printing

For any game, the menu is essential and the simplest part, directly on the code

void menu()
{
	printf("------------------mine clearance------------------\n");
	printf("---------------1.Start the game---------------\n");
	printf("---------------0.Exit the game---------------\n");
}
int main()
{
	srand((unsigned int)time(NULL));
	int a = 0;
	do
	{
		menu();
		scanf("%d", &a);
		if (a == 0)
		{
			break;
		}
		game();
	} while (a);
	return 0;
}

srand is used to find the random value to arrange the mine

2.game function

After the main menu is finished, enter the game function. In the game function, we will start the main game parts, such as chessboard initialization and printing. Of course, these steps are completed by functions. The game function is only equivalent to a collection of a series of game modules

void game()
{
	char mine[ROWS][COLS];
	char show[ROWS][COLS];
	initeboard(mine, ROWS, COLS, '0');
	initeboard(show, ROWS, COLS, '*');//Initial chessboard
	displayboard(show, ROW, COL);//Print chessboard
	mine_make(mine, ROW, COL);//Set mine
	//displayboard(mine, ROW, COL);
	find_mine(mine, show, ROWS, COLS);//Check thunder

}

3. Initialization and printing of chessboard

As you can see, I started two checkerboards in the game function. Why do I need two?

In fact, one is to place mines and the other is to show players. Why not use one? We should use '1' at the place where mines are placed and '0' at the place where mines are not placed. In this way, it will be easier to calculate the number of mines around a coordinate. Next, let's look at a section of code:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 10
#define COL 10
#define ROWS ROW+2
#define COLS COL+2

Here we see that a ROWS and COLS are defined. Why?

Return to the chessboard

  During minesweeping, when you confirm a point, it will line up the eight points around the point to see if there are tears. When the coordinates are located at the red line, it is not impossible to judge the eight points. Therefore, with ROWS and COLS, someone will ask: the place where the mine is buried can use ROW COL. there is no need to worry about the box we added when the mine runs outside. Our idea is very good, but we have two chessboards, It must correspond, and there is no case of running out of the mine. You will know by analyzing it further

void initeboard(char board[ROWS][COLS], int cols, int rows,char s)//For chessboard initialization, a step-saving method is used here, and two chessboards are not initialized in turn
{
	int i = 0;
	int j = 0;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			board[i][j] = s;
		}
	}
}
void displayboard(char board[ROWS][COLS], int row, int col)//Chessboard printing
{
	int i = 0;
	int j = 0;
	printf(" ");//Corresponding to 0%d printed in line
	for (j = 0; j <=col; j++)
	{
		printf(" %d  ", j);
	}
	printf("\n");
	printf("-");
	for (j = 1; j <= col + 1; j++)
	{
		printf("---");
		printf("|");
	}
	printf("\n");//Column corresponding printing completed
	for (i = 1; i <= row; i++)
	{
		if (i <= 9)
		{
			printf(" 0%d ", i);
		}
		else
		printf(" %d ", i);
		printf("|");
		for (j = 1; j <= col; j++)
		{
			printf(" %c ", board[i][j]);
			printf("|");
		}
		printf("\n");
		printf("-");
		for (j = 1; j <= col+1; j++)
		{
			printf("---");
			printf("|");
		}
		printf("\n");//The row correspondence is nested in front of the number printed internally, and 0 is added so that when the number of rows is greater than 9, it can correspond, such as 09 and 10
	}
}

The printing of the chessboard has row and column correspondence, so it may not be obvious

  4. Placement and number of Mines

The placement of Lei is very simple. Just place it at '0' on the chessboard, because our formula for random numbers makes random numbers only appear when 0-9 does not run out

mine_make(char mine[ROWS][COLS], int row, int col)//Set mine
{
	int count = 10;
	while (count)
	{
		int x = rand() % 10;
		int y = rand() % 10;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}
}

The number of Mines needs to be considered:

First of all, we need to judge whether there are mines in the eight surrounding positions and how many mines there are. At this time, we can use the type of '0' and '1', but note that this is a character, not a number

  A table shows us how to transform

Of course, remember to convert the returned number to character type

int get_mine(char mine[ROWS][COLS], int i, int j)//Get the number of mines near a coordinate
{
	return mine[i - 1][j - 1] + mine[i - 1][j] + mine[i - 1][j + 1] +
		mine[i][j - 1] + mine[i][j + 1] +
		mine[i + 1][j - 1] + mine[i +1 ][j] + mine[i + 1][j + 1] - 8 * '0';//Here, our numbers are actually characters, which can be transformed into digital shaping by this method
}

5. Achieve a recursive effect

When not for thunder, it will expand a nearby area of not for thunder to improve the efficiency of the game

void spread(char show[ROWS][COLS], char mine[ROWS][COLS], int x, int y)//Recursive method to achieve a large area
{
	show[x][y] = ' ';//First, let the coordinates of the input gold become a space, because it has been determined that there is thunder, so you can directly turn to a space
	int i = 0;
	int j = 0;
	int ret = 0;
	for (i = x - 1; i <= x + 1; i++)
	{
		for (j = y - 1; j <= y + 1; j++)//The nested for loop indicates that the input coordinates include eight self generated and surrounding coordinates
		{
			if (i > 0 && i <= ROW && j > 0 && j <= COL && mine[i][j] != '1' && show[i][j] == '*')//Avoid negative coordinates, thunder and repeated input
			{
				ret = get_mine(mine, i, j);//Judge whether ret is 0 or non-0, and obtain the number of surrounding mines
				if (!ret)//If ret=0,! ret is non-zero; For true
				{
					spread(show, mine, i, j);//recursion
				}
				if (ret)//ret!= If it is true at 0, the printing number will be printed
				{
					show[i][j] = ret + '0';//Convert numbers to corresponding characters
				}
			}

		}
	}
}

Effect display:

  6. Mine detection

Responsible for judging whether he was killed and winning the game

void find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)//Check thunder
{
	printf("Please enter coordinates\n");
	int i = 0;
	int j = 0;
	int win = 0;
	while (row*col-10)//Because it's ten thunder, it's - 10. Because you can win by subtracting 10 from the total number, you can jump out of the cycle. Of course, if the thunder position is 10, just set a variable, which won't be changed here
	{
		scanf("%d %d", &i, &j);
		if (mine[i][j] == '1')
		{
			printf("You hung up\n");
			displayboard(mine, ROW, COL);
			break;
		}
		else
		{
			show[i][j] = get_mine(mine, i, j)+'0';
			spread(show,mine, i, j);
			displayboard(show, ROW, COL);
			win++;
		}		
	}
	if (win ==row * col - 10)
	{
		printf("Congratulations on your success\n");
		displayboard(mine, ROW, COL);
	}
}

The specific comments are in the code

Under normal circumstances, just print the thunder disc notes, and you can play the game normally

  3, Complete code

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 10
#define COL 10
#define ROWS ROW+2
#define COLS COL+2
void menu()
{
	printf("------------------mine clearance------------------\n");
	printf("---------------1.Start the game---------------\n");
	printf("---------------0.Exit the game---------------\n");
}
void initeboard(char board[ROWS][COLS], int cols, int rows,char s)//For chessboard initialization, a step-saving method is used here, and two chessboards are not initialized in turn
{
	int i = 0;
	int j = 0;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			board[i][j] = s;
		}
	}
}
void displayboard(char board[ROWS][COLS], int row, int col)//Chessboard printing
{
	int i = 0;
	int j = 0;
	printf(" ");//Corresponding to 0%d printed in line
	for (j = 0; j <=col; j++)
	{
		printf(" %d  ", j);
	}
	printf("\n");
	printf("-");
	for (j = 1; j <= col + 1; j++)
	{
		printf("---");
		printf("|");
	}
	printf("\n");//Column corresponding printing completed
	for (i = 1; i <= row; i++)
	{
		if (i <= 9)
		{
			printf(" 0%d ", i);
		}
		else
		printf(" %d ", i);
		printf("|");
		for (j = 1; j <= col; j++)
		{
			printf(" %c ", board[i][j]);
			printf("|");
		}
		printf("\n");
		printf("-");
		for (j = 1; j <= col+1; j++)
		{
			printf("---");
			printf("|");
		}
		printf("\n");//The row correspondence is nested in front of the number printed internally, and 0 is added so that when the number of rows is greater than 9, it can correspond, such as 09 and 10
	}
}
mine_make(char mine[ROWS][COLS], int row, int col)//Set mine
{
	int count = 10;
	while (count)
	{
		int x = rand() % 10;
		int y = rand() % 10;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}
}
int get_mine(char mine[ROWS][COLS], int i, int j)//Get the number of mines near a coordinate
{
	return mine[i - 1][j - 1] + mine[i - 1][j] + mine[i - 1][j + 1] +
		mine[i][j - 1] + mine[i][j + 1] +
		mine[i + 1][j - 1] + mine[i +1 ][j] + mine[i + 1][j + 1] - 8 * '0';//Here, our numbers are actually characters, which can be transformed into digital shaping by this method
}
void spread(char show[ROWS][COLS], char mine[ROWS][COLS], int x, int y)//Recursive method to achieve a large area
{
	show[x][y] = ' ';//First, let the coordinates of the input gold become a space, because it has been determined that there is thunder, so you can directly turn to a space
	int i = 0;
	int j = 0;
	int ret = 0;
	for (i = x - 1; i <= x + 1; i++)
	{
		for (j = y - 1; j <= y + 1; j++)//The nested for loop indicates that the input coordinates include eight self generated and surrounding coordinates
		{
			if (i > 0 && i <= ROW && j > 0 && j <= COL && mine[i][j] != '1' && show[i][j] == '*')//Avoid negative coordinates, thunder and repeated input
			{
				ret = get_mine(mine, i, j);//Judge whether ret is 0 or non-0, and obtain the number of surrounding mines
				if (!ret)//If ret=0,! ret is non-zero; For true
				{
					spread(show, mine, i, j);//recursion
				}
				if (ret)//ret!= If it is true at 0, the printing number will be printed
				{
					show[i][j] = ret + '0';//Convert numbers to corresponding characters
				}
			}

		}
	}
}
void find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)//Check thunder
{
	printf("Please enter coordinates\n");
	int i = 0;
	int j = 0;
	int win = 0;
	while (row*col-10)//Because it's ten thunder, it's - 10. Because you can win by subtracting 10 from the total number, you can jump out of the cycle. Of course, if the thunder position is 10, just set a variable, which won't be changed here
	{
		scanf("%d %d", &i, &j);
		if (mine[i][j] == '1')
		{
			printf("You hung up\n");
			displayboard(mine, ROW, COL);
			break;
		}
		else
		{
			show[i][j] = get_mine(mine, i, j)+'0';
			spread(show,mine, i, j);
			displayboard(show, ROW, COL);
			win++;
		}		
	}
	if (win ==row * col - 10)
	{
		printf("Congratulations on your success\n");
		displayboard(mine, ROW, COL);
	}
}
void game()
{
	char mine[ROWS][COLS];
	char show[ROWS][COLS];
	initeboard(mine, ROWS, COLS, '0');
	initeboard(show, ROWS, COLS, '*');//Initial chessboard
	displayboard(show, ROW, COL);//Print chessboard
	mine_make(mine, ROW, COL);//Set mine
	displayboard(mine, ROW, COL);
	find_mine(mine, show, ROWS, COLS);//Check thunder

}
int main()
{
	srand((unsigned int)time(NULL));
	int a = 0;
	do
	{
		menu();
		scanf("%d", &a);
		if (a == 0)
		{
			break;
		}
		game();
	} while (a);
	return 0;
}
    

end. It's not easy to make. Give me some praise and pay attention.

 

Tags: C Back-end

Posted on Sat, 20 Nov 2021 12:30:33 -0500 by bluesoul