Shell 技巧 - Yahtzee 计分

作者:Dave Taylor

上个月,我开始谈论如何使用一些简单的 shell 脚本技术来创建一个流行的骰子游戏 Yahtzee 的计算机模拟。我不会编写整个游戏(电脑玩家对于 shell 脚本来说会非常复杂,这是一方面原因),但在我们继续讨论其他主题之前,让我们再用一栏来了解一些计分的基础知识。

Yahtzee 作为电脑游戏的一个优点是,电脑实际上不需要做太多工作,因为这款游戏作为单人纸牌游戏变体也能很好地运行:您只需玩游戏以最大化您的分数,并看看您的表现如何,与您之前的最高分竞争。

Yahtzee 的基本思想是,您最多掷三次五个骰子,以获得最佳的数值组合。然后,这些组合将根据固定的记分表进行评分,该记分表为特定组合提供特定分数,范围从掷出的每个“1”一分到五个相同点数(在游戏术语中称为“Yahtzee”)50分。

快速访问 Google 即可找到在线 Yahtzee 记分表;在继续之前,请查看一下:www.gamingcorner.nl/images/sheets/yahtzee-3.pdf

在很多方面,它就像用骰子玩的五张牌扑克,因此记分表的第一部分是针对组合:1点、2点、3点等等,其中您的每种组合的分数是骰子上该数值的总和。第二部分是其他扑克牌型,包括三条、四条、小顺子(五个骰子中有四个是连续值)、大顺子(所有五个都是连续值)、葫芦以及一个或多个 Yahtzee 掷骰。

您可以因达到某些级别而获得奖励,包括在顶部部分获得至少 63 分即可获得非常好的 35 分奖励,但记分表本身很简单。

因此,游戏的重点是弄清楚如何为给定的掷骰计分。如果您掷出四个 1 点,您想将其计为四条还是 1 点?如果两者都已填写怎么办?幸运的是,我们将由玩家来决定,但这仍然给我们留下了数据问题,即如何建模记分表上的不同框,以及界面问题,即如何提示用户选择要计分的框。让我们来看一看。

将记分表建模为数组

与大多数此类数据结构一样,我们将使用数组来建模记分表。数一下记分表上的框,您会看到总共有 13 个框,包括特殊的 Yahtzee 框,您可以在其中掷骰——并获得超过一次的积分(因此,一个游戏通常有 13 次掷骰,但可能会更多)。

如果我们通过用一个已知的停止值(例如 -1)填充所有数组值来初始化游戏,那么测试给定框是否已被填充就很简单

if [ scoresheet[1] != -1 ] ; then
  echo "1: Your one's" ; fi

诀窍是我们还想预先限定这些选项。如果玩家没有掷出五条,那么提示玩家将其掷骰选择为 Yahtzee 就没有意义。这被证明有点棘手,因此作为第一步,我将调整代码以在每次掷骰后自动按升序排列数组中的骰子。

完成这项任务可能需要很长时间,但与其在脚本中编写排序例程,我不如将任务推送给 sort 函数,然后将结果读回并将其放入骰子数组的各个槽中。听起来很复杂?确实如此

function sortDice()
{
   sorted="$( ( echo ${dice[1]} ; echo ${dice[2]}
     echo ${dice[3]} ; echo ${dice[4]}
     echo ${dice[5]} ) | sort )"

   index=1
   for value in $sorted ; do
     dice[$index]=$value
     index=$(( $index + 1 ))
   done
}

您可以在这里看到,我正在使用一个名为 sorted 的临时变量来存储结果值,并且我正在使用一个子 shell——即 $( ) 表示法——来完成实际工作。这个小函数最难的部分是弄清楚如何在一切都正确排序后将值放回数组中,而这是通过 for 循环完成的。

请注意,幸运的是,for 循环会自动遍历以空格(空格和回车符)分隔的字段,因此它非常适合将结果排序后的序列分解回单个值。

本月我们的篇幅快要用完了,恐怕我最终花了很多时间在谈话上,而不是编码。我下个月会弥补您,亲爱的读者!

Dave Taylor 是一位拥有 26 年 UNIX 经验的资深人士,The Elm Mail System 的创建者,以及最近畅销书 Wicked Cool Shell ScriptsTeach Yourself Unix in 24 Hours 的作者,这两本书只是他的 16 本技术书籍中的两本。他的主要网站是 www.intuitive.com,他还通过 AskDaveTaylor.com 提供技术支持。

加载 Disqus 评论