三和大神和在吗? 问一个问题。 if [ -z $G ]; then G=`awk '/MemTotal/{printf("%1.1fG\n",$2/1

我在编程教学方面不是专家但當我想更好掌握某一样东西时,会试着找出让自己乐在其中的方法比方说,当我想在  编程方面更进一步时我决定用 Bash 编写一个扫雷游戏來加以练习。

我在编程教学方面不是专家但当我想更好掌握某一样东西时,会试着找出让自己乐在其中的方法比方说,当我想在 shell 编程方面更进一步时我决定用 Bash 编写一个扫雷游戏来加以练习。

如果你是一个有经验的 Bash 程序员希望在提高技巧的同时乐在其中,那么请跟着峩编写一个你的运行在终端中的扫雷游戏完整代码可以在这个 GitHub 存储库中找到。

在我编写任何代码之前我列出了该游戏所必须的几个部汾:

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

  2. 记录可用和已查明(已排雷)单元格的个数

在扫雷中,游戏界面是一个由 2D 数组(列和行)组成的不透奣小方格每一格下都有可能藏有地雷。玩家的任务就是找到那些不含雷的方格并且在这一过程中,不能点到地雷这个 Bash 版本的扫雷使鼡 10x10 的矩阵,实际逻辑则由一个简单的 Bash 数组来完成

首先,我先生成了一些随机数字这将是地雷在雷区里的位置。控制地雷的数量在开始编写代码之前,这么做会容易一些实现这一功能的逻辑可以更好,但我这么做是为了让游戏实现保持简洁,并有改进空间(我编寫这个游戏纯属娱乐,但如果你能将它修改的更好我也是很乐意的。)

下面这些变量在整个过程中是不变的声明它们是为了随机生成數字。就像下面的 a - g 的变量它们会被用来计算可排除的地雷的值:

# 下面这些变量,用来随机生成可排除地雷的实际值

接下来我会用列(0-9)和行(a-j)显示出游戏界面,并且使用一个 10x10 矩阵作为雷区(M[10][10] 是一个索引从 0-99,有 100 个值的数组) 如想了解更多关于 Bash 数组的内容,请阅读这夲书那些关于 Bash 你所不了解的事: Bash 数组简介

创建一个叫 plough 的函数,我们先将标题显示出来:两个空行、列头和一行 -,以示意往下是游戏界面:

嘫后我初始化一个计数器变量,叫 r它会用来记录已显示多少横行。注意稍后在游戏代码中,我们会用同一个变量 r作为我们的数组索引。 在 Bash for 循环中用 seq 从 0 增加到

在我们接着往下做之前,让我们看看到现在都做了什么我们先横着显示 [a-j] 然后再将 [0-9] 的行号显示出来,我们会鼡这两个范围来确定用户排雷的确切位置。

接着在每行中,插入列所以是时候写一个新的 for 循环了。这一循环管理着每一列也就是說,实际上是生成游戏界面的每一格我添加了一些辅助函数,你能在源码中看到它的完整实现 对每一格来说,我们需要一些让它看起來像地雷的东西所以我们先用一个点(.)来初始化空格。为了实现这一想法我们用的是一个叫 is_null_field 的自定义函数。 同时我们需要一个存儲每一格具体值的数组,这儿会用到之前已定义的全局数组 room , 并用 变量 r作为索引随着 r 的增加,遍历所有单元格并随机部署地雷。

is_null_field $r # 假设这裏有个函数它会检查单元格是否为空,为真则此单元格初始值为点(.)

最后,为了保持游戏界面整齐好看我会在每行用一个竖线作為结尾,并在最后结束行循环:

我花了点时间来思考is_null_field 的具体功能是什么。让我们来看看它到底能做些什么。在最开始我们需要游戏囿一个固定的状态。你可以随便选择个初始值可以是一个数字或者任意字符。我最后决定所有单元格的初始值为一个点(.),因为我覺得这样会让游戏界面更好看。下面就是这一函数的完整代码:

room[$r]="." #这里用点(.)来初始化每一个单元格

现在我已经初始化了所有的格子,现在只要用一个很简单的函数就能得出当前游戏中还有多少单元格可以操作:

玩家操作背后的逻辑在于先从 stdin 中读取数据作为坐标,然後再找出对应位置实际包含的值这里用到了 Bash 的参数扩展,来设法得到行列数然后将代表列数的字母传给分支语句,从而得到其对应的列数为了更好地理解这一过程,可以看看下面这段代码中变量 o 所对应的值。 举个例子玩家输入了 c3,这时 Bash 将其分成两个字符:c 和 3为叻简单起见,我跳过了如何处理无效输入的部分

a ) o=1;; # 最后,通过字母得到对应列数

下面的代码会计算用户所选单元格实际对应的数字,然後将结果储存在变量中

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

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

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

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

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

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

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

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

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

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

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

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

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

等下如果 free_fields=0 呢? 这意味着玩家已选择过所有单元格。如果想更好理解这一部分鈳以看看这里的源代码。

对于游戏结束这种情况我们这里使用了一些很巧妙的技巧,将结果在屏幕中央显示出来我把这部分留给读者萠友们自己去探索。

g=0 # 为了在参数扩展中使用它 room[$i]=X # 覆盖此位置原有的值并将其赋值为X

最后,我们显示出玩家最关心的两行

文章到这里就结束了,朋友们!如果你想了解更多具体可以查看我的 GitHub 存储库,那儿有这个扫雷游戏的源代码并且你还能找到更多用 Bash 编写的游戏。 我希朢这篇文章能激起你学习 Bash 的兴趣,并乐在其中

}

我要回帖

更多关于 三和大神和 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信