IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> [C语言]扫雷游戏(史诗级喂饭教学,可随时提问) -> 正文阅读

[C++知识库][C语言]扫雷游戏(史诗级喂饭教学,可随时提问)

1、打开Visual Studio,在新建项目中分别创建saolei.h文件 、saolei.c文件、test.c文件。

saolei.h :用于声明函数、包含C语言库函数、define定义标识符常量

saolei.c :具体实现每一个函数

test.c? ? ?:(调用/测试)每一个函数,游戏项目的大体框架

文章最后会附上这三个文件的整体内容,可直接复制粘贴到编译器查看。

2、 主函数

1.menu()函数,将菜单内容展现在用户面前。

void menu()//写在test.c文件中main函数上面即可
{
	printf("#####################\n");
	printf("####  1.开始游戏  ###\n");
	printf("####  0.退出游戏  ###\n");
	printf("#####################\n");
}

2.main()函数,定义一个变量input,用户输入数字赋值给input,数字与菜单序号内容对应。

1)input==1则进入游戏,即调用game()函数,game()函数文章后面会补充。

2)input==0则执行空语句,紧接着退出do while循环。

3)input为其他任何字符都为真(非0),则提示重新输入。

int main()//写在test.c文件中
{
	int input = 0;
	do
	{
		menu();
		printf("请输入你的选择>:");
		scanf("%d", &input);
		if (input == 1)
        {
			game();
	    }
	    else if (input==0)
		{
	        ;
        }
		else
		{
			printf("请输入正确选项!\n");
		}
	} while (input);
	return 0;
}

3.test.c文件中包含"saolei.h"头文件,我们将会把需要的所有C语言库函数都写进saolei.h

//以下代码是写在test.c文件中的,建议写在最上面。
#define"saolei.h"

4.因为主函数有输入输出的库函数,所以在saolei.h头文件中写入C语言库函数stdio.h

//以下代码是写在saolei.h文件中的
#include<stdio.h>

3、game()函数

1.定义二维数组mine[ROWS][COLS]和show[ROWS][COLS]

????????1)ROWS和COLS是define定义的标识符常量

//以下代码是写在saolei.h文件中的
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2

????????2)棋盘设计思路

????????????????<1>平时我们游戏时,是在一个9*9的棋盘进行的,每次选择一个坐标进行扫雷时,如果不是雷,那么坐标上就会显示周围有多少个雷,要想知道周围有多少雷,我们需要对这个坐标周围的8个位置进行排查,也就是对这8个二维数组元素进行访问并判断是否是雷。假如我要扫最角落的一个坐标,那么就要访问到9*9棋盘之外的范围,所以为了不出现数组越界访问的情况,我们可以把棋盘设置成11*11的大小。游戏设计时,在9*9大小的棋盘之外不放置雷即可。

????????????????<2>因为定义了标识符常量ROW和COL,所以我们可以直接通过更改其大小从而更改棋盘大小。

????????????????<3>这里的ROWS和COLS等于11,mine数组是存放雷的棋盘,show数组是存放显示在用户面前的棋盘。

//以下代码是写在test.c文件中game()函数内的
char mine[ROWS][COLS] = { 0 };
char show[ROWS][COLS] = { 0 };

2.初始化数组函数

????????1)代码实现

//以下代码是写在saolei.c文件中的
void init_board(char board[COLS][ROWS], int row, int col,char set)//初始化棋盘函数实现
{
	for (int i=1;i<=row;i++)
	{
		for (int j=1;j<=col;j++)
		{
			board[i][j] = set;
		}
	}
}
//以下代码是写在saolei.h文件中的
void init_board(char board[COLS][ROWS], int row, int col, char set);//初始化棋盘函数声明
//以下函数是写在test.c文件game()函数中的
init_board(mine, ROW, COL, ' ');//初始化棋盘函数调用
init_board(show, ROW, COL, '*');

? ? ? ? 经过初始化函数的调用,mine和show棋盘中间9*9的范围内分别是字符' '和'*',9*9外的范围都是字符'\0'。

3.打印棋盘函数

? ? ? ? 1)代码实现

//以下代码写在saolei.c文件中
void display_board(char board[ROWS][COLS],int row ,int col )//打印棋盘函数实现
{
	printf("   ");
	for (int i=1;i<=col;i++)
	{
		printf("%d ", i);
	}
	printf("\n\n");
	for (int i = 1; i <= row; i++)
	{
		printf("%d  ", i);
		for (int j = 1; j <= col; j++)
		{
			printf("%c ",board[i][j]);
		}
		printf("\n");
	}
}

打印棋盘的实现可以根据自己的需求布置工整,以上是我的布置方式。

//以下代码写在saolei.h文件中
void display_board(char board[ROWS][COLS], int row, int col);//打印棋盘函数的声明

当我们需要打印棋盘在用户面前时,就需要调用该函数。

4.布置雷函数

//以下代码是写在saolei.h文件中的
#define easy_difficulty 10 //简单模式只布置10个雷
//以下代码写在saolei.c文件中
void place_mine(char mine[ROWS][COLS],int row, int col)//布置雷函数具体实现
{
	int count = easy_difficulty;//count表示需要布置的雷数
	while (count)
	{
		int x = rand() % row + 1;//利用rand()函数生成1~9的随机数,其中还涉及到srand()函数后面会提及。
		int y = rand() % col + 1;
		if (mine[x][y] == ' ')
		{
			mine[x][y] = 'X';//用'X'表示雷
			count--;
		}
	}
}
//以下代码写在saolei.h文件中
void place_mine(char board[ROWS][COLS], int row, int col);//布置雷函数声明
//以下代码写在test.c文件的game()函数中	
place_mine(mine, ROW, COL);//布置雷函数调用

5.计算周围雷数量函数

//以下代码写在saolei.c文件中
static int surrounding_mine_count(char mine[ROWS][COLS],int x,int y)//计算周围雷数函数的具体实现
{
	int count = 0;
	for (int i=0;i<3;i++)
	{
		for (int j=0;j<3;j++)
		{
			if (mine[x - 1 + i][y - 1 + j] == 'X')
				count++;
		}
	}
	return count;
}

//以下代码写在saolei.c文件中
void sweep_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)//扫雷函数的实现
{
	int x = 0;
	int y = 0;
	while (1)
	{
		printf("请选择坐标:>");
		scanf("%d%d", &x, &y);
		if ((x<1 || x>row) || (y<1 || y>col))//输入的坐标不在9*9范围内
		{
			system("cls");
			printf("请输入正确坐标!\n");
			Sleep(1500);
			display_board(show, row, col);
		}
		else if (show[x][y] != '*')//show棋盘内如果是'*'表示没有被排查过
		{
			system("cls");
			printf("该位置已被排查过,请重新输入!\n");
			Sleep(1500);
			display_board(show, row, col);
		}
		else if (mine[x][y] == 'X')
		{
			for (int i=1;i<=row;i++)//将有雷的格子赋值给对应的show棋盘,炸死后显示给你哪些位置有雷。
			{
				for (int j=1;j<=col;j++)
				{
					if (mine[i][j] == 'X')
					{
						show[i][j] = mine[i][j];
					}
				}
			}
			display_board(show, row, col);
			printf("你被炸死!\n");
			break;
		}
		else//统计周围雷数,并存储到show棋盘
		{
			extent_show(mine,show,x,y,row,col);
			system("cls");
			display_board(show, row, col);
		}
		int flag = 0;
		for (int i = 1; i <= row; i++)
		{
			for (int j = 1; j <= col; j++)
			{
				if (show[i][j] == '*')
					flag++;
			}
		}
		if (flag == easy_difficulty)
		{
			printf("恭喜你扫雷成功!\n");
			return 0;
		}
	}
}
//以下代码是写在saolei.h文件中的
void sweep_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);//扫雷函数的声明

6.展开函数

(写了半天累了,有人看的话,我继续把详细内容写下去,没人急着了解的话,我有空再写吧,其实好像还有可以优化的地方,详细内容也不够满意.....,三个文件都在下面需要的直接复制拿去)

1

1

1

1


saolei.h文件整体内容

#pragma once//这一行是vs默认存在的,我也没去了解是什么意思,最好加上吧,懂得兄弟也可以评论里说一下
#include<windows.h>
#include<stdlib.h>
#include<stdio.h>
#include<time.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define easy_difficulty 10

void init_board(char board[COLS][ROWS], int row, int col, char set);//初始化棋盘函数声明

void display_board(char board[ROWS][COLS], int row, int col);//打印棋盘函数声明

void place_mine(char board[ROWS][COLS], int row, int col);//布置雷棋盘函数声明

void sweep_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);//扫雷函数声明

saolei.c文件整体内容

#include"saolei.h"

//棋盘初始化
void init_board(char board[COLS][ROWS], int row, int col,char set)
{
	for (int i=1;i<=row;i++)
	{
		for (int j=1;j<=col;j++)
		{
			board[i][j] = set;
		}
	}
}

//打印棋盘
void display_board(char board[ROWS][COLS],int row ,int col )
{
	system("cls");
	printf("   ");
	for (int i=1;i<=col;i++)
	{
		printf("%d ", i);
	}
	printf("\n\n");
	for (int i = 1; i <= row; i++)
	{
		printf("%d  ", i);
		for (int j = 1; j <= col; j++)
		{
			printf("%c ",board[i][j]);
		}
		printf("\n");
	}
}

//布置雷
void place_mine(char mine[ROWS][COLS],int row, int col)
{
	int count = easy_difficulty;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (mine[x][y] == ' ')
		{
			mine[x][y] = 'X';//雷用'X'表示
			count--;
		}
	}
}

//计算附近地雷数量
static int surrounding_mine_count(char mine[ROWS][COLS],int x,int y)
{
	int count = 0;
	for (int i=0;i<3;i++)
	{
		for (int j=0;j<3;j++)
		{
			if (mine[x - 1 + i][y - 1 + j] == 'X')
				count++;
		}
	}
	return count;
}

//递归展开非雷区
static void extent_show(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y,int row,int col)
{
	if (show[x][y] != ' ')
	{
		show[x][y] = surrounding_mine_count(mine, x, y) + '0';
	}
	if (show[x][y] == '0')
	{
		show[x][y] = ' ';
		for (int i=0;i<3;i++)
		{
			for (int j=0;j<3;j++)
			{
				if ((x-1+i >= 1 && x-1+i <= row) && (y-1+j >= 1 && y-1+j <= col))
				{
					extent_show(mine, show, x - 1 + i, y - 1 + j, row, col);
				}
			}
		}
	}
}

//扫雷
void sweep_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	while (1)
	{
		printf("请选择坐标:>");
		scanf("%d%d", &x, &y);
		if ((x<1 || x>row) || (y<1 || y>col))
		{
			system("cls");
			printf("请输入正确坐标!\n");
			Sleep(1500);
			display_board(show, row, col);
		}
		else if (show[x][y] != '*')
		{
			system("cls");
			printf("该位置已被排查过,请重新输入!\n");
			Sleep(1500);
			display_board(show, row, col);
		}
		else if (mine[x][y] == 'X')
		{
			for (int i=1;i<=row;i++)//将有雷的格子赋值给对应的show棋盘,炸死后显示给你哪些位置有雷。
			{
				for (int j=1;j<=col;j++)
				{
					if (mine[i][j] == 'X')
					{
						show[i][j] = mine[i][j];
					}
				}
			}
			display_board(show, row, col);
			printf("你被炸死!\n");
			break;
		}
		else//统计周围雷数,并存储到show棋盘
		{
			extent_show(mine,show,x,y,row,col);
			system("cls");
			display_board(show, row, col);
		}
		int flag = 0;
		for (int i = 1; i <= row; i++)
		{
			for (int j = 1; j <= col; j++)
			{
				if (show[i][j] == '*')
					flag++;
			}
		}
		if (flag == easy_difficulty)
		{
			printf("恭喜你扫雷成功!\n");
			return 0;
		}
	}
}

test.c文件整体内容

#include"saolei.h"
void menu()
{
	printf("#####################\n");
	printf("####  1.开始游戏  ###\n");
	printf("####  0.退出游戏  ###\n");
	printf("#####################\n");
}
void game()
{
	//数组的创建
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };
	//这里给二维数组初始化,因为大括号里面的0没有加单引号,所以初始化的内容是ascii码值为0的字符'\0'。

	//初始化mine棋盘和show棋盘
	init_board(mine, ROW, COL, ' ');
	init_board(show, ROW, COL, '*');

	//打印棋盘
	display_board(show, ROW, COL);
	
	//布置雷
	place_mine(mine, ROW, COL);
	
	
	//扫雷
	sweep_mine(mine, show,ROW, COL);

	//按任意键退出
	system("pause");
	system("cls");
}
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请输入你的选择>:");
		scanf("%d", &input);
		if (input == 1)
			game();
		else if (input==0)
			;
		else
		{
			system("cls");
			printf("请输入正确选项!\n");
			Sleep(1500);
			system("cls");
		}
	} while (input);
	return 0;
}

easy_difficulty

随机数的创建srand

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-06 15:59:31  更:2022-04-06 16:01:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:26:24-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码