Jeu de démineur en langage C

teneur

1. Présentation des modèles de dragage de mines

2. Texte ---> Analyse logique

        2.1 Menu Générer

        2.2 Créer un échiquier

        2.3 Initialiser la carte

        2.4 Impression de l'échiquier

        2.5 Placement des mines

        2.6 Dépanner les mines

3. Code total

      3.1 fichier test.c

      3.2 fichier game.c

      3.3 fichier game.h


1. Présentation des modèles de dragage de mines

Cette image est un modèle de déminage que vous pouvez trouver sur la page Web, et en langage C, nous pouvons également écrire un code simple pour obtenir l'image ci-dessus. comme le montre l'image:

 Comment implémenter cette interface, je vous donnerai une explication détaillée plus tard :

2. Texte ---> Analyse logique

D'après le style de démineur simple ci-dessus, nous pouvons voir que premièrement, un répertoire doit être généré pour dire au joueur de jouer ou de quitter, et deuxièmement, lorsque le joueur commence à jouer, un échiquier sera affiché devant le joueur. À ce stade, un échiquier doit être créé et lui attribuer des caractères à initialiser, puis nous devons définir le nombre correspondant de mines à l'intérieur de l'échiquier et enfin vérifier si les coordonnées sont des mines une par une grâce à la saisie de coordonnées par l'utilisateur. valeurs.

Afin que le code interne du programme Minesweeper ait l'air organisé, nous devons configurer les fichiers correspondants pour gérer notre code et le rendre plus soigné. comme le montre l'image:

Premièrement : utilisez le fichier test.c pour tester la logique du jeu. Deuxièmement : utilisez le fichier game.c pour implémenter la logique du jeu. Troisièmement : utilisez le fichier game.h pour déclarer la fonction d'implémentation du jeu. Dans le contenu suivant, nous continuerons à utiliser ces trois fichiers

        2.1 Menu Générer

 L'étape la plus importante est de présenter un menu devant le joueur, indiquant au joueur s'il doit choisir de jouer au jeu ou de quitter le jeu, vous devez implémenter ce code dans le fichier test.c :

#include"game.h"  //引用总头文件,此做法简洁明了
void menu()
{
	printf("****************************************\n");
	printf("*******           1.play         *******\n");
	printf("*******           0.exit         *******\n");
	printf("****************************************\n");
}
void test()
{
	
	int input = 0;
	do
	{
		menu();
		printf("请输入:>");
		scanf("%d", &input);
		switch (input)  //用switch语句来处理玩家输入的信息
		{
		case 1:
			game();  //当玩家输入1时进入游戏,此时需要调用game()函数,后续会讲到
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("非法输入,请重新输入!\n");
			break;
		}
			
	} while (input);
}
int main()
{
	test();
	return 0;
}

Avant d'implémenter ce contenu de code, il y a une prémisse importante : se référer au fichier d'en-tête. Dans la première ligne de ce code, #include"game.h" fait référence au fichier d'en-tête de game.h. Dans le fichier game.h, vous devez compléter ce code :

Lorsque le code des deux fichiers ci-dessus est terminé, exécutons-le :

 

 Le menu a été généré avec succès.

        2.2 Créer un échiquier

Avant d'écrire le code, analysons à quoi ressemble vraiment l'échiquier

En théorie, le véritable échiquier devrait être tout le contenu avec *, ce qui peut être réalisé en créant un tableau bidimensionnel de 9*9, mais nous supposons une situation où lorsque le joueur coche le * dans le coin supérieur gauche, il y aura un accès hors limites, car lors de la vérification s'il y a une mine à l'emplacement, et qu'il y a plusieurs mines, nous comptons les 8 éléments adjacents autour de la coordonnée. Lors de la visite du coin supérieur gauche*, il n'y a que trois éléments autour qui peuvent être consultés, et les 5 éléments restants sont disponibles pour l'accès.Afin d'éviter cela, lors de la création d'un tableau, 11*11 doit être créé pour éviter la situation d'accès hors limites. Comme indiqué dans le code suivant :

#include"game.h"

void game()
{
	//创建数组
	char mine[ROWS][COLS] = { 0 };   //存放布置好的雷的信息
	char show[ROWS][COLS] = { 0 };   //存放排查出的雷的信息
//此时此刻ROWS代表行数,COLS代表列数。
//ROWS和COLS并未直接赋值是为了方便以后改变棋盘大小更为便捷



}

Les étudiants attentifs ici peuvent trouver que j'ai créé deux tableaux ici, le tableau mine et le tableau show. En fait, il est très nécessaire de créer un tableau de cette manière, car une fois que tout le code est terminé, lorsque nous exécutons, l'échiquier qui apparaît vraiment devant le joueur devrait être le tableau d'affichage, le tableau de mine est juste pour la pose mines plus tard, et le tableau de spectacle est nous Où le joueur va vraiment déminer. 

Bien sûr, ce code ne suffit pas, car ROWS et COLS n'ont pas été définis. À ce stade, nous devons le définir dans le fichier game.h pour y parvenir : comme indiqué dans le code ci-dessous :

        2.3 Initialiser la carte

Une fois l'échiquier créé avec un tableau à deux dimensions, nous devons initialiser l'échiquier. Le code suivant doit être complété dans le fichier test.c :

#include"game.h"

void game()
{
	//创建数组
	char mine[ROWS][COLS] = { 0 };   //存放布置好的雷的信息
	char show[ROWS][COLS] = { 0 };   //存放排查出的雷的信息

	//初始化数组mine全为‘0’
	InitBoard(mine, ROWS, COLS, '0');
	//初始化数组show全为‘*’
	InitBoard(show, ROWS, COLS, '*');
}

Afin d'implémenter l'ensemble du processus de la fonction InitBoard, nous devons compléter le code suivant dans le fichier game.c :

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
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;   //初始化对应的数组
		}
	}
}

//通过用for循环来初始化棋盘每一个元素为相应的字符

Avant de mettre en œuvre l'initialisation de la carte avec la fonction InitBoard, cette fonction doit être déclarée :

        2.4 Impression de l'échiquier

Lorsque nous initialisons le contenu sur l'échiquier, nous devons imprimer l'échiquier pour détecter de quel type de situation il s'agit. À ce moment, nous devons appeler la fonction DisplayBoard pour imprimer l'échiquier. Ensuite, vous devez compléter le code suivant dans le fichier 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 };   //存放布置好的雷的信息
	char show[ROWS][COLS] = { 0 };   //存放排查出的雷的信息

	//初始化数组mine全为‘0’
	InitBoard(mine, ROWS, COLS, '0');
	//初始化数组show全为‘*’
	InitBoard(show, ROWS, COLS, '*');
	//打印棋盘
	DisplayBoard(mine, ROW, COL);
	DisplayBoard(show, ROW, COL);
}

Dans le fichier game.c, l'ensemble du processus d'impression de l'échiquier avec la fonction DisplayBoard est implémenté. Comme indiqué dans le code suivant :

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");
	}
}

Afin de permettre aux joueurs de connaître plus facilement les coordonnées des lignes et des colonnes qu'ils souhaitent vérifier lorsqu'ils voient l'échiquier, nous pouvons afficher le numéro de ligne et le numéro de colonne devant le joueur. Cela se fait également à l'aide d'une instruction de boucle for. Après cela, la carte ne fonctionne toujours pas correctement car nous n'avons pas déclaré la fonction DisplayBoard dans le fichier d'en-tête game.h. Nous pouvons le faire comme ceci :

 Lorsque les opérations ci-dessus sont terminées, nous pouvons exécuter le code normalement pour observer la situation de l'échiquier : nous imprimerons à la fois le tableau show et le tableau mine pour voir :

        2.5 Placement des mines

Lorsque nous imprimons l'échiquier, nous devons installer des mines sur le réseau de mines. À ce stade, nous avons besoin que l'ordinateur génère automatiquement un certain nombre de mines et les répartisse dans des positions aléatoires des coordonnées. Nous devons utiliser une fonction importante srand ((unsigned int )time(NULL)); et faites correspondre les mines sur le tableau de mines au tableau d'exposition, à ce moment, l'impression du tableau de mines peut être bloquée, et seule l'impression du tableau d'exposition est générée pour le joueur pour nettoyer les mines.

Ensuite sur le fichier test.c, il faut compléter ce code :

#include"game.h"

void game()
{
	//创建数组
	char mine[ROWS][COLS] = { 0 };   //存放布置好的雷的信息
	char show[ROWS][COLS] = { 0 };   //存放排查出的雷的信息

	//初始化数组mine全为‘0’
	InitBoard(mine, ROWS, COLS, '0');
	//初始化数组show全为‘*’
	InitBoard(show, ROWS, COLS, '*');
	//打印棋盘
	//DisplayBoard(mine, ROW, COL);
	//DisplayBoard(show, ROW, COL);

	//布置雷
	SetMine(mine, ROW, COL);

	DisplayBoard(show, ROW, COL);

	
}


void test()
{
	srand((unsigned int)time(NULL));
	
}

De même, nous devons également utiliser la fonction SetMine sur le fichier game.c pour implémenter l'ensemble du processus d'arrangement des mines : le code est le suivant :

void SetMine(char mine[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';  //随机自动生成雷
			count--;
		}
	}

}

En même temps, il faut aussi déclarer la fonction dans le fichier game.h :

 Après avoir terminé les opérations ci-dessus, exécutons-le et voyons :

 Vous pouvez voir que le tableau mine est en dessous et le tableau show est au-dessus. Le tableau mine a automatiquement généré le mien et est représenté par le caractère 1.

        2.6 Dépanner les mines

La dernière étape consiste à vérifier la mine. Lorsque le joueur entre les coordonnées qu'il souhaite vérifier, le système déterminera si la position modifiée est une mine et utilisera une instruction if pour y parvenir. Si c'est le cas, le défi échouera. Plusieurs les mines sont affichées et la sortie est affichée à l'écran pour la référence du joueur. Lorsque toutes les mines ont été vérifiées, le déminage du joueur est réussi.

Dans le fichier test.c, nous devons compléter le code suivant :

#include"game.h"
void game()
{
	//创建数组
	char mine[ROWS][COLS] = { 0 };   //存放布置好的雷的信息
	char show[ROWS][COLS] = { 0 };   //存放排查出的雷的信息

	//初始化数组mine全为‘0’
	InitBoard(mine, ROWS, COLS, '0');
	//初始化数组show全为‘*’
	InitBoard(show, ROWS, COLS, '*');
	//打印棋盘
	//DisplayBoard(mine, ROW, COL);
	//DisplayBoard(show, ROW, COL);

	//布置雷
	SetMine(mine, ROW, COL);
	//DisplayBoard(show, ROW, COL);
	DisplayBoard(show, ROW, COL);


	//排雷
	FindMine(mine,show, ROW, COL);


}

Nous devons implémenter tout le processus de vérification du mien dans le fichier game.c :

#include"game.h"
int get_mine_count(char mine[ROWS][COLS], int x, int y)
{
	return mine[x - 1][y] +
		mine[x - 1][y - 1] +
		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 FindMine(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");
				DisplayBoard(mine, row, col);
				break;

			}
			else
			{
				//计算x,y坐标周围有几个雷
				int n = get_mine_count(mine, x, y);
				show[x][y] = n + '0';
				DisplayBoard(show, row, col);
				win++;
			}
		}
		else
		{
			printf("输入坐标非法,请重新输入\n");
		}
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你,排雷成功\n");
		DisplayBoard(mine, row, col);

	}
	
	
}

Encore une fois, nous devons faire une déclaration de fonction dans le fichier game.h

Lorsque tout le code a été exécuté, jetons un coup d'œil :

3. Code total

      3.1 fichier 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 };   //存放布置好的雷的信息
	char show[ROWS][COLS] = { 0 };   //存放排查出的雷的信息

	//初始化数组mine全为‘0’
	InitBoard(mine, ROWS, COLS, '0');
	//初始化数组show全为‘*’
	InitBoard(show, ROWS, COLS, '*');
	//打印棋盘
	//DisplayBoard(mine, ROW, COL);
	//DisplayBoard(show, ROW, COL);

	//布置雷
	SetMine(mine, ROW, COL);
	DisplayBoard(mine, ROW, COL);
	DisplayBoard(show, ROW, COL);


	//排雷
	FindMine(mine,show, ROW, COL);


}
void test()
{
	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);
}
int main()
{
	test();
	return 0;
}

      3.2 fichier game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
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;   //初始化对应的数组
		}
	}
}

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 SetMine(char mine[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 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] +
		mine[x - 1][y - 1] +
		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 FindMine(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");
				DisplayBoard(mine, row, col);
				break;

			}
			else
			{
				//计算x,y坐标周围有几个雷
				int n = get_mine_count(mine, x, y);
				show[x][y] = n + '0';
				DisplayBoard(show, row, col);
				win++;
			}
		}
		else
		{
			printf("输入坐标非法,请重新输入\n");
		}
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你,排雷成功\n");
		DisplayBoard(mine, row, col);

	}
	
	
}

      3.3 fichier game.h

#pragma once
//头文件的包含
#include<stdio.h>
#include<time.h>
#include<stdlib.h>

//符号的声明
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_COUNT 10

//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);

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

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

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

Je suppose que tu aimes

Origine blog.csdn.net/bit_zyx/article/details/121259261
conseillé
Classement