You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python开发:双9多米诺骨牌抽7张双牌的概率计算需求

双9多米诺骨牌手牌概率计算解决方法

一、先明确双9多米诺牌组结构

  • 双牌(两端数字相同):共10张,分别为0/0、1/1、…、9/9
  • 非双牌(两端数字不同):共45张(从0到9中选两个不同数字的组合,即C(10,2)=45)
  • 总牌数:10+45=55张
  • 游戏规则:4名玩家各抽10张,剩余15张留作牌堆

二、方法1:数学公式计算(精确概率)

计算逻辑

要计算自身10张手牌恰好包含7张双牌的概率,等价于从55张牌中选10张,其中7张为双牌、3张为非双牌的组合数,除以所有可能的10张手牌组合数:
[
P = \frac{\binom{10}{7} \times \binom{45}{3}}{\binom{55}{10}}
]
如果需要计算至少7张双牌的概率,则需累加恰好7、8、9、10张双牌的情况:
[
P = \frac{\binom{10}{7}\binom{45}{3} + \binom{10}{8}\binom{45}{2} + \binom{10}{9}\binom{45}{1} + \binom{10}{10}\binom{45}{0}}{\binom{55}{10}}
]

Python代码实现

import math

# 双牌、非双牌、总牌数
double_tiles = 10
non_double_tiles = 45
total_tiles = double_tiles + non_double_tiles

# 计算恰好7张双牌的概率
favorable_exact = math.comb(double_tiles, 7) * math.comb(non_double_tiles, 3)
total_combinations = math.comb(total_tiles, 10)
prob_exact_7 = favorable_exact / total_combinations

# 计算至少7张双牌的概率
favorable_at_least = (
    math.comb(double_tiles,7)*math.comb(non_double_tiles,3) +
    math.comb(double_tiles,8)*math.comb(non_double_tiles,2) +
    math.comb(double_tiles,9)*math.comb(non_double_tiles,1) +
    math.comb(double_tiles,10)*math.comb(non_double_tiles,0)
)
prob_at_least_7 = favorable_at_least / total_combinations

print(f"恰好7张双牌的概率: {prob_exact_7:.6f} ({prob_exact_7*100:.2f}%)")
print(f"至少7张双牌的概率: {prob_at_least_7:.6f} ({prob_at_least_7*100:.2f}%)")

三、方法2:蒙特卡洛模拟(通过大量试验估算概率)

这种方法完全模拟实际发牌流程,能直观解决你困惑的“其他玩家抽牌”问题——通过重复大量游戏试验,统计符合条件的次数来估算概率。

实现步骤

  1. 构建完整的多米诺牌组
  2. 重复大量试验(比如100万次):
    • 打乱牌组
    • 分给4个玩家各10张
    • 检查自己(第1个玩家)的手牌中双牌数量是否符合要求
  3. 用符合条件的次数除以总试验次数得到概率

Python代码实现

import random

def build_domino_deck():
    """构建双9多米诺牌组,每张牌用元组表示,如(0,0)、(0,1)"""
    deck = []
    # 添加双牌
    for num in range(10):
        deck.append((num, num))
    # 添加非双牌
    for i in range(10):
        for j in range(i+1, 10):
            deck.append((i, j))
    return deck

def count_double_tiles(hand):
    """统计手牌中双牌的数量"""
    return sum(1 for tile in hand if tile[0] == tile[1])

def simulate_one_game():
    """模拟一次游戏,返回自己手牌的双牌数量"""
    deck = build_domino_deck()
    random.shuffle(deck)
    # 发牌:4个玩家各10张
    player_hands = [deck[i*10 : (i+1)*10] for i in range(4)]
    # 自己是第0个玩家
    return count_double_tiles(player_hands[0])

# 运行模拟
total_trials = 1000000
success_exact_7 = 0
success_at_least_7 = 0

for _ in range(total_trials):
    double_count = simulate_one_game()
    if double_count == 7:
        success_exact_7 += 1
    if double_count >= 7:
        success_at_least_7 += 1

# 计算概率
prob_exact_7 = success_exact_7 / total_trials
prob_at_least_7 = success_at_least_7 / total_trials

print(f"模拟结果:恰好7张双牌的概率: {prob_exact_7:.6f} ({prob_exact_7*100:.2f}%)")
print(f"模拟结果:至少7张双牌的概率: {prob_at_least_7:.6f} ({prob_at_least_7*100:.2f}%)")

四、对你原有代码的修改说明

你之前的代码基于扑克牌结构,适配多米诺场景需要调整以下几点:

  1. 无需复杂的Card类,用元组就能简洁表示多米诺骨牌
  2. 构建牌组时要区分双牌和非双牌,抛弃扑克牌的花色、点数逻辑
  3. 模拟发牌时直接打乱牌组后切片分配,避免重复随机选牌的问题

内容的提问来源于stack exchange,提问作者user23443175

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 10:29:51