扫雷小游戏(简单详细)(内附完整代码)

设计总体思路

实现游戏可以一直玩,先打印棋盘,玩家和电脑下棋,最后分出胜负。

如果编写较大的程序,我们可以分不同模块

例如这个扫雷,我们可以创建三个文件

分别为:

  1. game.h 函数的声明
  2. game.c 函数的实现
  3. test.c 测试游戏逻辑

一、打印游戏菜单界面

首先要有开始界面并且有选项选择,开始你的游戏,代码以及效果图如下:

cpp 复制代码
void menu()
{
	printf("*********************************************\n");
	printf("*************       1. play         *********\n");
	printf("*************       0. exit         *********\n");
	printf("*********************************************\n");
}

int main()
{
	srand((unsigned int)time(NULL));   //随机数  无符号整型  时间戳   
                                       //头文件:stdlib.h  time.h
	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;
}

二、初始化棋盘

test.c

cpp 复制代码
void game()
{
	//mine数组是专门存放布置好的雷的信息
	char mine[ROWS][COLS] = {0};
	//show数组是专门存放排查出的雷的信息
	char show[ROWS][COLS] = {0};
	//初始化棋盘
	InitBoard(mine, ROWS, COLS, '0');//'0'
	InitBoard(show, ROWS, COLS, '*');//'*'
}

game.c

cpp 复制代码
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;       #因为两次调用,数组填充不同,set("0","*")
		}
	}
}

三、打印棋盘

test.c

cpp 复制代码
//打印棋盘
DisplayBoard(show, ROW, COL);   //打印show数组

game.c

cpp 复制代码
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");
	}
}

四、布置雷

test.c

cpp 复制代码
//布置雷
SetMine(mine,ROW,COL);

game.c

cpp 复制代码
void SetMine(char mine[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;
	while (count)
	{
		//rand()随机生成范围0-32767
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}
}

五、排查雷

test.c

cpp 复制代码
//排查雷
FindMine(mine,show,ROW,COL);

game.c

cpp 复制代码
int GetMineCount(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');
}


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 (show[x][y] == '*')
			{
				if (mine[x][y] == '1')
				{
					printf("很遗憾,你被炸死了\n");
					DisplayBoard(mine, ROW, COL);
					break;
				}
				else
				{
					//如果该坐标不是雷,就要统计这个坐标周围有几个雷
					int count = GetMineCount(mine, x, y);
					show[x][y] = count + '0';
					DisplayBoard(show, ROW, COL);
					win++;
				}
			}
			else
			{
				printf("该位置已经被排查\n");
			}
		}
		else
		{
			printf("排查的坐标非法,请重新输入\n");
		}
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你,排雷成功\n");
		DisplayBoard(mine, ROW, COL);
	}
}

六、最后整理代码(完整代码)

game.h

cpp 复制代码
#include<stdio.h>
#include<stdlib.h>
#include<time.h>


//初始化棋盘
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);

game.c

cpp 复制代码
#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;
	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");
	}
}

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

int GetMineCount(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');
}


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 (show[x][y] == '*')
			{
				if (mine[x][y] == '1')
				{
					printf("很遗憾,你被炸死了\n");
					DisplayBoard(mine, ROW, COL);
					break;
				}
				else
				{
					//如果该坐标不是雷,就要统计这个坐标周围有几个雷
					int count = GetMineCount(mine, x, y);
					show[x][y] = count + '0';
					DisplayBoard(show, ROW, COL);
					win++;
				}
			}
			else
			{
				printf("该位置已经被排查\n");
			}
		}
		else
		{
			printf("排查的坐标非法,请重新输入\n");
		}
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你,排雷成功\n");
		DisplayBoard(mine, ROW, COL);
	}
}

test.c

cpp 复制代码
#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()
{
	//mine数组是专门存放布置好的雷的信息
	char mine[ROWS][COLS] = {0};
	//show数组是专门存放排查出的雷的信息
	char show[ROWS][COLS] = {0};
	//初始化棋盘
	InitBoard(mine, ROWS, COLS, '0');//'0'
	InitBoard(show, ROWS, COLS, '*');//'*'
	//打印棋盘
	DisplayBoard(show, ROW, COL);
	//布置雷
	SetMine(mine,ROW,COL);
	//DisplayBoard(mine, ROW, COL);
	//排查雷
	FindMine(mine,show,ROW,COL);



}

int main()
{
	srand((unsigned int)time(NULL));   //随机数  无符号整型  时间戳   
									   //头文件:stdlib.h  time.h
	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;
}

七、游戏展示

个人建议第一个坐标填1 1(这样比较好排)

扩展:

  1. 展开一片

  2. 标记是否是雷

  3. 计时器

  4. 记录剩余雷数量

展开一片满足下列条件:

  1. 该坐标不是雷
  2. 该坐标周围没有雷
  3. 该坐标没有被排查过

满足就再遍历该坐标周围的八个坐标
本文是简单版的扫雷,之后我会出一个进阶版的扫雷

希望会对你有所帮助

相关推荐
2202_754421543 分钟前
生成MPSOC以及ZYNQ的启动文件BOOT.BIN的小软件
java·linux·开发语言
盼海4 分钟前
排序算法(四)--快速排序
数据结构·算法·排序算法
我只会发热10 分钟前
Java SE 与 Java EE:基础与进阶的探索之旅
java·开发语言·java-ee
red_redemption18 分钟前
自由学习记录(23)
学习·unity·lua·ab包
一直学习永不止步19 分钟前
LeetCode题练习与总结:最长回文串--409
java·数据结构·算法·leetcode·字符串·贪心·哈希表
懷淰メ19 分钟前
PyQt飞机大战游戏(附下载地址)
开发语言·python·qt·游戏·pyqt·游戏开发·pyqt5
hummhumm33 分钟前
第 22 章 - Go语言 测试与基准测试
java·大数据·开发语言·前端·python·golang·log4j
宁静@星空39 分钟前
006-自定义枚举注解
java·开发语言
幽兰的天空1 小时前
默语博主的推荐:探索技术世界的旅程
学习·程序人生·生活·美食·交友·美女·帅哥
hummhumm1 小时前
第 28 章 - Go语言 Web 开发入门
java·开发语言·前端·python·sql·golang·前端框架