这个看似简单的东西,其实也很有意思。
首先,明确要解决的问题:
- 用什么代表石头、剪刀、布,怎么判断输赢
- 人出什么可以由人来选,那电脑出什么怎么解决呢?
第2个问题很好解决:用随机数决定电脑出什么就好了
第1个问题怎么办呢?有人可能说,穷举出所有可能情况就好了,那样当然可以。但是我们今天准备用更简洁的方法,如下:
石头、剪刀、布之间的胜负关系,可以由上图表示。如果用连续的数代表石头、剪刀、布,(设a>b) 如果 数a-数b=1,那么数a代表的一方就赢了,如果数a-数b=2,那么数b代表的一方就赢了,如果 数a-数b=0,即数a=数b,那么平局。不理解?没关系,请往下看。
其实上面的图可以看成下图的形式。
这样就好理解多了把,a比b大1,就是a赢,a比b大2(相当于b比a打1)就是a输,它们相等,就是平局。
可能有同学要问:前后都要省略号,难道我们要用无穷个数吗?还有,如果a在b的左边,我们怎么判断。
别急,其实我们可以利用补码的思想,只用3个数就可以表示出的拳,以及胜负关系。补码的细节就不说了,其思想简单说下:可以想象下时钟,9点过了1小时是10点,即9+1=10,然而9点过了4个小时却是1,即9+4=1,怎么能让9+4=1呢? (9+4)再对12取余就好了。
对应于我们的游戏 我们想让a-b恒为正,即a恒大于b,在a-b前,让a先加3就好了,不过a+3-b之后是有可能大于3的,所以a+3-b之后还要再对3取余,即:
result = (human - computer + 3) % 3;//结果 0平局 1人胜 2电脑胜
这样,就解决了出拳的表示,以及输赢判断问题了。
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
int main()
{
char fist[3][20] = { "剪刀", "石头", "布" };//0代表剪刀,1代表石头,2代表布。
char res[3][20] = { "平局", "人胜", "电脑胜" };
int human;
int computer;
int result;
continue_play:
srand((unsigned)time(NULL));
computer = rand() % 3; //产生 0-2的随机数。
human_input:
printf("请输入:\n0)剪刀\n1)石头\n2)布\n");
scanf("%d", &human);
if (human < 0 || human>2)
{
printf("输入非法,重新输入\n");
goto human_input;
}
result = (human - computer + 3) % 3;//结果 0平局 1人胜 2电脑胜
printf("电脑:%s 人:%s %s\n", fist[computer], fist[human], res[result]);
printf("按任意键继续游戏,按q退出游戏\n");
if (getch() == 'q')
return 0;
goto continue_play;
}