猜数字与扫雷小游戏讲解

目录

猜数字教程如下:

1. 关键点 :

2. 具体代码:

3. 具体实现步骤  明确思路 

 第一步  首先是输出菜单

第二步 从键盘录入input的值 进行判断是否进入游戏

第三步 使用switch语句来实现3种选择

第四步 构造game函数

扫雷小游戏教程:

1.text.c

2.game.c

3.game.h


猜数字教程如下:

引言: 游戏开始运行时,玩家可选择开始游戏或退出游戏,选择开始游戏后系统将随机生成一个1~100的数字,玩家则是进行一个猜数字的操作,若猜的数字比答案大或小都分别会有相关提示,猜出正确答案后,玩家可选择再来一局或退出游戏,若再来一局系统将生成一个新的随机数作为答案,玩家则只需重复上述操作,若玩家选择退出则程序结束运行。

1. 关键点 :

不难看出 题目有三个关键点

1. 程序生成1~100直接的随机数

2. 猜数字的过程

   2.1  猜小了 会打印你猜小了  请重新输入

   2.2  猜大了 会打印你猜大了  请重新输入

   2.3  猜对了 会打印你恭喜你 恭喜你猜对啦

3.  游戏可以反复玩 表明需要用到循环语句

2. 具体代码:

#define _CRT_SECURE_NO_WARNINGS 
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
 
void menu()
{
	printf("*****************\n");
	printf("***  1->play  ***\n");
	printf("***  0->exit  ***\n");
	printf("*****************\n");
}
 
//rand函数在使用前 要先使用srand函数来设置随机数的生成器
//否则每次运行会生成相同的序列。
 
void game(void)
{
	int num = rand() % 100 + 1;
	//rand生成的是伪随机数: 就是每一次重新运行是随机数的顺序是确定的  
	//比如第一次是生成的前三个是42 99 5 那重新启动时 前三个随机数依然时42 99 5达不到目的
	do
	{
		int input1;
		scanf("%d", &input1);
		if (input1 > num)
		{
			printf("猜大了 请重新输入->\n");
		}
		else if (input1 < num)
		{
			printf("猜小了 请重新输入->\n");
		}
		else
		{
			printf("恭喜你 猜对了正确答案是:%d\n\n\n", num);
			break;
		}
	} while (1);
 
}
int main()
{
	int input;
	srand((unsigned int)time(NULL));
	//在C语言中,srand() 函数用于初始化随机数生成器的种子
		//只调用一次就够了 不然不够随机 连续快速输入两次可能会相同
	do
	{
		menu();
		printf("请选择;\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
		{
			printf("游戏开始\n");
			game();
			break;
		}
		case 0:
		{
			printf("退出游戏\n");
			break;
		}
		default:
		{
			printf("输入错误 请重新选择\n");
		}
		}
	} while (input);
	return 0;
}

3. 具体实现步骤  明确思路 

 第一步  首先是输出菜单

我们会自定义menu函数  目的是为了输出菜单选项

因为不需要返回值 所以用void 也不需要传入参数

void menu()
{
	printf("*****************\n");
	printf("***  1->play  ***\n");
	printf("***  0->exit  ***\n");
	printf("*****************\n");
}

第二步 从键盘录入input的值 进行判断是否进入游戏

printf("请选择;\n");
scanf("%d", &input);

第三步 使用switch语句来实现3种选择

输入1  则进入游戏    输入0 则使用break跳出    输入其他则 提示"输入错误 请重新输入"

关键点:由于游戏可以重复进行 因此我们需要将switch语句放置于while循环内 

	do
	{
		menu();
		printf("请选择;\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
		{
			printf("游戏开始\n");
			game();
			break;
		}
		case 0:
		{
			printf("退出游戏\n");
			break;
		}
		default:
		{
			printf("输入错误 请重新选择\n");
		}
		}
	} while (input);

而while循环条件是input   当input不为0时  则进入循环  若为0则braek跳出循环 

第四步 构造game函数

void game(void)
{
	int num = rand() % 100 + 1;
	//rand生成的是伪随机数: 就是每一次重新运行是随机数的顺序是确定的  
	//比如第一次是生成的是42 99 5...那重新启动时 随机数依然时42 99 5...达不到目的
	do
	{
		int input1;
		scanf("%d", &input1);
		if (input1 > num)
		{
			printf("猜大了 请重新输入->\n");
		}
		else if (input1 < num)
		{
			printf("猜小了 请重新输入->\n");
		}
		else
		{
			printf("恭喜你 猜对了正确答案是:%d\n\n\n", num);
			break;
		}
	} while (1);
 
}

1   game 不需要传参和输入   因此使用void来进行定义和传参

2  使用rand函数来生成随机数  并且对100取余 这样就可以随机生成0~99之间的随机数

 然后在num+1   从而 num就可以处在1~100之间

由于rand函数生成的时伪随机数 既每次运行会生成相同的序列

因此我们需要使用srand() 函数来初始化随机数生成器的种子

	srand((unsigned int)time(NULL));

  其中用到了time函数

关于time函数 有如下总结

4   进入game函数  定义 input1 并且进行键盘录入 

5    进入if 语句进行判断 将input1与正确答案num进行比较

若大于随机数num 则提示 猜大了  请重新输入

若小于随机数num 则提示 猜小了  请重新输入

若等于随机数num 则输出恭喜你   猜对了 

if (input1 > num)
{
	printf("猜大了 请重新输入->\n");
}
else if (input1 < num)
{
	printf("猜小了 请重新输入->\n");
}
else
{
	printf("恭喜你 猜对了正确答案是:%d\n\n\n", num);
	break;
}

6 头文件不能忘

#define _CRT_SECURE_NO_WARNINGS 
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

4. 运行结果 : 

扫雷小游戏教程:

引言:
扫雷游戏相比大家都清楚  现在我将帮助大家从0开始 用简单的c语言知识建立起一个扫雷小游戏

而具体的代码解释我都将放在注释中 方便大家理解

游戏弊端:

1. 只能通过键盘录入进行判断

2. 一次只能对一个位置进行判断

3. 无法进行插旗行为(既标记雷)

思路:
一共建立三个文件用来实现扫雷游戏

text.c文件     : 用于存放主函数以及简单的函数(例如菜单函数)

game.c文件  : 用于具体实现game函数

game.h文件  : 用于对game.c文件内函数的声明

具体代码:

1.text.c

#define _CRT_SECURE_NO_WARNINGS 
//防止scanf报错
#include"game.h"
//包含game.h头文件 里面是对game.c中函数的声明和行列的宏定义
// 这样就可以直接使用game.c的函数和字符
 
void menu()//实现打印菜单的函数
{
	printf("***********************\n");
	printf("***** 1. play *****\n");
	printf("***** 0. exit *****\n");
	printf("***********************\n");
}
 
void game()
{
	//首先定义两个数组
	char mine[ROWS][COLS]
		;//用来存放雷的信息或者说雷的位置  
	char show[ROWS][COLS];
	//用来存放排查出的雷的个数信息
	//ROWS是行 COLS是列 具体数字使用宏定义来确定
	//目的:为了便于后续的修改 减轻负担
 
 
	
	
	initboard(mine, ROWS, COLS, '0');
	//mine全部初始化为字符0,此时还没布置雷; 默认字符'0'为非雷 字符'1'为雷
	initboard(show, ROWS, COLS, '*');
	//show全部初始化为*,表示还没开始排查;既游戏初始页面
 
	//打印棋盘9*9
	printboard(show, ROW, COL);
	//ROW和COL分别是玩家可见的行数和列数 既实际游戏页面的行列数 
	//而ROW和COL与ROWS与COLS的区别在于   ROWS和COLS比ROW和COL都大2 
	// 因为在计算周围雷的个数时 我们需要对周围八个数进行统计 
	// 假如是第一个数呢?  那周围难不成只有3个数 这样在进行统计时 会产生数组越界的问题 
	// 因此行列都多两行防止越界 并且全部初始化为'0'
 
	//布置雷的函数
	setmine(mine, ROW, COL);
 
	//排查雷的函数
	findmine(mine, show, ROW, COL);
 
}
 
int main() 
{
	int num = 0;//用于选择进入游戏 或者退出游戏
	srand((unsigned int)time(NULL));
	//这个就是为了实现生成随机数 不理解的可以去看猜数字游戏 里面有具体讲解
	do
	{
		menu(); //打印菜单
		printf("请选择:>"); 
		scanf("%d", &num); //键盘录入用户选择
		switch (num)
		{
		case 1:
			game();
			break;
		case 0:
			printf("你已退出游戏\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (num != 0);//选择0时 退出循环
	return 0;
}

2.game.c

#define _CRT_SECURE_NO_WARNINGS//防止scanf报错
#include"game.h"//为了使用ROWS等宏定义的字符
 
//棋盘初始化函数
void initboard(char board[ROWS][COLS], int rows, int cols, int set)
//set用于选择是初始化为'0'还是'*'
{
	int i = 0;
	for (i = 0; i < rows; i++)
	{
		int j = 0;
		for (j = 0; j < cols; j++)
		{
			board[i][j] = set;
		}
	}
}
 
 
//打印棋盘函数
void printboard(char mine[ROWS][COLS], int row, int col)
{
	int i;
	printf("-----扫雷游戏-----\n");
	for (i = 0; i <= row; i++)
	{
		printf("%d ", i);//打印行号
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		int j = 0;
		printf("%d ", i);//打印列号
		for (j = 1; j <= col; j++)
		{
			printf("%c ", mine[i][j]);
		}
		printf("\n"); //每打印一行就换行
	}
}
 
 
 
//布置雷的函数
void setmine(char mine[ROWS][COLS], int row, int col)
{
	//随机布置10个雷
	int count = EASY_COUNT;
	while (count)//只有当雷的数量count==0时 才确保雷被布置完
	{
		int x = rand() % row + 1;//用于生成随机的坐标 
		int y = rand() % col + 1;
		if (mine[x][y] == '0') //if语句是为了避免随机时 将两个雷布置在同一个坐标上
		{
			mine[x][y] = '1';//布置雷
			count--;//布置一个雷就-1
		}
	}
}
 
 
//获取周围雷的个数的函数
int getmine(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');
	//计算你选择的坐标周围的八个位置中累的个数
	// 因为存放的是字符0和1 因此需要减去字符0和1才能确保得到的是数字
}
 
 
//排查雷的函数
void findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int w = 0;
	while (w < row * col - EASY_COUNT)
		// row * col表示位置总数  EASY_COUNT表示雷的数量 
		// w用于计算排查次数 当非雷位置排查完就表示游戏成功
	{
		printf("请输入要排查的坐标:");
		scanf("%d %d", &x, &y);// 键盘例如 你要排查的位置
		if (x >= 1 && x <= row && y >= 1 && y <= col)
			//判断输入的合法性 不可输入规定坐标以外的位置
		{
			if (mine[x][y] == '1')//判断是不是雷
			{
				printf("很遗憾,你被炸死了\n");
				printboard(mine, ROW, COL);
				break;
			}
			else if (show[x][y] == '*')//不是雷的情况就是*
			{
				//统计坐标周围雷的个数
				int c = getmine(mine, x, y);//非雷时将周围的雷总数赋值给此位置 
				show[x][y] = c + '0';
				system("cls");//用于屏幕更新
				// 因为我们设置的是字符数组 只能存放字符 因此数字+‘0’变为数字对应的字符 才可以打印
				printboard(show, ROW, COL);//调用打印函数
				w++;//排查次数的累加
			}
			else
			{
				printf("该坐标已被查找,请重新输入\n");//防止重复输入同一个坐标 导致w的额外增加
			}
		}
		else
		{
			printf("非法输入,请重新输入\n");
		}
		if (w == row * col - EASY_COUNT)//判断排雷成功的条件
		{
			printf("恭喜你,排雷成功\n");
			printboard(mine, ROW, COL);//打印雷的位置 方便玩家观看
		}
 
	}
 
}

3.game.h

#include<stdio.h>  
#include<stdlib.h>
#include<time.h> //使用time函数必须包含的头文件
 
//宏定义   用于定义行和列的信息
#define ROW 9
#define COL 9
 
#define ROWS ROW+2
#define COLS COL+2
 //定义雷的数量
#define EASY_COUNT 10 
 
//下面是对game.c中函数的声明
 
//棋盘初始化
void initboard(char board[ROWS][COLS], int rows, int cols, int set);
 
//打印棋盘
void printboard(char mine[ROWS][COLS], int row, int col);
 
//布置雷
void setmine(char mine[ROWS][COLS], int row, int col);
 
//获取周围雷的个数
int getmine(char mine[ROWS][COLS], int x, int y);
 
//排查雷
void findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

运行结果估如下:

以上就是全部的代码以及注释 希望能帮到大家

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿方猛敲c嘎嘎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值