“猜数字游戏是令游戏机随机产生一个100以内的正整数,用户输入一个数对其进行猜测,需要你编写程序自动对其与随机产生的被猜数进行比较,并提示大了(“Too big”),还是小了(“Too small”),相等表示猜到了。如果猜到,则结束程序。程序还要求统计猜的次数,如果1次猜出该数,提示“Bingo!”;如果3次以内猜到该数,则提示“Lucky You!”;如果超过3次但是在N(>3)次以内(包括第N次)猜到该数,则提示“Good Guess!”;如果超过N次都没有猜到,则提示“Game Over”,并结束程序。如果在到达N次之前,用户输入了一个负数,也输出“Game Over”,并结束程序。”
输入样例:
58 4
70
50
56
58
60
-2
输出样例:
Too big
Too small
Too small
Good Guess!
原代码:
#include<stdio.h>
int main(){
int cnt=0,input,N,rightguess;
int sign=0;
scanf("%d %d",&rightguess,&N);
scanf("%d",&input);
while(input>=0){
cnt++;
if(cnt>N)
break;
//printf("%d \n",cnt);
if(input>rightguess)
printf("Too big\n");
if(input<rightguess)
printf("Too small\n");
if(input==rightguess){
if(cnt==1){
printf("Bingo!\n");
sign=1;
break;
}
else if(cnt<3){
printf("Lucky You!\n");
sign=1;
break;
}
else if(cnt>=3&&cnt<=N){
printf("Good Guess!\n");
sign=1;
break;
}
}
scanf("%d",&input);
}
if(sign==0)
printf("Game Over");
return 0;
}
这个是第一次写这个题的程序,PTA上面得不到满分,后来才发现是自己做input==rightguess的子判断,出现问题,题目要求不超过三次答对的话输出lucky you ,我的"cnt<3"改成“cnt<=3“才对。
但同时引发了我的一个问题,关于while循环还是for循环,还有,我这代码是不是可以优化一下?
这个猜数字游戏,比如rightguess 是58 N 是 4 。我们希望如果第四次还是没对,他应该要输出一个GAME OVER。可我的程序无法输出这个,因为我的循环末尾是一个SCANF函数,不执行这一步将卡在循环里面出不来。
解决方法:思考过在不进行太多改动的条件下,使之可以实现功能且跳出循环。想了蛮久,感觉是想不出来,因为我用的while循环有个本质的矛盾,我驱动循环的条件是判断input的值,这也就导致我想跳出循环只能用做一个判断接上break或者是用scanf改变input的值,可是这都会影响我功能的实现(input和rightguess比大小,输出too small/big,etc)。
所以我仔细看了别人(月落乌啼霜月落)的代码,并对其进行一个分析,通过对代码的分析,希望可以对以后类似的问题做一个抛砖引玉,让自己写出更好的代码,我这代码可读性真的太差了。
ps:我改了别人代码的变量名,尽量使其和我原代码的变量名一致,同时做了一丝丝改动。
#include<stdio.h>
int main()
{
int rightguess, N;
scanf("%d %d",&rightguess,&N);
int i;
int input;
int sign = 0;
for (i = 1;i <= N;i ++)
{
scanf("%d",&input);
if (input < 0)
break;
if (input > rightguess)
printf("Too big\n");
if (input < rightguess)
printf("Too small\n");
if (input == rightguess)
{
if (i == 1)
{
sign = 1;
printf("Bingo!\n");
break;
}
else if (i <=3)
{
sign = 1;
printf("Lucky You!\n");
break;
}
else
{
sign = 1;
printf("Good Guess!\n");
break;
}
}
}
if (sign == 0)
printf("Game Over\n");
return 0;
}
//本代码非常简洁,可读性也很好。我将以我一个小白的理解,逐步复现这个代码的书写思路。
/*猜数字游戏的本质,就是判断,做几次判断跟N的值是息息相关的,意味着循环跟N息息相关,当循环有一个明确值,选用for循环会比较合适。当N=4的时候,意味着我们最多要猜4轮,同时意味着离开循环时候i的值应该是5,按照这个例子不难有for(i=1;i<=N;i++)。每一轮循环我们要做什么事情?
首先必须要先有个位置,放置我们的输入input,依照题意,当用户输入负数的时候,我们不用进行比较大小了,马上输出一个gameover,这件事情本质上就是做判断并跳出循环,所以有 if(input<0).做一个break。这也指导了,在for循环之后 我们要printf一个gameover 。至此,我们有了一个总体的框架,我们要做的事情就是不断填充里面的内容,并且进行调试。回到比大小这件事情,在循环里面我们确认input不是负数的时候,依次进行判断if(input<rightguess),if(input>rightguess),if(input==rightguess),其中input==rightguess的情况中,还要进一步的判断(i=1 i<=3 i>3),这里我用的else if级联的方式。题目的要求是如果bingo 或者luckyyou、goodguess的时候只输出这几个字符串,不能输出gameover,所以我们可以用sign做一个判断,影响循环外的gameover的输出。
以上基本上就是这个代码是如何写出来的,心路历程了。