Preparation of minesweeping game program


In the era of computer or Windows xp and Windows 7, many people must be exposed to a very classic game, mine sweeping game. The simple interface, easy to use difficulty and the mode of playing without surfing the Internet make it very popular. Although the mine sweeping game is no longer installed by default on Windows 10 system, we can remember our feelings when we used to play by writing our own code. However, due to my limited ability, I can only realize the position confirmation by keyboard input.

General idea

First of all, we need to clarify the rules of the minesweeping game. We enter the coordinates through the keyboard to determine the location of mine clearance. If there are mines in this location, the game ends. If there are no mines in this location, the game continues and the number of mines around is displayed. If we confirm all the places without mines and know all the places with mines, the player will win.
Then we can think about how to achieve it. Because the data of Mines cannot be known by the player during playing, and the data entered by the player needs to be stored. At the same time, the data displayed on the panel should be the number of surrounding mines. The two are different. For the above two reasons, we need to create two two-dimensional arrays, one for displaying the number of unmade places and surrounding mines, named show_board, another location used to store mines, is named mine_board.
But there is another key point. If we want to show a 66 panel, should we create two two-dimensional arrays of 66? Although this is most in line with our most direct idea, the following problems have also been solved. If the coordinates entered by the player are located in the border of the panel, such as the top row, we do not need to detect the data in the top row when calculating the number of mines around us, but if it is in the bottom row, we do not need to detect the lower row, even if it is in the upper left corner, we do not need to detect the upper and left rows, This will be a lot of trouble for us to write code to detect the number of mines around. Therefore, we need to add a circle on the outside to create an 8 * 8 array, which will be much more convenient for display and storage.
Then we can write the function we need. The function functions we need include: Menu to display the directory, SetMines to bury mines, ShowBoard to display the panel, CountMines to calculate the number of mines around, and Game to execute Game related commands. When we sort out our ideas, we can start writing programs.

Function function

Menu function for displaying directories

This function is used to provide players with the option to play or exit.

void Menu()
{
	printf("########################\n");
	printf("# 1. Play       0.Exit #\n");
	printf("########################\n");
}

Function SetMines of buried mines

Take two random numbers as coordinates and assign a value to the position they point to, then it is to bury a mine. At the same time, the macro definition is defined, and the number NUM of mines is defined as 20, which is convenient for modification during later program maintenance.

#define NUM 20
static void SetMines(char board[][COL], int row, int col)
{
	int count = NUM;
	while (count){
		int x = rand() % (row - 2) + 1;
		int y = rand() % (col - 2) + 1;//Find a random location
		if (board[x][y] == '0'){
			board[x][y] = '1';//Lay mines
			count--;
		}
	}
}

Function of display panel ShowBoard

Will show_ All values in the board are displayed in a loop. Because each ROW should display the lower border of the table, for convenience and beauty, write a separate function ShowLine to display the lower border. Define two macros, ROW and COL, to represent the rows and columns of the created array.

#define ROW 8
#define COL 8

static void ShowBoard(char board[][COL], int row, int col)
{
	printf("     ");
	for (int i = 1; i <= (col - 2); i++){
		printf("%d   ", i);
	}
	printf("\n");
	ShowLine(col);
	for (int i = 1; i <= (row - 2); i++){
		printf("%-3d|", i);
		for (int j = 1; j <= (col - 2); j++){
			printf(" %c |", board[i][j]);
		}
		printf("\n");
		ShowLine(col);
	}
}
static void ShowLine(int col)
{
	for (int i = 0; i <= (col - 2); i++){
		printf("----");
	}
	printf("\n");
}

Function CountMines to calculate the number of surrounding mines

This function adds all the data of the 8 positions of the seat pointing to the coordinates, and it is the number of all the mines around. When a mine is not buried at a location, the displayed value is 0. After the mine is buried, the displayed value is changed to 1 to add the values of the eight locations, but the value we store is char type. Therefore, it is necessary to subtract 7 '0' values to truly represent the number of surrounding mines.

static char CountMines(char board[][COL], 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 + 1][y + 1] + board[x + 1][y] + \
		board[x + 1][y - 1] + board[x][y - 1] - 7 * '0';
}

A function that executes Game related commands

First, we need to show the player the panel, let the player enter a coordinate, and then judge whether the coordinate is legal, judge whether the coordinate exceeds the range limited by the panel, and judge whether it has been occupied. If the above two situations occur, relevant prompt statements need to be displayed. For the convenience of players to view prompt statements, put the prompt statements on the next display panel, and use the selection statements to display different prompt statements. If the coordinate is legal, judge whether there is thunder in this coordinate. If there is thunder, the game ends. If there is no thunder, assign the position only thought of by the coordinate. When there is no place other than mines on the panel, the game wins.

#define ROW 8
#define COL 8
#define STYLE '?'
#define NUM 20

void Game()
{
	srand((unsigned long)time(NULL));

	char show_board[ROW][COL];
	char mine_board[ROW][COL];

	memset(show_board, STYLE, sizeof(show_board));
	memset(mine_board, '0', sizeof(mine_board));//Initialize show_board and mine_board

	SetMines(mine_board, ROW, COL);

	int count = (ROW - 2)*(COL - 2) - NUM;//Calculate the total number of locations other than mines
	int error = 0;
	while (count){
		system("cls");
		if (error == 1){
			printf("Postion Error!\n");
		}//The coordinates entered by the player are out of range
		else if(error == 2){
			printf("Postion Is not *\n");
		}//The coordinates entered by the player have been occupied
		ShowBoard(show_board, ROW, COL);
		printf("Please Enter Your Postion<x,y># ");
		int x = 0;
		int y = 0;
		scanf("%d %d", &x, &y);
		if (x < 1 || x > ROW - 2 || y < 1 || y > COL - 2){
			error = 1;
			continue;
		}
		if (show_board[x][y] != STYLE){
			error = 2;
			continue;
		}
		if (mine_board[x][y] == '1'){
			printf("game over!\n");
			ShowBoard(mine_board, ROW, COL);
			break;//Demining failed, end the game
		}
		error = 0;
		show_board[x][y] = CountMines(mine_board, x, y);
		count--;
	}
	if (!count){
		printf("You win!\n");//Successful demining
	}
}

main function

First display the directory, let the player enter the operation he wants to perform, and execute the corresponding command.

int main()
{
	int quit = 0;
	int select = 0;
	while (!quit){
		Menu();
		printf("Please Enter# ");
		scanf("%d", &select);
		switch (select){
		case 1:
			Game();
			break;
		case 0:
			quit = 1;
			break;
		default:
			printf("Postion Error, Try Again!\n");
			break;
		}
	}

	printf("byebye!\n");

	system("pause");
	return 0;
}

So far, all the programs of Sanzi have been written, and the result of combining all the previous codes is shown below.

Collection

The game.h file in the collection mainly includes macro definitions and function declarations; game.c file for the preparation of all function functions; The main.c file is the preparation of the main calling function.

clear_mine.h file

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>

#define ROW 8
#define COL 8
#define STYLE '?'
#define NUM 20

extern void Game();
extern void Menu();

clear_mine.c file

#include "clear_mine.h"

void Menu()
{
	printf("########################\n");
	printf("# 1. Play       0.Exit #\n");
	printf("########################\n");
}

static void SetMines(char board[][COL], int row, int col)
{
	int count = NUM;
	while (count){
		int x = rand() % (row - 2) + 1;
		int y = rand() % (col - 2) + 1;
		if (board[x][y] == '0'){
			board[x][y] = '1';
			count--;
		}
	}
}

static void ShowLine(int col)
{
	for (int i = 0; i <= (col - 2); i++){
		printf("----");
	}
	printf("\n");
}

static void ShowBoard(char board[][COL], int row, int col)
{
	printf("     ");
	for (int i = 1; i <= (col - 2); i++){
		printf("%d   ", i);
	}
	printf("\n");
	ShowLine(col);
	for (int i = 1; i <= (row - 2); i++){
		printf("%-3d|", i);
		for (int j = 1; j <= (col - 2); j++){
			printf(" %c |", board[i][j]);
		}
		printf("\n");
		ShowLine(col);
	}
}

static char CountMines(char board[][COL], 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 + 1][y + 1] + board[x + 1][y] + \
		board[x + 1][y - 1] + board[x][y - 1] - 7 * '0';
}

void Game()
{
	srand((unsigned long)time(NULL));

	char show_board[ROW][COL];
	char mine_board[ROW][COL];

	memset(show_board, STYLE, sizeof(show_board));
	memset(mine_board, '0', sizeof(mine_board));

	SetMines(mine_board, ROW, COL);

	int count = (ROW - 2)*(COL - 2) - NUM;
	int error = 0;
	while (count){
		system("cls");
		if (error == 1){
			printf("Postion Error!\n");
		}
		else if(error == 2){
			printf("Postion Is not *\n");
		}
		ShowBoard(show_board, ROW, COL);
		printf("Please Enter Your Postion<x,y># ");
		int x = 0;
		int y = 0;
		scanf("%d %d", &x, &y);
		if (x < 1 || x > ROW - 2 || y < 1 || y > COL - 2){
			error = 1;
			continue;
		}
		if (show_board[x][y] != STYLE){
			error = 2;
			continue;
		}
		if (mine_board[x][y] == '1'){
			printf("game over!\n");
			ShowBoard(mine_board, ROW, COL);
			break;
		}
		error = 0;
		show_board[x][y] = CountMines(mine_board, x, y);
		count--;
	}
	if (!count){
		printf("You win!\n");
	}
}

main.c file

#include "clear_mine.h"
int main()
{
	int quit = 0;
	int select = 0;
	while (!quit){
		Menu();
		printf("Please Enter# ");
		scanf("%d", &select);
		switch (select){
		case 1:
			Game();
			break;
		case 0:
			quit = 1;
			break;
		default:
			printf("Postion Error, Try Again!\n");
			break;
		}
	}

	printf("byebye!\n");
	system("pause");
	return 0;
}

Posted by signs on Wed, 27 Oct 2021 01:29:31 -0700