当前位置:网站首页>C language to achieve a simple game - minesweeping

C language to achieve a simple game - minesweeping

2022-06-11 07:43:00 Fried tomatoes 110

What I want to share with you today is the code implementation of mine sweeping , And the one I wrote the other day Sanzi almost , The general idea is to take the two-dimensional array as the carrier , Write design functions to implement its various functions . Let's take a look at the final results ( The complete code is at the end of the article ~)

First of all, we can see from this achievement map , You can choose to do it again after the game , You can also exit , So in the code, we must put the whole game process in a loop , I used do-while loop , The general idea is the same as the Sanzi chess written above . Look at the code :

void test()
{
	int input = 0;
	do
	{
		srand((unsigned)time(NULL));// Use timestamp to set random seed 
		menu();
		printf(" Please select ->");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf(" Mine clearance \n");
			game();
			break;
		case 0:
			printf(" Quit the game \n");
			break;
		default:
			printf(" Illegal input , Please re-enter !\n");
		}
	} while (input);
}

  Here I would like to add the reason why input As while The condition of the cycle , Because input 1 when ,input The value of is 1, It's true , The corresponding is play, Start the game ; Input 0 when , For false , The corresponding is exit, Just like jumping out of the loop , You will be asked to re-enter other values , Until input 0 or 1. This arrangement kills two birds with one stone .

When the input 1 after , The program will go to game() function , That is the main design of our game .

I mainly created Two identical two-dimensional arrays ,mine[ROWS][COLS] Array is used to store mine information ;show[ROWS][COLS] Array is used to show the thunder disk , The subsequent demining process is also shown in this two-dimensional array .

If the data design of the whole game is based on a two-dimensional array, it is relatively easy to confuse , For example, if there is only one array , In addition to distinguishing mined areas from non mined areas , There is also information to be processed for subsequent demining . It's not that you can't use a two-dimensional array , use 2 A two-dimensional array is designed to make the idea clearer .

Once created, call the following function InitBoard() Initialize them

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

Then we can write a function that prints the array DisplayBoard(), It is used to simulate the thunder disk that appears on the interface when playing games .

void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i <=row; i++)
	{
		printf(" %d ", i);
	}
	printf("\n");
	for (i = 1; i <=col; i++)
	{
		printf(" %d ", i);
		for (j = 1; j <=col; j++)
		{
			printf(" %c ", board[i][j]);
		}
		printf("\n");
	}

}

And then we're going to start talking about mine The array is mined , because mine Array is used to store the information of mine , and show To show , So there's no need to be right show Array buries mines . Minefields are represented by characters ‘1’ To express , Characters for non mined areas ‘0’ To express . It's used here SetMine() function , The following is the code implementation :

void SetMine(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	int count = COUNT;
	while(count)// The number of ray 
	{
		i = rand() % row + 1;
		j = rand() % col + 1;
		if (board[i][j] == '0')
		{
			board[i][j] = '1';
			count--;
		}
	}
}

The following function is used to count several minefields around a non minefield , use get_mine_count() Function implementation . It's simple , Let's look directly at the code :

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';
}

The above is basically the preparatory work , The next step is demining . It mainly uses  FindMine() Function to implement . Mine clearance operation is mainly for show Array data . Because what is displayed in front of everyone is show Array to simulate a chessboard . because mine Array and show The format of the array is the same and one-to-one correspondence . Then the general idea is to set the coordinates of the user to be checked in mine Array comparison , For example, if you step on a mine or there are several mines around it , Then reflect the results to show On the coordinates corresponding to the array . Let's look at how the code is implemented :

void FindMine(char board1[ROWS][COLS], char board2[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	int n = 0;
	while (n < (ROW * COL - COUNT))
	{
		printf(" Please enter the coordinates to be checked ->");
		scanf("%d %d", &i, &j);
		if (i >= 1 && i <= 9&& j >= 1 && j <= 9&& board2[i][j]=='*')
		{
			if (board1[i][j] == '1')
			{
				printf(" unfortunately ,, You're killed in the blast \n");
				DisplayBoard(board1, ROW, COL);
				break;
			}
			else//
			
			{	
				spread(board1, board2, i, j);
				DisplayBoard(board2, row, col);
				n++;
			}
		}
		else
			printf(" Illegal input , Please re-enter !");
	}
	if (n == row * col - COUNT)
		printf(" Mine clearance is successful !!!\n");
}

Here is a spread() Functions have to be explained , This is also a difficult point in game design . Its function is to take the input coordinates as the center , If it's around 8 If there is no ray in all the coordinates, this 8 Expand all coordinates . Then take the expanded coordinates as the center in turn , Judge its surroundings 8 Whether there is no ray in the coordinates ( The expanded coordinates need not be judged , Otherwise, dead recursion will be formed ), If it doesn't exist, expand the surrounding 8 A coordinate , And then to this 8 Determine the coordinates in turn ...... And so on , Until it can't unfold again . Let's take a look at the specific code :

void spread(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 (show[i][j] == '*' && i >0  && j > 0 && i <=ROW && j <= COL)
					spread(mine, show, i, j);
		}
	}
	else
	{
		int m = get_mine_count(mine, x, y);
		show[x][y] = m + '0';
	}
	
}

How does this code achieve the above functions ? It's not hard to see. , It's used here recursive thinking . I judge the coordinates first , If this coordinate corresponds to mine Around the coordinates of the array 8 There are no coordinates, ray , The coordinate corresponding to show Set the elements of the array to characters ‘ ’, And then to the surrounding 8 Check the coordinates one by one , If there is no thunder around a certain coordinate , Then set one of these coordinates to ‘ ’, And then around some coordinates 8 Check the coordinates one by one ....... Until around a certain coordinate of the search 8 When there is at least one thunder around each coordinate, it stops , Then these cannot be set to ‘  ’ Corresponding to the coordinates of show Set the elements of the array to numeric characters , A few thunders will show the number of characters .

Finally, I would like to add , How do I use numeric characters to show that there are several mines around a non mined area . Because an array defines an array of characters , therefore It cannot be expressed directly in numbers . Well, if there is... Around a non mined area 3 How can we reset the element of the character array so that the player can know ? I have to take a look at this first ASCII surface :

  Numbers 3 It cannot be used to express , But we can use characters ‘3’ To express , It can be seen from the above figure that if you want to get characters ‘3’, Then you only need to use the character ‘0’ Add a number to it 3 that will do , character ‘0’ Corresponding ASCII The code value is 48, add 3 Namely 51, It just corresponds to the character ‘3’. alike , If you want to get characters ‘2’, You just need to use ‘0’+2 That's it , namely use ‘0’+ You can get the same characters as the numbers .

Good good , So far, the functions to realize each function are roughly finished , If you think it's OK, just give me a compliment , Of course, Sanlian is the best . Finally, I attach all the codes here .test.c Inside is the game implementation logic ,game.c Inside is the game function implementation logic ,game.h Inside is the contents of the header file , Functions 、 Declaration of symbols . As for why it is so designed, you are welcome to read what I wrote a few days ago Sanzi Ha , There are explanations in it .

game.h

#pragma once
// The header file contains 
#include<stdio.h>
#include<time.h>
#include<stdlib.h>

// Declaration of symbols 
#define ROW 9
#define COL 9
#define COLS COL+2
#define ROWS ROW+2
#define COUNT 10

// Declaration of functions 
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);// Initialize chessboard 
void DisplayBoard(char bodrd[ROWS][COLS], int row, int col);// Print chessboard 
void SetMine(char[ROWS][COLS], int row, int col);// Arrange thunder 
void FindMine(char board1[ROWS][COLS], char board2[ROWS][COLS], int row, int col);// Check the thunder 

game.c

// Game functions to achieve logic 
#define _CRT_SECURE_NO_WARNINGS 
#include "game.h"
#define _CRT_SECURE_NO_WARNINGS 

// Initialize chessboard 
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			board[i][j] = set;
		}
	}
}

// Print chessboard 
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i <=row; i++)
	{
		printf(" %d ", i);
	}
	printf("\n");
	for (i = 1; i <=col; i++)
	{
		printf(" %d ", i);
		for (j = 1; j <=col; j++)
		{
			printf(" %c ", board[i][j]);
		}
		printf("\n");
	}

}
void SetMine(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	int count = COUNT;
	while(count)// The number of ray 
	{
		i = rand() % row + 1;
		j = rand() % col + 1;
		if (board[i][j] == '0')
		{
			board[i][j] = '1';
			count--;
		}
	}
}
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';
}

/* If the input coordinate is taken as the center , Around it 8 If there is no thunder in each coordinate, it will be completely expanded .
 Then take the expanded coordinates as the center in turn , Judge its surroundings 8 Whether there is thunder ( The expanded coordinates need not be judged , Otherwise, dead recursion will be formed ) And so on , Until it can't unfold again .*/
void spread(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 (show[i][j] == '*' && i >0  && j > 0 && i <=ROW && j <= COL)
					spread(mine, show, i, j);
		}
	}
	else
	{
		int m = get_mine_count(mine, x, y);
		show[x][y] = m + '0';
	}
	
}

void FindMine(char board1[ROWS][COLS], char board2[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	int n = 0;
	while (n < (ROW * COL - COUNT))
	{
		printf(" Please enter the coordinates to be checked ->");
		scanf("%d %d", &i, &j);
		if (i >= 1 && i <= 9&& j >= 1 && j <= 9&& board2[i][j]=='*')
		{
			if (board1[i][j] == '1')
			{
				printf(" unfortunately ,, You're killed in the blast \n");
				DisplayBoard(board1, ROW, COL);
				break;
			}
			else// Count the number of thunder 
			
			{	
				spread(board1, board2, i, j);
				DisplayBoard(board2, row, col);
				n++;
			}
		}
		else
			printf(" Illegal input , Please re-enter !");
	}
	if (n == row * col - COUNT)
		printf(" Mine clearance is successful !!!\n");
}

test.c

#define _CRT_SECURE_NO_WARNINGS 
#include"game.h"
void menu()
{
	printf("************************\n");
	printf("******** 1.play ********\n");
	printf("******** 0.exit ********\n");
	printf("************************\n");

}
void game()
{
	char mine[ROWS][COLS] = { 0 };// Lay out Ray's chessboard 
	char show[ROWS][COLS] = { 0 };// Check Ray's chessboard , That is, the chessboard seen by the client 
	InitBoard(mine, ROWS, COLS, '0');// initialization mine The array is all '0'
	InitBoard(show, ROWS, COLS, '*');//c initialization show The array is all ’*‘
	
	SetMine(mine, ROW, COL);// Arrange thunder 
	//DisplayBoard(mine, ROW, COL);
	DisplayBoard(show, ROW, COL);// Print Ray's chessboard 	
	FindMine(mine,show,ROW,COL);// Demining 
}
void test()
{
	int input = 0;
	do
	{
		srand((unsigned)time(NULL));// Use timestamp to set random seed 
		menu();
		printf(" Please select ->");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf(" Mine clearance \n");
			game();
			break;
		case 0:
			printf(" Quit the game \n");
			break;
		default:
			printf(" Illegal input , Please re-enter !\n");
		}
	} while (input);
}
int main()
{
	test();
	return 0;
}

原网站

版权声明
本文为[Fried tomatoes 110]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/03/202203020519105969.html