C语言实战之猜拳游戏

前言

所涉及的知识内容

1.switch分支语句
2.随机数的生成与种子的变更
3.do循环语句
4.指针数组
在这里插入图片描述

游戏设计

基本设计逻辑

为了实现猜拳游戏,我们简单的设计以下基本的流程。
1.确定计算机的手势。
2.显示 ” 石头剪刀布 “ ,然后玩家输入自己要出的手势。
3.进行输赢判断,显示结果。
4.询问是否继续,如果要继续就回到 1 。

下面我们来逐条解释如何完成各个步骤:

确定计算机手势

可以用随机数确定计算机手势

显示 ”石头剪刀布“,如何玩家输入要出的手势

显示手势,我们最好使用数字而非字符串,因为字符串很容易出现输入错误的问题。为了避免这种错误,我们将石头剪刀布分别设计为数字。如:石头(0) 剪刀(1)布(2)

进行判断,显示结果

我们设置变量human和comp来分别表示玩家和计算机的手势,那么就可以根据共同表达式 (human - comp +3)% 3 来进行,如果结果为0就是平局,1就是电脑胜利,2就是玩家胜利

是否继续

我们应该使用do语句

代码展示:

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
int main()
{
	int human; /*玩家的手势*/
	int comp;/*计算机的手势*/
	int judge;/*胜负判断*/
	int retry;/*是否再来一次*/
	srand(time(NULL));
	puts("开始游戏!");
	do
	{
		comp = rand() % 3;/*设置计算机的手势代表数字范围(0~2)*/
		printf("\a\n石头剪刀布···石头(0) 剪刀(1) 布(2):");
		scanf("%d", &human);
		printf("计算机出的是:");
		switch (comp)
		{
		case 0:printf("石头\n"); break;
		case 1:printf("剪刀\n"); break;
		case 2:printf("布\n");   break;
		}
		judge = (human - comp + 3) % 3;
		switch (judge)
		{
		case 0:printf("我们是平局哦!"); break;
		case 1:printf("你输了哦!"); break;
		case 2:printf("你赢了哦!"); break;
		}
		printf("再来一次吗?··否(0)是(1)");
		scanf("%d", &retry);
	} while (retry == 1);
	return 0;
}

我们看一下具体的运行结果:
在这里插入图片描述

上述代码运用了分支语句switch

如何更好的显示手势

上面的代码仅显示了计算机的手势,没有显示玩家的手势,这样的程序显然不具备可玩性,下面我们根据上面的思路将玩家的手势也显示出来。

代码展示:

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
int main()
{
	int human; /*玩家的手势*/
	int comp;/*计算机的手势*/
	int judge;/*胜负判断*/
	int retry;/*是否再来一次*/
	srand(time(NULL));
	puts("开始游戏!");
	do
	{
		comp = rand() % 3;/*设置计算机的手势代表数字范围(0~2)*/
		do 
		{
			printf("\a\n石头剪刀布···石头(0) 剪刀(1) 布(2):");
			scanf("%d", &human);
		} while (human < 0 || human>2);/*显示玩家的输入数字,防止玩家乱输入*/
		printf("程序出的是:");
		switch (comp)
		{
		case 0:printf("石头\n"); break;
		case 1:printf("剪刀\n"); break;
		case 2:printf("布\n");   break;
		}
		printf("玩家出的是:");
		switch (human)
		{
		case 0:printf("石头\n"); break;
		case 1:printf("剪刀\n"); break;
		case 2:printf("布\n");   break;
		}
		judge = (human - comp + 3) % 3;
		switch (judge)
		{
		case 0:printf("我们是平局哦!"); break;
		case 1:printf("你输了哦!"); break;
		case 2:printf("你赢了哦!"); break;
		}
		printf("再来一次吗?··否(0)是(1)");
		scanf("%d", &retry);
	} while (retry == 1);
	return 0;
}

运行结果:

在这里插入图片描述
上述的代码虽然能够解决问题,但是表示石头剪刀布的字符串应该作为数组存在,而非每次我们都需要写一遍。下面我们先展示代码。

代码展示:

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
int main()
{
	int i;
	int human; /*玩家的手势*/
	int comp;/*计算机的手势*/
	int judge;/*胜负判断*/
	int retry;/*是否再来一次*/
	const char *hd[] = { "石头","剪刀","布" }; /*手势*/
	srand(time(NULL));
	puts("开始游戏!");
	do
	{
		comp = rand() % 3;/*设置计算机的手势代表数字范围(0~2)*/
		do
		{
			printf("石头剪刀布···");
			for (i = 0; i < 3; i++)
			{
				printf("(%d) %s ", i, hd[i]);
			}
			printf(":");
			scanf("%d", &human);
		} while (human < 0 || human>2);
		printf("程序出%s,玩家出%s\n", hd[comp], hd[human]);
		judge = (human - comp + 3) % 3;
		switch (judge)
		{
		case 0:printf("我们是平局哦!"); break;
		case 1:printf("你输了哦!"); break;
		case 2:printf("你赢了哦!"); break;
		}
		printf("再来一次吗?··否(0)是(1)");
		scanf("%d", &retry);
	} while (retry == 1);
	return 0;
}

我们用了指向字符串的指针数组,这样写的效果会好于二维数组
值得一提的是如果我们这样写:char *hd [ ]={“石头”,“剪刀”,“布”} 我们有些编译器会出现报错,原因是因为:字符串“石头剪刀布”是字符串常量,需要保存在全局const内存区,所以我们应该这样写:const char *hd [ ]={“石头”,“剪刀”,“布”}

增加胜负次数的显示

随着我们功能的增多,我们会发现,程序越来越大,如果所有的功能都要求main函数来完成,显然有些过分,所以我们应该使用函数,将相应的功能分类,这样就可以使程序更容易被看懂。

我们来看一下修改后的代码:

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
int human;/*玩家手势*/
int comp;/*电脑手势*/
int win_no;/*胜利次数*/
int lose_no;/*失败次数*/
int draw_no;/*平局次数*/

const char* hd[] = { "石头","剪刀","布" };

/*---初始化处理---*/
void initialize()
{
	win_no = 0;
	lose_no = 0;
	draw_no = 0;
	srand(time(NULL));/*随机数种子*/
	printf("猜拳游戏开始!\n");
}
/*---读取/生成手势---*/
void jyanken()
{
	int i;
	comp = rand() % 3;/*随机数范围*/
	do
	{
		printf("石头剪刀布···");
		for (i = 0; i < 3; i++)
		{
			printf("(%d) %s ", i, hd[i]);
		}
		printf(":");
		scanf("%d", &human);/*读取玩家手势*/
	} while (human < 0 || human>2);
}
/*---更新失败/胜利/平局次数---*/
void count_no(int result)
{
	switch ( result)
	{
	case 0:draw_no++; break;
	case 1:lose_no++; break;
	case 2:win_no++; break;
	}
}
/*---显示判断结果---*/
void disp_result(int result)
{
	switch (result)
	{
	case 0:puts("平局!"); break;
	case 1:puts("你失败了!"); break;
	case 2:puts("你胜利了!"); break;
	}
}
/*---是否继续游戏---*/
int confirm_retry()
{
	int x;
	printf("再来一次吗?···否(0)是(1)");
	scanf("%d", &x);
	return x;
}


int main()
{
	int judge = 0;
	int retry = 0;
	initialize();
	do
	{
		jyanken();
		printf("程序出%s,玩家出%s\n", hd[comp], hd[human]);
		judge = (human - comp + 3) % 3;
		count_no(judge);
		disp_result(judge);
		retry = confirm_retry();

	} while (retry == 1);
	printf("%d胜%d负%d平。\n", win_no, lose_no, draw_no);
	return 0;
}

运行结果展示:

在这里插入图片描述
这样我们就通过书写不同作用的函数,将原本臃肿的main函数变得很容易看得懂了。

完美版本猜拳游戏

为了使猜拳游戏更加完美,我们增加了赢三次自动结束比赛的功能,这样就不需要询问玩家是否继续了。
增加这个功能,可以更好的展示,我们将一个大的程序的功能分割成单个函数后,对于后期的代码增添修改的巨大帮助。将大程序的功能分割的越小的函数,那么这个功能可重复使用的次数就会越多,对于后期的维稳就会更加便捷!
代码展示:

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
int human;/*玩家手势*/
int comp;/*电脑手势*/
int win_no;/*胜利次数*/
int lose_no;/*失败次数*/
int draw_no;/*平局次数*/

const char* hd[] = { "石头","剪刀","布" };

/*---初始化处理---*/
void initialize()
{
	win_no = 0;
	lose_no = 0;
	draw_no = 0;
	srand(time(NULL));/*随机数种子*/
	printf("猜拳游戏开始!\n");
}
/*---读取/生成手势---*/
void jyanken()
{
	int i;
	comp = rand() % 3;/*随机数范围*/
	do
	{
		printf("石头剪刀布···");
		for (i = 0; i < 3; i++)
		{
			printf("(%d) %s ", i, hd[i]);
		}
		printf(":");
		scanf("%d", &human);/*读取玩家手势*/
	} while (human < 0 || human>2);
}
/*---更新失败/胜利/平局次数---*/
void count_no(int result)
{
	switch ( result)
	{
	case 0:draw_no++; break;
	case 1:lose_no++; break;
	case 2:win_no++; break;
	}
}
/*---显示判断结果---*/
void disp_result(int result)
{
	switch (result)
	{
	case 0:puts("平局!"); break;
	case 1:puts("你失败了!"); break;
	case 2:puts("你胜利了!"); break;
	}
}
/*---是否继续游戏---*/
int confirm_retry()
{
	int x;
	printf("再来一次吗?···否(0)是(1)");
	scanf("%d", &x);
	return x;
}


int main()
{
	int judge = 0;
	int retry = 0;
	initialize();
	do
	{
		jyanken();
		printf("程序出%s,玩家出%s\n", hd[comp], hd[human]);
		judge = (human - comp + 3) % 3;
		count_no(judge);
		disp_result(judge);
		retry = confirm_retry();

	} while (win_no < 3 && lose_no < 3);
	printf(win_no == 3 ? "\n你胜利了!\n" : "\n我胜利了!\n");
	printf("%d胜%d负%d平。\n", win_no, lose_no, draw_no);
	return 0;
}

在这里插入图片描述
我们甚至没有重新书写三行以上的代码,但是我们却加入了一个新的功能。原因就是因为前面我们分割出来的函数足够详细,因此我们加入新功能也只需将main函数中最后的判断修改一下。

总结

游戏代码

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
int human;/*玩家手势*/
int comp;/*电脑手势*/
int win_no;/*胜利次数*/
int lose_no;/*失败次数*/
int draw_no;/*平局次数*/

const char* hd[] = { "石头","剪刀","布" };

/*---初始化处理---*/
void initialize()
{
	win_no = 0;
	lose_no = 0;
	draw_no = 0;
	srand(time(NULL));/*随机数种子*/
	printf("猜拳游戏开始!\n");
}
/*---读取/生成手势---*/
void jyanken()
{
	int i;
	comp = rand() % 3;/*随机数范围*/
	do
	{
		printf("石头剪刀布···");
		for (i = 0; i < 3; i++)
		{
			printf("(%d) %s ", i, hd[i]);
		}
		printf(":");
		scanf("%d", &human);/*读取玩家手势*/
	} while (human < 0 || human>2);
}
/*---更新失败/胜利/平局次数---*/
void count_no(int result)
{
	switch ( result)
	{
	case 0:draw_no++; break;
	case 1:lose_no++; break;
	case 2:win_no++; break;
	}
}
/*---显示判断结果---*/
void disp_result(int result)
{
	switch (result)
	{
	case 0:puts("平局!"); break;
	case 1:puts("你失败了!"); break;
	case 2:puts("你胜利了!"); break;
	}
}
/*---是否继续游戏---*/
int confirm_retry()
{
	int x;
	printf("再来一次吗?···否(0)是(1)");
	scanf("%d", &x);
	return x;
}


int main()
{
	int judge = 0;
	int retry = 0;
	initialize();
	do
	{
		jyanken();
		printf("程序出%s,玩家出%s\n", hd[comp], hd[human]);
		judge = (human - comp + 3) % 3;
		count_no(judge);
		disp_result(judge);
		retry = confirm_retry();

	} while (win_no < 3 && lose_no < 3);
	printf(win_no == 3 ? "\n你胜利了!\n" : "\n我胜利了!\n");
	printf("%d胜%d负%d平。\n", win_no, lose_no, draw_no);
	return 0;
}

知识总结

分支语句

if语句和switch语句都是分支语句,但是如果要是单一表达式来实现程序的分支,此时switch语句明显好过if语句。

指针数组

在大多数情况下,使用指向字符串的指针数组来实现长度不同的字符串集合,要比用二维数组更加便捷。

字符串“xxx”是字符串常量,需要保存在全局const内存区,所以我们应该这样写:const char *hd [ ]。

作用域

标识符是变量和函数的名称,其通用的范围就是作用域。
在块{ }内声明的标识符,在块内是有效的,而在块外是无效的。一次块内的变量在块外就无效了,这种变量也叫局部变量。

函数分割

当一个程序的功能足够多,足够复杂时,我们应该将每个小板块的功能分割为一个函数,这样会便于后期的维护和添加新功能。而且一个函数的功能越少,那么它可以用的范围就会越广!

  • 27
    点赞
  • 103
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
很抱歉,根据提供的引用内容,没有找到关于C语言实现猜拳游戏的具体示例代码或详细介绍。但是,我可以为您提供一个简单的C语言猜拳游戏的示例代码,供您参考: ```c #include <stdio.h> #include <stdlib.h> #include <time.h> int main() { int playerChoice, computerChoice; int playerScore = 0, computerScore = 0; int round = 1; srand(time(0)); // 设置随机数种子 printf("欢迎来到猜拳游戏!\n"); while (round <= 3) { printf("\n第 %d 轮\n", round); printf("请选择:\n"); printf("1. 石头\n"); printf("2. 剪刀\n"); printf("3. 布\n"); printf("请输入您的选择(1-3):"); scanf("%d", &playerChoice); if (playerChoice < 1 || playerChoice > 3) { printf("无效的选择,请重新选择!\n"); continue; } computerChoice = rand() % 3 + 1; printf("您选择了:"); switch (playerChoice) { case 1: printf("石头\n"); break; case 2: printf("剪刀\n"); break; case 3: printf("布\n"); break; } printf("电脑选择了:"); switch (computerChoice) { case 1: printf("石头\n"); break; case 2: printf("剪刀\n"); break; case 3: printf("布\n"); break; } if (playerChoice == computerChoice) { printf("本轮平局!\n"); } else if ((playerChoice == 1 && computerChoice == 2) || (playerChoice == 2 && computerChoice == 3) || (playerChoice == 3 && computerChoice == 1)) { printf("您赢了本轮!\n"); playerScore++; } else { printf("电脑赢了本轮!\n"); computerScore++; } round++; } printf("\n游戏结束!\n"); printf("您的得分:%d\n", playerScore); printf("电脑的得分:%d\n", computerScore); if (playerScore > computerScore) { printf("恭喜您获胜!\n"); } else if (playerScore < computerScore) { printf("很遗憾,电脑获胜!\n"); } else { printf("本局平局!\n"); } return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

子夜的星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值