这里也用到了很多的 shuf 命令,shuf 是一个专门用来生成随机序列的 Linux 命令。-i 选项后面需要提供需要打乱的数或者范围,-n 选项则规定输出结果最多需要返回几个值。Bash 中,可以在两个圆括号内进行数学计算,这里我们会多次用到。
还是沿用之前的例子,玩家输入了 c3 。 接着,它被转化成了 ro=3 和 o=3 。 之后,通过上面的分支语句代码, 将 c 转化为对应的整数,带进公式,以得到最终结果 i 的值。
i=$(((ro*10)+o)) # 遵循运算规则,算出最终值 is_free_field $i $(shuf -i 0-5 -n 1) # 调用自定义函数,判断其指向空/可选择单元格。
仔细观察这个计算过程,看看最终结果 i 是如何计算出来的:
i=$(((ro*10)+o)) i=$(((3*10)+3))=$((30+3))=33
最后结果是 33。在我们的游戏界面显示出来,玩家输入坐标指向了第 33 个单元格,也就是在第 3 行(从 0 开始,否则这里变成 4),第 3 列。
创建判断单元格是否可选的逻辑
为了找到地雷,在将坐标转化,并找到实际位置之后,程序会检查这一单元格是否可选。如不可选,程序会显示一条警告信息,并要求玩家重新输入坐标。
在这段代码中,单元格是否可选,是由数组里对应的值是否为点(. )决定的。如果可选,则重置单元格对应的值,并更新分数。反之,因为其对应值不为点,则设置变量 not_allowed 。为简单起见,游戏中警告消息这部分源码,我会留给读者们自己去探索。
is_free_field() { local f=$1 local val=$2 not_allowed=0 if [[ "${room[$f]}" = "." ]]; then room[$f]=$val score=$((score+val)) else not_allowed=1 fi }
Extracting mines
如输入坐标有效,且对应位置为地雷,如下图所示。玩家输入 h6 ,游戏界面会出现一些随机生成的值。在发现地雷后,这些值会被加入用户得分。
Extracting mines
还记得我们开头定义的变量,a - g 吗,我会用它们来确定随机生成地雷的具体值。所以,根据玩家输入坐标,程序会根据(m )中随机生成的数,来生成周围其他单元格的值(如上图所示)。之后将所有值和初始输入坐标相加,最后结果放在 i (计算结果如上)中。
请注意下面代码中的 X ,它是我们唯一的游戏结束标志。我们将它添加到随机列表中。在 shuf 命令的魔力下,X 可以在任意情况下出现,但如果你足够幸运的话,也可能一直不会出现。
m=$(shuf -e a b c d e f g X -n 1) # 将 X 添加到随机列表中,当 m=X,游戏结束 if [[ "$m" != "X" ]]; then # X 将会是我们爆炸地雷(游戏结束)的触发标志 for limit in ${!m}; do # !m 代表 m 变量的值 field=$(shuf -i 0-5 -n 1) # 然后再次获得一个随机数字 index=$((i+limit)) # 将 m 中的每一个值和 index 加起来,直到列表结尾 is_free_field $index $field done
我想要游戏界面中,所有随机显示出来的单元格,都靠近玩家选择的单元格。
Extracting mines
记录已选择和可用单元格的个数
这个程序需要记录游戏界面中哪些单元格是可选择的。否则,程序会一直让用户输入数据,即使所有单元格都被选中过。为了实现这一功能,我创建了一个叫 free_fields 的变量,初始值为 0 。用一个 for 循环,记录下游戏界面中可选择单元格的数量。 如果单元格所对应的值为点(. ),则 free_fields 加一。
get_free_fields() { free_fields=0 for n in $(seq 1 ${#room[@]}); do if [[ "${room[$n]}" = "." ]]; then ((free_fields+=1)) fi done }
(编辑:ASP站长网)
|