用C语言写猜数字小游戏(附部分解析及全部代码)

目录

前言

一、思路分析

二、流程分析及实践

1. 创建文件

2. 菜单与窗口

3. 生成随机数

4. 主函数内部搭建

5. 游戏内部搭建

三、效果展示及改良

1. 一阶段效果展示

2. 二阶段程序

3. 二阶段效果展示

4. 增加新的难度

5. 新增难度效果展示

四、代码

1. main.c

2. game.c

3.game.h

4.menu.c

5.menu.h

结语:


 

前言

在之前的文章中,我们介绍了分支语句、循环语句与转向语句的使用方法:

(上) C语言中的语句分类及分支语句:if语句、switch语句介绍-CSDN博客

(下) C语言中的循环与转向语句:do while语句、while语句、for语句、break语句、goto语句、continue语句介绍-CSDN博客

今天让我们来使用它们来制作一个小游戏吧。 

 

一、思路分析

1. 我们随便猜1到100的一个数字,如果我们猜小了或猜大了,就告诉我们猜小了或猜大了,并告诉我们新的区间以及还有几次猜的机会。

2. 如果我们的机会都用完了,那么就告诉我们猜字失败,并告诉我们正确的数字。

3. 如果我们猜对了,就告诉我们猜对了,并询问是否再来一局。

 

二、流程分析及实践

1. 创建文件

首先我们需要创建我们所需的文件,三个.c文件,一个.h文件。

(1) main.c

62113b361cbf4e4386f599e596c8e265.png

(2) menu.c

d1366d1d80df48bcb5656aabdd539fcb.png

(3) menu.h

b3ee40c2b5d34641a182267a933484aa.png

(3) game.c

244d50197a3d4942a96e8a789f0422f7.png

(4) game.h

033a0468d45b4787a9e6ac593e64054c.png

自创的.h文件可以用于声明和定义函数、变量和数据结构,以供其他源文件引用和使用。

一般自创的.h文件包含时使用双引号"",用来区分库文件与自创文件。

图中的#pragma once的作用是防止被重复编译,或者说被多次编译。

图中的#ifndef和define以及#endif是条件编译的一般格式,它的作用是防止头文件的重复包含和编译,以及便于程序的调试和移植。

 

2. 菜单与窗口

既然是做一个游戏,那么肯定要有一个菜单,如果我们需要选择难度,那么就需要一个菜单和一个选择难度的窗口。 ​​​​​c6854203c5f245f0a6bb89ac6773b3dc.png

这里在menu.c里定义了两个函数,菜单以及窗口,void类型说明函数没有返回值,menu和window是函数名,()里面没有参数,说明这是一个没有返回值,没有参数的函数,它们的功能就是打印菜单及窗口。

86d102de67b84bfabaf1caa1c3692730.png

将两个函数的定义放到menu.h文件里,注意结尾需要加引号。

 

3. 生成随机数

我们猜数字时,如果是自己指定数字去猜的话,数字就很容易重复。所以下面我们来生成一个根据时间变化而变化的随机数。

(1) time.h

在C语言的time.h头文件中,时间戳是指从1970年1月1日00:00:00(也称为UNIX纪元)到特定时间点所经过的秒数。可以使用time()函数来获取当前时间的时间戳。

01d0daf672d240e08f9a65c8d58951c3.png

time(NULL) 是一个 C 语言函数,它用于获取当前系统时间的秒数。而(unsigned)在这里是将返回的时间值强制转换为无符号整数。所以(unsigned)time(NULL)的意思是可以用来获取一个无符号整数表示的当前系统时间。

(2) stdlib.h

在stdlib.h文件中,我们需要使用srand函数来设置随机数种子,然后使用rand函数来生成随机数。

01d0daf672d240e08f9a65c8d58951c3.png

671cb10f632a4d5797ab3d0dbdea086f.png

由于我们需要猜的范围是1到100,所以我们先让rand函数对100取余得到0到99的随机数,然后加上1,得到1到100的随机数。

这里放到game函数而不放在main函数里的原因,是因为放到game函数里,每一场猜数字游戏的开始,都会生成一个新的随机数。

 

4. 主函数内部搭建

(1) do while与switch使用

d884c03a7e8d4fe19d6e15aa5a92791f.png

首先,利用了do while必定先执行一次循环体的特性,先打印一次菜单后判断开始或退出。

将n同时作为第一层switch分支与do while循环的条件,当输入n为0时,既退出了switch分支又退出了do while循环,也就达到了退出游戏的效果。当输入n为1时,开始游戏。当输入的n为switch上没有写的数字时,执行default语句,提示请重新输入,并返回菜单。

system函数包含在stdlib.h文件里,这里的system("cls")是一个清屏的效果。

 

5. 游戏内部搭建

(1) while与if else使用

63b0b3cdb7dc4618a76cfef9a0f59c83.png

我们用变量,也就是机会的次数来限制while循环。然后判断输入的数字是否在1-100里面,如果猜的数字大于随机的数字,那么就告诉我们猜大了,反之,告诉我们猜小了,并减少一次机会。当猜的数字与随机数相等时,告诉我们猜对了。如果次数用完了还是没有猜对,就告诉我们正确的数字并宣告失败。

 

三、效果展示及改良

1. 一阶段效果展示

8de71c4f26c24f9c9c76546642348f11.png

ed6bb72d14ab497aa53a7238f9fa923d.png

bf4c57f760254a4d9d466a193562cb80.png

add491aeeb4a4b10960ecda953ae4efa.png

 

2. 二阶段程序

(1) windows.h

在windows.h文件中,使用Sleep函数可以暂停程序的执行一段时间。

18457d23adfa46c59adf2971442b3118.png

这里是延迟一秒后清屏的意思。

(2) 改良后的程序

945778f310fe44f09b0897b5d29a8b30.png

a05754924c4a4e198cf3246df2cf7d41.png

增加了两个变量,用来控制已知区间的变化,增加了一秒延时清屏,增加了game结束后,是否再来一局的判断。

 

3. 二阶段效果展示

e98080a7867f4adb9117eedb20e8fae1.png

a9f022cec9424b94a52b3f59d0a0de64.png

a288f26926db4fa2ae1b20707715a0d3.png

33a32000b7ed4eecbd08dbec202b5869.png

 

4. 增加新的难度

05262c3357e9457785af81e89daa0848.png

b16515c4ed6e4a21aaf54753886501d7.png

增加了一个难度(只是一阶段加了个随机数,没有优化),添加了goto语句,当选择模式输入的数字是除了1和2以外的数字时,延迟一秒后,自动跳转到菜单位置。

 

5. 新增难度效果展示

d47eae1e7a0748bb837912043bf9062c.png

6cdf2768e28343e1b505e28397f018a9.png

8c43ac91c90546ddac1b8c54e4e7ef47.png

5b67371819a74b08aec719e09d1c29d8.png

296a3bcdd0874c72bb9156f625a5100f.png

9fe549a42c814605a15b3a5f46f69330.png

可以自己想想可以添加什么新的玩法,这里只做了一个如何添加新模式的介绍。

 

四、代码

1. main.c

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h> //调用输入输出
#include <stdlib.h> //调用伪随机数
#include <time.h> //调用时间戳
#include <windows.h> //调用延时
#include "menu.h" //调用菜单与窗口
#include "game.h" //调用游戏内部

int main()
{
	int n = 0; //输入开始或退出
	int m = 0; //选择模式
	srand((unsigned)time(NULL)); //随机数种子
	do
	{
		mu:
		menu();
		printf("请输入:");
		scanf("%d", &n);
		system("cls");
		switch (n)
		{
		  case 0:break;
		  case 1:window();
				 printf("请输入:");
				 scanf("%d", &m);
				 system("cls");
				 switch (m)
				 {
				 case 1:game1();
					    break;
				 case 2:game2();
					    break;
				 case 3:printf("目前暂无此模式,返回菜单");
						Sleep(1000);
						system("cls");
						goto mu;
				 case 4:printf("目前暂无此模式,返回菜单");
					    Sleep(1000);
					    system("cls");
					    goto mu;;
				 default:printf("输入错误,返回菜单");
					     Sleep(1000);
					     system("cls");
					     goto mu;
				 }
				 break;
		  default:printf("输入错误,请重新输入\n");
			      break;
		}
		printf("是否再来一局(0/1):");
		scanf("%d",&n);
		system("cls");
	} while (n);

	return 0;
}

2. game.c

#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h> 
#include <stdio.h>
#include <windows.h>
#include "game.h"

void game1()
{
	int i = rand() % 100 + 1; //随机数
	int j = 0; //猜的数字
	int c = 7; //可以猜的次数
	int a = 1, b = 100; //区间
	while (c)
	{
		printf("请从%d-%d中猜数字:",a,b);
		scanf("%d", &j);
		if (j >= 1 && j <= 100)
		{
			if (j > i)
			{
				if(b > j)
				   b = j;
				printf("猜大了\n");
			}
			else if (j < i)
			{
				if(a < j)
				   a = j;
				printf("猜小了\n");
			}
			else
			{
				printf("恭喜你,猜对了。\n\n");
				break;
			}
			c--;
			printf("您还剩%d次机会", c);
		}
		else
		{
			printf("输入错误,请重试\n");
		}
		Sleep(1000);
		system("cls");
	}
	if (c == 0)
	{
		printf("挑战失败,数字是%d\n\n", i);
	}
}

void game2()
{
	int i = rand() % 100 + 1; //随机数1
	int n = rand() % 100 + 1; //随机数2
	int j = 0; //猜的数字1
	int m = 0; //猜的数字2
	int c = 8; //可以猜的次数
	while (c)
	{
		printf("请输入您猜的两个数字:");
		scanf("%d %d", &j, &m);
		if (j >= 1 && j <= 100)
		{
			if (j > i)
			{
				printf("第一个数字猜大了 ");
			}
			else if (j < i)
			{
				printf("第一个数字猜小了 ");
			}
			else
			{
				printf("第一个数字猜对了 ");
			}

			if (m > n)
			{
				printf("第二个数字猜大了\n");
			}
			else if (m < n)
			{
				printf("第二个数字猜小了\n");
			}
			else
			{
				printf("第二个数字猜对了\n");
			}

			if (j == i && m == n)
			{
				printf("恭喜你,挑战成功。\n\n");
				break;
			}
			c--;
			printf("您还剩%d次机会\n", c);
		}
		else
		{
			printf("输入错误,请重试\n");
		}
	}
	if (c == 0)
	{
		printf("\n挑战失败, 第一个数字是%d,第二个数字是%d\n", i, n);
	}
}

3.game.h

#ifndef __GAME_H__
#define __GAME_H__
#pragma once

void game1();
void game2();

#endif /* __GAME_H__ */

4.menu.c

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include "menu.h"

void menu() //菜单
{
	printf("----------------------------\n");
	printf("|                          |\n");
	printf("|       猜数字小游戏       |\n");
	printf("|                          |\n");
	printf("|        1.开始游戏        |\n");
	printf("|        0.退出游戏        |\n");
	printf("|                          |\n");
	printf("----------------------------\n");
	printf("        |          |        \n");
	printf("        |          |        \n");
	printf("----------------------------\n");
}

void window() //难度选择窗口
{
	printf("----------------------------\n");
	printf("|                          |\n");
	printf("|       1.简单难度         |\n");
	printf("|       2.中等难度         |\n");
	printf("|       3.困难难度         |\n");
	printf("|       4.地狱难度         |\n");
	printf("|                          |\n");
	printf("----------------------------\n");
}

这个复制过来后就不正了,可以自己调整一下。

5.menu.h

#ifndef __MENU_H__
#define __MENU_H__
#pragma once

void menu();
void window();

#endif /* __MENU_H__ */

 

结语:

猜数字小游戏制作就到这里了,如果文章中有什么话语上的问题,或是程序上的问题,请在评论区中帮忙指出错误的地方,我会及时改正。

 

 

 

  • 23
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值