Shell 技巧 - 终局

作者:Dave Taylor

这是我们 Blackjack 系列的最后一篇文章,在这篇文章中,我展示了将游戏脚本的所有不同部分编织成可玩游戏的最终代码片段。由于显而易见的原因,我无法在本杂志中展示整个脚本(它将近 300 行),因此我强烈建议您访问 Linux Journal FTP 站点,并在阅读时获取脚本副本 (ftp.linuxjournal.com/pub/lj/listings/issue148/9051.tgz)。

与许多博彩游戏一样,Blackjack 已经演变出许多深奥的规则,包括分牌、保险和各种其他使相对简单的东西变得更复杂的事物。但是,我们将忽略所有这些,也忽略游戏的博彩部分(毕竟这是一本 [geek] 家庭杂志),而只关注游戏玩法。

庄家亮出一张牌

因此,我们需要知道的第一件事是,玩家可以看到发出的两张牌,以及庄家为自己发出的两张牌中的一张。这是我们需要添加的第一段代码,因为我们不允许保险或投注,所以需要在代码中黑杰克测试之后立即包含它

echo -n "** Dealer's hand: "
showCard ${dealer[1]} ; echo -n "$cardname, "
echo "(card face down)"
echo ""

从战略角度来看,如果您对概率有基本的了解,您就会知道,牌面价值为 10 的牌比牌组中任何其他牌面价值的牌都更有可能出现。例如,如果庄家亮出 8 或 9,则很有可能它的手牌价值为 18 或 19。因此,这也将改变您自己的游戏策略,例如,如果您手牌的临时价值为 17,则更有可能再拿一张牌;然而,例如,如果庄家亮出 5,您可能更愿意坚持手牌价值 16。

在之前的专栏中,您已经看到了显示和计算手牌价值的基本脚本,所以这没什么新鲜的

echo -n "** Dealer's hand: "
showCard ${dealer[1]} ; echo -n "$cardname, "
showCard ${dealer[2]} ; echo "$cardname"

handValue ${dealer[1]} ${dealer[2]}

但是,现在我们将在下面添加一个循环,该循环将不断拿牌,直到手牌价值达到 17 或更高(这是拉斯维加斯 Blackjack 标准规则:16 或更低,庄家“要牌”或再拿一张牌,17 或更高,庄家“停牌”或坚持手牌)。

这有点棘手,所以请花时间阅读

while [ $handvalue -lt 17 ]
do
  dealer[$nextdealercard]=${newdeck[$nextcard]}

  showCard ${dealer[$nextdealercard]}

  nextcard=$(( $nextcard + 1 ))
  nextdealercard=$(( $nextdealercard + 1 ))

  echo """ ; echo "** Dealer takes: $cardname"

  handValue ${dealer[1]} ${dealer[2]} ${dealer[3]} \
            ${dealer[4]} ${dealer[5]}
done

有了已经到位的一些好的例程和变量,结果证明让庄家打出它的手牌出奇地简洁。为此出色的设计欢呼!

谁赢了游戏?

现在我们有了游戏逻辑,剩下的就是拥有一组条件来确定谁赢了,或者游戏是否以平局结束

if [ $handvalue -gt 21 ]
then
	echo "**** Dealer busted!  Player wins with \
	$playerhandvalue!"
  playerwin=$(( $playerwin + 1 ))
elif [ $handvalue -eq $playerhandvalue ]
then
	echo "**** Dealer and player tie with \
	$handvalue points."
elif [ $handvalue -lt $playerhandvalue ]
then
	echo "**** Player wins with $playerhandvalue"
  playerwin=$(( $playerwin + 1 ))
else
	echo "**** Dealer wins with $handvalue"
  dealerwin=$(( $dealerwin + 1 ))
fi

你觉得怎么样?代码列表够了吗?

让我们看看游戏现在是如何进行的

$ sh blackjack.sh

**** Welcome to Blackjack.sh! ****

Dealer's hand: Queen of Hearts, (card face down)

You've been dealt: 2 of Spades, 7 of Hearts

H)it or S)tand? (recommended: hit) hit

You've been dealt: 10 of Diamonds

H)it or S)tand? (recommended: stand) stand

You stand with a hand value of 19

Dealer's hand: Queen of Hearts, 4 of Hearts

Dealer takes: Queen of Clubs

**** Dealer busted!  Player wins with 19!

您可以看到我们有 2S 和 7H(9 点),拿了一张牌,10D,给了我们 19 点。我们坚持了下来,庄家亮出它有 QH 4H,14 点,并拿了另一张牌,结果是 QC,这使庄家超过了 21 点。我们赢了!

该程序还有一些细微之处,包括跟踪庄家或玩家获胜的次数,并且在您被问到“要牌还是停牌”时,您现在可以输入quit(或 q)退出。然后,它会显示您

H)it or S)tand? (recommended: stand) q

Player quits.  Standings: dealer wins: 5 and player wins: 3
仍然存在一个错误

代码中还有一个突出的错误,我邀请您挖掘并找出它。如果庄家在游戏中拿到一张 A,它会自动算作 11 点,而不是 1 点或 11 点,正如它应该的那样。您的挑战:找出问题出现在哪里以及如何修复它。如果您认为您知道,请给我发送电子邮件,提出您的解决方案(可能是您的版本与 Linux Journal FTP 站点上的版本之间的差异),我们将看看您做得如何。

下个月,我们将打开一个完全不同的 shell 脚本任务,看看我们能做些什么来帮助您完成日常 Linux 管理任务,因为我们可能已经在一个赌场游戏上浪费了足够多的墨水!到时见。

Dave Taylor 是一位拥有 26 年 UNIX 经验的资深人士,The Elm Mail System 的创建者,也是畅销书 Wicked Cool Shell ScriptsTeach Yourself Unix in 24 Hours 的作者,以及他的 16 本技术书籍。他的主要网站是 www.intuitive.com

加载 Disqus 评论