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

设计总体思路

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

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

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

分别为:

  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. 该坐标没有被排查过

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

希望会对你有所帮助

相关推荐
测试界的酸菜鱼1 分钟前
Python 大数据展示屏实例
大数据·开发语言·python
我是谁??1 分钟前
C/C++使用AddressSanitizer检测内存错误
c语言·c++
小码农<^_^>3 分钟前
优选算法精品课--滑动窗口算法(一)
算法
Mephisto.java5 分钟前
【大数据学习 | kafka高级部分】kafka中的选举机制
大数据·学习·kafka
羊小猪~~5 分钟前
神经网络基础--什么是正向传播??什么是方向传播??
人工智能·pytorch·python·深度学习·神经网络·算法·机器学习
晨曦_子画11 分钟前
编程语言之战:AI 之后的 Kotlin 与 Java
android·java·开发语言·人工智能·kotlin
Black_Friend19 分钟前
关于在VS中使用Qt不同版本报错的问题
开发语言·qt
假装我不帅31 分钟前
asp.net framework从webform开始创建mvc项目
后端·asp.net·mvc
软工菜鸡31 分钟前
预训练语言模型BERT——PaddleNLP中的预训练模型
大数据·人工智能·深度学习·算法·语言模型·自然语言处理·bert
南宫生34 分钟前
贪心算法习题其三【力扣】【算法学习day.20】
java·数据结构·学习·算法·leetcode·贪心算法