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

Python扑克手牌评分报错排查与FastAPI集成实现技术问询

手牌评估错误排查与FastAPI集成方案

一、错误根源

报错TypeError: 'Hand' object is not iterable的核心原因:

  • Evaluator.get_rank方法中直接遍历传入的Hand实例,但Hand类未实现迭代器协议(未定义__iter__方法),Python无法识别如何遍历这个自定义对象。
  • 实际卡牌数据存储在Hand类内部的self.hand列表中,直接遍历Hand实例而非其内部列表会触发迭代错误。

二、代码修复

1. 让Hand类支持迭代(推荐方案)

给Hand类添加__iter__方法,使其可以被直接遍历,代码更简洁直观:

class Hand(Deck):
    def __init__(self):
        super().__init__()
        self.hand = []

    def __str__(self):
        return " ".join([str(card) for card in self.hand])

    # 添加迭代器方法,让Hand实例可直接遍历
    def __iter__(self):
        return iter(self.hand)

    def draw_cards(self, deck, num):
        for i in range(num):
            card = deck.deal()
            if card:
                self.hand.append(card)
            else:
                return False
        return True

2. 修复Evaluator的逻辑bug

原Evaluator类存在牌型判断条件错误、顺子逻辑漏洞等问题,以下是修复后的完整版本:

class Evaluator:
    @staticmethod
    def is_cards_in_sequence(ranks):
        # 将牌面转换为数值,方便顺子判断
        rank_values = {'2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9, '10':10, 
                       'J':11, 'Q':12, 'K':13, 'A':14}
        num_ranks = [rank_values[r] for r in ranks]
        sorted_ranks = sorted(num_ranks)
        
        # 普通顺子判断
        is_straight = all(sorted_ranks[i] +1 == sorted_ranks[i+1] for i in range(len(sorted_ranks)-1))
        # 特殊情况:A-2-3-4-5的小顺子
        if sorted_ranks == [2,3,4,5,14]:
            is_straight = True
        return is_straight

    @staticmethod
    def get_rank_counts(ranks):
        # 返回去重并排序后的牌面出现次数,方便牌型判断
        rank_set = set(ranks)
        counts = sorted([ranks.count(r) for r in rank_set], reverse=True)
        return counts

    def get_rank(self, hand):
        # 现在可直接遍历hand实例(因Hand实现了__iter__)
        suits = [card.suit for card in hand]
        ranks = [card.rank for card in hand]
        counts = self.get_rank_counts(ranks)
        
        if self.is_cards_in_sequence(ranks) and len(set(suits)) == 1:
            return 'Straight Flush'
        elif counts[0] ==4:
            return 'Four of a Kind'
        elif counts[0] ==3 and counts[1] ==2:
            return 'Full House'
        elif len(set(suits)) ==1:
            return 'Flush'
        elif self.is_cards_in_sequence(ranks):
            return 'Straight'
        elif counts[0] ==3:
            return 'Three of a Kind'
        elif counts[0] ==2 and counts[1] ==2:
            return 'Two Pair'
        elif counts[0] ==2:
            return 'One Pair'
        else:
            return 'High Card'

三、结合FastAPI实现发牌评估API

1. 安装依赖

先安装FastAPI和ASGI服务器:

pip install fastapi uvicorn

2. 完整API实现代码

假设你已实现基础的Deck类(包含shuffle洗牌和deal发牌方法),以下是完整API代码:

from fastapi import FastAPI
# 导入你修复后的Hand、Evaluator、Deck类

app = FastAPI(title="Poker Hand Evaluator")

@app.get("/deal-and-evaluate")
def deal_and_evaluate_hand(num_cards: int =5):
    # 初始化牌堆并洗牌
    deck = Deck()
    deck.shuffle()
    
    # 给玩家发牌
    player_hand = Hand()
    draw_success = player_hand.draw_cards(deck, num_cards)
    if not draw_success:
        return {"error": "Not enough cards in deck"}
    
    # 评估手牌等级
    evaluator = Evaluator()
    hand_rank = evaluator.get_rank(player_hand)
    
    return {
        "hand": str(player_hand),
        "rank": hand_rank
    }

3. 启动API

运行以下命令启动服务器:

uvicorn main:app --reload

访问http://localhost:8000/deal-and-evaluate即可获取发牌和评估结果,也可通过http://localhost:8000/docs查看自动生成的API文档。

内容的提问来源于stack exchange,提问作者Jean-Luc

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 22:10:24