【诏安扑克牌玩法 —— 宝】庄家(宝官)一定会赢吗?

宝的玩法介绍

这是一种简单、不需要技术仅靠运气的扑克牌玩法。

开始前先在牌组中取出大小王,使用剩余的 52 张牌。庄家(闽南语为宝官)从自己开始,依次(通常为逆时针)给每个玩家发 1 张牌直至每个人手里有 2 张牌。然后每一个闲家分别与庄家比较手牌、计算输赢的筹码。比较方法如下:

如果两张牌一样,则称为牌。宝牌比非宝牌大。其中宝A最大,并且赢得的筹码为底注的 10 倍接下来依次为宝K、宝Q、宝J,并且赢得的筹码为底注的 6 倍最后依次为宝10到宝2,并且赢得的筹码为底注的 5 倍

如果两张牌不一样,则为非宝牌。此时先需要计算点数。点数的计算方法为两张牌的大小的和对 10 取余。例如 13 和 8 的点数为 (13 + 8) % 10 = 1 。最大的点数为 9 ,并且赢得的筹码为底注的 4 倍。接下来为 8 ,并且赢得的筹码为底注的 3 倍。接下来为 7 ,并且赢得的筹码为底注的 2 倍。最后依次为 6、5、4、3、2、1、0,赢得的筹码仅为底注。

如果遇到庄家和闲家手牌一样大的时候,若均为 0 点则庄家赢,否则算和(即都不输不赢)。

以上是最为常见的玩法,其他玩法规定的翻倍数量可能与此不一致(如7点和8点均只赢得底注的两倍),但是比较大小的方式都是一致的。

关于洗牌

虽然 numpy 有自带的洗牌算法,但是为了确保模拟的真实性,我设计了接近于真实洗牌方式的算法。

首先将场上的废(旧)牌随机打乱后置于牌组的最下方。

再将牌组分为两半,依次从两个子牌组中取一张牌置于新牌组的最下方,组成新的牌组。

最后从新牌组的中间随机抽取一定的牌置于新牌组的最上方,重复若干次。

实验步骤

自变量为参与的玩家数总局数

对于每一种情况,进行 10000 次的模拟。最后统计出庄家赢的概率以及庄家平均输赢情况、至多输多少筹码等数据。

底注为 1

详情可以阅读最后的源代码。

实验结果

我将原始数据中庄家(宝官)赢的概率汇总成下表。可以很明显地看出,随着玩家数以及总局数的增加,庄家(宝官)赢得概率也在增加

实验结果统计表

需要注意的是,从原始数据中也可以观察出,虽然随着两个自变量的增加庄家(宝官)赢得概率也在增加,但 最大输钱数也在增加

原始数据

当玩家数为3且局数为60时,经过10000次模拟,庄赢的平均概率为73.34%、平均输赢23.3433、最多输112.0.

当玩家数为4且局数为60时,经过10000次模拟,庄赢的平均概率为74.89%、平均输赢35.5615、最多输157.0.

当玩家数为5且局数为60时,经过10000次模拟,庄赢的平均概率为75.67%、平均输赢47.3386、最多输209.0.

当玩家数为6且局数为60时,经过10000次模拟,庄赢的平均概率为75.76%、平均输赢58.8061、最多输265.0.

当玩家数为7且局数为60时,经过10000次模拟,庄赢的平均概率为76.94%、平均输赢70.632、最多输260.0.

当玩家数为8且局数为60时,经过10000次模拟,庄赢的平均概率为77.53%、平均输赢84.0324、最多输339.0.

当玩家数为9且局数为60时,经过10000次模拟,庄赢的平均概率为76.82%、平均输赢94.7196、最多输334.0.

当玩家数为10且局数为60时,经过10000次模拟,庄赢的平均概率为77.83%、平均输赢109.4082、最多输400.0.

当玩家数为3且局数为120时,经过10000次模拟,庄赢的平均概率为81.8%、平均输赢47.9537、最多输141.0.

当玩家数为4且局数为120时,经过10000次模拟,庄赢的平均概率为83.45%、平均输赢71.8813、最多输210.0.

当玩家数为5且局数为120时,经过10000次模拟,庄赢的平均概率为84.28999999999999%、平均输赢96.2556、最多输235.0.

当玩家数为6且局数为120时,经过10000次模拟,庄赢的平均概率为84.97%、平均输赢119.3891、最多输394.0.

当玩家数为7且局数为120时,经过10000次模拟,庄赢的平均概率为85.34%、平均输赢142.3758、最多输354.0.

当玩家数为8且局数为120时,经过10000次模拟,庄赢的平均概率为85.7%、平均输赢169.3407、最多输361.0.

当玩家数为9且局数为120时,经过10000次模拟,庄赢的平均概率为85.63%、平均输赢189.4551、最多输555.0.

当玩家数为10且局数为120时,经过10000次模拟,庄赢的平均概率为85.37%、平均输赢212.9877、最多输526.0.

当玩家数为3且局数为180时,经过10000次模拟,庄赢的平均概率为87.21%、平均输赢72.2576、最多输147.0.

当玩家数为4且局数为180时,经过10000次模拟,庄赢的平均概率为88.06%、平均输赢108.2103、最多输212.0.

当玩家数为5且局数为180时,经过10000次模拟,庄赢的平均概率为89.35%、平均输赢142.3371、最多输335.0.

当玩家数为6且局数为180时,经过10000次模拟,庄赢的平均概率为89.02%、平均输赢176.5479、最多输342.0.

当玩家数为7且局数为180时,经过10000次模拟,庄赢的平均概率为89.8%、平均输赢213.5803、最多输435.0.

当玩家数为8且局数为180时,经过10000次模拟,庄赢的平均概率为90.18%、平均输赢249.577、最多输417.0.

当玩家数为9且局数为180时,经过10000次模拟,庄赢的平均概率为90.88000000000001%、平均输赢287.5184、最多输613.0.

当玩家数为10且局数为180时,经过10000次模拟,庄赢的平均概率为90.52%、平均输赢318.8327、最多输568.0.

当玩家数为3且局数为240时,经过10000次模拟,庄赢的平均概率为89.72%、平均输赢94.3631、最多输176.0.

当玩家数为4且局数为240时,经过10000次模拟,庄赢的平均概率为91.83%、平均输赢146.1417、最多输237.0.

当玩家数为5且局数为240时,经过10000次模拟,庄赢的平均概率为91.79%、平均输赢188.042、最多输265.0.

当玩家数为6且局数为240时,经过10000次模拟,庄赢的平均概率为92.75%、平均输赢236.2983、最多输367.0.

当玩家数为7且局数为240时,经过10000次模拟,庄赢的平均概率为93.41000000000001%、平均输赢287.2637、最多输445.0.

当玩家数为8且局数为240时,经过10000次模拟,庄赢的平均概率为93.08999999999999%、平均输赢331.8281、最多输431.0.

当玩家数为9且局数为240时,经过10000次模拟,庄赢的平均概率为93.95%、平均输赢384.8663、最多输527.0.

当玩家数为10且局数为240时,经过10000次模拟,庄赢的平均概率为93.42%、平均输赢425.7611、最多输686.0.

当玩家数为3且局数为300时,经过10000次模拟,庄赢的平均概率为92.25%、平均输赢119.3373、最多输182.0.

当玩家数为4且局数为300时,经过10000次模拟,庄赢的平均概率为93.95%、平均输赢177.6401、最多输223.0.

当玩家数为5且局数为300时,经过10000次模拟,庄赢的平均概率为94.33%、平均输赢237.6228、最多输342.0.

当玩家数为6且局数为300时,经过10000次模拟,庄赢的平均概率为95.37%、平均输赢298.3355、最多输358.0.

当玩家数为7且局数为300时,经过10000次模拟,庄赢的平均概率为95.46%、平均输赢359.8397、最多输431.0.

当玩家数为8且局数为300时,经过10000次模拟,庄赢的平均概率为95.82000000000001%、平均输赢419.1998、最多输562.0.

当玩家数为9且局数为300时,经过10000次模拟,庄赢的平均概率为95.6%、平均输赢475.8426、最多输528.0.

当玩家数为10且局数为300时,经过10000次模拟,庄赢的平均概率为95.43%、平均输赢535.6997、最多输644.0.

当玩家数为3且局数为360时,经过10000次模拟,庄赢的平均概率为94.58%、平均输赢143.9054、最多输281.0.

当玩家数为4且局数为360时,经过10000次模拟,庄赢的平均概率为95.06%、平均输赢214.5873、最多输249.0.

当玩家数为5且局数为360时,经过10000次模拟,庄赢的平均概率为96.13000000000001%、平均输赢284.2925、最多输316.0.

当玩家数为6且局数为360时,经过10000次模拟,庄赢的平均概率为96.61999999999999%、平均输赢358.3319、最多输431.0.

当玩家数为7且局数为360时,经过10000次模拟,庄赢的平均概率为96.76%、平均输赢428.8452、最多输508.0.

当玩家数为8且局数为360时,经过10000次模拟,庄赢的平均概率为96.76%、平均输赢497.4775、最多输457.0.

当玩家数为9且局数为360时,经过10000次模拟,庄赢的平均概率为96.93%、平均输赢573.3052、最多输509.0.

当玩家数为10且局数为360时,经过10000次模拟,庄赢的平均概率为96.91%、平均输赢640.4309、最多输534.0.

当玩家数为3且局数为420时,经过10000次模拟,庄赢的平均概率为95.37%、平均输赢167.5455、最多输206.0.

当玩家数为4且局数为420时,经过10000次模拟,庄赢的平均概率为96.67999999999999%、平均输赢251.7031、最多输328.0.

当玩家数为5且局数为420时,经过10000次模拟,庄赢的平均概率为97.07000000000001%、平均输赢336.361、最多输332.0.

当玩家数为6且局数为420时,经过10000次模拟,庄赢的平均概率为97.28%、平均输赢418.8386、最多输375.0.

当玩家数为7且局数为420时,经过10000次模拟,庄赢的平均概率为97.6%、平均输赢497.3985、最多输430.0.

当玩家数为8且局数为420时,经过10000次模拟,庄赢的平均概率为98.04%、平均输赢584.6059、最多输471.0.

当玩家数为9且局数为420时,经过10000次模拟,庄赢的平均概率为97.97%、平均输赢669.745、最多输637.0.

当玩家数为10且局数为420时,经过10000次模拟,庄赢的平均概率为97.98%、平均输赢752.0614、最多输575.0.

当玩家数为3且局数为480时,经过10000次模拟,庄赢的平均概率为96.63000000000001%、平均输赢192.2562、最多输225.0.

当玩家数为4且局数为480时,经过10000次模拟,庄赢的平均概率为97.42%、平均输赢289.2354、最多输280.0.

当玩家数为5且局数为480时,经过10000次模拟,庄赢的平均概率为97.83%、平均输赢382.8224、最多输304.0.

当玩家数为6且局数为480时,经过10000次模拟,庄赢的平均概率为98.2%、平均输赢476.5121、最多输411.0.

当玩家数为7且局数为480时,经过10000次模拟,庄赢的平均概率为98.26%、平均输赢570.4368、最多输427.0.

当玩家数为8且局数为480时,经过10000次模拟,庄赢的平均概率为98.55000000000001%、平均输赢664.7697、最多输641.0.

当玩家数为9且局数为480时,经过10000次模拟,庄赢的平均概率为98.46000000000001%、平均输赢763.2813、最多输470.0.

当玩家数为10且局数为480时,经过10000次模拟,庄赢的平均概率为98.47%、平均输赢857.6433、最多输635.0.

当玩家数为3且局数为540时,经过10000次模拟,庄赢的平均概率为97.08%、平均输赢215.498、最多输190.0.

当玩家数为4且局数为540时,经过10000次模拟,庄赢的平均概率为98.06%、平均输赢322.5979、最多输289.0.

当玩家数为5且局数为540时,经过10000次模拟,庄赢的平均概率为98.42%、平均输赢430.8459、最多输307.0.

当玩家数为6且局数为540时,经过10000次模拟,庄赢的平均概率为98.53%、平均输赢535.6848、最多输375.0.

当玩家数为7且局数为540时,经过10000次模拟,庄赢的平均概率为98.67%、平均输赢641.1271、最多输451.0.

当玩家数为8且局数为540时,经过10000次模拟,庄赢的平均概率为98.78%、平均输赢751.9006、最多输374.0.

当玩家数为9且局数为540时,经过10000次模拟,庄赢的平均概率为98.83%、平均输赢855.2707、最多输569.0.

当玩家数为10且局数为540时,经过10000次模拟,庄赢的平均概率为98.86%、平均输赢964.0856、最多输659.0.

源代码(Python)

import numpy as np
import random


bao = [0, 10, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6]
nBao = [1, 1, 1, 1, 1, 1, 1, 2, 3, 4]


def judge(a, b):
    # 如果 a 是宝
    if a[0] == a[1]:
        # 如果 b 不是宝
        if b[0] != b[1]:
            return bao[a[0].astype(np.int16)]
        # 如果 b 是宝
        else:
            # 如果 a 是宝 1 (最大)
            if a[0] == 1:
                if b[0] == 1:
                    return 0
                else:
                    return bao[a[0].astype(np.int16)]
            # 如果 a 不是宝 1
            else:
                if b[0] == 1:
                    return -bao[b[0].astype(np.int16)]
                else:
                    if a[0] > b[0]:
                        return bao[a[0].astype(np.int16)]
                    elif a[0] < b[0]:
                        return -bao[b[0].astype(np.int16)]
                    else:
                        return 0
    # 如果 a 不是宝
    else:
        # 如果 b 是宝
        if b[0] == b[1]:
            return -bao[b[0].astype(np.int16)]
        # 如果 a 和 b 都不是宝,就要比点数了
        else:
            an = int((a[0] + a[1]) % 10)
            bn = int((b[0] + b[1]) % 10)
            if an == 0 & bn == 0:
                return nBao[an]
            elif an > bn:
                return nBao[an]
            elif bn > an:
                return -nBao[bn]
            else:
                return 0


class Poker:
    poker_num = 52
    pokers = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
                       1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
                       1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
                       1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13])

    def __init__(self):
        # 随机打乱牌组,模拟一副旧的扑克牌
        np.random.shuffle(self.pokers)

        # 洗牌
        self.shuffle()

    # 虽然 numpy 有自带的洗牌算法,但是为了模拟真实场景我还是采取自己编写的洗牌算法
    def shuffle(self):
        # 把扑克牌组分成两半,依次取两部分的第一张牌组成新的扑克牌组
        new_pokers = np.zeros((52,))
        for i in range(0, self.poker_num, 2):
            new_pokers[i] = self.pokers[int(i / 2)]
            new_pokers[i + 1] = self.pokers[int((i + self.poker_num) / 2)]
        self.pokers = new_pokers
        # 随机从扑克牌组中间抽取一定的牌放到牌堆的最上方,重复1~4次
        for time in range(random.randint(1, 4)):
            new_pokers = np.zeros((52,))
            # 将第 begin 张牌以下的 num 张牌放到最上面(不包括第 begin 张牌)
            begin = random.randint(1, self.poker_num - 1)
            num = random.randint(1, self.poker_num - begin)
            new_pokers[0:num] = self.pokers[begin:begin + num]
            new_pokers[num:num + begin] = self.pokers[0:begin]
            new_pokers[num + begin:self.poker_num] = self.pokers[begin + num:self.poker_num]
            self.pokers = new_pokers

    # 发牌(顺便把废牌重新组合后放到排扑克牌堆最下面)
    # (int) n 为玩家数
    def deal(self, n):
        old_pokers = []
        hs = []
        # 发牌
        for i in range(n):
            hs += [[self.pokers[i], self.pokers[i + n]]]
            old_pokers += [self.pokers[i]]
            old_pokers += [self.pokers[i + n]]
        # 处理废牌
        np.random.shuffle(old_pokers)
        new_pokers = []
        new_pokers[0:self.poker_num - 2 * n] = self.pokers[2 * n:self.poker_num]
        new_pokers[self.poker_num - 2 * n:self.poker_num] = old_pokers
        self.pokers = new_pokers
        return hs

    def print(self):
        print(self.pokers)


if __name__ == '__main__':
    test_num = 10000
    for game_num in range(60, 600, 60):
        for player_num in range(3, 11):
            host_win_num = 0
            host_win_money = 0.
            host_most_loss = 0.
            for tn in range(test_num):
                poker = Poker()
                players = np.zeros(player_num)
                for gn in range(game_num):
                    poker.shuffle()
                    hands = poker.deal(player_num)
                    for i in range(1, player_num):
                        money = judge(hands[0], hands[i])
                        players[0] += money
                        players[i] -= money
                # print(f'第{tn}次模拟的输赢情况如下:', players)
                if players[0] >= 0:
                    host_win_num += 1
                if players[0] < host_most_loss:
                    host_most_loss = players[0]
                host_win_money += players[0]
            print(f'当玩家数为{player_num}且局数为{game_num}时,经过{test_num}次模拟,庄赢的平均概率为{host_win_num/test_num*100}%、平均输赢{host_win_money/test_num}、最多输{-host_most_loss}.')

要想不输,惟有不赌!

以上结果均为概率统计!

要想不输,惟有不赌!

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值