C language to achieve a simple minesweeping game

Posted by shoppingspree on Thu, 27 Jan 2022 17:40:18 +0100

Basic idea:

  1. Create an array of laying mines and an array showing the number of mines near mines
  2. Random number arrangement

  3. Enter the array coordinates for mine sweeping. If it is a mine, the game will end. If it is not, the number of nearby mines will be displayed in this coordinate

  4. Cycle until the end of the game

Key:

  1. The minesweeping is a 9 * 9 square array, but the array of actual mines should be defined as a two-dimensional array of 11 * 11, so as to calculate the number of mines near a coordinate
  2. Mine laying, minesweeping and printing are only the 9 * 9 array in the middle of 11 * 11

The first is to create game c,test.c two source files and custom header file game h. Game functions are written in game C, in test C to realize the overall game logic

The main functions are as follows

Array initialization

Pass in the array of arr characters. The rows and columns are rows and cols respectively. The initialization value is' set '

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

Print

The overall game interface is printed here, including the reference coordinates of the array and the minesweeping area:

The passed in array is an 11 * 11 array. This function only prints the 9 * 9 elements in the middle

void display(char arr[ROWS][COLS], int row, int col)  
{
	printf("------SEEKMINE------\n");
	for (int i = 0; i <= row; i++)     //Print reference columns
	{
		printf("%d ", i);
	}
	printf("\n");
	for (int i = 1; i <= row; i++)       //Print minesweeping interface
	{
		printf("%d ", i);             //Print reference lines
		for (int j = 1; j <= col; j++)   
		{
			printf("%c ", arr[i][j]);  //Print 9 * 9 array in the middle of 11 * 11 array
		}
		printf("\n");
	} 
	printf("------SEEKMINE------\n");
}

Random mine laying

Note that the srand function should be called in the main function before using the rand function.

The parameter passed in here is the mine[ROWS][COLS] array, a character array defined as 11 * 11. The mine function randomly arranges the mine in the 9 * 9 element in the middle of the array

//Set n mines
void set_mine(char arr[ROWS][COLS], int row, int col,int n)  //The array passed in is 11 * 11, but Lei wants to assign it to the 9 * 9 array in the middle
{
	for (int i = 0; i < n; i++)  //The number of cycles is n
	{
		int x = 0, y = 0;
		do  
		{
			x = rand() % row;  //Generate random numbers from 0 to 8
			y = rand() % col;
		} while (arr[x + 1][y + 1] != '0');  //Judge whether there is thunder in this coordinate, and if so, take the coordinates at random again
		arr[x+1][y+1] = '1';  //Assign mine to '1'
	}
}

Judge the number of surrounding mines

Because the value in the mine array is' 0 'during initialization and the value of mine during mine laying is' 1', the ASCII code value of '1' - '0' is 1, so you can read the elements of the eight arrays around the incoming array coordinates, add them, subtract 8 * '0', and then you can get the number of mines in the eight coordinates around this coordinate, and then return this number as the return value

This shows the advantage of setting the minefield array to 11 * 11. In the middle 9 * 9 array, there will be 8 elements around any element, which can realize the judgment of this function without crossing the boundary

//Judge the number of surrounding mines
int get_mine(char arr[ROWS][COLS],int x,int y)
{
	return arr[x - 1][y - 1] +   //Read the array elements in the surrounding 8 grids and subtract '0' to get the number of mines
		arr[x - 1][y] + 
		arr[x - 1][y + 1] + 
		arr[x][y - 1] +
		arr[x][y + 1] + 
		arr[x + 1][y - 1] +
		arr[x + 1][y] + 
		arr[x + 1][y + 1] - 8 * '0';
}

mine clearance

This function introduces two arrays, one is the mine array, one is the show array, and the mine array stores the information of the thunder already arranged. Show is used to print the display array, input the coordinates, and judge the mine array. The mine function obtains the number of nearby mines and assigns this value to the show array

int find_mine(char arr1[ROWS][COLS],char arr2[ROWS][COLS],int row,int col)
{
	int x = 0, y = 0;
	int count = 0;
	while (count < row * col - EASYMINE)  //Judge whether minesweeping is over
	{
		printf("Please enter minesweeping coordinates:");
		scanf("%d %d", &x, &y);  //x. Number with y from 1 to 9
		if (arr1[x][y] == '1')   //It's ray
		{
			printf("You were killed\n");
			display(arr1, ROW, COL);
			return -1;
		}
		else if (arr1[x][y] == '0')        //Not ray
		{
			count++;                       //Count plus one
			if (get_mine(arr1, x, y) > 0)  //If the number of nearby mines is not 0
			{
				arr2[x][y] = '0' + get_mine(arr1, x, y);  //Assign the nearby thunder number to the show array, because the ASCII code value of the number is increasing, so + n can represent the corresponding number
			}
			else arr2[x][y] = ' ';        //If the number of nearby mines is 0, the value is assigned as a space
		}
		else
		{
			printf("Error, please re-enter:\n");
		}
		display(arr2, ROW, COL);
	}
	if (count == row * col - EASYMINE)
	{
		printf("Successful mine clearance\n");
	}
	return 0;
}

Full code:

game.h

#define _CRT_SECURE_NO_WARNINGS 1

#define ROW 9
#define COL 9
#define ROWS 11
#define COLS 11
#define EASYMINE 10 / / number of Mines

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

void init_game(char arr[ROWS][COLS], int row, int col, char set);
void display(char arr[ROWS][COLS], int row, int col);
void set_mine(char arr[ROWS][COLS], int row, int col, int n);
void show_mine(char arr[ROWS][COLS], int rows, int cols);
int find_mine(char arr1[ROWS][COLS], char arr2[ROWS][COLS], int row, int col);

game.c

#define _CRT_SECURE_NO_WARNINGS 1

#include"game.h"

//initialization
void init_game(char arr[ROWS][COLS], int rows, int cols, char set)  
{
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			arr[i][j] = set;
		}
	}
}

//Print
void display(char arr[ROWS][COLS], int row, int col)  
{
	printf("------SEEKMINE------\n");
	for (int i = 0; i <= row; i++)     //Print reference columns
	{
		printf("%d ", i);
	}
	printf("\n");
	for (int i = 1; i <= row; i++)       //Print minesweeping interface
	{
		printf("%d ", i);             //Print reference lines
		for (int j = 1; j <= col; j++)   
		{
			printf("%c ", arr[i][j]);  //Print 9 * 9 array in the middle of 11 * 11 array
		}
		printf("\n");
	} 
	printf("------SEEKMINE------\n");
}


//Test function, which is used to check whether the mine is successfully arranged
void show_mine(char arr[ROWS][COLS], int rows, int cols)
{
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			printf("%c ", arr[i][j]);
		}
		printf("\n");
	}
}

//Set n mines
void set_mine(char arr[ROWS][COLS], int row, int col,int n)  //The array passed in is 11 * 11, but Lei wants to assign it to the 9 * 9 array in the middle
{
	for (int i = 0; i < n; i++)  //The number of cycles is n
	{
		int x = 0, y = 0;
		do  
		{
			x = rand() % row;  //Generate random numbers from 0 to 8
			y = rand() % col;
		} while (arr[x + 1][y + 1] != '0');  //Judge whether there is thunder in this coordinate, and if so, take the coordinates at random again
		arr[x+1][y+1] = '1';  //Assign mine to '1'
	}
}

//Judge the number of surrounding mines
int get_mine(char arr[ROWS][COLS],int x,int y)
{
	return arr[x - 1][y - 1] +   //Read the array elements in the surrounding 8 grids and subtract '0' to get the number of mines
		arr[x - 1][y] + 
		arr[x - 1][y + 1] + 
		arr[x][y - 1] +
		arr[x][y + 1] + 
		arr[x + 1][y - 1] +
		arr[x + 1][y] + 
		arr[x + 1][y + 1] - 8 * '0';
}

//mine clearance
int find_mine(char arr1[ROWS][COLS],char arr2[ROWS][COLS],int row,int col)
{
	int x = 0, y = 0;
	int count = 0;
	while (count < row * col - EASYMINE)  
	{
		printf("Please enter minesweeping coordinates:");
		scanf("%d %d", &x, &y);  //x. Number with y from 1 to 9
		if (arr1[x][y] == '1')   //It's ray
		{
			printf("You were killed\n");
			display(arr1, ROW, COL);
			return -1;
		}
		else if (arr1[x][y] == '0')        //Not ray
		{
			count++;                       //Count plus one
			if (get_mine(arr1, x, y) > 0)  //If the number of nearby mines is not 0
			{
				arr2[x][y] = '0' + get_mine(arr1, x, y);  //Assign the nearby thunder number to the show array, because the ASCII code value of the number is increasing, so + n can represent the corresponding number
			}
			else arr2[x][y] = ' ';        //If the number of nearby mines is 0, the value is assigned as a space
		}
		else
		{
			printf("Error, please re-enter:\n");
		}
		display(arr2, ROW, COL);
	}
	if (count == row * col - EASYMINE)
	{
		printf("Successful mine clearance\n");
	}
	return 0;
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1

#include"game.h"

void menu()
{
	printf("**************************\n");
	printf("********    mine clearance   *******\n");
	printf("**************************\n");
	printf("********   1.play  *******\n");
	printf("********   0.quit  *******\n");
	printf("**************************\n");

}
void game()
{
	char mine[ROWS][COLS] = { 0 };       //Array for storing mine positions, 11 * 11
	init_game(mine, ROWS, COLS, '0');    //Initialize array to 0
	char show[ROWS][COLS] = { 0 };       //Store an array showing the number of nearby mines
	init_game(show, ROWS, COLS, '*');    //Initialize array to*

	set_mine(mine, ROW, COL, EASYMINE);  //Set the number of mines to EASYMINE
	display(show, ROW, COL);             

	find_mine(mine, show, ROW, COL);      //Start minesweeping
}
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		scanf("%d", &input);
		switch (input)    //Skip selection according to input
		{
		case 1:
			game();
			break;
		case 0:
			printf("Exit the game\n");
			break;
		default:
			printf("Error, please re-enter:\n");
			break;
		}
	} while (input);
	return 0;
}

Topics: C Game Development