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

如何在Python Match/Case中同时测试多条件?21点程序案例排查

问题:Python Match/Case 多条件匹配失效(21点程序)

我知道可以用|作为"或"逻辑分隔测试用例,但当前场景更复杂:我有4个布尔相关变量,对应真值表的16种状态。我给21点程序写的动作测试代码里,所有case都没触发,代码如下:

for x in range(10):
    myHandTotal = myHand.getTotal()   #获取当前手牌的总点数
    isSoft = myHand.isSoft            #判断手牌是否为软牌(至少有一张A计为11点)
    hardAction = at.getHardAction(myHand, dealer) #根据硬牌策略表获取Hit或Stand动作
    softAction = at.getSoftAction(myHand, dealer) #根据软牌策略表获取Hit或Stand动作
    print("Total: ", myHandTotal, " - isSoft: ", isSoft, " - getHardAction: ", hardAction, " - getSoftAction: ", softAction)
    match (myHandTotal < 21, isSoft, hardAction, softAction):
        case [True, True, "Stand", "Hit" | True, True, "Hit", "Hit"]:   #若为软牌且软牌策略表要求Hit
            myHand.draw1(deck)
            print("Should Hit")
            continue
        case [True, False, "Hit", "Hit" | True, False, "Hit", "Stand"]:  #若为硬牌且硬牌策略表要求Hit
            myHand.draw1(deck)
            print("Should Hit")
            continue
        case [False, True, "Stand", "Hit" | False, True, "Hit", "Hit" | False, False, "Hit", "Hit" | False, False, "Hit", "Stand" | False, True, "Stand", "Stand" | False, False, "Stand", "Stand" | False, True, "Hit", "Stand" | False, False, "Stand", "Hit"]:
            break #爆牌(bust)
        case [True, True, "Stand", "Stand" | True, True, "Hit", "Stand"]: #若手牌点数小于21且软牌策略表要求Stand
            break
        case [True, False, "Stand", "Stand" | True, False, "Stand", "Hit"]: #若手牌点数小于21且硬牌策略表要求Stand
            break
解决方案

你的代码核心问题是Match/Case中"或"逻辑的语法使用错误:Python模式匹配里,|只能用来分隔完整的匹配模式,不能在单个列表/元组模式内部直接拼接多组条件。

修正步骤

1. 拆分"或"条件为独立完整模式

把每个需要"或"的完整四元组用|分隔,而不是混在一个列表里。比如原来的软牌Hit条件,要拆成两个独立的元组模式:

case (True, True, "Stand", "Hit") | (True, True, "Hit", "Hit"):

2. 简化爆牌逻辑

爆牌只需要判断第一个变量myHandTotal < 21为False,后面三个变量可以用通配符_匹配任意值,不用枚举所有8种情况,大幅简化代码。

3. 统一匹配模式类型

你用(...)定义了匹配目标(元组),case里用元组()更贴合语法,避免和列表混淆(虽然Python支持列表匹配,但元组更对应)。

修正后的完整代码

for x in range(10):
    myHandTotal = myHand.getTotal()   #获取当前手牌的总点数
    isSoft = myHand.isSoft            #判断手牌是否为软牌(至少有一张A计为11点)
    hardAction = at.getHardAction(myHand, dealer) #根据硬牌策略表获取Hit或Stand动作
    softAction = at.getSoftAction(myHand, dealer) #根据软牌策略表获取Hit或Stand动作
    print("Total: ", myHandTotal, " - isSoft: ", isSoft, " - getHardAction: ", hardAction, " - getSoftAction: ", softAction)
    match (myHandTotal < 21, isSoft, hardAction, softAction):
        # 软牌且软牌策略要求Hit的两种情况
        case (True, True, "Stand", "Hit") | (True, True, "Hit", "Hit"):
            myHand.draw1(deck)
            print("Should Hit")
            continue
        # 硬牌且硬牌策略要求Hit的两种情况
        case (True, False, "Hit", "Hit") | (True, False, "Hit", "Stand"):
            myHand.draw1(deck)
            print("Should Hit")
            continue
        # 爆牌:总点数>=21,其余条件任意
        case (False, _, _, _):
            break #爆牌(bust)
        # 软牌且软牌策略要求Stand的两种情况
        case (True, True, "Stand", "Stand") | (True, True, "Hit", "Stand"):
            break
        # 硬牌且硬牌策略要求Stand的两种情况
        case (True, False, "Stand", "Stand") | (True, False, "Stand", "Hit"):
            break

额外说明

  • 通配符_在模式匹配中表示匹配任意值,适合用来忽略不需要判断的变量。
  • 每个case的逻辑要保持单一明确,避免把多个无关条件混在一起,方便后续维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 09:16:00