C language implementation of minesweeping game package + optimization (recursion)

Mine sweeping game can be said to be a very classic game. Today we will try to realize this game in C language

catalogue

1. Ideas

  2. Code

3. Ideas

4. Optimization (recursion)

1. ideas

Before writing code, think about how the framework can realize the game. First, it has a 9 * 9 chessboard with randomly placed mines,

Click one of the coordinates to judge whether it is a mine. When it is not a mine, judge the surrounding 8 coordinates and return the number of Mines under the surrounding 8 coordinates. When we think of this, it is not difficult to find that it is actually realized through a two-dimensional array, but there may be boundary crossing when judging the surrounding coordinates during random lightning, so we change the chessboard to 11 * 11 to achieve the effect as shown in the figure below. After knowing the size of the array, we can start to complete the code

  2. Code

In order to improve the readability of the code, we still divide it into three files: 1.game.h    2.game.c   3.test.c

Let's look at the contents of different documents

1.game.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define MY_MINE 10
void Initboard(char board[ROWS][COLS], int rows, int cols, char ret);//initialization
void Displayboard(char board[ROWS][COLS], int row, int col);//Print
void Set_mine(char board[ROWS][COLS], int row, int col);//Buried mine
void Find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);//mine clearance

In the header file game.h, there are #include library functions, #define constants and function declarations to implement the game

2.game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void Initboard(char board[ROWS][COLS], int rows, int cols, char ret)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			board[i][j] = ret;
		}
	}
}
void Displayboard(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	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");
	}
}
void Set_mine(char board[ROWS][COLS], int row, int col)
{
	int count = MY_MINE;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (board[x][y] == '0')
		{
			board[x][y] = '1';
			count--;
		}
	}
}
static 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] +
		mine[x + 1][y + 1] +
		mine[x][y + 1] +
		mine[x - 1][y + 1] - 8 * '0';
}
static void blank(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
	if (0 == get_mine_count(mine, x, y))
	{
		show[x][y] = ' ';
		int i = 0;
		int j = 0;
		for (i = x - 1; i <= x + 1; i++)
		{
			for (j = y - 1; j <= y + 1; j++)
			{
				if (i > 0 && i <= ROW && j > 0 && j <= COL && mine[i][j] != '1'&&show[i][j] == '*')
				{
					blank(mine, show, i, j);
				}
			}
		}
	}
	else
	{
		show[x][y] = (get_mine_count(mine, x, y)) + '0';
	}
}
void Find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int win = 0;
	while (win<row*col-MY_MINE)
	{
		printf("Please enter the coordinates to find:");
		scanf("%d %d", &x, &y);
		if (x > 0 && x <= row && y > 0 && y <= col)
		{
			if (mine[x][y] == '1')
			{
				printf("Congratulations on being blown up!\n");
				Displayboard(mine, row, col);
				break;
			}
			else
			{//The coordinates are not ray
				blank(mine, show, x, y);
				Displayboard(show, row, col);
				win++;
			}
		}
		else
		{
			printf("Illegal coordinates, please re-enter:");
		}
	}
	if (win == row * col - MY_MINE)
	{
		printf("Game victory!\n");
		Displayboard(mine, row, col);
	}
}

In game.c, it is the specific function of the game, such as array initialization, printing chessboard, burying mines, minesweeping and so on

3.test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu()
{
	printf("************************\n");
	printf("****    1.  play    ****\n");
	printf("****    0.  exit    ****\n");
	printf("************************\n");
}
void game()
{
	char mine[ROWS][COLS] = { 0 };//arrangement
	char show[ROWS][COLS] = { 0 };//Exhibition
	Initboard(mine, ROWS, COLS, '0');//initialization
	Initboard(show, ROWS, COLS, '*');
	//Displayboard(mine, ROW,COL);// Print
	Displayboard(show, ROW, COL);//Print
	Set_mine(mine, ROW,COL);//Buried mine
	Displayboard(mine, ROW, COL);
	Find_mine(mine,show,ROW,COL);//mine clearance
}
void test()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("Please select:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("Exit the game\n");
			break;
		default:
			printf("Select error, reselect:\n");
			break;
		}
	} while (input);
}
int main()
{
	test();
	return 0;
}

test.c is the framework of the game, so as to connect the functions of various functions

3. Ideas

So much code may still not understand how to implement it. Then I'll simply sort out the logic for easy understanding

In order to start playing the game and play it continuously, I chose do while(); Loop. menu() is the menu printing function. The player selects 1 / 0 to judge whether the game is going on. When the player selects 1, he enters the game(): function. First, we need to initialize two two two-dimensional arrays (mine array is the game buried mine mark, and show array is displayed for the player). After initialization, we can print it out and have a look. Then we complete the buried mine, The buried mine is a random number, and the corresponding coordinates are easy to understand. After the buried mine is completed, it can also be printed out to facilitate timely error correction. Finally, it is minesweeping. Minesweeping can judge whether it is mine by inputting coordinates. This is the simple logic.

4. Optimization (recursion)

The basic implementation of the game is very simple, but it's just the smell of shortcomings, that is, it can't unfold. What do you mean? Let's see the figure above

 

  How is this implemented? In fact, the idea of recursion is used. If you want to write it, you have to know the conditions of recursion

1. The coordinates are not thunder

2. There is no thunder around this coordinate

3. This coordinate has not been checked

4. Do not cross the border

Knowing these can complete the optimization of mine sweeping code

static void blank(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
	if (0 == get_mine_count(mine, x, y))
	{
		show[x][y] = ' ';
		int i = 0;
		int j = 0;
		for (i = x - 1; i <= x + 1; i++)
		{
			for (j = y - 1; j <= y + 1; j++)
			{
				if (i > 0 && i <= ROW && j > 0 && j <= COL && mine[i][j] != '1'&&show[i][j] == '*')
				{
					blank(mine, show, i, j);
				}
			}
		}
	}
	else
	{
		show[x][y] = (get_mine_count(mine, x, y)) + '0';
	}
}

This is the code to realize recursion. Pay attention to avoid dead recursion, empty coordinates and judge the conditions of recursion. I hope it will help you. Of course, you can also copy the code and run by yourself to deepen your understanding. The above code is already the optimized code.  

Keywords: C

Added by balsdorf on Fri, 12 Nov 2021 01:44:15 +0200