• C语言 新手村学习:石头剪刀布小游戏的代码设计和优化探讨


    石头剪刀布

    小时候都玩过石头剪刀布的游戏,这里通过C语言来制作一个史上最牛逼的石头剪刀布小游戏用来学习交流,这是一篇完整的小游戏代码设计,新手能够很容易的掌握本课程小项目,并且学习怎么优化代码和优化算法,从入门到精通!!!

    首先先整理一下:

    • 先玩家输入一个数,然后打印
    • 然后机器人随机一个数 ,然后打印
    • 最后将这两个数作为判断输赢的依据

    游戏核心逻辑

    通过代号的思想依次构建如下结构体系:

    • 0 — 石头
    • 1 — 剪刀
    • 2 — 布

    游戏规则
    然后根据游戏规则 石头 > 剪刀 > 布 ,其次特殊情况是 布 > 石头。

    通过数字代号表示就是 0 > 1 > 2,其次 2  > 0
    
    可见,规律就是除了2和0比较外,谁小谁就是最大的
    
    • 1
    • 2
    • 3

    代码描述
    在游戏中一方扮演机器人,另一方就是玩家,所以定义两个变量play和rob

    • play — 玩家
    • rob — 机器人

    //预设play=1,rob=2的情况下

    #include
    void main()
    {
    	int play = 1;
    	int rob = 2;
    	
    	//判断
    	if(play == rob)	//相等就是平局
    	{
    		printf("平局");
    	}
    	else		//不相等的情况下
    	{
    		//判断特殊情况 是否存在 一个是2 另一个是0的情况
    		if(play == 2 && rob == 0)
    		{
    			printf("玩家胜利");
    		}
    		else if(play == 0 && rob == 2)
    		{
    			printf("机器人胜利");
    		}
    		else		//不处于特殊情况的话 谁小谁就赢
    		{
    				if(play < rob)
    				{
    					printf("玩家胜利");
    				}
    				else
    				{
    					printf("机器人胜利");
    				}
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    如上面代码,能够完美的实现此逻辑。然后我们加入随机数,讲机器人随机起来。
    在c语言中,生成随机数需要3步:

    1. 导入stdlib头文件和time头文件
    2. 创建随机种子
    3. 调用随机函数生成随机数
    #include	//第一步
    #include
    int main()
    {
    	srand((unsigned)time(NULL));	//第二部 根据time.h头文件中的方法time()来设置随机种子数
    	int rob = rand()%3	//第三步	rand函数会生成 0 到 32767之间的伪随机数 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    通过rand()函数,控制自己想要随机数的范围

    例如:

    rand()%3
    
    • 1
    通过这个方法,与3求余,我们就会得到0 到 2之间随机
    
    • 1

    因此最终代码为:

    #include
    #include
    #include
    void main()
    {
    	int play;
    	int rob;
    	srand((unsigned)time(NULL));
    	scanf("%d",&play);
    	rob = rand()%3;
    	printf("玩家:%d\n",play);
    	printf("机器人:%d\n",rob);
    	//判断
    	if(play == rob)	//相等就是平局
    	{
    		printf("平局");
    	}
    	else		//不相等的情况下
    	{
    		//判断特殊情况 是否存在 一个是2 另一个是0的情况
    		if(play == 2 && rob == 0)
    		{
    			printf("玩家胜利");
    		}
    		else if(play == 0 && rob == 2)
    		{
    			printf("机器人胜利");
    		}
    		else		//不处于特殊情况的话 谁小谁就赢
    		{
    				if(play < rob)
    				{
    					printf("玩家胜利");
    				}
    				else
    				{
    					printf("机器人胜利");
    				}
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    优化代码

    首先将代码划分为模块化,用函数来封装,这样会使得代码更加简洁明了,方便阅读

    使用标记逻辑来优化算法
    下面代码将核心逻辑封装在函数coreLogic中,然后此函数返回 1或0或-1这三个值,然后在printWin函数中判断返回的值并且打印结果,如下逻辑:

    • return 1 — 玩家胜利
    • return 0 — 平局
    • return -1 — 机器人胜利
    #include
    #include
    #include
    
    int coreLogic(int play, int rob)
    {
        //判断
    	if(play == rob)	//相等就是平局
    	{
    		//printf("平局");
    		return 0;
    	}
    	else		//不相等的情况下
    	{
    		//判断特殊情况 是否存在 一个是2 另一个是0的情况
    		if(play == 2 && rob == 0)
    		{
    			//printf("玩家胜利");
    			return 1;
    		}
    		else if(play == 0 && rob == 2)
    		{
    			//printf("机器人胜利");
    			return -1;
    		}
    		else		//不处于特殊情况的话 谁小谁就赢
    		{
    				if(play < rob)
    				{
    					//printf("玩家胜利");
    					return 1;
    				}
    				else
    				{
    					//printf("机器人胜利");
    					return -1;
    				}
    		}
    	}
    }
    
    void printWin(ret)
    {
    	if(ret == 0)
    	{
    		printf("平局");
    	}
    	else if(ret > 0)
    	{
    		printf("玩家胜利");
    	}	
    	else
    	{
    		printf("机器人胜利");
    	}
    }
    
    void main()
    {
    	int play;
    	int rob;
    	int ret;	//用来存储逻辑结果的
    	srand((unsigned)time(NULL));
    	scanf("%d",&play);
    	rob = rand()%3;
    	printf("玩家:%d\n",play);
    	printf("机器人:%d\n",rob);
    	ret = coreLogic(play,rob);
    	printWin(ret);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70

    优化算法

    继续优化函数checkWin,使其更加简短易读:

    仔细想想,我们上面将checkWin函数的返回值 1代表玩家胜利,-1代表机器人胜利,0代表平局

    将这个逻辑继续优化的话就可以变成:

    —负数为机器人胜利
    —正数为玩家胜利
    —0为平局。

    根据两个数的相差即可获得正负数结果:
    正常情况下 : -(玩家的值 - 机器人的值)

    然后,之前提到过的,还有一种特殊情况:一方出的是布,另一方出的是石头。即取个负号即可得到特殊情况的结果了:
    特殊情况下: 玩家的值 - 机器人的值

    实现优化后的代码逻辑

    将coreLogic函数优化成如下代码:

    int coreLogic(int play, int rob)
    {
    	if(play + rob == 2 && play != rob)	//这里通过play+rob==2和play不等于rob来判断是否特殊情况
    	{
    		return (play - rob);	//特殊情况下,玩家值大玩家获胜
    	}
    	return -(play - rob);	//正常情况下,玩家值小玩家获胜,所以前面加了一个负号
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    这样优化过来,代码量大大减小了,阅读也更加容易了。

    最后,最终的代码如下:

    #include
    #include
    #include
    
    int coreLogic(int play, int rob)
    {
    	if(play + rob == 2 && play != rob)
    	{
    		return (play - rob);	
    	}
    	return -(play - rob);
    }
    
    void printWin(ret)
    {
    	if(ret == 0)
    	{
    		printf("平局");
    	}
    	else if(ret > 0)
    	{
    		printf("玩家胜利");
    	}	
    	else
    	{
    		printf("机器人胜利");
    	}
    }
    
    void main()
    {
    	int play;
    	int rob;
    	int ret;	//用来存储逻辑结果的
    	srand((unsigned)time(NULL));
    	scanf("%d",&play);
    	rob = rand()%3;
    	printf("玩家:%d\n",play);
    	printf("机器人:%d\n",rob);
    	ret = coreLogic(play,rob);
    	printWin(ret);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
  • 相关阅读:
    java开发环境安装-202209
    正定核的充分必要条件与再生核希尔伯特空间
    java-php-python-ssm电商后台管理系统计算机毕业设计
    月报总结|Moonbeam 8月份大事一览
    Spring系列18:Resource接口及内置实现
    做自媒体月入一千的有超过百分之十吗?
    【C++】Map和Set -- 详解
    移植案例与原理 - startup子系统之bootstrap_lite服务启动引导部件(1)
    ASO优化:教你学会如何选词,技巧有哪些?
    hadoop 3.x大数据集群搭建系列4-安装Spark
  • 原文地址:https://blog.csdn.net/qq_25755645/article/details/126973350