C语言实现扫雷小游戏---纯C

C语言实现扫雷小游戏---纯C,第1张

文章目录
  • 前言
  • 一、代码逻辑测试
  • 二、游戏代码实现
  • 三、游戏代码声明
  • 四、整体代码
  • 五、游戏代码难点部分
    • 1.Find_Mine(排查雷) 并且Unfold_show(展开一片区域)
    • 2.判断胜利
  • 总结


前言

今天,我们用C语言来写一个小游戏----扫雷。

整体逻辑
1.要有一个棋盘(二维数组)存放雷,另一个棋盘显示给玩家,两个二维数组大小相同
2.放置雷,一个二维数组用来存放雷,另一个二维数组用来给玩家排雷
3.排查雷,在放置雷的二维数组中判断输入坐标的周围的雷的个数,在另一个二维数组中显示给玩家。坐标周围有雷,显示雷的个数,没有雷,展开该坐标
4.标记雷的位置
5.判断是否获胜

一、代码逻辑测试

写在test.c

#define _CRT_SECURE_NO_WARNINGS 
#include"game.h"
void menu()
{
	printf("*******************************\n");
	printf("*******************************\n");
	printf("*****  1.play     0.exit  *****\n");
	printf("*******************************\n");
	printf("*******************************\n");
}
void game()
{
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };
	Initboard(mine, '0');  //初始化棋盘
	Initboard(show, '*');
	Set_Mine(mine, ROW, COL);	//布置雷
	//DisplayBoard(mine, ROW, COL);
	DisplayBoard(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();
			//printf("扫雷\n");
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);
	return 0;
}
二、游戏代码实现

写在game.c中

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"

//初始化数组
void Initboard(char board[ROWS][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;
	printf("-------扫雷游戏--------\n");
	for (j = 0; j <= col; j++)
	{
		printf("%d ", j);
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);
		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
	printf("-------扫雷游戏--------\n");
}
//布置雷
void Set_Mine(char mine[ROWS][COLS], int row, int col)
{
	int count = 0;
	while (count< EASY_MINE)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count++;
		}
	}
}


//排查mine数组中x,y坐标周围有几个雷
int Get_Mine_Num(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 Unfold_show(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
	if (x >= 1 && x <= ROW && y >= 1 && y <= COL)
	{
		if (Get_Mine_Num(mine, x, y) != 0)
		{
			show[x][y] = Get_Mine_Num(mine, x, y) + '0';
			return;
		}
		if (show[x][y] == '#')
		{
			return;
		}
		show[x][y] = '#';
		Unfold_show(mine, show, x - 1, y);
		Unfold_show(mine, show, x - 1, y - 1);
		Unfold_show(mine, show, x, y - 1);
		Unfold_show(mine, show, x + 1, y - 1);
		Unfold_show(mine, show, x + 1, y);
		Unfold_show(mine, show, x + 1, y + 1);
		Unfold_show(mine, show, x, y + 1);
		Unfold_show(mine, show, x - 1, y + 1);
		show[x][y] = ' ';
	}
}
//排查雷
void Find_Mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int i = 0;
	int j = 0;
	int count = 0;
	int input = 0;
	while (1)
	{
		printf("1.排雷  2.锁定雷  3.取消锁定\n");
		printf("请输入你的选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("请输入要排查的坐标:");
			scanf("%d %d", &x, &y);
			if (show[x][y] == '*')
			{
				if (mine[x][y] == '1')
				{
					printf("很遗憾,你被炸死了\n");
					DisplayBoard(mine, ROW, COL);
					return;
				}
				else
				{
					if (Get_Mine_Num(mine, x, y) == 0)
					{
						Unfold_show(mine, show, x, y);
					}
					else
					{
						char num = Get_Mine_Num(mine, x, y) + '0';
						show[x][y] = num;
					}
					DisplayBoard(show, ROW, COL);
				}
			}
			else
			{
				printf("该坐标已被排查过,请重新输入坐标\n");
			}
			break;
		case 2:
			printf("请输入要锁定的坐标:");
			scanf("%d %d", &x, &y);
			show[x][y] = '?';
			DisplayBoard(show, ROW, COL);
			break;
		case 3:
			printf("请输入要取消锁定的坐标:");
			scanf("%d %d", &x, &y);
			show[x][y] = '*';
			DisplayBoard(show, ROW, COL);
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
		//是否找出所有雷
		for (i = 1; i <= row; i++)
		{
			for (j = 1; j <= col; j++)
			{
				if ( show[i][j] == '?' && mine[i][j] == '1')
					count++;
			}
		}
		if (count == EASY_MINE)
		{
			printf("恭喜你,扫雷成功\n");
			return;
		}
		count = 0;
	}
}

三、游戏代码声明

写在game.h中

#pragma once
#include
#include
#include

#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_MINE 10

//初始化棋盘
void Initboard(char board[ROWS][COLS],char set);
//显示棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col);
//布置雷
void Set_Mine(char board[ROWS][COLS], int row, int col);
//排查雷
void Find_Mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
四、整体代码
//game.h
#pragma once
#include
#include
#include

#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_MINE 10

void Initboard(char board[ROWS][COLS],char set);
void DisplayBoard(char board[ROWS][COLS], int row, int col);
void Set_Mine(char board[ROWS][COLS], int row, int col);
void Find_Mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

//test.c
#define _CRT_SECURE_NO_WARNINGS 
#include"game.h"
void menu()
{
	printf("*******************************\n");
	printf("*******************************\n");
	printf("*****  1.play     0.exit  *****\n");
	printf("*******************************\n");
	printf("*******************************\n");
}
void game()
{
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };
	Initboard(mine, '0');  //初始化棋盘
	Initboard(show, '*');
	Set_Mine(mine, ROW, COL);	//布置雷
	//DisplayBoard(mine, ROW, COL);
	DisplayBoard(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();
			//printf("扫雷\n");
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);
	return 0;
}
//gama.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"

//初始化数组
void Initboard(char board[ROWS][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;
	printf("-------扫雷游戏--------\n");
	for (j = 0; j <= col; j++)
	{
		printf("%d ", j);
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);
		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
	printf("-------扫雷游戏--------\n");
}
//布置雷
void Set_Mine(char mine[ROWS][COLS], int row, int col)
{
	int count = 0;
	while (count< EASY_MINE)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count++;
		}
	}
}


//排查mine数组中x,y坐标周围有几个雷
int Get_Mine_Num(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 Unfold_show(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
	if (x >= 1 && x <= ROW && y >= 1 && y <= COL)
	{
		if (Get_Mine_Num(mine, x, y) != 0)
		{
			show[x][y] = Get_Mine_Num(mine, x, y) + '0';
			return;
		}
		if (show[x][y] == '#')
		{
			return;
		}
		show[x][y] = '#';
		Unfold_show(mine, show, x - 1, y);
		Unfold_show(mine, show, x - 1, y - 1);
		Unfold_show(mine, show, x, y - 1);
		Unfold_show(mine, show, x + 1, y - 1);
		Unfold_show(mine, show, x + 1, y);
		Unfold_show(mine, show, x + 1, y + 1);
		Unfold_show(mine, show, x, y + 1);
		Unfold_show(mine, show, x - 1, y + 1);
		show[x][y] = ' ';
	}
}
//排查雷
void Find_Mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int i = 0;
	int j = 0;
	int count = 0;
	int input = 0;
	while (1)
	{
		printf("1.排雷  2.锁定雷  3.取消锁定\n");
		printf("请输入你的选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("请输入要排查的坐标:");
			scanf("%d %d", &x, &y);
			if (show[x][y] == '*')
			{
				if (mine[x][y] == '1')
				{
					printf("很遗憾,你被炸死了\n");
					DisplayBoard(mine, ROW, COL);
					return;
				}
				else
				{
					if (Get_Mine_Num(mine, x, y) == 0)
					{
						Unfold_show(mine, show, x, y);
					}
					else
					{
						char num = Get_Mine_Num(mine, x, y) + '0';
						show[x][y] = num;
					}
					DisplayBoard(show, ROW, COL);
				}
			}
			else
			{
				printf("该坐标已被排查过,请重新输入坐标\n");
			}
			break;
		case 2:
			printf("请输入要锁定的坐标:");
			scanf("%d %d", &x, &y);
			show[x][y] = '?';
			DisplayBoard(show, ROW, COL);
			break;
		case 3:
			printf("请输入要取消锁定的坐标:");
			scanf("%d %d", &x, &y);
			show[x][y] = '*';
			DisplayBoard(show, ROW, COL);
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
		//是否找出所有雷
		for (i = 1; i <= row; i++)
		{
			for (j = 1; j <= col; j++)
			{
				if ( show[i][j] == '?' && mine[i][j] == '1')
					count++;
			}
		}
		if (count == EASY_MINE)
		{
			printf("恭喜你,扫雷成功\n");
			return;
		}
		count = 0;
	}
}
五、游戏代码难点部分 1.Find_Mine(排查雷) 并且Unfold_show(展开一片区域)
//排查雷
void Find_Mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int i = 0;
	int j = 0;
	int count = 0;
	int input = 0;
	while (1)
	{
		printf("1.排雷  2.锁定雷  3.取消锁定\n");
		printf("请输入你的选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("请输入要排查的坐标:");
			scanf("%d %d", &x, &y);
			//判断该坐标是否被排查过
			if (show[x][y] == '*')
			{
				//判断该坐标是否为雷
				if (mine[x][y] == '1')
				{
					printf("很遗憾,你被炸死了\n");
					DisplayBoard(mine, ROW, COL);
					return;
				}
				else
				{
					//如果该坐标周围没有雷,递归展开该坐标周围的区域
					if (Get_Mine_Num(mine, x, y) == 0)
					{
						Unfold_show(mine, show, x, y);
					}
					//如果该坐标周围有雷,标记出雷数
					else
					{
						char num = Get_Mine_Num(mine, x, y) + '0';
						show[x][y] = num;
					}
					DisplayBoard(show, ROW, COL);
				}
			}
			else
			{
				printf("该坐标已被排查过,请重新输入坐标\n");
			}
			break;
		case 2:
			printf("请输入要锁定的坐标:");
			scanf("%d %d", &x, &y);
			show[x][y] = '?';
			DisplayBoard(show, ROW, COL);
			break;
		case 3:
			printf("请输入要取消锁定的坐标:");
			scanf("%d %d", &x, &y);
			show[x][y] = '*';
			DisplayBoard(show, ROW, COL);
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
		//是否找出所有雷
		for (i = 1; i <= row; i++)
		{
			for (j = 1; j <= col; j++)
			{
				if ( show[i][j] == '?' && mine[i][j] == '1')
					count++;
			}
		}
		if (count == EASY_MINE)
		{
			printf("恭喜你,扫雷成功\n");
			return;
		}
		count = 0;
	}
}

展开部分的关键在于,展开的某一个坐标的周围有没有雷,如果有雷,标记出雷数,并且停止该坐标的展开

//展开棋盘
void Unfold_show(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
	//首先判断坐标是否在棋盘内
	if (x >= 1 && x <= ROW && y >= 1 && y <= COL)
	{
		//判断该坐标周围有没有雷
		if (Get_Mine_Num(mine, x, y) != 0)
		{
			show[x][y] = Get_Mine_Num(mine, x, y) + '0';
			return;
		}
		//判断该坐标是否被展开过,防止死递归
		if (show[x][y] == '#')
		{
			return;
		}
		show[x][y] = '#';
		//递归展开
		Unfold_show(mine, show, x - 1, y);
		Unfold_show(mine, show, x - 1, y - 1);
		Unfold_show(mine, show, x, y - 1);
		Unfold_show(mine, show, x + 1, y - 1);
		Unfold_show(mine, show, x + 1, y);
		Unfold_show(mine, show, x + 1, y + 1);
		Unfold_show(mine, show, x, y + 1);
		Unfold_show(mine, show, x - 1, y + 1);
		show[x][y] = ' ';
	}
}

统计坐标周围雷数

//排查mine数组中x,y坐标周围有几个雷
int Get_Mine_Num(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');
}
2.判断胜利

只有找到所有雷并且标记出来,才算获胜,至于其他判断胜利的方法,我没有想出来,欢迎大家给出建议。


总结

以上就是用C语言实现的扫雷小游戏,大家下来可以自行测试代码,如果找出BUG,欢迎评论告诉我。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/875783.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-13
下一篇 2022-05-13

发表评论

登录后才能评论

评论列表(0条)

保存