An article takes you to understand the minesweeper game (implemented in c language)

Table of contents

foreword

1. Game design logic

2. Game thinking and implementation process 

2.1 Establishment of symbols and chessboard

2.2 Initialization and printing of chessboard 

2.3 Lay out mines

2.4 Check for mines and set the end flag

3. Code display 

test.c 

game.c

game.h

foreword

Minesweeper is a classic small game, so how to implement it in C language? Next, I will take you through the minesweeper game.

Note: The files used in this game are similar to those in the previous article, and the code display is attached at the end.

1. Game design logic

1. Lay out mines - 10

2. Minesweeper

   input coordinates;

   If it is mine - it will blow up and the game is over;

   If it's not mine - tell you how many mines there are in the 8 coordinates around this coordinate;

   Until all the locations of non-minefields are found, the game is over and the minesweeping is successful.

2. Game thinking and implementation process 

2.1 Establishment of symbols and chessboard

                                                               

Let's take a 9*9 chessboard as an example. If you only use a two-dimensional array, use '*' to represent mines, '#' to represent non-mines, and use numbers to represent the information of checking mines. Then when you check, you need to traverse the entire array, which is too troublesome. So for this situation, we need to use two character-type two-dimensional arrays to achieve. Between the arrays of your brother, a mine array is used to print the information of the arranged mines , and a show array is used to print the information of the mines detected

Use '1'- mine , '0'- not mine. Use '*' to indicate unchecked locations, and numeric characters to indicate checked locations.

On the 8 coordinates around the digital character display, if it is close to the edge, some coordinates will exceed the coordinate range, and the phenomenon that the array is out of bounds will occur. What we want to write is a 9*9 board, then we will add one to each row and column to become an 11*11 board. We only use the middle 9*9 board. Then our array will become like this.

                                                          

Macro defines the rows and columns of the two-dimensional array in game.h. 

#define ROW 9
#define COL 9

#define ROWS ROW+2
#define COLS COL+2

 Create a two-dimensional array, which is the chessboard needed for minesweeping

	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };

2.2 Initialization and printing of chessboard 

Initialize the chessboard, the effect we want is that the mine array is all '0' at the beginning, and the show array is all '*'

The specific implementation of the function is in game.c

	init_board(mine, ROWS, COLS,'0');
	init_board(show, ROWS, COLS, '*');
void init_board(char arr[][], int rows, int cols, char set)
{
	int i = 0;
	for (i = 0; i < rows; i++)
	{
		int j = 0;
		for (j = 0; j < cols; j++)
		{
			arr[i][j] = set;
		}
	}
}

To print the chessboard, if we want to quickly know where the next position is, we can print out the row and column numbers.

	show_board(mine, ROW, COL);
	show_board(show, ROW, COL);
void show_board(char arr[ROWS][COLS], int row, int col)
{
	int i = 0;
	printf("------------扫雷------------\n");
	for (i = 0; i<= col; i++)//打印列号
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		printf("%d ",i);//打印行号
		int j = 0;
		for (j = 1; j <=col; j++)
		{
			printf("%c ", arr[i][j]);
		}
		printf("\n");
	}
	printf("------------扫雷------------\n");
}

2.3 Lay out mines

	set_mine(mine, ROW, COL);
#define EASY_COUNT 10
void set_mine(char mine[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int count = EASY_COUNT;
	while (count)
	{
		x = rand() % 9 + 1;
		y = rand() % 9 + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}
}

A macro definition constant is used for later modification for convenience. With the printing function in the aspect, you can try to print out the chessboard to see if the mine is arranged.

2.4 Check for mines and set the end flag

When troubleshooting mines, we need to figure out that two arrays are used. We put the information in the mine array into the show array, and the troubleshooting involves both arrays.

find_mine(mine, show, ROW, COL);

Because 1'- thunder , '0'- non mine , we want to display the number of surrounding mines, we must first select a coordinate to drop, and then traverse the surrounding eight coordinates                           

We need to know one thing '1'-'0' == 1 . This is why we use '1' and '0' to represent mine information, which is very convenient for us to check mine. We want to return the information of the surrounding eight coordinates, just add the characters (ascll value) of the surrounding eight coordinates together, and then subtract 8*'0' , then we can get the information of how many mines are around. We also know that we set a total of 10 mines in this game, and we win when we find all the positions that are not mines. I used a win to mark the game won state. Teach you a method of game testing, we can change the macro definition constant EASY_COUNT to 80, then there will be only one non-mine position, after setting up the minefield, first print out the mine array, and then follow the arrangement Yes, because at this time we only have one position without thunder, so we can quickly test the result of winning.

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-EASY_COUNT)
	{
		printf("请输入坐标:>");
		scanf("%d %d", &x, &y);

		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (mine[x][y] == '1')
			{
				printf("你被炸死了\n");
				show_board(mine, ROW, COL);
				break;
			}
			else
			{
				int count = get_mine_count(mine, x, y);
				show[x][y] = count + '0';
				show_board(show, ROW, COL);
				win++;
			}
		}
		else
		{
			printf("坐标非法,请重新输入\n");
		}
	}

	if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你,你赢了\n");
		show_board(mine, ROW, COL);
	}
}
int get_mine_count(char mine[ROWS][COLS], int x, int y)
{
	return mine[x - 1][y - 1] +
		mine[x - 1][y] + 
		mine[x - 1][y + 1] + 
		mine[x][y - 1] + 
		mine[x][y + 1] + 
		mine[x + 1][y - 1] +
		mine[x + 1][y] + 
		mine[x + 1][y + 1] - 8 * '0';
}

3. Code display 

test.c 

#include "game.h"

void menu()
{
	printf("******************\n");
	printf("***** 1.play *****\n");
	printf("***** 0.exit *****\n");
	printf("******************\n");
}
//扫雷游戏的实现
void game()
{
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };
	//初始化
	init_board(mine, ROWS, COLS, '0');
	init_board(show, ROWS, COLS, '*');

	//打印棋盘

	//show_board(show, ROW, COL);
	// 
	//布置雷
	set_mine(mine, ROW, COL);
	//show_board(mine, ROW, COL);
	show_board(show, ROW, COL);

	//排查雷
	find_mine(mine, show, ROW, COL);

}


int main()
{
	srand((unsigned int)time(NULL));
	int input = 0;
	do
	{
		menu();
		printf("请输入:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,重新选择\n");
			break;

		}
	} while (input);
	return 0;
}

game.c

#include "game.h"
//初始化棋盘
void init_board(char arr[ROWS][COLS], int rows, int cols, char set)
{
	int i = 0;
	for (i = 0; i < rows; i++)
	{
		int j = 0;
		for (j = 0; j < cols; j++)
		{
			arr[i][j] = set;
		}
	}
}
//打印棋盘
void show_board(char arr[ROWS][COLS], int row, int col)
{
	int i = 0;
	printf("------------扫雷------------\n");
	for (i = 0; i <= col; i++)//打印列号
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		printf("%d ",i);//打印行号
		int j = 0;
		for (j = 1; j <= col; j++)
		{
			printf("%c ", arr[i][j]);
		}
		printf("\n");
	}
	printf("------------扫雷------------\n");
}

//布置雷
void set_mine(char mine[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int count = EASY_COUNT;
	while (count)
	{
		x = rand() % 9 + 1;
		y = rand() % 9 + 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 - 1] +
		mine[x - 1][y] + 
		mine[x - 1][y + 1] + 
		mine[x][y - 1] + 
		mine[x][y + 1] + 
		mine[x + 1][y - 1] +
		mine[x + 1][y] + 
		mine[x + 1][y + 1] - 8 * '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-EASY_COUNT)
	{
		printf("请输入坐标:>");
		scanf("%d %d", &x, &y);

		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (mine[x][y] == '1')
			{
				printf("你被炸死了\n");
				show_board(mine, ROW, COL);
				break;
			}
			else
			{
				int count = get_mine_count(mine, x, y);
				show[x][y] = count + '0';
				show_board(show, ROW, COL);
				win++;
			}
		}
		else
		{
			printf("坐标非法,请重新输入\n");
		}
	}

	if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你,你赢了\n");
		show_board(mine, ROW, COL);
	}
}

game.h

#pragma once

#include <stdio.h>

#define ROW 9
#define COL 9

#define ROWS ROW+2
#define COLS COL+2

#define EASY_COUNT 10

//初始化
void init_board(char arr[ROWS][COLS], int rows, int cols, char set);

//打印棋盘
void show_board(char arr[ROWS][COLS], int row, int col);

//布置雷
void set_mine(char arr[ROWS][COLS], int row, int col);

//排查雷
void find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

This is the implementation of a simple minesweeper game.

Guess you like

Origin blog.csdn.net/m0_63562631/article/details/125678797