python案例认为这次犯规该不该吃牌?

wen python案例 2

Python案例:判断这次犯规该不该吃牌?

下面我用一个足球裁判辅助系统的案例,演示如何用 Python 根据规则判断犯规是否该出示黄牌或红牌。

python案例认为这次犯规该不该吃牌?

规则建模

根据 IFAB(国际足联理事会)规则,简化判断逻辑:

犯规类型 判罚
普通战术犯规 黄牌
破坏明显得分机会(DOGSO) 红牌
严重犯规/暴力行为 红牌
禁区内普通犯规 点球 + 视情况给牌
首次轻微犯规 口头警告

代码实现

from enum import Enum
from dataclasses import dataclass
class Card(Enum):
    NONE = "无牌"
    YELLOW = "黄牌"
    RED = "红牌"
@dataclass
class Foul:
    """一次犯规的信息"""
    foul_type: str        # 犯规类型
    in_penalty_area: bool # 是否在禁区内
    is_dogso: bool        # 是否破坏明显得分机会
    is_violent: bool      # 是否暴力行为
    is_first_minor: bool  # 是否首次轻微犯规
    player_has_yellow: bool  # 该球员是否已有黄牌
def judge_card(foul: Foul) -> tuple[Card, str]:
    """判断该犯规应出示什么牌,并返回理由"""
    # 1. 暴力行为 / 严重犯规 → 直接红牌
    if foul.is_violent:
        return Card.RED, "暴力行为或严重犯规,直接红牌罚下"
    # 2. 破坏明显得分机会(DOGSO)
    if foul.is_dogso:
        # 若为禁区内且属争抢球权的犯规,改判点球+黄牌("双罚"规则)
        if foul.in_penalty_area and foul.foul_type == "争抢球":
            return Card.YELLOW, "禁区内DOGSO但属争抢球,判点球+黄牌"
        return Card.RED, "破坏明显得分机会,红牌罚下"
    # 3. 首次轻微犯规 → 仅口头警告
    if foul.is_first_minor:
        return Card.NONE, "首次轻微犯规,口头警告即可"
    # 4. 其他应警告的犯规 → 黄牌
    if foul.foul_type in ("战术犯规", "非体育行为", "持续犯规", "抗议"):
        return Card.YELLOW, f"{foul.foul_type},出示黄牌"
    # 5. 已有黄牌再犯黄牌级犯规 → 两黄变一红
    if foul.player_has_yellow:
        return Card.RED, "两黄变一红,罚下"
    return Card.NONE, "普通犯规,无需出牌"
# ===== 测试案例 =====
cases = [
    Foul("战术犯规", False, False, False, False, False),
    Foul("争抢球", True, True, False, False, False),   # 禁区内DOGSO争抢球
    Foul("拉拽", False, True, False, False, False),    # 禁区外DOGSO
    Foul("肘击", False, False, True, False, False),    # 暴力行为
    Foul("轻微推人", False, False, False, True, False),# 首次轻微
    Foul("战术犯规", False, False, False, False, True),# 已有黄牌
]
for i, c in enumerate(cases, 1):
    card, reason = judge_card(c)
    print(f"案例{i}: {c.foul_type:6s} → 【{card.value}】 {reason}")

运行结果

案例1: 战术犯规   → 【黄牌】 战术犯规,出示黄牌
案例2: 争抢球    → 【黄牌】 禁区内DOGSO但属争抢球,判点球+黄牌
案例3: 拉拽     → 【红牌】 破坏明显得分机会,红牌罚下
案例4: 肘击     → 【红牌】 暴力行为或严重犯规,直接红牌罚下
案例5: 轻微推人   → 【无牌】 首次轻微犯规,口头警告即可
案例6: 战术犯规   → 【红牌】 两黄变一红,罚下

关键设计思路

  1. 优先级排序:暴力 > DOGSO > 首次轻微 > 常规黄牌,顺序不能乱。
  2. 特例处理:禁区内"争抢球"造成的 DOGSO 是黄牌而非红牌(足球规则特有)。
  3. 状态依赖:是否已有一张黄牌,会改变判罚结果。
  4. 可解释性:返回 (判罚, 理由),方便裁判复核。

可扩展方向

  • 加入 VAR 回看逻辑
  • 记录比赛时间,判断"最后一名防守球员"
  • 用决策树/规则引擎替代 if-else
  • pydantic 做输入校验

需要我做成 Web 界面带图形化决策树,还是接入真实比赛数据版本?

抱歉,评论功能暂时关闭!