Shell 脚本应用 - <emphasis>百家乐庄家闲家</emphasis>,第二部分

作者:Dave Taylor

上个月,我们参观了蒙特卡洛昂贵的私人玩家房间,了解了精英博彩游戏百家乐。这个游戏很简单,但是它受一套相当复杂的规则支配。

尽管在其最基本的层面,百家乐有两个玩家:庄家和闲家,并且每人发两张牌,牌的点数加起来计算出获胜的手牌。

任何总点数为10或以上的手牌都除以10,所以 9 + 6 不是 15,而是 5,而 3 + 4 = 7 的手牌确实会胜过它。

在庄家是否应该拿第三张牌的情况下,情况变得复杂起来。闲家只能在两张牌的点数总和小于六点时拿一张牌,但庄家是否拿牌只能根据闲家的初始手牌、闲家拿的牌以及庄家的手牌点数来决定。规则如下:

  1. 如果闲家没有拿牌,庄家在 0–5 点时拿牌,否则停牌。

  2. 如果闲家拿了一张 2 或 3,且庄家的总点数为 0–4,则庄家拿牌。

  3. 如果闲家拿了一张 4 或 5,且庄家的总点数为 0–5,则庄家拿牌。

  4. 如果闲家拿了一张 6 或 7,且庄家的总点数为 0–6,则庄家拿牌。

  5. 如果闲家拿了一张 8,且庄家的总点数为 0–2,则庄家拿牌。

  6. 如果闲家拿了一张 9、10、人头牌或 A,且庄家的总点数为 0–3,则庄家拿牌。

在所有上述未详细说明的情况下,庄家不能拿牌,百家乐手牌将结束,结果可能是闲家赢、庄家赢或égalité,即平局。

正如您所看到的,这是一套规则,显然只有计算机程序员才会喜欢,因此它看起来非常适合我们朝这个方向扩展 baccarat.sh 游戏。

脚本继续

上个月的百家乐游戏考虑了所有因素,直到但不包括庄家拿第三张牌,以及上面详细说明的所有复杂规则。

按原样运行,这是一个典型的序列

$ sh baccarat.sh 

Welcome to Baccarat. You can choose to either 
stake the player or dealer to win this game. 
Remember, face cards are worthless and all point values
are modulo 10, with '9' the best possible hand value. 
We're using Punto Banco rules with this simulation, 
if you're already an expert...

** Player was dealt: 3 of Hearts, 10 of Clubs (hand value = 3)
** Dealer was dealt: 4 of Clubs, 10 of Spades (hand value = 4)

Player takes a card: 6 of Hearts (hand value = 12)

** Banker play rules yet to come...game ends inconclusively.

正如您所看到的,我没有捕获这些规则,而只是有一个“即将推出”的占位符。可以把它看作是,嗯,目前还处于早期 alpha 阶段。

实际上,它还处于 alpha 阶段,以至于上面的序列中显示了一个错误。您能看到它吗?闲家的手牌点数怎么可能是 12 呢?

幸运的是,很容易看出问题所在

playerhandvalue=$(( $playerhandvalue + 
    $handvalue ))

这完全是错误的。因为上面这行代码将所有三张闲家的牌都传递给了 handValue 函数,所以这里只需要更简单的代码

playerhandvalue=$handvalue

呼。很容易修复。现在,我们到哪里了?

我们需要容易确定的一个事情是闲家是否拿了牌。这可以通过实际测试闲家手牌中的牌数来完成,但我只是创建了一个新变量 playerDrewCard,在初始发牌时将其设置为零,如果闲家再拿一张牌,则将其翻转为一。

现在,第一个规则可以这样捕获

if [ $playerDrewCard -eq 0 ] ; then
  if [ $bankerhandvalue -lt 6 ] ; then
    # Banker draws a card
    banker[$nextbankercard]=${newdeck[$nextcard]}

    handValue ${banker[1]} ${banker[2]}
      ${banker[3]}
    bankerhandvalue=$handvalue

    echo -n "Banker takes a card: "
    showCard ${banker[$nextbankercard]}
    echo "$cardname (hand value = 
      $bankerhandvalue)"
  fi
else

请注意,如果闲家拿了牌且庄家的手牌价值为六点或更多,则没有 else 子句,并且正确地,在确定最终游戏获胜者之前没有其他操作。

然而,底部的 else 是我们进入以下情况的入口:庄家和闲家都没有 8 或 9(这已经在游戏中捕获),并且闲家拿了另一张牌。现在,这只是一组条件语句。

为了让事情变得容易,让我们手头掌握闲家拿的牌的点数

pdcRank=$(( ${player[3]} % 13 ))

不幸的是,尽管 test 的手册页表明您可以使用括号在逻辑上将复杂的测试分组,但务实的现实表明,它的可移植性远不如我们希望的那么好,因此,我们将把每个规则分解为两个 if 语句,而不是一个漂亮的 (A 或 B) 且 C 语句,就像这样

if [ $pdcRank -eq 2 -o $pdcRank -eq 3 ] ; then
  if [ $bankerhandvalue -lt 5 ]; then

在这种情况下,我们正在测试闲家拿的牌(第 3 张牌),并测试庄家的手牌是否低于某个值。如果两者都为真,我们就有条件 #2,如上所述。

现在,只需按顺序排列这些测试,即可构建 百家乐庄家闲家所需的所有规则。

在其所有疯狂嵌套的 if 语句的荣耀中

if [ $pdcRank -eq 2 -o $pdcRank -eq 3 ] ; then
    if [ $bankerhandvalue -lt 5 ]; then
      dealBanker;
    fi
  elif [ $pdcRank -eq 4 -o $pdcRank -eq 5 ] ; then
    if [ $bankerhandvalue -lt 6 ] ; then
      dealBanker;
    fi
  elif [ $pdcRank -eq 6 -o $pdcRank -eq 7 ] ; then
    if [ $bankerhandvalue -lt 7 ] ; then
      dealBanker;
    fi
  elif [ $pdcRank -eq 8 -a $bankerhandvalue -lt 3 ]
  then
    dealBanker;
  elif [ $pdcRank -eq 9 -o $pdcRank -eq 0 ] ; then
    if [ $bankerhandvalue -lt 4 ] ; then
      dealBanker;
    fi
  fi

最后,我们可以在我们方便的 Linux 机器上玩百家乐

> sh baccarat.sh 

Welcome to Baccarat. You can choose to either stake 
the player or banker to win this game. Remember, face 
cards are worthless and all point values are modulo 10, 
with '9' the best possible hand value. We're using Punto
Banco rules with this simulation, if you're already an expert...

** Player was dealt: 6 of Clubs, 8 of Hearts (hand value = 4)
** Banker was dealt: King of Spades, Ace of Hearts (hand value = 1)

Player takes a card: 9 of Hearts (hand value = 3)
Banker takes a card: 5 of Clubs (hand value = 6)

Play is complete. Banker wins

当然,现在您可以运行数百万次,并计算庄家赢与闲家赢与平局情况的几率,并在下次您在法国南部时成为一个冷静、精于计算的赌徒。有帮助,不是吗?

baccarat.sh 脚本可在Linux杂志 FTP 站点上找到:ftp.linuxjournal.com/pub/lj/listings/issue161/9780.tgz

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

加载 Disqus 评论