加入收藏 | 设为首页 | 会员中心 | 我要投稿 源码网 (https://www.900php.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Windows > 正文

通过编写扫雷游戏提高你的Bash技巧

发布时间:2019-10-10 11:19:45 所属栏目:Windows 来源:Abhishek Tamrakar
导读:副标题#e# 那些令人怀念的经典游戏可是提高编程能力的好素材。今天就让我们仔细探索一番,怎么用 Bash 编写一个扫雷程序。 我在编程教学方面不是专家,但当我想更好掌握某一样东西时,会试着找出让自己乐在其中的方法。比方说,当我想在 shell 编程方面更进

这里也用到了很多的 shuf 命令,shuf 是一个专门用来生成随机序列的 Linux 命令。-i 选项后面需要提供需要打乱的数或者范围,-n 选项则规定输出结果最多需要返回几个值。Bash 中,可以在两个圆括号内进行数学计算,这里我们会多次用到。

还是沿用之前的例子,玩家输入了 c3。 接着,它被转化成了 ro=3o=3。 之后,通过上面的分支语句代码, 将 c 转化为对应的整数,带进公式,以得到最终结果 i 的值。

  1. i=$(((ro*10)+o)) # 遵循运算规则,算出最终值
  2. is_free_field $i $(shuf -i 0-5 -n 1) # 调用自定义函数,判断其指向空/可选择单元格。

仔细观察这个计算过程,看看最终结果 i 是如何计算出来的:

  1. i=$(((ro*10)+o))
  2. i=$(((3*10)+3))=$((30+3))=33

最后结果是 33。在我们的游戏界面显示出来,玩家输入坐标指向了第 33 个单元格,也就是在第 3 行(从 0 开始,否则这里变成 4),第 3 列。

创建判断单元格是否可选的逻辑

为了找到地雷,在将坐标转化,并找到实际位置之后,程序会检查这一单元格是否可选。如不可选,程序会显示一条警告信息,并要求玩家重新输入坐标。

在这段代码中,单元格是否可选,是由数组里对应的值是否为点(.)决定的。如果可选,则重置单元格对应的值,并更新分数。反之,因为其对应值不为点,则设置变量 not_allowed。为简单起见,游戏中警告消息这部分源码,我会留给读者们自己去探索。

  1. is_free_field()
  2. {
  3.   local f=$1
  4.   local val=$2
  5.   not_allowed=0
  6.   if [[ "${room[$f]}" = "." ]]; then
  7.     room[$f]=$val
  8.     score=$((score+val))
  9.   else
  10.     not_allowed=1
  11.   fi
  12. }

通过编写扫雷游戏提高你的Bash技巧

Extracting mines

如输入坐标有效,且对应位置为地雷,如下图所示。玩家输入 h6,游戏界面会出现一些随机生成的值。在发现地雷后,这些值会被加入用户得分。

通过编写扫雷游戏提高你的Bash技巧

Extracting mines

还记得我们开头定义的变量,a - g 吗,我会用它们来确定随机生成地雷的具体值。所以,根据玩家输入坐标,程序会根据(m)中随机生成的数,来生成周围其他单元格的值(如上图所示)。之后将所有值和初始输入坐标相加,最后结果放在 i(计算结果如上)中。

请注意下面代码中的 X,它是我们唯一的游戏结束标志。我们将它添加到随机列表中。在 shuf 命令的魔力下,X 可以在任意情况下出现,但如果你足够幸运的话,也可能一直不会出现。

  1. m=$(shuf -e a b c d e f g X -n 1) # 将 X 添加到随机列表中,当 m=X,游戏结束
  2. if [[ "$m" != "X" ]]; then # X 将会是我们爆炸地雷(游戏结束)的触发标志
  3. for limit in ${!m}; do # !m 代表 m 变量的值
  4. field=$(shuf -i 0-5 -n 1) # 然后再次获得一个随机数字
  5. index=$((i+limit)) # 将 m 中的每一个值和 index 加起来,直到列表结尾
  6. is_free_field $index $field
  7.     done

我想要游戏界面中,所有随机显示出来的单元格,都靠近玩家选择的单元格。

通过编写扫雷游戏提高你的Bash技巧

Extracting mines

记录已选择和可用单元格的个数

这个程序需要记录游戏界面中哪些单元格是可选择的。否则,程序会一直让用户输入数据,即使所有单元格都被选中过。为了实现这一功能,我创建了一个叫 free_fields 的变量,初始值为 0。用一个 for 循环,记录下游戏界面中可选择单元格的数量。 如果单元格所对应的值为点(.),则 free_fields 加一。

  1. get_free_fields()
  2. {
  3.   free_fields=0
  4.   for n in $(seq 1 ${#room[@]}); do
  5.     if [[ "${room[$n]}" = "." ]]; then
  6.       ((free_fields+=1))
  7.     fi
  8.   done
  9. }

(编辑:源码网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读