本文已参与「新人创作礼」活动,一起开启掘金创作之路。
想起之前玩过的报数游戏,今天使用C语言来实现一下。
游戏规则其实很简单,就是2个人轮流报数,每个人每次只能报1或者2,不能选择不报。然后每次报的数会累计,谁先到30谁就赢。
举个例子,为了方便,我直接从20开始了:
玩家A报:2;那么数值就是20+2=22
玩家B报:1;那么数值就是23
玩家A报:2;那么数值就是25
玩家B报:1;那么数值就是26
玩家A报:2;那么数值就是28
玩家B报:2;那么数值就是30
玩家B先到30,玩家B获胜。
OK,这就是基本规则,其实这个规则还有一点没有说明,那就是谁先开始。因为2个人玩的游戏,其结果不能因为谁先开始而产生差异。比如象棋、围棋、乒乓球、羽毛球等等。这些游戏总得要一个人先开始,那么先开始的是不是有优势呢,如果有,那么这个游戏就不公平。我们先不讨论这个,直接先上代码:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int computer (int n);
int man (int t);
main()
{
int seed,ret=0;
srand(time(NULL));
seed=rand()%2;
if (seed==0)
{
ret=man(ret);
}
while (ret<30)
{
ret=computer (ret);
if (ret==30)
{
printf("sorry! you fail.\n");
}
else
{
ret=man(ret);
if (ret==30)
{
printf("congratulate you !win\n");
}
}
}
}
int man (int t)
{
int a;
printf("please input a count:\n");
do
{
scanf("%d",&a);
}while (a>2||a<1);
printf("yuor count:%d\n",t+a);
return t+a;
}
int computer (int n)
{
int s;
if ((30-n)%3==1)
{
printf("computer count:%d\n",n+1);
return n+1;
}
else if ((30-n)%3==2)
{
printf("computer count:%d\n",n+2);
return n+2;
}
else
{
s=rand()%2+1;
printf("computer count:%d\n",s+n);
return n+s;
}
}
以上就是完整的C语言代码。因为我没有写注释,所以需要做一些说明。我定义了2个函数,一个是man,一个是computer,从函数名也可以得知,一个是人类报数,一个是计算机报数。人报数就比较简单,里面有一个while循环,这个while循环作用是避免人类输错。因为我们只能是1或者2,所以当检测到不是1和2的时候,就一直让人输入。
至于谁先开始,我采用随机数的方法,rand()函数每次调用前都会查询是否调用过srand(seed),是否给seed设定了一个值,如果有那么它会自动调用srand(seed)一次来初始化它的起始值。若之前没有调用srand(seed),那么系统会自动给seed赋初始值,即srand(1)自动调用它一次。
很显然,我使用了srand()给它设置了随机种子。rand()产生随机数时,如果用srand(seed)播下种子之后,一旦种子相同,产生的随机数将是相同的。很多时候为了刻意让rand()产生随机化的随机数,用时间作种子 srand(time(NULL)),因为每次运行程序的时间肯定是不相同的,产生的随机数肯定就不一样了。
rand()函数产生的是一个0-0x7fff的随机数,即0~32767之间的一个数。我让该数对2求余,那么其结果必然是0或者1。我的设计是:如果是0,那就人先开始,如果是1,那就计算机先开始。
我们接着看计算机的函数computer(),这次本程序最核心的地方:
int computer (int n)
{
int s;
if ((30-n)%3==1)
{
printf("computer count:%d\n",n+1);
return n+1;
}
else if ((30-n)%3==2)
{
printf("computer count:%d\n",n+2);
return n+2;
}
else
{
s=rand()%2+1;
printf("computer count:%d\n",s+n);
return n+s;
}
}
该函数有3个if-else的判断。判断逻辑就是,用30减去目前的数,也就是30-n,用这个数对3求余,根据余数性质我们可以知道,其结果只可能是0、1、2三种情况。如果对3求余结果为1,那么就报1;如果对3求余结果为2,那么就报2。如果对3求余结果为0,也就是3的倍数,那么就1和2随机报数。
举个例子,假如人先报数,比如报了1,那么30-1=29,29%3=2,那么就会执行第二个if判断,让其加2,那就变成了3。
假如人先报2,那么30-2=28,28%3=1,那就执行第一个if判断,让其加1,结果还是3。
到这里可能大家已经发现了猫腻,也就是只要是人先报数,无论报1还是2,计算机都会让他最终变成3。变成3以后,根据计算机的判断逻辑,我们再看:
假设人报1,那么结果变成了4,计算机根据30-4=26,26%3=2,执行第二个if语句,让其加2,结果就是6。假设人报2,那么结果就是5,计算机根据30-5=25,25%3=1,执行第一个if语句,让其加1,结果还是6。
以此类推,后面计算机会让其不断成为3的倍数,9、12、15、18、21、24、27,到了27的时候,轮到人开始报数了,此时,不管人报1还是2,计算机都赢了。也就是说,该游戏并非是一个公平的游戏,先报数的人一定会输,后报数的人一定会赢。只要轮到自己报数时,一直保持自己是3的倍数就行。不过这个可以针对小学阶段来玩一玩,提高其数学思维能力。