【小游戏】AB猜数字

这个游戏由来已久。记得我小学的时候流行过电子词典,就是袖珍版的笔记本电脑。主要功能是查英语单词的翻译。记得当时我手里这款里边有几种小游戏,现在还记得的有一个养猫游戏,每天给它喂食、给它球玩之类的。另一个记得的就是这个猜数字的游戏,当时觉得还挺难的,经常无法通关。最近又在某视频平台看到有人玩,于是想拿出来再玩玩。

最近正好在整理 shell 编程相关的知识,就用 shell 写一个小游戏吧。正好这个游戏的逻辑不复杂。游戏名实在是忘了,就叫它AB猜数字吧,lol

先介绍一下游戏规则。每局游戏会生成一个随机排列的四位数字,四个数字不重复。玩家有8次机会给出自己的答案。如果数字和位置都正确,用A标记;如果数字正确但位置错误,用B标记。比如正确答案是2478,如果玩家给出的答案是1286,返回的标记是0A2B,如果玩家给出的答案是2487,返回的标记是2A2B。

好的,规则就这么一点儿。
下边来看一下代码实现逻辑:
第一步,生成随机四位数字作为正确答案:

# 创建数组,元素是0到9
num_array=( $(seq 0 9) )
# 定义一个变量amount, 生成随机数使用
amount=10
# 定义一个空数组 bingo,用来放置生成的四个数字
declare -a bingo
# 定义变量i, 作为循环变量
i=0

# 四次循环,因为答案是四个数字
while [ $i -lt 4 ]
do
	# num 是 1-10 的随机数
	num=$((RANDOM%amount))
	# n 是 以 num 为索引从数组中取出的一个数字(0到9)
	n=${num_array[$num]}
	# 如果在之前的循环中已经取出了数字,就直接进入下一次循环
	if [ -z "$n" ]
	then
		continue
	else
		# 将取出的数字存到数组 bingo 中
		bingo[$i]=$n
		# 将取出的数字从原数组中删除,避免出现重复数字
		unset 'num_array[$n]'
	fi
	# 索引自增
	(( i++ ))
done

第二步,游戏进行:

# 记录A结果的变量
a_result=0
# 记录B结果的变量
b_result=0
# 记录游戏次数
count=0
# 整个进行阶段使用一个 while 循环包起来,最主要的功能是读取用户输入
while read -rp "请输入你的答案:" ans
do
	# 如果给出的答案不足四个数字,打印错误
	if [ ${#ans} -ne 4 ]
	then
		echo "格式错误"
		continue
	else
		# 这里用了双层 for 循环,分别比较正确答案和给出的答案的每一位数字是否相同
		for bingo_index in {0..3}
		do
			for ans_index in {0..3}
			do
				# 如果数字相同且位置也相同,记录A的结果的变量 a_result 自增1
				# 如果数字相同但位置不相同,记录B的结果的变量 b_result 自增1
				if [ "${bingo[$bingo_index]}" -eq "${ans:${ans_index}:1}" ]
				then
					if [ "$bingo_index" -eq "$ans_index" ]
					then
						(( a_result++ ))
						break
					else
						(( b_result++ ))
						break
					fi
				fi
			done
		done
		# 如果 a_result 等于4,也就是答案正确,游戏结束,打印恭喜玩家字样
		if [ "$a_result" -eq 4 ]
		then
			echo "恭喜你答对了!"
			exit 1
		else
			# 如果 a_result 不等于4,打印当前的答案状态,即xAyB,并打印剩余猜测次数
			echo "${a_result}A${b_result}B	加油!你还有$(( 7 - count ))次机会~"
		fi
		# 标记当前次数的变量 count 自增 1
		(( count++ ))
		# 如果 count 等于8,也就是说这是最后一次,打印失败字样,并打印正确答案
		if [ "$count" -eq 8 ]
		then
			echo "你已经尝试8次了,挑战失败"
			echo "正确答案是:${bingo[*]}"
			exit 1
		fi
		# 每次循环之后清空 a_result 和 b_result
		a_result=0
		b_result=0
	fi
done

游戏截图:
在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
猜数字  猜数字   猜数字可以算是一种益智类小游戏,一般两个人,也可以由一个人和电脑,可以在纸上、在网上都可以。这种游戏规则简单,但可以考验人的严谨和耐心。   目录   1 规则   1.1 次数限制   1.2 含重复数字猜数字   2 解法   2.1 计算机解   2.2 推理解   2.3 代入解   2.4 其他   3 参看   规则   这个游戏的规则比较简单,一般两个人,一方出数字,一方猜。出数字的人要想好一个没有重复数字的4位数,不能让猜得人知道。猜的人就可以开始猜。每猜一个数字,出数者就要根据这个数字给出几A几B,其中A前面的数字表示位置正确的数的个数,而B前的数字表示数字正确而位置不对的数的个数。   如正确答案为5234,而猜的人猜5346,则是1A2B,其中有一个5的位置对了,记为1A,而3和4这两个数字对了,而位置没对,因此记为2B,合起来就是1A2B。   接着猜的人再根据出题者的几A几B继续猜,直到猜中为止。   次数限制   有的时候,这个游戏有猜测次数上的限制。根据计算机测算,这个游戏,如果以最严谨的计算,任何数字可以在7次之内猜出。而有些地方把次数限制为6次或更少,则会导致有些数可能猜不出来。而有些地方考虑到人的逻辑思维难以达到计算机的那么严谨,故设置为8次甚至10次。也有的没有次数上的限制。   含重复数字猜数字   有一种使用范围比较狭窄的猜数字,是允许重复数字存在的猜数字,但由于其规则较复杂,故没有得到广泛的推广。其规则如下:   除了上面的规则外,如果有出现重复的数字,则重复的数字每个也只能算一次,且以最优的结果为准,   如正确答案为5543,猜的人猜5255,则在这里不能认为猜测的第一个5对正确答案第二个,根据最优结果为准的原理和每个数字只能有一次的规则,两个比较后应该为1A1B,第一个5位子正确,记为1A;猜测数字中的第三个5或第四个5和答案的第二个5匹配,只能记为1B。当然,如果有猜5267中的第一个5不能与答案中的第二个5匹配,因此只能记作1A0B。   解法   对于不同的人,常常会用到不同的解法   计算机解   通常采用的计算机解是通过排除法,即遍历所有可能的数,将不符合要求的数剃掉。   下面是一个计算机处理的例子:   for (int i = 0; i < Array.Count; i++) { if (Array与当前输出数字的比较 != 用户输入的与正确答案对比的结果) { Array.Remove(i); i--; } }      这个代码采用C#的语法,其中Array表示所有可能的数字的集合。这个例子为了方便说明,结合了语言的描述。   这样的方法充分利用了计算机计算速度快的优势,迅速排出不符合要求的数。通常第一次猜测的时间(有的引擎为第二次猜测)会在10秒左右,而随着猜测次数的不断增加,猜测的时间会越来越短,最后几乎不需要时间,这是由于集合中的数越来越少,排除需要的时间也随之减少。   推理解   计算机解释根据这种方法推广的。这种解法的中心思想是假设猜的这个数字是正确答案,即如果它为正确答案,那么这个数应该符合已经猜测的数及其结果。如已经有   1234 0A0B   那么下一步就不能猜含有1234中任一数字的数,因为如果正确答案含1234中任一,结果就不可能为0A0B。   这种解法对猜者要求较高,通常,可能会被定式思维所干扰,导致难以猜出。   基于这个解法,根据个人思维风格和起始数字选择的不同,以及对出题者出数风格的猜测,有时可以把猜测次数控制在5步内,但不总能在5步内猜出。   使用这种解法需要考虑的时间很久,和计算机解正好相反,人使用这种方法,通常随着猜测次数的增加,需要考虑的东西不断增多,反而考虑的时间会变得越来越长。   代入解   还有一种方法,在人的猜测中很常用,即将推理出不可能含有的数字,代入,察看那些数字是有的。   但这种方法其猜测次数难以确定,且通常的猜测次数比推理解多。   其他   可能还有其他的方法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值