C语法(Java语法)---顺序循环选择+猜数字游戏实现

前言

欢迎来到我的C语言的语法博客,本篇致力于帮助同学们快速上手熟练C语言的逻辑结构使用,并实现一个迭代版的猜数字游戏。

不必担心,不会涉及过多C语言后面的知识,我们目的就是练习。

建议同学们任读一本C语言书籍的这部分内容,再看此篇博客,课本有的用不着我说,我谈我的经验。

近日,学习Java想写相关博客,发现与C高度相似(重点写差别部分),为此又写一篇Java的分支循环没有意义,不如完善此篇。java部分用紫色标注,不了解Java无视即可。

学习目的:

1.掌握 rand函数,srand函数  ,time函数,会学会生成固定范围的随机数。

2.熟练if……else ,switch case ,break,continue;while ,do while ,for这些关键字的适用。

适用人群:

初学C语言的小萌新。

注意:为了代码简洁,配有注释;代码简单易懂,人性化;头文件省略,请自行补上。

赠君一席话:你的时间有限,忽视别人对我们的指点,谁在乎?只有我们自己,记住往后的人生,为自己而活,别为他人而活。

我来这个世界,世界是为了我而服务;万法注我,我心即路。

猜数字游戏实现的结构分析

要素:一个要猜的数字+玩家输入数字。

int main()
{
	int input = 0;
	int goal = 7;//任写一个要猜数字
	printf("请输入一个数字\n");
	printf(">");
	scanf("%d", &input);
	return 0;
}

玩家输入的数字跟要猜的数字,无非就是三种可能,即猜大了,猜小了,猜对了;

if(条件表达式)

    表达式1;

对于C语言来说:0表示假,非0表示真。if结构,条件表达式结果为真,则执行后面的语句,否则只判断条件,不执行。

Java:if(),括号里面的表达式必须为布尔表达式,即表达式结果必须为true或者false。

Java中true不表示1,false不表示0,它们是单独的boolean类型。

对比C语言,宏定义明示常量(编译时替换),true false分别表示 1 , 0;true和false本质是int类型。

#define false 0
#define true  1

简而言之,Java判断真假只能是true false,C语言中本质用整型0,非0来辨别真假。

这里有三种情况(猜大,猜小,猜对)

if(条件表达式)

 {

     语句1;

}else{

     语句2;

}

显然if……else的分支结构也不行,用来表示两种完全相反的情况。


 if(条件表达式1)

 {

     语句1;

}else if(条件表达式2){

     语句2;

}else{

      语句3;

}

这种结构,中间可以插入无数条else if分支(只要你愿意),三种情况就可以表示了。

下面加入if_else if_else语句;

int main()
{
	int input = 0;
	int goal = 7;
	printf("请输入一个你要猜的数字\n");
	printf(">");
	scanf("%d", &input);
	if (input > goal)
	{
		printf("猜大了\n");
	}else if (input == goal)
	{
		printf("猜对了\n");
	}else
	{
		printf("猜小了\n");
	}
	return 0;
}

这种写法,自上而下先判断if语句,再判断else if语句,最后再考虑执行else里语句。

中间判断成立了就不再进行后续的判断。

讲先后,有顺序!

Java的if else完全一样。

很显然,我们只能猜一次,为了能保证猜对正确答案,多猜几次,写个while循环实现。

while(条件表达式)

{

   语句1;

   语句2;

  ……

}

Java中while小括号内必须为布尔表达式。

猜对答案就终止循环了,表达式怎么写呢?

如果你不清楚表达式具体怎么写,先写while(1),这么写循环会一直执行,这个时候借助break就行了,当数字猜对了就用break结束循环。

int main()
{
	int input = 0;
	int goal = 7;
	printf("请输入一个你要猜的数字\n");
	while (1)
	{
		printf(">");//输入必须包括在循环内,否则死循环。
		scanf("%d", &input);
		if (input > goal)
		{
			printf("猜大了\n");
		}
		else if (input == goal)
		{
			printf("猜对了\n");
			break;
		}
		else
		{
			printf("猜小了\n");
		}
	}
	return 0;
}



下面总结一下:

1.while特点 先判断后执行;

 特别适用于一开始循环条件难找,可以先进循环,满足条件再用break打破循环。

2.break特点 强制打破循环

补充:针对while循环 for循环 do……while循环,和分支中的switch。请记住,break只能打破当前的上述4种结构。请注意它们自身或者互相嵌套的适用。

break只能在循环和开关(switch)使用,否则编译器会告诉你。

3.while和break对于Java也一样,注意表达式是布尔表达式即可。

我们要设计一个初始界面,控制游戏的开始进行,先把上面的的猜数字游戏封装成一个函数game;像下面一样操作即可。

void game()
{
	int input = 0;
	int goal = 7;
	printf("请输入一个你要猜的数字\n");
	while (1)
	{
		printf(">");
		scanf("%d", &input);
		if (input > goal)
		{
			printf("猜大了\n");
		}
		else if (input == goal)
		{
			printf("猜对了\n");
			break;
		}
		else
		{
			printf("猜小了\n");
		}
	}
}

下面设置一个菜单函数,方便玩家选择

void menu()
{
    //连续用printf打印即可。
	printf("*****************\n");
	printf("**** 1.-> play **\n");
	printf("**** 0.-> exit **\n");
	printf("*****************\n");
}

初始界面打印菜单,供玩家选择;

玩家选择上面菜单的1或者0选择play或者exit。这种只涉及整数的分支结构,就用switch case的分支结构。

switch(整型表达式)

{

  case 常量1:

             相关语句;

 case  常量2:

             相关语句;

 …………

default:

           相关语句;

}

switch case的注意事项有点多,请先记住这个结构,结合下面代码。

int main()
{
	int input = 0;
	menu();//菜单函数调用
	printf("请输入一个数字\n");
	printf(">");
	scanf("%d", &input);
	switch (input)
	{
	case 1:
		game();//玩猜数字的游戏
		break;
	case 0:
		printf("退出游戏\n");
		exit(0);//程序正常结束。
	default:
		printf("非法输入!\n");
        break;
	}
	return 0;
}

简单梳理一下switch case:

1.switch后面紧跟着小括号(),小括号里面是整型表达式(表达式结果为整型),或者整型常量,整型变量,字符类型。

对于Java:switch的小括号内必须是 小于等于4字节的整数类型,或者字符类型,不能是布尔表达式。

列举一下:byte short int char  ,注意long这种整型不行。另外字符串类型和枚举类型也可以。

2.case,case后面跟着数字或字符常量值,多个case后面不能跟着相同的常量值。

3.case一般后面跟着break,因为case决定了入口,进去了会一直向下执行。如果单独实现某个分支语句记得加break。break能跳出当前的switch,但是对if……else没有作用。

4.default相当于if else中的else的地位,若没有case满足,则default就是入口。

2,3,4条Java完全相同。

上面的写法玩家只能选择一次(玩或者退出),我们再加上循环,可以反复玩,再由玩家决定是否退出。

这里我们希望它先执行一次,正好do while循环满足先执行再判断。

do

{

    语句1;

    语句2;

…………;

}while(条件表达式/布尔表达式);

这种循环会先进入执行一次,再做判断要不要继续执行!

这里使用system("cls");//清理了控制台,需要引windows.h的头文件!

 system("pause"),暂停观察结果,头文件同上。

int main()
{
	int input = 0;
	do
	{
		menu();//菜单函数调用
		printf("请输入一个数字\n");
		printf(">");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
            system("pause");//暂停观看结果。
			system("cls");//完成一次游戏清理一下控制台
			break;
		case 0:
			printf("退出游戏\n");
			exit(0);
		default:
			printf("非法输入!\n");
		}
	} while (input);
	return 0;
}

do while循环的特点和易错点分析:

1.先循环后判断

2.while(表达式)后面要跟分号;

这里没有涉及for循环,continue.请同学们自行多加练习。

好了,前戏已经结束了,生成随机数的问题没解决。

请重点观看下面的内容。

一、生成随机数相关函数介绍

1.1前言

网站:cplusplus.com/doc/    

C语言相关知识:

1.顺序,分支,循环结构的使用。

学完指针重新回顾此篇吧。

1.2rand函数

头文件:stdlib.h

int rand (void);

功能:生成随机数,随机数范围0~32767(看编译器) ,32767==2^15-1

返回值:返回一个伪随机数。

int rand (void);//函数原型

 什么是伪随机数?试着多次运行下列程序,程序结果都是一样,真随机结果都是无法预测的。

伪随机数不是真正的随机数,是通过某种算法⽣成的随机数。

事实上,rand函数基于一个种子算法进行某种运算得到的。 之所以前⾯每次运⾏程序产⽣的随机数序列是⼀样的,那是因为rand函数⽣成随机数的默认种⼦是1,如果要让每次结果不一样,我们就要每次运行时都要改变这个种子,接下来我们介绍srand函数。

#include<stdio.h>
#include<stdlib.h>//
int main()
{
	printf("%d\n", rand());
	printf("%d\n", rand());
	printf("%d\n", rand());
	printf("%d\n", rand());
	printf("%d\n", rand());
	printf("%d\n", rand());
	printf("%d\n", rand());
	printf("%d\n", rand());
	printf("%d\n", rand());
	printf("%d\n", rand());
	
	return 0;
}

1.3srand函数:详情看下

头文件:stdlib.h(和rand函数头文件相同) 

void srand (unsigned int seed);

参数类型:unsigned int  无符号整数

返回类型为 空类型。 

随机值在调用rand1函数之前先调用srand改变种子,通过 srand 函数的参数seed来设置rand函数⽣成随机数的时候的种⼦,只要种⼦在变化,每次⽣成的随机数序列也就变化起来了。但是产生一个随机数需要输入另外一个随机数,这很矛盾。这里的种子要有常量改成变量,且不需要我们认为输入。接下来我们用程序运行时间(稍后我们会介绍一个函数)作为种子,程序运行时间是不断变化的,我们就不用手动输入随机数,因此每次运行结果就不同了。

1.4time函数

头文件:time.h

C语言中有一函数为 time,就可以获得这个时间。函数原型如下:

time_t time (time_t* timer);

返回类型

time 函数会返回当前的⽇历时间,其实返回的是1970年1⽉1⽇0时0分0秒到现在程序运⾏时间之间的差值,单位是秒。因此每次运行程序时间不同,所以生成的随机数不同。

time_t我们用vs2022选中time_t按键盘F12转到定义。

typedef是类型重命名的关键字,简单理解给这个数据类型起了一个新名。

 typedef __time64_t time_t;
typedef __int64                       __time64_t;

所以time_t是一位64位的整型数据类型。

函数参数

time函数的参数 timer 如果是⾮NULL的指针的话,函数也会将这个返回的差值放在timer指向的内存 中带回去。

我们只需知道,如果 timer 是NULL(空指针),就只返回这个时间的差值。time函数返回的这个时间差也被叫做:时间戳。

时间戳(Unix timestamp)转换工具 - 在线工具 (tool.lu)

#ifndef NULL//空指针的定义
    #ifdef __cplusplus
        #define NULL 0
    #else
        #define NULL ((void *)0)
    #endif

简而言之,我们只是希望这个函数返回时间戳,就可以简单写成如下,

time(NULL);//调⽤time函数返回时间戳,这⾥没有接收返回值

1.5设置随机数范围

由于随机数在给定范围内任意,我们人为指定范围就要通过下面的运算了。

%取余操作符,我们这里讨论a,b均为正整数的情况,不难看出a%b(除数不能为0)的范围是[0,b-1]。

所以得到0~100的范围可以是rand%(101)结果必然是[0,100]。

因此,若(a<b),则a+rand()%(b-a+1)表示[a,b]的范围。

二、猜数字游戏


2.1初步实现

#include<stdio.h>
#include<windows.h>
#include<time.h>

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

void game()
{
	int input = 0;
	srand((unsigned)time(NULL)); // 每次程序运行生成不同的种子。
	int goal = rand()%101;//生成0~100的随机数
	printf("请输入你要猜的一个数字\n");
	while (1)
	{
		printf(">");
		scanf("%d", &input);
		if (input > goal)
		{
			printf("猜大了\n");
		}
		else if (input == goal)
		{
			printf("猜对了\n");
			break;
		}
		else
		{
			printf("猜小了\n");
		}
	}
}


int main()
{
	int input = 0;
	do
	{
		menu();//菜单函数调用
		printf("请输入一个数字\n");
		printf(">");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			system("pause");//暂停观察结果。
			system("cls");//完成一次游戏清理一下控制台
			break;
		case 0:
			printf("退出游戏\n");
			exit(0);
		default:
			printf("非法输入!\n");
		}
	} while (input);
	return 0;
}

 过去的版本


#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void game()
{
	int r = rand() % 100 + 1;
	int guess = 0;
	while (1)
	{
		printf("请猜数字>:");
		scanf("%d", &guess);
		if (guess < r)
		{
			printf("猜小了\n");
		}
		else if (guess > r)
		{
			printf("猜大了\n");
		}
		else
		{
			printf("恭喜你,猜对了\n");
			break;
		}
	}
}
void menu()
{
	printf("***********************\n");
	printf("****** 1. play ******\n");
	printf("****** 0. exit ******\n");
	printf("***********************\n");
}
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	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;
}

2.2优化游戏内容 

下面我们来尝试优化游戏内容:

作者做出了如下调整:

1.调整了函数名和变量名,增强了可读性。

2.修改了菜单,使其变得更加美观。

3.检查了输入的有效性。

4.打印信息修改为英文,注释为中文,方便阅读代码。

限定猜的次数

#include<stdio.h>
#include<windows.h>
#include<time.h>

void PrintMenu()
{
	printf("*************************\n");
	printf("**Guess the number game**\n");
	printf("**      1.-> play      **\n");
	printf("**      0.-> exit      **\n");
	printf("*************************\n");
}

void PlayGame()
{
	int guess = 0;

	int total_count = 10;//合计猜的总的次数
	int now_count = 0;//当前使用的次数

	srand((unsigned)time(NULL)); // 每次程序运行生成不同的种子。
	int goal = rand()%101;//生成0~100的随机数
	printf("Choose an integer number(0~100) ,please.\n");
	while (1)
	{
		printf(">");
		if (1 != scanf("%d", &guess))//限定了guess的范围0~100。
		{
			while (getchar() != '\n');//清空缓冲区,清除其它非法字符。
            printf("Invalid input. Please enter an integer.\n");
			continue;//到下一次循环重新输入!
		}
		if (guess < 0 || guess>100)
		{
			printf("Range : from 0 to 100\n");//范围不符合要求。
			continue;//到下一次循环重新输入!
		}
		if (guess > goal)
		{
			printf("Too high , try a smaller number.\n");
		}
		else if (guess == goal)
		{
			printf("That's right!\n");
			break;
		}
		else
		{
			printf("Too low , try a higher number.\n");
		}
		now_count++;
		printf("You still have %d chance.\n", total_count - now_count);//提醒一下玩家还有多少次机会。
		if (now_count == total_count)//失败了的情况
		{
			printf("------------------------------------------\n");
			printf("You failed. The correct answer is %d\n", goal);
		}
	}
}


int main()
{
	int input = 0;
	do
	{
		PrintMenu();//菜单函数调用
		printf("Please choose.\n");
		printf("1 -> YES\n");
		printf("0 -> NO \n");
		printf(">");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			PlayGame();
			system("pause");//暂停观察结果。
			system("cls");//完成一次游戏清理一下控制台
			break;
		case 0:
			printf("See you again!\n");
			exit(0);
		default:
			printf("Input error,pleae try again!\n");
			system("pause");//暂停观察结果。
			system("cls");
		}
	} while (input);
	return 0;
}







显示输入记录

这里用一个简单的一维数组存储每次输入的整数。

#define MAX_Count 10//定义了一个宏,数组的元素个数

#include<stdio.h>
#include<windows.h>
#include<time.h>

#define MAX_Count 10//定义了一个宏
void PrintMenu()
{
	printf("*************************\n");
	printf("**Guess the number game**\n");
	printf("**      1.-> play      **\n");
	printf("**      0.-> exit      **\n");
	printf("*************************\n");
}

void PlayGame()
{
	int guess = 0;

	int total_count = 10;//合计的总的次数
	int now_count = 0;//当前使用的次数

	int arr[MAX_Count];//定义一个元素个数为10的数组。

	srand((unsigned)time(NULL)); // 每次程序运行生成不同的种子。
	int goal = rand()%101;//生成0~100的随机数


	printf("Choose an integer number(0~100) ,please.\n");
	while (1)
	{
		printf(">");
		if (1 != scanf("%d", &guess))//限定了guess的范围0~100。
		{
			while (getchar() != '\n');//清空缓冲区,清除其它非法字符。
            printf("Invalid input. Please enter an integer.\n");
			continue;//到下一次循环重新输入!
		}
		if (guess < 0 || guess>100)
		{
			printf("Range : from 0 to 100\n");//范围不符合要求。
			continue;//到下一次循环重新输入!
		}
		arr[now_count] = guess;//存储有效的数据。
		if (guess > goal)
		{
			printf("Too high , try a smaller number.\n");
		}
		else if (guess == goal)
		{
			printf("That's right!\n");
			break;
		}
		else
		{
			printf("Too low , try a higher number.\n");
		}
		now_count++;
		printf("You still have %d chance.\n", total_count - now_count);//提醒一下玩家还有多少次机会。
		if (now_count == total_count)//失败了的情况
		{
			printf("------------------------------------------\n");
			printf("You failed. The correct answer is %d\n", goal);
            break;
		}
	}
	//打印输入的信息
	printf("-------Input Record-------\n");
	for (int i = 0; i < now_count; i++)
	{                                              //计算猜的数与实际的差值
		printf("%2d  :%4d   %4d\n", i + 1, arr[i], abs(arr[i] - goal));//abs绝对值函数,stdlib.h头文件上。
	}
}


int main()
{
	int input = 0;
	do
	{
		PrintMenu();//菜单函数调用
		printf("Please choose.\n");
		printf("1 -> YES\n");
		printf("0 -> NO \n");
		printf(">");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			PlayGame();
			system("pause");//暂停观察结果。
			system("cls");//完成一次游戏清理一下控制台
			break;
		case 0:
			printf("See you again!\n");
			exit(0);
		default:
			printf("Input error,pleae try again!\n");
			system("pause");//暂停观察结果。
			system("cls");
		}
	} while (input);
	return 0;
}

划分难度等级

可以说是最终版本了,分难度等级。自行阅读。

#include<stdio.h>
#include<windows.h>
#include<time.h>

#define MAX_Count 10//定义了一个宏
void PrintMenu()
{
	printf("*************************\n");
	printf("**Guess the number game**\n");
	printf("**      1.-> play      **\n");
	printf("**      0.-> exit      **\n");
	printf("*************************\n");
}

void PlayGame()
{
	srand((unsigned)time(NULL)); // 每次程序运行生成不同的种子。
	int input = 0;//选择难度
	int guess = 0;//要猜的值
    int goal = 0;//随机值
	int max = 0;//根据难度确定右值
	int total_count = 10;//合计的总的次数
	int now_count = 0;//当前使用的次数
	int arr[MAX_Count];//定义一个元素个数为10的数组。

	//Random难度的准备
	int left = 0;//左右值的初始化
	int right = 0;

	do {
		printf("Please choose your difficulty level\n");
		printf("1.->Practice:    0~9\n");//新手入手
		printf("2.->Easy:        0~99\n");//初级
		printf("3.->Intermediate:0~999\n");//中级
		printf("4.->Advanced:    0~9999\n");//高级
		printf("5.->Random:      ?~?\n");//随机难度
		if (1 != scanf("%d", &input))
		{
			while (getchar() != '\n');//清理缓冲区
			printf("Invalid input. Please enter an integer.\n");
			continue;//到下一次循环重新输入!
		}
		while (getchar() != '\n');
		switch (input)
		{
		case 1:
			goal = rand() % 10;//生成0~9的随机数
			max = 9;
			goto start;//跳转
		case 2:
			goal = rand() % 100;//生成0~99的随机数
			max = 99;
			goto start;
		case 3:
			goal = rand() % 1000;//生成0~999的随机数
			max = 999;
			goto start;
		case 4:
			goal = rand() % 10000;//生成0~9999的随机数
			max = 9999;
			goto start;
		case 5:
			left = rand();//左值
			right = rand();//右值
			if (left > right)
			{
				int tmp = left;
				left = right;
				right = tmp;
			}
			max = -1;//进入随机难度的标志
			goal = left + rand() % (right-left)+1;//范围(left---right);
			goto random;
		default:
			printf("Input error,pleae try again!\n");
		}
	} while (1);

	start :
	printf("Choose an integer number(0~%d) ,please.\n",max);
	while (1)
	{
		printf(">");
		if (1 != scanf("%d", &guess))
		{
			while (getchar() != '\n');//清空缓冲区,清除其它非法字符。
            printf("Invalid input. Please enter an integer.\n");
			continue;//到下一次循环重新输入!
		}
		while (getchar() != '\n');
			if (guess < 0 || guess>max)
			{
				printf("Range : from 0 to %d\n", max);//范围不符合要求。
				continue;//到下一次循环重新输入!
			}
		arr[now_count] = guess;//存储有效的数据。
		if (guess > goal)
		{
			printf("Too high , try a smaller number.\n");
		}
		else if (guess == goal)
		{
			printf("That's right!\n");
			break;
		}
		else
		{
			printf("Too low , try a higher number.\n");
		}
		now_count++;
		printf("You still have %d chance.\n", total_count - now_count);//提醒一下玩家还有多少次机会。
		printf("------------------------------------------\n");
		if (now_count == total_count)//失败了的情况
		{
			printf("------------------------------------------\n");
			printf("You failed. The correct answer is %d\n", goal);
			break;
		}
	}
	if (max == -1)
	{
	random:
		printf("Choose an integer number.(? ~ ?)\n");
		while (1)
		{
			printf(">");
			if (1 != scanf("%d", &guess))
			{
				while (getchar() != '\n');//清空缓冲区,清除其它非法字符。
				printf("Invalid input. Please enter an integer.\n");
				continue;
			}
			if (guess < 0)
			{
				printf("Range : at least >= 0 \n");//范围不符合要求。
				continue;//到下一次循环重新输入!
			}
			arr[now_count] = guess;//存储有效的数据。
			if (guess > goal)
			{
				printf("Too high , try a smaller number.\n");
			}
			else if (guess == goal)
			{
				printf("That's right!\n");
				break;
			}
			else
			{
				printf("Too low , try a higher number.\n");
			}
			now_count++;
			printf("You still have %2d chance.\n", total_count - now_count);//提醒一下玩家还有多少次机会。
			printf("------------------------------------------\n");
			if (now_count == total_count)//失败了的情况
			{
				printf("------------------------------------------\n");
				printf("You failed. The correct answer is %d\n", goal);
				break;
			}
		}

	}

	//打印输入的信息
	printf("-------Input Record-------\n");
	for (int i = 0; i < now_count; i++)
	{                                              //计算猜的数与实际的差值
		printf("%2d  :%5d   %5d\n", i + 1, arr[i], abs(arr[i] - goal));//abs绝对值函数,stdlib.h头文件上。
	}
}


int main()
{
	int input = 0;
	do
	{
		PrintMenu();//菜单函数调用
		printf("Please choose.\n");
		printf("1 -> YES\n");
		printf("0 -> NO \n");
		printf(">");
		if (1 != scanf("%d", &input))
		{
			while (getchar() != '\n');//清理缓冲区
			printf("Invalid input. Please enter an integer.\n");
			system("cls");
			continue;//到下一次循环重新输入!
		}
		while (getchar() != '\n');//清理缓冲区
		switch (input)
		{
		case 1:
			PlayGame();
			system("pause");//暂停观察结果。
			system("cls");//完成一次游戏清理一下控制台
			break;
		case 0:
			printf("See you again!\n");
			exit(0);
		default:
			printf("Input error,pleae try again!\n");
			system("pause");//暂停观察结果。
			system("cls");
		}
	} while (input);
	return 0;
}

计时(最终版本)

尝试学习time函数如何计算运行时间的差值部分吧

#include<stdio.h>
#include<windows.h>
#include<time.h>

#define MAX_Count 10//定义了一个宏
void PrintMenu()
{
	printf("*************************\n");
	printf("**Guess the number game**\n");
	printf("**      1.-> play      **\n");
	printf("**      0.-> exit      **\n");
	printf("*************************\n");
}

void PlayGame()
{
	srand((unsigned)time(NULL)); // 每次程序运行生成不同的种子。
	int input = 0;//选择难度
	int guess = 0;//要猜的值
    int goal = 0;//随机值
	int max = 0;//根据难度确定右值
	int total_count = 10;//合计的总的次数
	int now_count = 0;//当前使用的次数
	int arr[MAX_Count];//定义一个元素个数为10的数组。

	//Random难度的准备
	int left = 0;//左右值的初始化
	int right = 0;

	time_t startTime, endTime;
	double elapsedTime;

	do {
		printf("Please choose your difficulty level\n");
		printf("1.->Practice:    0~9\n");//新手入手
		printf("2.->Easy:        0~99\n");//初级
		printf("3.->Intermediate:0~999\n");//中级
		printf("4.->Advanced:    0~9999\n");//高级
		printf("5.->Random:      ?~?\n");//随机难度
		printf(">");
		if (1 != scanf("%d", &input))
		{
			while (getchar() != '\n');//清理缓冲区
			printf("Invalid input. Please enter an integer.\n");
			continue;//到下一次循环重新输入!
		}
		while (getchar() != '\n');
		switch (input)
		{
		case 1:
			goal = rand() % 10;//生成0~9的随机数
			max = 9;
			goto start;//跳转
		case 2:
			goal = rand() % 100;//生成0~99的随机数
			max = 99;
			goto start;
		case 3:
			goal = rand() % 1000;//生成0~999的随机数
			max = 999;
			goto start;
		case 4:
			goal = rand() % 10000;//生成0~9999的随机数
			max = 9999;
			goto start;
		case 5:
			left = rand();//左值
			right = rand();//右值
			if (left > right)
			{
				int tmp = left;
				left = right;
				right = tmp;
			}
			max = -1;//进入随机难度的标志
			goal = left + rand() % (right-left)+1;//范围(left---right);
			goto random;
		default:
			printf("Input error,pleae try again!\n");
		}
	} while (1);

	start :
	printf("Choose an integer number(0~%d) ,please.\n",max);
	time(&startTime);
	while (1)
	{
		printf(">");
		if (1 != scanf("%d", &guess))
		{
			while (getchar() != '\n');//清空缓冲区,清除其它非法字符。
            printf("Invalid input. Please enter an integer.\n");
			continue;//到下一次循环重新输入!
		}
		while (getchar() != '\n');
			if (guess < 0 || guess>max)
			{
				printf("Range : from 0 to %d\n", max);//范围不符合要求。
				continue;//到下一次循环重新输入!
			}
		arr[now_count] = guess;//存储有效的数据。
		if (guess > goal)
		{
			printf("Too high , try a smaller number.\n");
		}
		else if (guess == goal)
		{
			printf("That's right!\n");
			break;
		}
		else
		{
			printf("Too low , try a higher number.\n");
		}
		now_count++;
		printf("You still have %d chance.\n", total_count - now_count);//提醒一下玩家还有多少次机会。
		printf("------------------------------------------\n");
		if (now_count == total_count)//失败了的情况
		{
			printf("------------------------------------------\n");
			printf("You failed. The correct answer is %d\n", goal);
			break;
		}
	}
	if (max == -1)
	{
	random:
		printf("Choose an integer number.(? ~ ?)\n");
		while (1)
		{
			printf(">");
			if (1 != scanf("%d", &guess))
			{
				while (getchar() != '\n');//清空缓冲区,清除其它非法字符。
				printf("Invalid input. Please enter an integer.\n");
				continue;
			}
			if (guess < 0)
			{
				printf("Range : at least >= 0 \n");//范围不符合要求。
				continue;//到下一次循环重新输入!
			}
			arr[now_count] = guess;//存储有效的数据。
			if (guess > goal)
			{
				printf("Too high , try a smaller number.\n");
			}
			else if (guess == goal)
			{
				printf("That's right!\n");
				break;
			}
			else
			{
				printf("Too low , try a higher number.\n");
			}
			now_count++;
			printf("You still have %2d chance.\n", total_count - now_count);//提醒一下玩家还有多少次机会。
			printf("------------------------------------------\n");
			if (now_count == total_count)//失败了的情况
			{
				printf("------------------------------------------\n");
				printf("You failed. The correct answer is %d\n", goal);
				break;
			}
		}

	}
	time(&endTime);
	elapsedTime = difftime(endTime, startTime);
	printf("It took a total of %.3lf seconds.\n",elapsedTime);
	//打印输入的信息
	printf("-------Input Record-------\n");
	for (int i = 0; i < now_count; i++)
	{                                              //计算猜的数与实际的差值
		printf("%2d  :%5d   %5d\n", i + 1, arr[i], abs(arr[i] - goal));//abs绝对值函数,stdlib.h头文件上。
	}
}


int main()
{
	int input = 0;
	do
	{
		PrintMenu();//菜单函数调用
		printf("Please choose.\n");
		printf("1 -> YES\n");
		printf("0 -> NO \n");
		printf(">");
		if (1 != scanf("%d", &input))
		{
			while (getchar() != '\n');//清理缓冲区
			printf("Invalid input. Please enter an integer.\n");
			system("cls");
			continue;//到下一次循环重新输入!
		}
		while (getchar() != '\n');//清理缓冲区
		switch (input)
		{
		case 1:
			PlayGame();
			system("pause");//暂停观察结果。
			system("cls");//完成一次游戏清理一下控制台
			break;
		case 0:
			printf("See you again!\n");
			exit(0);
		default:
			printf("Input error,pleae try again!\n");
			system("pause");//暂停观察结果。
			system("cls");
		}
	} while (input);
	return 0;
}

图形库(自学,这里只是个标题) 

以下为过去的版本,可以看看。


我们可以自己丰富一下这个游戏。方便起见,函数原型和函数定义均在同一源文件上。读者可自行丰富改进代码。

#define _CRT_SECURE_NO_WARNINGS 1//vs2022,scanf函数不安全要使用必须加上这行代码。
#include<stdio.h>//调用printf,scanf要引用的头文件
#include<stdlib.h>//调用rand,srand的头文件
#include<time.h>//调用time的头文件
void menu(void);//游戏菜单函数声明
void game(void);//猜数字游戏内部函数
int main()
{
	int input;
	//选择开始游戏,退出游戏的变量。

	do
	{
		menu();//游戏菜单,具体看函数定义
		printf("请输入一个数字:\n");
		printf("1->play\n");
		printf("0->exit\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();//游戏内容的具体实现
			break;
		case 0:
			printf("游戏愉快!\n");
			break;
		default:printf("选择错误,重新选择!\n");
			break;

		}
	} while (input);
	return 0;
}

void menu(void)//不需要传参和返回,只需要该函数打印游戏开始界面即可
{
	printf("***********************\n");
	printf("******  1. play  ******\n");
	printf("******  0. exit  ******\n");
	printf("***********************\n");
	return;
}
void game(void)
{
	int guess;
	srand((unsigned int)time(NULL));
	printf("请问是否需要自定义难度(自定义范围+次数限制):\n");
	printf("1->YES\n");
	printf("0->NO\n");
	int n = 0;
	int ret;
	int a, b;
	unsigned int cnt = 1;//默认难度始终为一
	int flag = 1;//是否需要自定义难度的标志。cnt变量可以赋值更改了,变为while循环次数限制的变量
	scanf("%d", &n);
	switch (n)
	{
	case 1:
	{
		do
		{
			error:
			printf("请输入两个数表示你要猜的数字范围(注意右边数大于左边数):");
			scanf("%d%d", &a, &b);
			if (a > b)
			{
				printf("非法输入,请遵守规则!\n");
				goto error;
			}
			printf("请输入限制的次数:\n");
			scanf("%u", &cnt);
			flag = 0;
			ret = a + rand() % (b - a + 1);
			if (a >= b)
				printf("输入错误,请重新选择\n");
		} while (a >= b);
		break;
	}
	default:
		printf("输入错误,默认开启正常难度\n");
	case 0:
		printf("注意:默认范围是0~100,无次数限制\n");
		ret = rand() % 100 + 1;
	}
	while (cnt)
	{
		if (flag == 0)
		{
			printf("你还有%2u次机会,", cnt);
		}
		printf("请输入你要猜的数字:->");
		if (scanf("%d", &guess) != EOF)
		{
			if (guess > ret)
			{
				printf("猜大了\n");
				printf("--------\n");

			}
			else if (guess < ret)
			{
				printf("猜小了\n");
				printf("--------\n");
			}
			else
			{
				printf("恭喜你,猜对了!,答案就是%d。\n", ret);
				break;
			}
			if (!flag)//循环调整,循环一次,cnt次数减一。
				--cnt;
		}
		else
		{
			printf("输入错误,正确答案是%d,欢迎下次挑战。\n", ret);
			break;
		}

	}
	if (cnt == 0)
		printf("你失败了,正确答案是%d,下次加油\n", ret);
	printf("----------------\n");
	return;
}

结尾

C语言是一门程序型设计语言,顺序,分支,循环。谨以此篇巩固学习,权当记录了。

路漫漫其修远兮,吾将上下而求索。-----23年11月写下

今日偶然想起此篇,更Java的同时完结C语言的此篇。

如果我感到痛苦的话,我会先怀疑世界,然后给自己两嘴巴。--------2024/5/7,5:48.

早安,朋友们!

  • 33
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值