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:蒙特卡洛模拟(通过大量试验估算概率)
这种方法完全模拟实际发牌流程,能直观解决你困惑的“其他玩家抽牌”问题——通过重复大量游戏试验,统计符合条件的次数来估算概率。
实现步骤
- 构建完整的多米诺牌组
- 重复大量试验(比如100万次):
- 打乱牌组
- 分给4个玩家各10张
- 检查自己(第1个玩家)的手牌中双牌数量是否符合要求
- 用符合条件的次数除以总试验次数得到概率
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}%)")
四、对你原有代码的修改说明
你之前的代码基于扑克牌结构,适配多米诺场景需要调整以下几点:
- 无需复杂的
Card类,用元组就能简洁表示多米诺骨牌 - 构建牌组时要区分双牌和非双牌,抛弃扑克牌的花色、点数逻辑
- 模拟发牌时直接打乱牌组后切片分配,避免重复随机选牌的问题
内容的提问来源于stack exchange,提问作者user23443175
相关产品推荐
相关产品推荐

