package taurus.util;

import com.game.Global;

import java.util.*;

public class HongZhongSuanFaTest {
    private static final int HONG_ZHONG = 412;

    public int drawnCards;
    // 权重配置 -
    private static final int WEIGHT_COMPLETED_MELD = 70;   // 已完成的面子权重更高
    private static final int WEIGHT_PAIR = 60;            // 对子权重提高
    private static final int WEIGHT_POTENTIAL_TRIPLET = 50;
    private static final int WEIGHT_POTENTIAL_PAIR = 40;
    private static final int WEIGHT_CLOSE_ADJACENT = 60;  // 相邻牌更重要
    private static final int WEIGHT_FAR_ADJACENT = 25;    // 远邻牌权重微调
    private static final int WEIGHT_MIDDLE_RANK = 25;     // 中张牌权重提高
    private static final int PENALTY_EDGE_RANK = 15;      // 边张惩罚增加
    private static final int PENALTY_ISOLATED = 40;       // 孤张惩罚增加

    // 牌局阶段枚举 -
    private enum GamePhase {
        EARLY,    // 早期（1-5巡）
        MIDDLE,   // 中期（6-12巡）
        LATE      // 后期（13巡以后）
    }

    // 牌型策略枚举 - 真实玩家通常会考虑的策略方向
    private enum StrategyType {
        ATTACK,   // 进攻型（追求快速胡牌）
        BALANCED, // 平衡型（兼顾进攻和防守）
        DEFEND    // 防守型（避免点炮）
    }

    // 特殊牌型枚举 -
    private enum SpecialPattern {
        NONE,
        QING_YI_SE,       // 清一色
        DUAN_YAO_JIU,     // 断幺九
        QUAN_YAO_JIU,     // 全幺九
        LONG_QI_DUI,      // 龙七对
        HONG_ZHONG_MANY   // 多红中
    }



    /**
     * 主算法入口：在摸牌后、打牌前进行全面分析，确定最优出牌策略
     * 核心流程：摸牌分析 -> 听牌检测 -> 策略制定 -> 出牌选择
     */
    public String outCardSuanFa(List<Integer> cardInhand, int card) {
        long startTime = System.currentTimeMillis();

        List<Integer> handCards = new ArrayList<>(cardInhand);
        handCards.sort(Integer::compareTo);
        logInfo("排序后机器人手牌: " + handCards);

        // 关键步骤1：摸牌分析 - 检测是否已经听牌或可听牌
        boolean isTingAfterDraw = analyzeDrawCard(cardInhand,drawnCards);

        System.out.println("是否听牌: " + isTingAfterDraw);
        // 分析手牌结构 - 获取完整的手牌分析结果
        HandAnalysis analysis = analyzeHand(handCards);



        // 分析当前牌局阶段
        GamePhase currentPhase = determineGamePhase(handCards);
        logInfo("当前牌局阶段: " + currentPhase);

        // 确定策略类型，考虑是否听牌状态
        StrategyType strategy = determineStrategy(analysis, currentPhase);
        logInfo("采用策略: " + strategy);

        // 分析是否有特殊牌型潜力
        SpecialPattern specialPattern = analyzeSpecialPatternPotential(analysis);
        logInfo("特殊牌型潜力: " + specialPattern);

        // 分析红中利用方式
        analyzeHongZhongUsage(analysis);

        // 输出手牌分析详情
//        logInfo("红中数量: " + analysis.hongZhongCount);
//        logInfo("红中利用建议: " + analysis.hongZhongSuggestions);
//        logInfo("按花色分组的计数: " + analysis.cardCounts);
//        logInfo("已完成的刻子、顺子: " + analysis.completedMelds);
//        logInfo("对子: " + analysis.pairs);
//        logInfo("孤张牌: " + analysis.isolatedCards);
//        logInfo("每张牌的有用程度: " + analysis.cardUsefulness);
//        logInfo("听牌状态: " + analysis.isTingPai);

        // 计算出牌优先级 - 综合考虑各种因素
        Map<Integer, Integer> discardPriority = calculateDiscardPriority(
                handCards, analysis, currentPhase, strategy, specialPattern);

        // 分析打出哪张牌可以听牌（如果还没听牌）
        Map<Integer, Set<Integer>> discardToTingOptions = findDiscardToTing(handCards);

        //选择要打出的牌 - 优先选择可以打出后听牌的牌
        int cardToDiscard = selectCardToDiscard(
                handCards, discardPriority, analysis, currentPhase, strategy, discardToTingOptions);
        logInfo("最终打出牌: " + cardToDiscard);

        // 执行时间统计
        long endTime = System.currentTimeMillis();
//        logInfo("算法执行时间: " + (endTime - startTime) + "ms");
        System.out.println("听的牌----"+analysis.tingCards);
        if (isTingAfterDraw && drawnCards!=412 ) {
            System.out.println("1111");
            return String.valueOf(drawnCards);
        }


        return String.valueOf(cardToDiscard);
    }

    private static class HandAnalysis {
        int hongZhongCount = 0;
        Map<Integer, Integer> cardCounts = new HashMap<>();
        List<List<Integer>> completedMelds = new ArrayList<>();
        List<Integer> pairs = new ArrayList<>();
        List<Integer> isolatedCards = new ArrayList<>();
        Map<Integer, Integer> cardUsefulness = new HashMap<>();
        Map<Integer, List<Integer>> cardsBySuit = new HashMap<>();
        List<String> hongZhongSuggestions = new ArrayList<>();
        boolean isTingPai = false;
        Set<Integer> tingCards = new HashSet<>(); // 听的牌
        int meldCount = 0; // 面子数量
        int shantenCount = Integer.MAX_VALUE; // 向听数
        int pairCount = 0; // 对子数量
        boolean hasLongQiDuiPotential = false; // 是否有龙七对潜力
        Set<Integer> usedInMelds = new HashSet<>(); // 用于面子的牌
        Set<Integer> usedInPairs = new HashSet<>(); // 用于对子的牌
        List<Integer> remainingCards = new ArrayList<>(); // 剩余需要分析的牌
        int hongZhongContributedTingCards = 0; // 红中贡献的听牌数量
        int lastDrawnCard = 0; // 最后摸的牌
    }

    // 改进的手牌分析 - 更全面的手牌评估
    private HandAnalysis analyzeHand(List<Integer> handCards) {
        HandAnalysis analysis = new HandAnalysis();

        // 分离红中和普通牌，并按花色分组
        for (int card : handCards) {
            if (card == HONG_ZHONG) {
                analysis.hongZhongCount++;
            } else {
                int suit = card / 100;
                analysis.cardCounts.put(card, analysis.cardCounts.getOrDefault(card, 0) + 1);
                analysis.cardsBySuit.computeIfAbsent(suit, k -> new ArrayList<>()).add(card);
            }
        }

        // 分析基本牌型
        analyzeCardPatterns(analysis);

//        analyzeTingPaiStatus(handCards,analysis);
        // 检查是否听牌
        checkTingPai(analysis);

        // 查找听的牌
        findTingCards(analysis);

        // 执行备用的听牌分析，确保全面检查
        performBackupTingAnalysis(analysis);

        // 分析红中对听牌的影响
        analyzeHongZhongImpactOnTingCards(analysis);


        // 计算向听数（更准确的牌型评估）
        calculateShantenCount(analysis);

        // 听牌检测 - 使用优化的听牌检测方法
        checkTingPaiOptimized(analysis);

        // 计算面子数量
        analysis.meldCount = analysis.completedMelds.size();
        analysis.pairCount = analysis.pairs.size();

        // 检查是否有龙七对潜力
        checkLongQiDuiPotential(analysis);

        return analysis;
    }

    // 改进的红中分析 -
    private void analyzeHongZhongUsage(HandAnalysis analysis) {
        if (analysis.hongZhongCount == 0) return;

        // 1. 红中作为杠牌的价值
        if (analysis.hongZhongCount >= 3) {
            analysis.hongZhongSuggestions.add("红中可开杠，增加番数");
        }

        // 2. 红中补面子的分析
        for (Map.Entry<Integer, List<Integer>> entry : analysis.cardsBySuit.entrySet()) {
            List<Integer> suitCards = new ArrayList<>(entry.getValue());
            suitCards.sort(Integer::compareTo);

            // 检查刻子潜力
            Map<Integer, Integer> countMap = new HashMap<>();
            for (int card : suitCards) {
                countMap.put(card, countMap.getOrDefault(card, 0) + 1);
            }

            for (Map.Entry<Integer, Integer> cardEntry : countMap.entrySet()) {
                int card = cardEntry.getKey();
                int count = cardEntry.getValue();

                if (count == 2 && analysis.hongZhongCount >= 1) {
                    analysis.hongZhongSuggestions.add("红中补刻子: " + card);
                } else if (count == 1 && analysis.hongZhongCount >= 2) {
                    analysis.hongZhongSuggestions.add("红中补刻子: " + card + "(需2红中)");
                }
            }

            // 检查顺子潜力（更自然的顺子分析）
            analyzeSequenceWithHongZhong(suitCards, analysis);
        }

        // 3. 红中作为万能牌的灵活运用
        if (analysis.hongZhongCount >= 2) {
            analysis.hongZhongSuggestions.add("多红中可灵活变换牌型，根据情况决定用途");
        }
    }

    // 更自然的顺子+红中组合分析
    private void analyzeSequenceWithHongZhong(List<Integer> suitCards, HandAnalysis analysis) {
        if (suitCards.size() < 2) return;

        // 排序以方便分析
        Collections.sort(suitCards);

        // 查找可能的顺子缺口
        for (int i = 0; i < suitCards.size() - 1; i++) {
            int current = suitCards.get(i) % 100;
            int next = suitCards.get(i + 1) % 100;

            // 检查是否有隔一张的牌
            if (next - current == 2) {
                analysis.hongZhongSuggestions.add("红中补顺子缺口: " + suitCards.get(i) + "+红中+" + suitCards.get(i + 1));
            }
            // 检查是否有连续的两张牌
            else if (next - current == 1) {
                // 可以向前补
                if (current > 1) {
                    analysis.hongZhongSuggestions.add("红中向前补顺子: 红中+" + suitCards.get(i) + "+" + suitCards.get(i + 1));
                }
                // 可以向后补
                if (next < 9) {
                    analysis.hongZhongSuggestions.add("红中向后补顺子: " + suitCards.get(i) + "+" + suitCards.get(i + 1) + "+红中");
                }
            }
        }
    }

    // 改进的牌型分析 - 更清晰地分离可组成牌和剩余牌
    private void analyzeCardPatterns(HandAnalysis analysis) {
        Set<Integer> usedInMelds = new HashSet<>();
        Set<Integer> usedInPairs = new HashSet<>();

        for (List<Integer> suitCards : new ArrayList<>(analysis.cardsBySuit.values())) {
            // 数据验证
            if (suitCards == null || suitCards.isEmpty()) {
                continue;
            }

            List<Integer> cardsCopy = new ArrayList<>(suitCards);

            // 移除空值或异常值
            cardsCopy.removeIf(Objects::isNull);

            try {
                Collections.sort(cardsCopy);
            } catch (StackOverflowError e) {
                // 使用备用排序方法
                cardsCopy.sort((a, b) -> {
                    if (a == null && b == null) return 0;
                    if (a == null) return -1;
                    if (b == null) return 1;
                    return Integer.compare(a, b);
                });
            }

            findSequencesOptimized(cardsCopy, analysis, usedInMelds);
            findTripletsOptimized(cardsCopy, analysis, usedInMelds);
            findPairsOptimized(cardsCopy, analysis, usedInPairs);
            analysis.isolatedCards.addAll(cardsCopy);
        }
    }


    // 优化的刻子查找 - 记录使用的牌
    private void findTripletsOptimized(List<Integer> cards, HandAnalysis analysis, Set<Integer> usedInMelds) {
        Map<Integer, Integer> countMap = new HashMap<>();
        for (int card : cards) {
            countMap.put(card, countMap.getOrDefault(card, 0) + 1);
        }

        List<Integer> toRemove = new ArrayList<>();
        for (Map.Entry<Integer, Integer> entry : countMap.entrySet()) {
            int card = entry.getKey();
            int count = entry.getValue();

            if (count >= 3) {
                analysis.completedMelds.add(Arrays.asList(card, card, card));
                // 移除三张牌
                toRemove.add(card);
                toRemove.add(card);
                toRemove.add(card);
                // 记录使用的牌
                usedInMelds.add(card);
            }
        }

        // 从原列表中移除找到的刻子
        for (int card : toRemove) {
            cards.remove(Integer.valueOf(card));
        }
    }

    // 优化的顺子查找 - 记录使用的牌
    private void findSequencesOptimized(List<Integer> cards, HandAnalysis analysis, Set<Integer> usedInMelds) {
        if (cards.size() < 3) return;

        // 获取花色和点数信息
        List<Integer> ranks = new ArrayList<>();
        int suit = cards.get(0) / 100;
        for (int card : cards) {
            ranks.add(card % 100);
        }
        Collections.sort(ranks);

        // 创建点数计数映射
        Map<Integer, Integer> rankCount = new HashMap<>();
        for (int rank : ranks) {
            rankCount.put(rank, rankCount.getOrDefault(rank, 0) + 1);
        }

        // 寻找顺子（更自然的查找方式）
        for (int start = 1; start <= 7; start++) {
            int mid = start + 1;
            int end = start + 2;

            if (rankCount.getOrDefault(start, 0) > 0 &&
                    rankCount.getOrDefault(mid, 0) > 0 &&
                    rankCount.getOrDefault(end, 0) > 0) {

                // 找到一个顺子
                int card1 = suit * 100 + start;
                int card2 = suit * 100 + mid;
                int card3 = suit * 100 + end;

                analysis.completedMelds.add(Arrays.asList(card1, card2, card3));

                // 从原始牌列表中移除这三张牌
                cards.remove(Integer.valueOf(card1));
                cards.remove(Integer.valueOf(card2));
                cards.remove(Integer.valueOf(card3));

                // 记录使用的牌
                usedInMelds.add(card1);
                usedInMelds.add(card2);
                usedInMelds.add(card3);

                // 递归查找更多顺子
                findSequencesOptimized(cards, analysis, usedInMelds);
                return;
            }
        }
    }

    // 优化的对子查找 - 记录使用的牌
    private void findPairsOptimized(List<Integer> cards, HandAnalysis analysis, Set<Integer> usedInPairs) {
        Map<Integer, Integer> countMap = new HashMap<>();
        for (int card : cards) {
            countMap.put(card, countMap.getOrDefault(card, 0) + 1);
        }

        List<Integer> toRemove = new ArrayList<>();

        for (Map.Entry<Integer, Integer> entry : countMap.entrySet()) {
            int card = entry.getKey();
            int count = entry.getValue();

            if (count >= 2 && !toRemove.contains(card)) {
                analysis.pairs.add(card);
                toRemove.add(card);
                toRemove.add(card);
                // 记录使用的牌
                usedInPairs.add(card);
            }
        }

        // 从原列表中移除找到的对子
        for (int card : toRemove) {
            cards.remove(Integer.valueOf(card));
        }
    }

    // 分析剩余牌 - 识别需要重点考虑的牌
    private void analyzeRemainingCards(HandAnalysis analysis) {
        List<Integer> remainingCards = new ArrayList<>();

        // 遍历所有手牌，找出未被用于面子或对子的牌
        for (Map.Entry<Integer, List<Integer>> entry : analysis.cardsBySuit.entrySet()) {
            for (int card : entry.getValue()) {
                // 如果牌没有被用于面子或对子，则视为剩余牌
                if (!analysis.usedInMelds.contains(card) && !analysis.usedInPairs.contains(card)) {
                    remainingCards.add(card);
                }
            }
        }

        // 保存剩余牌
        analysis.remainingCards = remainingCards;
    }

    // 调整剩余牌的价值 - 更细致的评估
    private int adjustRemainingCardValue(int card, HandAnalysis analysis) {
        int value = analysis.cardUsefulness.getOrDefault(card, 0);

        // 已经用于面子或对子的牌价值更高，避免破坏已有结构
        if (analysis.usedInMelds.contains(card)) {
            value += WEIGHT_COMPLETED_MELD;
        }
        if (analysis.usedInPairs.contains(card)) {
            value += WEIGHT_PAIR;
        }

        return value;
    }

    // 计算向听数 - 更准确的牌型评估
    private void calculateShantenCount(HandAnalysis analysis) {
        // 简化版向听数计算
        int totalCards = analysis.hongZhongCount;
        for (List<Integer> suitCards : analysis.cardsBySuit.values()) {
            totalCards += suitCards.size();
        }

        // 基础向听数 = 理想牌型的面子数 - 当前面子数
        int idealMelds = (totalCards + analysis.hongZhongCount) / 3;
        analysis.shantenCount = Math.max(0, idealMelds - analysis.meldCount);
    }

    // 检查七对潜力
    private void checkLongQiDuiPotential(HandAnalysis analysis) {

        // 七对需要至少5个对子加上红中
        if (analysis.pairCount >= 5 || analysis.hongZhongCount >= 2) {
            analysis.hasLongQiDuiPotential = true;
            if (analysis.pairCount >=4 && analysis.hongZhongCount>=2){
                analysis.isTingPai=true;
            }
            if (analysis.pairCount>=6){
                analysis.isTingPai=true;
            }
        }


    }

    /**
     * 高级听牌检测 - 精确判断手牌是否已经听牌
     * 在摸牌后分析的核心方法之一
     *
     * @param analysis 手牌分析结果对象
     */
    private void checkTingPai(HandAnalysis analysis) {
//        logInfo("开始检测听牌状态...");
        analysis.tingCards.clear(); // 清空之前可能存在的听牌

        // 检查基本听牌条件：牌数是否符合标准
        int totalCards = analysis.hongZhongCount;
        for (List<Integer> suitCards : analysis.cardsBySuit.values()) {
            totalCards += suitCards.size();
        }



        // 检查向听数，如果向听数大于1，则不可能听牌
        if (analysis.shantenCount > 1) {
//            logInfo("向听数大于1，不可能听牌");
            analysis.isTingPai = false;
            return;
        }

        // 标准麻将听牌条件：
        // 1. 标准型听牌：一对将牌 + 四面子，且向听数为0
        // 2. 七对子型听牌：有龙七对潜力且牌数达到听牌要求
        boolean standardTing = (totalCards - 2) % 3 == 0 && analysis.shantenCount == 0;
        boolean sevenPairsTing = analysis.hasLongQiDuiPotential && totalCards >= 12;

        // 特殊情况：如果有红中，需要考虑红中作为万能牌的影响
        if (analysis.hongZhongCount > 0) {
            // 红中可以代替任何牌，所以需要更灵活的判断
            // 检查是否通过红中可以形成听牌状态
            boolean canTingWithHongZhong = canFormTingWithHongZhong(analysis);
            analysis.isTingPai = standardTing || sevenPairsTing || canTingWithHongZhong;
        } else {
            analysis.isTingPai = standardTing || sevenPairsTing;
        }

        // 使用优化版算法找出具体的听牌组
        long startTime = System.currentTimeMillis();
        findTingCardsOptimized(analysis);
        long endTime = System.currentTimeMillis();



        if (!analysis.tingCards.isEmpty()) {
            analysis.isTingPai = true;
//            logInfo("优化版听牌检测完成: 听牌数量=" + analysis.tingCards.size() +
//                    ", 耗时=" + (endTime - startTime) + "ms");
        } else if (analysis.isTingPai) {
            // 如果逻辑判断为听牌但未找到具体听牌组，使用原始方法作为后备
//            logInfo("尝试使用原始方法查找听牌组...");
//            findTingCards(analysis);
//            logInfo("原始方法找到听牌数量: " + analysis.tingCards.size());
        }

//        logInfo("最终听牌状态: " + analysis.isTingPai + ", 听牌数量: " + analysis.tingCards.size());
    }

    /**
     * 优化版的听牌检测方法
     * 1. 提前过滤明显不可能听牌的情况
     * 2. 优化牌数统计和计算逻辑
     * 3. 使用预计算的向听数快速判断
     * 4. 优化红中对听牌状态的影响分析
     */
    private void checkTingPaiOptimized(HandAnalysis analysis) {
        // 极早期快速退出 - 向听数>1的情况下不可能听牌
        if (analysis.shantenCount > 1) {
            analysis.isTingPai = false;
            analysis.tingCards.clear();
            return;
        }

        // 清空听牌集合，准备新的分析
        analysis.tingCards.clear();

        // 预计算总牌数 - 使用提前计算的值或快速计算
        int totalCards = analysis.hongZhongCount;
        for (List<Integer> suitCards : analysis.cardsBySuit.values()) {
            totalCards += suitCards.size();
        }

        // 特殊牌型快速检测 - 提前计算是否需要检查七对子
        boolean checkSevenPairs = analysis.hasLongQiDuiPotential && totalCards >= 12;

        // 优化的红中听牌分析 - 先检查红中情况，可能避免后续计算
        boolean hasHongZhongTing = false;
        if (analysis.hongZhongCount > 0) {
            if (analysis.shantenCount == 0) {
                hasHongZhongTing = true;
            } else if (analysis.shantenCount == 1) {
                // 只有在向听数为1时才进行复杂计算
                hasHongZhongTing = canFormTingWithHongZhongOptimized(analysis, totalCards);
            }
        }

        // 只有在有潜在听牌可能时才执行完整的听牌检测
        boolean needFullAnalysis = hasHongZhongTing || checkSevenPairs || analysis.shantenCount == 0;

        if (needFullAnalysis) {
            // 执行高效的听牌检测算法
            findTingCardsOptimized(analysis);

            // 设置最终听牌状态
            analysis.isTingPai = !analysis.tingCards.isEmpty();
        } else {
            analysis.isTingPai = false;
        }
    }

    /**
     * 优化版红中听牌判断
     * 1. 使用位掩码和预计算值
     * 2. 简化计算逻辑
     * 3. 避免不必要的循环和集合操作
     */
    private boolean canFormTingWithHongZhongOptimized(HandAnalysis analysis, int totalCards) {
        // 快速判断：如果红中数量足够多，可以替代任何缺失的牌
        if (analysis.hongZhongCount >= 3) {
            return true;
        }

        // 计算红中作为面子的最大可能数量
        int maxMeldsFromHongZhong = analysis.hongZhongCount / 3;
        int remainingHongZhong = analysis.hongZhongCount % 3;

        // 计算理论上可以形成的面子总数
        int totalPossibleMelds = analysis.meldCount + maxMeldsFromHongZhong;

        // 需要的面子数和对子数
        int neededMelds = Math.max(0, 4 - totalPossibleMelds);
        int neededPairs = analysis.pairCount > 0 ? 0 : 1;

        // 检查是否可以通过剩余红中满足需求
        // 每张红中可以作为一个面子的一部分或一个对子的一部分
        return (neededMelds + neededPairs) <= remainingHongZhong + 1;
    }

    /**
     * 检查是否通过红中可以形成听牌状态
     * @param analysis 手牌分析结果对象
     * @return 是否可以通过红中形成听牌
     */
    private boolean canFormTingWithHongZhong(HandAnalysis analysis) {
        // 计算去掉红中后的牌数
        int nonHongZhongCount = 0;
        for (List<Integer> suitCards : analysis.cardsBySuit.values()) {
            nonHongZhongCount += suitCards.size();
        }

        // 计算红中可以替代的面子数
        int hongZhongAsMelds = analysis.hongZhongCount / 3;
        int remainingHongZhong = analysis.hongZhongCount % 3;

        // 计算总面子数（包括红中形成的面子）
        int totalMeldCount = analysis.meldCount + hongZhongAsMelds;

        // 检查是否接近听牌（剩余红中可以作为对子或填补顺子）
        boolean nearTing = false;
        int neededMelds = 4 - totalMeldCount;
        int neededPairs = 1 - (analysis.pairCount > 0 ? 1 : 0);

        // 如果需要的面子数和对子数之和小于等于剩余红中，那么可以形成听牌
        if (neededMelds + neededPairs <= remainingHongZhong) {
            nearTing = true;
        }

        // 如果向听数很小，也认为接近听牌
        if (analysis.shantenCount <= 1) {
            nearTing = true;
        }

        return nearTing;
    }

    /**
     * 统一日志输出方法
     */
    private void logInfo(String message) {
        System.out.println(message);
    }

    /**
     * 高级听牌组分析 - 精确找出听的牌
     * @param analysis 手牌分析结果对象
     */
    /**
     * 优化版听牌组分析 - 使用预计算和优化的数据结构提高性能
     * @param analysis 手牌分析结果对象
     */
    private void findTingCardsOptimized(HandAnalysis analysis) {
        // 提前检查 - 如果手牌太少或结构明显不合理，可以提前返回
        int totalCards = analysis.hongZhongCount;
        for (List<Integer> suitCards : analysis.cardsBySuit.values()) {
            totalCards += suitCards.size();
        }

        // 牌数过少，不可能形成有效的听牌
        if (totalCards < 13) {
            return;
        }

        // 预先为所有花色创建计数映射，避免重复计算
        // 更精确地预估容量，避免过度分配
        final int expectedSuitCount = analysis.cardsBySuit.size();
        final int expectedRankCount = 9; // 麻将中每个花色最多9个不同的牌值
        Map<Integer, Map<Integer, Integer>> suitToRankCounts = new HashMap<>(expectedSuitCount);

        // 优化循环，同时构建计数映射
        for (Map.Entry<Integer, List<Integer>> suitEntry : analysis.cardsBySuit.entrySet()) {
            int suit = suitEntry.getKey();
            List<Integer> suitCards = suitEntry.getValue();

            // 仅在非空花色上创建映射
            if (suitCards.isEmpty()) {
                continue;
            }

            // 预先分配更准确的容量
            Map<Integer, Integer> countByRank = new HashMap<>(Math.min(expectedRankCount, suitCards.size()));

            // 快速计数算法
            for (int card : suitCards) {
                int rank = card % 100;
                // 直接使用getOrDefault来增加计数
                countByRank.put(rank, countByRank.getOrDefault(rank, 0) + 1);
            }

            suitToRankCounts.put(suit, countByRank);
        }

        // 优化分析流程 - 先分析主要花色，再考虑特殊情况
        for (Map.Entry<Integer, Map<Integer, Integer>> entry : suitToRankCounts.entrySet()) {
            // 只有当花色中存在牌时才进行分析
            if (entry.getValue().isEmpty()) {
                continue;
            }

            analyzeSuitTingCardsOptimized(entry.getKey(), entry.getValue(), analysis);

            // 如果已经找到了足够多的听牌，可以考虑提前终止分析
            // 这里可以根据实际需求调整提前终止的条件
            if (analysis.tingCards.size() > 10) { // 假设找到超过10张听牌就足够了
                break;
            }
        }

        // 仅在必要时分析红中影响 - 红中数量大于0且当前听牌较少时
        if (analysis.hongZhongCount > 0 && analysis.tingCards.size() < 5) {
            analyzeHongZhongImpactOnTingCardsOptimized(analysis, suitToRankCounts);
        }

        // 仅在确实需要时执行兜底分析 - 听牌为空且向听数<=1
        if (analysis.tingCards.isEmpty() && analysis.shantenCount <= 1) {
            performBackupTingAnalysisOptimized(analysis, suitToRankCounts);
        }
    }

    /**
     * 优化版花色听牌分析 - 使用数组而非HashMap进行快速查询
     */
    private void analyzeSuitTingCardsOptimized(int suit, Map<Integer, Integer> countByRank, HandAnalysis analysis) {
        // 将Map转换为数组，提高查询速度
        int[] rankCounts = new int[10]; // 索引0不使用，1-9对应牌点
        for (Map.Entry<Integer, Integer> entry : countByRank.entrySet()) {
            rankCounts[entry.getKey()] = entry.getValue();
        }

        // 分析两面听
        for (int i = 1; i <= 7; i++) {
            if (rankCounts[i] > 0 && rankCounts[i + 2] > 0) {
                int potentialCard = suit * 100 + (i + 1);
                analysis.tingCards.add(potentialCard);
            }
        }

        // 分析边张听
        if (rankCounts[1] > 0 && rankCounts[2] > 0) {
            analysis.tingCards.add(suit * 100 + 3);
        }
        if (rankCounts[8] > 0 && rankCounts[9] > 0) {
            analysis.tingCards.add(suit * 100 + 7);
        }

        // 分析坎张听
        for (int i = 3; i <= 7; i++) {
            if (rankCounts[i - 1] > 0 && rankCounts[i + 1] > 0) {
                analysis.tingCards.add(suit * 100 + i);
            }
        }

        // 分析对子听和刻子听
        for (int i = 1; i <= 9; i++) {
            int count = rankCounts[i];
            if (count == 2 || count == 3) {
                analysis.tingCards.add(suit * 100 + i);
            }
        }
    }

    /**
     * 优化版红中影响分析 - 使用预计算的花色计数避免重复计算
     */
    private void analyzeHongZhongImpactOnTingCardsOptimized(HandAnalysis analysis, Map<Integer, Map<Integer, Integer>> suitToRankCounts) {
        Set<Integer> additionalTingCards = new HashSet<>();
        int hongZhongCount = analysis.hongZhongCount;

        for (Map.Entry<Integer, Map<Integer, Integer>> suitEntry : suitToRankCounts.entrySet()) {
            int suit = suitEntry.getKey();
            Map<Integer, Integer> countByRank = suitEntry.getValue();

            // 将Map转换为数组，提高查询速度
            int[] rankCounts = new int[10];
            for (Map.Entry<Integer, Integer> entry : countByRank.entrySet()) {
                rankCounts[entry.getKey()] = entry.getValue();
            }

            // 分析红中作为对子的情况
            if (hongZhongCount >= 1) {
                for (int i = 1; i <= 9; i++) {
                    if (rankCounts[i] == 1) {
                        additionalTingCards.add(suit * 100 + i);
                    }
                }

                // 分析红中填补顺子缺口的情况
                for (int i = 1; i <= 7; i++) {
                    if (rankCounts[i] > 0 && rankCounts[i + 2] > 0) {
                        additionalTingCards.add(suit * 100 + (i + 1));
                    }
                }
            }

            // 当有2个或更多红中时
            if (hongZhongCount >= 2) {
                for (int i = 1; i <= 9; i++) {
                    additionalTingCards.add(suit * 100 + i);
                }
            }
        }

        // 添加额外听牌并记录贡献数量
        if (!additionalTingCards.isEmpty()) {
            analysis.tingCards.addAll(additionalTingCards);
            analysis.hongZhongContributedTingCards = additionalTingCards.size();
        }
    }

    /**
     * 优化版兜底听牌分析 - 仅在必要时执行，避免不必要的计算
     */
    private void performBackupTingAnalysisOptimized(HandAnalysis analysis, Map<Integer, Map<Integer, Integer>> suitToRankCounts) {
        // 分析接近听牌的情况
        Set<Integer> potentialTingCards = new HashSet<>();

        for (Map.Entry<Integer, Map<Integer, Integer>> suitEntry : suitToRankCounts.entrySet()) {
            int suit = suitEntry.getKey();
            Map<Integer, Integer> countByRank = suitEntry.getValue();

            // 将Map转换为数组
            int[] rankCounts = new int[10];
            for (Map.Entry<Integer, Integer> entry : countByRank.entrySet()) {
                rankCounts[entry.getKey()] = entry.getValue();
            }

            // 分析可能形成对子的牌
            for (int i = 1; i <= 9; i++) {
                if (rankCounts[i] == 1) {
                    potentialTingCards.add(suit * 100 + i);
                }
            }

            // 分析可能形成顺子的牌
            for (int i = 1; i <= 7; i++) {
                if (rankCounts[i] > 0 && rankCounts[i + 1] > 0) {
                    potentialTingCards.add(suit * 100 + (i + 2));
                }
                if (rankCounts[i] > 0 && rankCounts[i + 2] > 0) {
                    potentialTingCards.add(suit * 100 + (i + 1));
                }
                if (rankCounts[i + 1] > 0 && rankCounts[i + 2] > 0) {
                    potentialTingCards.add(suit * 100 + i);
                }
            }
        }

        // 只在找到潜在听牌时才添加
        if (!potentialTingCards.isEmpty()) {
            analysis.tingCards.addAll(potentialTingCards);
        }
    }

    private void findTingCards(HandAnalysis analysis) {
//        logInfo("开始精确分析听牌组...");

        // 针对不同花色分别分析听牌组
        for (Map.Entry<Integer, List<Integer>> suitEntry : analysis.cardsBySuit.entrySet()) {
            int suit = suitEntry.getKey();
            List<Integer> suitCards = suitEntry.getValue();

            // 统计该花色中每种牌的数量
            Map<Integer, Integer> countByRank = new HashMap<>();
            for (int card : suitCards) {
                int rank = card % 100;
                countByRank.put(rank, countByRank.getOrDefault(rank, 0) + 1);
            }

            // 分析该花色中可能的听牌
            analyzeSuitTingCards(suit, countByRank, analysis);
        }

        // 考虑红中对听牌的影响
        if (analysis.hongZhongCount > 0) {
            analyzeHongZhongImpactOnTingCards(analysis);
        }

        // 如果听牌组为空，进行兜底分析
        if (analysis.tingCards.isEmpty()) {
            performBackupTingAnalysis(analysis);
        }

//        logInfo("精确分析完成，听牌组: " + analysis.tingCards);
    }

    /**
     * 分析单个花色的听牌组
     */
    private void analyzeSuitTingCards(int suit, Map<Integer, Integer> countByRank, HandAnalysis analysis) {
        // 分析两面听
        for (int i = 1; i <= 7; i++) {
            if (countByRank.getOrDefault(i, 0) > 0 && countByRank.getOrDefault(i + 2, 0) > 0) {
                int potentialCard = suit * 100 + (i + 1);
                analysis.tingCards.add(potentialCard);
//                logInfo("两面听: " + potentialCard + " (由 " + (suit * 100 + i) + " 和 " + (suit * 100 + (i + 2)) + " 组成)");
            }
        }

        // 分析边张听
        if (countByRank.getOrDefault(1, 0) > 0 && countByRank.getOrDefault(2, 0) > 0) {
            int potentialCard = suit * 100 + 3;
            analysis.tingCards.add(potentialCard);
//            logInfo("边张听: " + potentialCard + " (由 " + (suit * 100 + 1) + " 和 " + (suit * 100 + 2) + " 组成)");
        }
        if (countByRank.getOrDefault(8, 0) > 0 && countByRank.getOrDefault(9, 0) > 0) {
            int potentialCard = suit * 100 + 7;
            analysis.tingCards.add(potentialCard);
//            logInfo("边张听: " + potentialCard + " (由 " + (suit * 100 + 8) + " 和 " + (suit * 100 + 9) + " 组成)");
        }

        // 分析坎张听
        for (int i = 3; i <= 7; i++) {
            if (countByRank.getOrDefault(i - 1, 0) > 0 && countByRank.getOrDefault(i + 1, 0) > 0) {
                int potentialCard = suit * 100 + i;
                analysis.tingCards.add(potentialCard);
//                logInfo("坎张听: " + potentialCard + " (由 " + (suit * 100 + (i - 1)) + " 和 " + (suit * 100 + (i + 1)) + " 组成)");
            }
        }

        // 分析对子听（将对听牌）
        for (int i = 1; i <= 9; i++) {
            if (countByRank.getOrDefault(i, 0) == 2) {
                int potentialCard = suit * 100 + i;
                analysis.tingCards.add(potentialCard);
//                logInfo("对子听: " + potentialCard + " (已有两张)");
            }
        }

        // 分析刻子听（三张听刻）
        for (int i = 1; i <= 9; i++) {
            if (countByRank.getOrDefault(i, 0) == 3) {
                int potentialCard = suit * 100 + i;
                analysis.tingCards.add(potentialCard);
//                logInfo("刻子听: " + potentialCard + " (已有三张)");
            }
        }
    }

    /**
     * 分析红中对听牌的影响 - 优化版
     * 更精确地计算红中如何帮助形成听牌
     */
    private void analyzeHongZhongImpactOnTingCards(HandAnalysis analysis) {
        // 红中作为万能牌，可以替代缺少的牌来形成听牌
        Set<Integer> additionalTingCards = new HashSet<>();
        int hongZhongCount = analysis.hongZhongCount;

        // 对于每种花色，分析红中可以带来的额外听牌
        for (Map.Entry<Integer, List<Integer>> suitEntry : analysis.cardsBySuit.entrySet()) {
            int suit = suitEntry.getKey();
            List<Integer> suitCards = suitEntry.getValue();

            // 统计该花色中每种牌的数量
            Map<Integer, Integer> countByRank = new HashMap<>();
            for (int card : suitCards) {
                int rank = card % 100;
                countByRank.put(rank, countByRank.getOrDefault(rank, 0) + 1);
            }

            // 根据红中数量计算可能的听牌
            if (hongZhongCount >= 1) {
                // 分析红中作为对子的情况
                for (int i = 1; i <= 9; i++) {
                    if (countByRank.getOrDefault(i, 0) == 1) {
                        // 已有一张，红中作为第二张形成对子，听第三张
                        int card = suit * 100 + i;
                        additionalTingCards.add(card);
//                        logInfo("红中作为对子听: " + card + " (红中+已有一张)");
                    }
                }

                // 分析红中填补顺子缺口的情况
                for (int i = 1; i <= 7; i++) {
                    int count1 = countByRank.getOrDefault(i, 0);
                    int count2 = countByRank.getOrDefault(i + 2, 0);

                    if ((count1 > 0 && count2 > 0) && (count1 + count2 + hongZhongCount >= 3)) {
                        // 可以用红中填补中间的牌形成顺子
                        int middleCard = suit * 100 + (i + 1);
                        additionalTingCards.add(middleCard);
//                        logInfo("红中填补顺子听: " + middleCard + " (红中+" + (suit * 100 + i) + "+" + (suit * 100 + (i + 2)) + ")");
                    }
                }

                // 当有2个或更多红中时，可以形成更多听牌
                if (hongZhongCount >= 2) {
                    // 红中作为两张形成对子，听任何第三张
                    for (int i = 1; i <= 9; i++) {
                        int card = suit * 100 + i;
                        additionalTingCards.add(card);
                    }
                }
            }
        }

        // 去重并将额外的听牌组添加到总听牌组中
        Set<Integer> uniqueAdditionalTingCards = new HashSet<>(additionalTingCards);
        analysis.tingCards.addAll(uniqueAdditionalTingCards);
        if (!uniqueAdditionalTingCards.isEmpty()) {
//            logInfo("红中带来的额外听牌: " + uniqueAdditionalTingCards);
            // 记录红中带来的听牌数量
            analysis.hongZhongContributedTingCards = uniqueAdditionalTingCards.size();
        }
    }

    /**
     * 兜底听牌分析 - 优化版
     * 当主要分析方法无法找到听牌组时使用，提供更智能的兜底分析
     */
    private void performBackupTingAnalysis(HandAnalysis analysis) {
//        logInfo("执行兜底听牌分析...");

        // 1. 检查接近听牌的情况
        if (analysis.shantenCount <= 1) {
            // 接近听牌时，分析可能的进张
            Set<Integer> potentialTingCards = new HashSet<>();

            // 分析每个花色中可能形成面子的牌
            for (Map.Entry<Integer, List<Integer>> suitEntry : analysis.cardsBySuit.entrySet()) {
                int suit = suitEntry.getKey();
                List<Integer> suitCards = suitEntry.getValue();

                // 统计该花色中每种牌的数量
                Map<Integer, Integer> countByRank = new HashMap<>();
                for (int card : suitCards) {
                    int rank = card % 100;
                    countByRank.put(rank, countByRank.getOrDefault(rank, 0) + 1);
                }

                // 分析可能形成对子的牌
                for (int i = 1; i <= 9; i++) {
                    if (countByRank.getOrDefault(i, 0) == 1) {
                        potentialTingCards.add(suit * 100 + i);
                    }
                }

                // 分析可能形成顺子的牌
                for (int i = 1; i <= 7; i++) {
                    if (countByRank.getOrDefault(i, 0) > 0 && countByRank.getOrDefault(i + 1, 0) > 0) {
                        potentialTingCards.add(suit * 100 + (i + 2));
                    }
                    if (countByRank.getOrDefault(i, 0) > 0 && countByRank.getOrDefault(i + 2, 0) > 0) {
                        potentialTingCards.add(suit * 100 + (i + 1));
                    }
                    if (countByRank.getOrDefault(i + 1, 0) > 0 && countByRank.getOrDefault(i + 2, 0) > 0) {
                        potentialTingCards.add(suit * 100 + i);
                    }
                }
            }

            analysis.tingCards.addAll(potentialTingCards);
//            logInfo("接近听牌兜底分析结果: " + potentialTingCards);
        }

        // 2. 如果仍然没有找到听牌，才进行简单兜底
        if (analysis.tingCards.isEmpty()) {
            // 简化兜底分析：优先考虑中张牌
            for (int suit : analysis.cardsBySuit.keySet()) {
                // 先添加中张牌
                for (int i = 3; i <= 7; i++) {
                    int potentialCard = suit * 100 + i;
                    analysis.tingCards.add(potentialCard);
                }
                // 再添加边张牌
                for (int i = 1; i <= 2; i++) {
                    int potentialCard = suit * 100 + i;
                    analysis.tingCards.add(potentialCard);
                }
                for (int i = 8; i <= 9; i++) {
                    int potentialCard = suit * 100 + i;
                    analysis.tingCards.add(potentialCard);
                }
            }

//            logInfo("简单兜底分析完成，听牌组: " + analysis.tingCards);
        }
    }

    // 确定牌局阶段
    private GamePhase determineGamePhase(List<Integer> handCards) {
        // 简化实现：根据手牌数量估计牌局阶段
        // 实际应用中应该根据已打出的牌数或游戏进度
        int remainingCards = handCards.size();
        if (remainingCards >= 13) {
            return GamePhase.EARLY;
        } else if (remainingCards >= 9) {
            return GamePhase.MIDDLE;
        } else {
            return GamePhase.LATE;
        }
    }

    // 确定策略类型
    private StrategyType determineStrategy(HandAnalysis analysis, GamePhase phase) {
        // 听牌时采取进攻策略
        if (analysis.isTingPai) {
            return StrategyType.ATTACK;
        }

        // 向听数少，进攻为主
        if (analysis.shantenCount <= 1) {
            return StrategyType.ATTACK;
        }

        // 后期防守策略
        if (phase == GamePhase.LATE) {
            return StrategyType.DEFEND;
        }

        // 中期根据向听数决定
        if (phase == GamePhase.MIDDLE) {
            return analysis.shantenCount <= 2 ? StrategyType.BALANCED : StrategyType.DEFEND;
        }

        // 早期通常是平衡型或进攻型
        return StrategyType.BALANCED;
    }

    // 分析特殊牌型潜力
    private SpecialPattern analyzeSpecialPatternPotential(HandAnalysis analysis) {
        // 检查多红中
        if (analysis.hongZhongCount >= 3) {
            return SpecialPattern.HONG_ZHONG_MANY;
        }

        // 检查清一色潜力
        if (analysis.cardsBySuit.size() == 1 && analysis.hongZhongCount <= 2) {
            return SpecialPattern.QING_YI_SE;
        }

        // 检查断幺九潜力
        boolean hasYaoJiu = false;
        for (List<Integer> suitCards : analysis.cardsBySuit.values()) {
            for (int card : suitCards) {
                int rank = card % 100;
                if (rank == 1 || rank == 9) {
                    hasYaoJiu = true;
                    break;
                }
            }
            if (hasYaoJiu) break;
        }
        if (!hasYaoJiu) {
            return SpecialPattern.DUAN_YAO_JIU;
        }

        // 检查龙七对潜力
        if (analysis.hasLongQiDuiPotential) {
            return SpecialPattern.LONG_QI_DUI;
        }

        return SpecialPattern.NONE;
    }




    // 计算刻子潜力
    private int calculateTripletPotential(int sameCardCount, int hongZhongCount) {
        if (sameCardCount == 3) {
            return WEIGHT_POTENTIAL_TRIPLET + 20; //  Already triplet
        } else if (sameCardCount == 2) {
            return WEIGHT_POTENTIAL_TRIPLET + (hongZhongCount * 15); // Pair+hongZhong can easily form triplet
        } else if (sameCardCount == 1 && hongZhongCount >= 2) {
            return 30 + (hongZhongCount * 10); // Single card+2hongZhong can form triplet
        }
        return 0;
    }

    // 计算顺子潜力
    private int calculateSequencePotential(int card, List<Integer> sameSuitCards) {
        int potential = 0;
        int suit = card / 100;
        int rank = card % 100;

        // 获取当前花色所有牌的点数
        Set<Integer> ranks = new HashSet<>();
        for (int c : sameSuitCards) {
            ranks.add(c % 100);
        }

        // 检查可能的顺子组合
        // 向前检查：x, x+1, x+2
        for (int start = Math.max(1, rank - 2); start <= Math.min(7, rank); start++) {
            int mid = start + 1;
            int end = start + 2;

            int matchCount = 0;
            if (ranks.contains(start)) matchCount++;
            if (ranks.contains(mid)) matchCount++;
            if (ranks.contains(end)) matchCount++;

            // 根据匹配数量增加潜力值
            if (matchCount == 3) {
                potential += 60; // 完整顺子
            } else if (matchCount == 2) {
                potential += 35; // 两搭子
            } else if (matchCount == 1) {
                potential += 15; // 单张
            }
        }

        // 相邻牌奖励
        if (ranks.contains(rank - 1) || ranks.contains(rank + 1)) {
            potential += WEIGHT_CLOSE_ADJACENT;
        }

        return potential;
    }

    // 计算牌张位置价值
    private int calculateRankValue(int rank) {
        int value = 0;

        // 中张牌价值更高
        if (rank >= 3 && rank <= 7) {
            value += WEIGHT_MIDDLE_RANK;
            // 金3银7特殊价值
            if (rank == 3 || rank == 7) {
                value += 10; // 更高的中张价值
            }
        } else {
            value -= PENALTY_EDGE_RANK;
        }

        return value;
    }

    // 计算出牌优先级 - 优先考虑剩余牌和牌的潜力
    private Map<Integer, Integer> calculateDiscardPriority(List<Integer> handCards,
                                                           HandAnalysis analysis,
                                                           GamePhase phase,
                                                           StrategyType strategy,
                                                           SpecialPattern specialPattern) {
        Map<Integer, Integer> priority = new HashMap<>();

        for (int card : handCards) {
            if (card == HONG_ZHONG) {
                // 红中策略根据阶段和策略调整
                int hongZhongValue = calculateHongZhongValue(analysis, phase, strategy, specialPattern);
                priority.put(card, hongZhongValue);
                continue;
            }

            // 获取基本价值
            int usefulness = analysis.cardUsefulness.getOrDefault(card, 0);
            int discardValue = usefulness;

            // 调整剩余牌的价值 - 优先从剩余牌中选择要打出的牌
            discardValue = adjustRemainingCardValue(card, analysis);

            // 根据策略调整牌的价值
            discardValue = adjustValueByStrategy(card, discardValue, analysis, strategy, phase);

            // 特殊牌型策略调整
            discardValue = adjustValueBySpecialPattern(card, discardValue, analysis, specialPattern);

            // 集成牌潜力分析到出牌优先级中
            int potentialScore = calculateCardPotentialScore(card, analysis);
            // 根据阶段调整潜力权重 - 后期更重视潜力
            int potentialWeight = (phase == GamePhase.LATE) ? 8 : 5;
            discardValue += potentialScore * potentialWeight;

            priority.put(card, discardValue);
        }

        return priority;
    }

    // 计算红中的价值
    private int calculateHongZhongValue(HandAnalysis analysis, GamePhase phase, StrategyType strategy, SpecialPattern specialPattern) {
        // 基础价值
        int value = 1000;

        // 根据数量调整
        value -= (analysis.hongZhongCount * 100);

        // 根据牌局阶段调整
        if (phase == GamePhase.LATE) {
            // 后期红中价值降低
            value -= 200;
        }

        // 多红中时的策略调整
        if (analysis.hongZhongCount >= 3 && specialPattern == SpecialPattern.HONG_ZHONG_MANY) {
            // 多红中时保留价值更高
            value += 300;
        }

        // 防守策略时可能需要保留红中
        if (strategy == StrategyType.DEFEND) {
            value += 100;
        }

        // 集成红中的潜力分析
        int potentialScore = calculateCardPotentialScore(HONG_ZHONG, analysis);
        // 由于我们已经在calculateCardPotentialScore中为红中提供了特殊处理，
        // 这里使用较低的权重来避免过度提升红中的价值
        value += potentialScore * 3; // 适度考虑潜力因素

        return Math.max(value, 200); // 红中最低价值
    }

    // 根据策略调整牌的价值
    private int adjustValueByStrategy(int card, int value, HandAnalysis analysis, StrategyType strategy, GamePhase phase) {
        // 进攻策略：重视听牌和组成面子
        if (strategy == StrategyType.ATTACK) {
            // 进攻时更重视对子
            if (analysis.pairs.contains(card)) {
                value += 30;
            }
            // 进攻时更重视顺子潜力
            if (!analysis.isolatedCards.contains(card)) {
                value += 20;
            }
        }
        // 防守策略：避免危险牌，保留安全牌
        else if (strategy == StrategyType.DEFEND) {
            // 防守时更倾向于保留孤张
            if (analysis.isolatedCards.contains(card)) {
                value += 15;
            }
            // 防守时减少对子价值
            if (analysis.pairs.contains(card)) {
                value -= 10;
            }
        }

        // 后期策略调整
        if (phase == GamePhase.LATE) {
            // 后期更倾向于保留中张
            int rank = card % 100;
            if (rank >= 3 && rank <= 7) {
                value += 10;
            }
        }

        return value;
    }

    // 根据特殊牌型调整牌的价值
    private int adjustValueBySpecialPattern(int card, int value, HandAnalysis analysis, SpecialPattern specialPattern) {
        int rank = card % 100;

        switch (specialPattern) {
            case DUAN_YAO_JIU:
                // 断幺九时，幺九牌价值降低
                if (rank == 1 || rank == 9) {
                    value -= 50;
                }
                break;
            case LONG_QI_DUI:
                // 龙七对时，对子价值提高
                if (analysis.pairs.contains(card)) {
                    value += 40;
                }
                break;
            case QING_YI_SE:
                // 清一色时，当前花色的牌价值提高
                value += 30;
                break;
        }

        return value;
    }

    // 选择要打出的牌 - 优先从剩余牌中选择，听牌时保护听牌组，红中固定不能出
    private int selectCardToDiscard(List<Integer> handCards,
                                    Map<Integer, Integer> priority,
                                    HandAnalysis analysis,
                                    GamePhase phase,
                                    StrategyType strategy,
                                    Map<Integer, Set<Integer>> discardToTingOptions) {

        logInfo("选择----"+handCards);
        // 1. 核心策略：优先考虑可以打出后听牌的牌
        if (!discardToTingOptions.isEmpty()) {
//            logInfo("【重要】发现可打出后听牌的选项，优先选择这些牌");


            // 从候选牌中过滤出可打出后听牌的牌
            List<Integer> tingCandidateCards = new ArrayList<>();
            for (int card : handCards) {
                if (discardToTingOptions.containsKey(card) && card != HONG_ZHONG) {
                    tingCandidateCards.add(card);
                }
            }

            if (!tingCandidateCards.isEmpty()) {
                // 智能排序：优先选择数量较多且听牌组较大的牌
                int bestCardToDiscard = sortTingCandidateCards(tingCandidateCards, analysis, discardToTingOptions, priority);

                logInfo("优先选择可听牌的牌: " + bestCardToDiscard + ", 听牌组: " + discardToTingOptions.get(bestCardToDiscard));
                return bestCardToDiscard;
            }
        }

//        // 2. 优先考虑孤张牌，特别是顺子中多余的牌
//        List<Integer> isolatedCandidateCards = new ArrayList<>();
        for (int card : handCards) {
            // 排除红中（固定不能出）
            if (card == HONG_ZHONG) {
                continue;
            }
            // 听牌时，排除听牌组中的牌
            if (analysis.isTingPai && analysis.tingCards.contains(card)) {
                continue;
            }
//            // 检查是否是孤张牌
//            if (analysis.isolatedCards.contains(card)) {
//                isolatedCandidateCards.add(card);
//            }
        }

        // 如果有孤张牌，优先从孤张牌中选择
        if (!analysis.isolatedCards.isEmpty()) {
//            logInfo("发现孤张牌，优先从孤张牌中选择要打出的牌: " + analysis.isolatedCards);
            // 从孤张牌中找出最低优先级的牌
            return sortCandidateCards(analysis.isolatedCards, priority, analysis, strategy, phase, discardToTingOptions);
        }


        // 新增：摸牌后特殊处理 - 检查新摸的牌是否需要优先保留
        if (analysis.lastDrawnCard != 0 && analysis.lastDrawnCard != HONG_ZHONG) {
            // 创建一个排除新摸牌的候选列表（除非新摸牌确实是最差选择）
            List<Integer> nonDrawnCandidateCards = new ArrayList<>();
            for (int card : handCards) {
                if (card != HONG_ZHONG && card != analysis.lastDrawnCard &&
                        !(analysis.isTingPai && analysis.tingCards.contains(card))) {
                    nonDrawnCandidateCards.add(card);
                }
            }

            if (!nonDrawnCandidateCards.isEmpty()) {
                // 评估新摸牌的优先级与其他牌的差距
                int drawnCardPriority = priority.getOrDefault(analysis.lastDrawnCard, 50);
                int lowestPriority = Integer.MAX_VALUE;
                for (int card : nonDrawnCandidateCards) {
                    lowestPriority = Math.min(lowestPriority, priority.getOrDefault(card, 50));
                }

                // 如果新摸牌的优先级不是明显高于其他牌，优先保留新摸牌
                if (lowestPriority < drawnCardPriority + 10) { // 设置10的阈值作为缓冲
                    logInfo("优先保留新摸的牌: " + analysis.lastDrawnCard);
                    int cardToDiscard = sortCandidateCards(nonDrawnCandidateCards, priority, analysis, strategy, phase, discardToTingOptions);
                    return cardToDiscard;
                }
            }
        }

        // 如果没有孤张牌，则从剩余牌中选择要打出的牌
        List<Integer> remainingCandidateCards = new ArrayList<>();
        for (int card : handCards) {
            // 排除红中（固定不能出）
            if (card == HONG_ZHONG) {
                continue;
            }
            // 听牌时，排除听牌组中的牌
            if (analysis.isTingPai && analysis.tingCards.contains(card)) {
                continue;
            }
            if (analysis.remainingCards.contains(card)) {
                remainingCandidateCards.add(card);
            }
        }

        // 如果有剩余牌，优先从剩余牌中选择
        if (!remainingCandidateCards.isEmpty()) {
            // 从剩余牌中找出最低优先级的牌
            return sortCandidateCards(remainingCandidateCards, priority, analysis, strategy, phase, discardToTingOptions);
        }

        // 否则从所有牌中选择，但排除听牌组中的牌和红中
        List<Integer> allCandidateCards = new ArrayList<>();
        for (int card : handCards) {
            // 排除红中（固定不能出）
            if (card == HONG_ZHONG) {
                continue;
            }
            // 排除听牌组中的牌
            if (!(analysis.isTingPai && analysis.tingCards.contains(card))) {
                allCandidateCards.add(card);
            }
        }

        // 如果所有牌都在听牌组中或全是红中（极端情况），至少保留一张非红中牌
        if (allCandidateCards.isEmpty() && !handCards.isEmpty()) {
            // 找出所有非红中且不在听牌组中的牌
            List<Integer> fallbackCards = new ArrayList<>();
            for (int card : handCards) {
                if (card != HONG_ZHONG) {
                    fallbackCards.add(card);
                }
            }

            if (!fallbackCards.isEmpty()) {
                // 选择数量最多的牌打出一张
                int maxCount = 0;
                int cardToDiscard = fallbackCards.get(0);
                for (int card : fallbackCards) {
                    int count = analysis.cardCounts.getOrDefault(card, 0);
                    if (count > maxCount) {
                        maxCount = count;
                        cardToDiscard = card;
                    }
                }
                return cardToDiscard;
            }
        }

        return sortCandidateCards(allCandidateCards, priority, analysis, strategy, phase, discardToTingOptions);
    }

    /**
     * 专门为可听牌的候选牌进行排序
     * 按照优先级：听牌组数量 > 牌的数量 > 牌的价值
     */
    private int sortTingCandidateCards(List<Integer> candidates, HandAnalysis analysis,
                                       Map<Integer, Set<Integer>> discardToTingOptions,
                                       Map<Integer, Integer> priority) {
        // 按照优先级排序：1. 听牌组数量 2. 牌的数量 3. 牌的价值
        candidates.sort((a, b) -> {
            // 1. 优先比较听牌组数量
            int tingGroupComparison = Integer.compare(
                    discardToTingOptions.get(b).size(),
                    discardToTingOptions.get(a).size()
            );
            if (tingGroupComparison != 0) {
                return tingGroupComparison;
            }

            // 2. 比较牌的数量
            int countA = analysis.cardCounts.getOrDefault(a, 0);
            int countB = analysis.cardCounts.getOrDefault(b, 0);
            int countComparison = Integer.compare(countB, countA);
            if (countComparison != 0) {
                return countComparison;
            }

            // 3. 比较牌的价值（优先级值越低越好）
            int priorityA = priority.getOrDefault(a, 0);
            int priorityB = priority.getOrDefault(b, 0);
            return Integer.compare(priorityA, priorityB);
        });

        return candidates.get(0);
    }

    // 排序候选牌 - 提取排序逻辑为单独方法，听牌时特殊处理
    private int sortCandidateCards(List<Integer> candidateCards,
                                   Map<Integer, Integer> priority,
                                   HandAnalysis analysis,
                                   StrategyType strategy,
                                   GamePhase phase,
                                   Map<Integer, Set<Integer>> discardToTingOptions) {
        // 听牌时的特殊处理：确保不会拆听牌组
        if (analysis.isTingPai) {
            // 过滤掉听牌组中的牌
            List<Integer> filteredCards = new ArrayList<>();
            for (int card : candidateCards) {
                if (!analysis.tingCards.contains(card)) {
                    filteredCards.add(card);
                }
            }
            if (!filteredCards.isEmpty()) {
                candidateCards = filteredCards;
            }
        }
//        // 找到最低优先级的牌
//        int minPriority = Integer.MAX_VALUE;
//        List<Integer> minPriorityCards = new ArrayList<>();
        //candidateCards


        // 简化的相邻牌检测逻辑
        Map<Integer, Set<Integer>> suitToValues = new HashMap<>();

// 按花色分组并记录牌值
        for (int card : candidateCards) {
            int suit = card / 100;
            int value = card % 100;
            suitToValues.computeIfAbsent(suit, k -> new HashSet<>()).add(value);
        }

        List<Integer> nonAdjacentCards = new ArrayList<>();

// 检查每个花色中的牌，只保留没有相邻关系的牌
        for (int card : candidateCards) {
            int suit = card / 100;
            int value = card % 100;
            Set<Integer> values = suitToValues.get(suit);

            // 检查这张牌是否有相邻牌（左边或右边）
            boolean hasLeftAdjacent = values.contains(value - 1);
            boolean hasRightAdjacent = values.contains(value + 1);


            if (!(hasLeftAdjacent || hasRightAdjacent)){
                nonAdjacentCards.add(card);
            }
        }

        // 简化的相邻牌检测逻辑
        Map<Integer, Set<Integer>> suitToValues1 = new HashMap<>();
        for (int card : nonAdjacentCards) {
            int suit = card / 100;
            int value = card % 100;
            suitToValues1.computeIfAbsent(suit, k -> new HashSet<>()).add(value);
        }
        List<Integer> nonAdjacentCards1 = new ArrayList<>();
        for (int card : nonAdjacentCards){
            int suit = card / 100;
            int value = card % 100;
            Set<Integer> values = suitToValues1.get(suit);
            // 2. 检查是否有卡隆牌（间隔一张）
            boolean hasLeftCardLong = values.contains(value - 2);  // 如3和5
            boolean hasRightCardLong = values.contains(value + 2); // 如5和3

            if (!(hasLeftCardLong || hasRightCardLong)){
                nonAdjacentCards1.add(card);
            }
        }


        if (!nonAdjacentCards1.isEmpty()){
            nonAdjacentCards=nonAdjacentCards1;
        }

        List<Integer> resultCards = new ArrayList<>();
        if (nonAdjacentCards.isEmpty()){
            // 如果nonAdjacentCards为空，优先找边张
            List<Integer> edgeCards = new ArrayList<>();



            for (int card : candidateCards) {
                int value = card % 100;
                // 边张：1或9（假设麻将牌值范围是1-9）
                if (value == 1 || value == 9) {
                    edgeCards.add(card);
                }
            }


            if (!edgeCards.isEmpty()) {
                // 有边张，使用边张
                nonAdjacentCards = edgeCards;
                return nonAdjacentCards.get(0);
            } else {
                // 没有边张，取下标为1的牌（第二个元素）
                if (candidateCards.size() > 1) {
                    nonAdjacentCards.add(candidateCards.get(1));
                    return nonAdjacentCards.get(0);
                } else {
                    // 如果只有一个元素，就取这个元素
                    nonAdjacentCards.add(candidateCards.get(0));
                    return nonAdjacentCards.get(0);
                }
            }
        }
        if (!nonAdjacentCards.isEmpty()){

            for (int card : nonAdjacentCards) {
                int value = card % 100;
                // 边张：1或9（假设麻将牌值范围是1-9）
                if (value == 1 || value == 9) {
                    resultCards.add(card);
                }

            }
            if (!resultCards.isEmpty()){
                return resultCards.get(0);
            }

        }

        List<Integer> resultCards1 = new ArrayList<>();
        if (resultCards.isEmpty()){
            for (int card : nonAdjacentCards) {
                int value = card % 100;


                if (value==8 || value==2){
                    resultCards1.add(card);
                }


            }
            if (!resultCards1.isEmpty()){
                return resultCards1.get(0);
            }
        }

        List<Integer> resultCards2= new ArrayList<>();
        if (resultCards1.isEmpty()){
            for (int card : nonAdjacentCards) {
                int value = card % 100;


                if (value==7 || value==3 || value==6 || value==4 || value==5){
                    resultCards2.add(card);
                }


            }
            if (!resultCards2.isEmpty()){
                return resultCards2.get(0);
            }
        }


// 现在 nonAdjacentCards 中只包含不能组成顺子的牌
// 对于输入 [206, 304, 305]，结果将是 [206]



        if (!nonAdjacentCards.isEmpty()) {
            // 更自然的排序逻辑，优先考虑孤张牌的刻子和边搭可能性
            nonAdjacentCards.sort((a, b) -> {

                int rankA = a % 100;
                int rankB = b % 100;
                int suitA = a / 100;
                int suitB = b / 100;

                // 1. 特殊处理：检查是否可以通过打这张牌听牌
                boolean canTingA = discardToTingOptions != null && discardToTingOptions.containsKey(a);
                boolean canTingB = discardToTingOptions != null && discardToTingOptions.containsKey(b);

                // 如果只有一张牌可以打出听牌，则优先打那张牌
                if (canTingA && !canTingB) {
                    return -1;
                }
                if (!canTingA && canTingB) {
                    return 1;
                }

                // 如果两张牌都可以听牌，比较听牌组数量
                if (canTingA && canTingB) {
                    int tingGroupA = discardToTingOptions.get(a).size();
                    int tingGroupB = discardToTingOptions.get(b).size();
                    return Integer.compare(tingGroupB, tingGroupA); // 听牌组多的优先
                }

                // 2. 特殊处理：检查是否是顺子中多余的牌（比如顺子234中多出的3）
                boolean isExtraInSequenceA = isExtraCardInSequence(a, analysis);
                boolean isExtraInSequenceB = isExtraCardInSequence(b, analysis);

                // 如果一个是顺子中多余的牌，另一个不是，则优先打出多余的牌
                if (isExtraInSequenceA && !isExtraInSequenceB) {
                    return -1; // A是顺子中多余的牌，优先打A
                }
                if (!isExtraInSequenceA && isExtraInSequenceB) {
                    return 1; // B是顺子中多余的牌，优先打B
                }

                // 1. 孤张牌处理：优先考虑没有潜力或潜力低的孤张
                boolean isIsolatedA = analysis.isolatedCards.contains(a);
                boolean isIsolatedB = analysis.isolatedCards.contains(b);

                // 计算潜力分数
                int potentialA = calculateCardPotentialScore(a, analysis);
                int potentialB = calculateCardPotentialScore(b, analysis);

                // 摸牌后特殊处理：检查是否是新摸的牌
                boolean isDrawnCardA = a == analysis.lastDrawnCard;
                boolean isDrawnCardB = b == analysis.lastDrawnCard;

                // 如果其中一张是新摸的牌，给予适当的优先级提升
                if (isDrawnCardA && !isDrawnCardB) {
                    // 新摸的牌有潜力时优先保留
                    if (potentialA > 15) {
                        return 1; // 保留新摸的有潜力的牌
                    }
                } else if (isDrawnCardB && !isDrawnCardA) {
                    // 新摸的牌有潜力时优先保留
                    if (potentialB > 15) {
                        return -1; // 保留新摸的有潜力的牌
                    }
                }

                // 首先，将没有任何潜力的孤张牌优先打出
                if (isIsolatedA && potentialA == 0 && !(isIsolatedB && potentialB == 0)) {
                    return -1; // A是没有任何潜力的孤张，优先打A
                }
                if (isIsolatedB && potentialB == 0 && !(isIsolatedA && potentialA == 0)) {
                    return 1; // B是没有任何潜力的孤张，优先打B
                }

                // 如果都是孤张，按潜力分数排序
                if (isIsolatedA && isIsolatedB) {
                    // 潜力低的优先打出
                    if (potentialA != potentialB) {
                        return Integer.compare(potentialA, potentialB);
                    }
                    // 潜力相同时，检查是否是新摸的牌，优先保留新摸的牌
                    if (isDrawnCardA && !isDrawnCardB) {
                        return 1; // 保留新摸的牌
                    } else if (isDrawnCardB && !isDrawnCardA) {
                        return -1; // 保留新摸的牌
                    }
                }
                // 如果一个是孤张，一个不是，则比较它们的潜力
                else if (isIsolatedA && !isIsolatedB) {
                    // 孤张但有一定潜力，与非孤张比较
                    if (potentialA < potentialB - 5) { // 设置阈值，避免过于保守
                        return -1; // A潜力明显低于B，优先打A
                    }
                    // 孤张但有潜力且是新摸的牌，优先保留
                    if (isDrawnCardA && potentialA > 10) {
                        return 1; // 保留新摸的有潜力的孤张牌
                    }
                }
                else if (!isIsolatedA && isIsolatedB) {
                    // 孤张但有一定潜力，与非孤张比较
                    if (potentialB < potentialA - 5) { // 设置阈值
                        return 1; // B潜力明显低于A，优先打B
                    }
                    // 孤张但有潜力且是新摸的牌，优先保留
                    if (isDrawnCardB && potentialB > 10) {
                        return -1; // 保留新摸的有潜力的孤张牌
                    }
                }

                // 2. 边张处理：优先考虑没有刻子或边搭可能性的边张
                boolean isEdgeA = (rankA == 1 || rankA == 9);
                boolean isEdgeB = (rankB == 1 || rankB == 9);

                if (isEdgeA && isEdgeB) {
                    // 两个都是边张，优先打出没有潜力的边张
                    boolean hasPotentialA = hasEdgeCardPotential(a, analysis);
                    boolean hasPotentialB = hasEdgeCardPotential(b, analysis);

                    if (hasPotentialA != hasPotentialB) {
                        return hasPotentialA ? 1 : -1; // 有潜力的边张优先保留
                    }
                    // 如果都有或都没有潜力，再比较具体的潜力分数
                    if (potentialA != potentialB) {
                        return Integer.compare(potentialA, potentialB);
                    }
                } else if (isIsolatedA && isEdgeA && !isIsolatedB && !isEdgeB) {
                    // A是孤立的边张，B不是，检查A是否有潜力
                    if (!hasEdgeCardPotential(a, analysis)) {
                        return -1; // A是孤立且没有潜力的边张，优先打A
                    }
                } else if (isIsolatedB && isEdgeB && !isIsolatedA && !isEdgeA) {
                    // B是孤立的边张，A不是，检查B是否有潜力
                    if (!hasEdgeCardPotential(b, analysis)) {
                        return 1; // B是孤立且没有潜力的边张，优先打B
                    }
                }

                // 4. 次边张处理（2,8）
                boolean isSubEdgeA = (rankA == 2 || rankA == 8);
                boolean isSubEdgeB = (rankB == 2 || rankB == 8);

                if (isSubEdgeA && !isSubEdgeB) {
                    // A是次边张，B不是，检查A是否有潜力
                    if (!hasEdgeCardPotential(a, analysis)) {
                        return -1; // A是没有潜力的次边张，优先打A
                    }
                }
                if (!isSubEdgeA && isSubEdgeB) {
                    // B是次边张，A不是，检查B是否有潜力
                    if (!hasEdgeCardPotential(b, analysis)) {
                        return 1; // B是没有潜力的次边张，优先打B
                    }
                }
                // 如果两个都是次边张，比较它们的潜力
                if (isSubEdgeA && isSubEdgeB) {
                    boolean hasPotentialA = hasEdgeCardPotential(a, analysis);
                    boolean hasPotentialB = hasEdgeCardPotential(b, analysis);

                    if (hasPotentialA != hasPotentialB) {
                        return hasPotentialA ? 1 : -1; // 有潜力的次边张优先保留
                    }
                }

                // 5. 根据策略调整
                if (strategy == StrategyType.DEFEND) {
                    // 防守时保留中张
                    if (isMiddleCard(rankA) && !isMiddleCard(rankB)) return 1;
                    if (!isMiddleCard(rankA) && isMiddleCard(rankB)) return -1;
                }

                // 6. 最后按点数排序
                return Integer.compare(a, b);
            });

            return nonAdjacentCards.get(0);
        }

        // 默认返回第一张牌
        return nonAdjacentCards.get(0);
    }

    /**
     * 检查一张牌是否是顺子中多余的牌（比如顺子234中多出的3）
     * @param card 要检查的牌
     * @param analysis 手牌分析结果
     * @return 如果是顺子中多余的牌，返回true，否则返回false
     */
    private boolean isExtraCardInSequence(int card, HandAnalysis analysis) {
        // 获取牌的点数和花色
        int rank = card % 100;
        int suit = card / 100;

        // 检查这张牌的数量
        int cardCount = analysis.cardCounts.getOrDefault(card, 0);

        // 如果这张牌的数量大于1，并且它参与了至少一个顺子
        if (cardCount > 1) {
            // 检查这张牌是否在顺子中
            boolean isInSequence = false;
            for (List<Integer> meld : analysis.completedMelds) {
                // 检查是否是顺子（不是刻子）
                if (!(meld.get(0).equals(meld.get(1)) && meld.get(1).equals(meld.get(2)))) {
                    // 检查顺子中是否包含这张牌
                    if (meld.contains(card)) {
                        isInSequence = true;
                        break;
                    }
                }
            }

            // 如果这张牌在顺子中，并且数量大于1，那么它可能是顺子中多余的牌
            if (isInSequence) {
                // 计算这张牌在顺子中被使用的次数
                int usedInSequenceCount = 0;
                for (List<Integer> meld : analysis.completedMelds) {
                    if (!(meld.get(0).equals(meld.get(1)) && meld.get(1).equals(meld.get(2)))) {
                        for (int c : meld) {
                            if (c == card) {
                                usedInSequenceCount++;
                            }
                        }
                    }
                }

                // 如果这张牌在顺子中被使用的次数小于它的总数量，那么它是顺子中多余的牌
                return usedInSequenceCount < cardCount;
            }
        }

        return false;
    }

    // 判断边张牌是否有刻子或边搭的可能性
    private boolean hasEdgeCardPotential(int card, HandAnalysis analysis) {
        // 使用增强版的潜力计算方法
        return calculateCardPotentialScore(card, analysis) > 0;
    }

    // 判断是否为中张牌
    private boolean isMiddleCard(int rank) {
        return rank >= 3 && rank <= 7;
    }

    // 检查边张牌是否有刻子或边搭的可能性 - 使用统一的潜力计算方法


    /**
     * 高级摸牌分析 - 全面检测摸牌后是否可听牌，并深入分析手牌结构
     * 在摸牌后、打牌前调用此方法进行全面分析，确定是否已经听牌或如何打出牌可以听牌
     * @param currentHand 摸牌前的手牌
     * @param drawnCard 刚摸到的牌
     * @return 当前手牌是否已经听牌
     */
    public boolean analyzeDrawCard(List<Integer> currentHand, int drawnCard) {
        System.out.println("机器人手牌" + currentHand);
        // 创建包含摸牌后的手牌
        List<Integer> newHand = new ArrayList<>(currentHand);
//        newHand.add(drawnCard);
        newHand.sort(Integer::compareTo);
        drawnCard = drawnCards;
        System.out.println("drawnCards ======= " + drawnCards);
        logInfo("\n===== 开始摸牌分析 =====");
        logInfo("摸牌: " + drawnCard + "，摸牌后手牌: " + newHand);

        // 分析新的手牌结构和听牌状态
        HandAnalysis analysis = analyzeHand(newHand);
        analysis.lastDrawnCard = drawnCard; // 记录最后摸的牌



        // 额外检查：确保孤牌字段被正确更新
        // 如果摸牌后有新的牌型变化，可能需要重新计算孤牌
        reanalyzeIsolatedCards(analysis, newHand);

        // 输出详细分析结果
        logInfo("摸牌后分析结果:");
        logInfo("- 是否听牌: " + analysis.isTingPai);
        if (analysis.isTingPai) {
//            logInfo("- 可听的牌组: " + analysis.tingCards);
//            // 分析听牌类型
//            String tingType = analyzeTingType(analysis);
//            logInfo("- 听牌类型: " + tingType);
//            // 评估听牌强度
//            int tingStrength = evaluateTingStrength(analysis);
//            logInfo("- 听牌强度评分: " + tingStrength);
        } else {
            // 分析向听数和改进建议
//            logInfo("- 向听数: " + analysis.shantenCount);
//            logInfo("- 改进建议: " + getImprovementSuggestions(analysis));
        }
//        logInfo("- 红中数量: " + analysis.hongZhongCount);
//        logInfo("- 已完成的面子数: " + analysis.meldCount);
//        logInfo("- 对子数量: " + analysis.pairCount);
//        logInfo("- 孤张牌: " + analysis.isolatedCards);

        // 特别分析新摸的牌对牌型的影响
        int newCardCount = 0;
        for (int card : newHand) {
            if (card == drawnCard) newCardCount++;
        }

        logInfo("- 新摸牌 " + drawnCard + " 的数量: " + newCardCount);

        // 分析新摸牌的潜力
        int drawnCardPotential = calculateCardPotentialScore(drawnCard, analysis);
        logInfo("- 新摸牌的潜力分数: " + drawnCardPotential);

        // 分析新摸牌的类型
        String cardType = analyzeCardType(drawnCard, newCardCount, analysis);
//        logInfo("- 新摸牌类型: " + cardType);
//
//        //分析打出哪张牌可以听牌
//        logInfo("\n分析打出哪张牌可以听牌:");
        Map<Integer, Set<Integer>> discardToTingOptions = findDiscardToTing(newHand);

        // 分析最佳出牌策略
        if (!discardToTingOptions.isEmpty()) {
            analyzeBestDiscardStrategy(discardToTingOptions, analysis);
        }

        // 将刻子、顺子、红中单独拎出后分析剩余牌，帮助确定出牌策略
        separateAndAnalyzeHand(newHand);

        logInfo("===== 摸牌分析完成 =====\n");

        // 返回当前手牌是否已经听牌
        return analysis.isTingPai;
    }

    /**
     * 分析听牌类型 - 精确版
     * 更详细地识别不同类型的听牌
     * @param analysis 手牌分析结果对象
     * @return 听牌类型描述
     */
    /**
     * 重新分析孤牌 - 在摸牌后调用，确保孤牌字段的准确性
     * @param analysis 手牌分析结果对象
     * @param handCards 完整的手牌（包括刚摸的牌）
     */
    private void reanalyzeIsolatedCards(HandAnalysis analysis, List<Integer> handCards) {
        // 清空现有的孤牌列表
        analysis.isolatedCards.clear();

        // 重新分析孤牌
        // 1. 首先找出所有没有被用于面子或对子的牌
        List<Integer> potentialIsolated = new ArrayList<>();
        for (Map.Entry<Integer, List<Integer>> entry : analysis.cardsBySuit.entrySet()) {
            for (int card : entry.getValue()) {
                if (!analysis.usedInMelds.contains(card) && !analysis.usedInPairs.contains(card)) {
                    potentialIsolated.add(card);
                }
            }
        }

        // 2. 对每个潜在的孤牌，检查它是否真的孤立（没有相邻牌）
        for (int card : potentialIsolated) {
            int rank = card % 100;
            int suit = card / 100;
            boolean isIsolated = true;

            // 检查前一张牌是否存在
            if (rank > 1) {
                int prevCard = suit * 100 + (rank - 1);
                if (analysis.cardCounts.getOrDefault(prevCard, 0) > 0) {
                    isIsolated = false;
                }
            }

            // 检查后一张牌是否存在
            if (rank < 9 && isIsolated) {
                int nextCard = suit * 100 + (rank + 1);
                if (analysis.cardCounts.getOrDefault(nextCard, 0) > 0) {
                    isIsolated = false;
                }
            }

            // 检查红中的影响（如果有红中，单张牌不那么孤立）
            if (isIsolated && analysis.hongZhongCount > 0) {
                // 有红中时，评估这张牌的潜力
                int potentialScore = calculateCardPotentialScore(card, analysis);
                if (potentialScore > 10) { // 设置一个阈值，潜力较高的牌不视为孤牌
                    isIsolated = false;
                }
            }

            if (isIsolated) {
                analysis.isolatedCards.add(card);
            }
        }

        logInfo("重新分析后的孤牌: " + analysis.isolatedCards);
    }

    /**
     * 分析听牌类型 - 精确版
     * 更详细地识别不同类型的听牌
     */
    private String analyzeTingType(HandAnalysis analysis) {
        Set<Integer> tingCards = analysis.tingCards;
        int tingCardCount = tingCards.size();

        if (tingCardCount == 0) {
            return "未知听牌类型";
        }

        // 统计各花色的听牌数量
        Map<Integer, Integer> suitTingCount = new HashMap<>();
        for (int card : tingCards) {
            int suit = card / 100;
            suitTingCount.put(suit, suitTingCount.getOrDefault(suit, 0) + 1);
        }

        // 检查是否为清一色或混一色听牌
        boolean isPureSuit = suitTingCount.size() == 1 && !suitTingCount.containsKey(HONG_ZHONG / 100);

        // 检查红中的影响
        boolean hasHongZhongImpact = analysis.hongZhongCount > 0 && analysis.hongZhongContributedTingCards > 0;

        // 详细的听牌类型判断
        if (tingCardCount == 1) {
            return "单调张听牌" + (hasHongZhongImpact ? "（红中辅助）" : "");
        } else if (tingCardCount == 2) {
            // 检查是否为两面听
            List<Integer> sortedTingCards = new ArrayList<>(tingCards);
            Collections.sort(sortedTingCards);
            int suit1 = sortedTingCards.get(0) / 100;
            int suit2 = sortedTingCards.get(1) / 100;
            int rank1 = sortedTingCards.get(0) % 100;
            int rank2 = sortedTingCards.get(1) % 100;

            if (suit1 == suit2 && Math.abs(rank1 - rank2) == 2) {
                return "两面听牌" + (hasHongZhongImpact ? "（红中辅助）" : "");
            } else {
                return "双碰听牌" + (hasHongZhongImpact ? "（红中辅助）" : "");
            }
        } else if (tingCardCount == 3) {
            // 检查是否为三面听（如1,4,7或3,6,9）
            List<Integer> sortedTingCards = new ArrayList<>(tingCards);
            Collections.sort(sortedTingCards);
            boolean sameSuit = true;
            int suit = sortedTingCards.get(0) / 100;
            for (int card : sortedTingCards) {
                if (card / 100 != suit) {
                    sameSuit = false;
                    break;
                }
            }

            if (sameSuit) {
                int rank1 = sortedTingCards.get(0) % 100;
                int rank2 = sortedTingCards.get(1) % 100;
                int rank3 = sortedTingCards.get(2) % 100;

                if ((rank1 == 1 && rank2 == 4 && rank3 == 7) ||
                        (rank1 == 3 && rank2 == 6 && rank3 == 9)) {
                    return "三面听牌" + (hasHongZhongImpact ? "（红中辅助）" : "");
                }
            }

            return "多面听牌" + (hasHongZhongImpact ? "（红中辅助）" : "");
        } else if (tingCardCount >= 4 && tingCardCount <= 6) {
            return "多面听牌" + (hasHongZhongImpact ? "（红中辅助）" : "");
        } else {
            // 大量听牌，可能是清幺九或其他特殊牌型
            if (isPureSuit) {
                return "清一色广听牌" + (hasHongZhongImpact ? "（红中辅助）" : "");
            } else {
                return "广听牌（听多张）" + (hasHongZhongImpact ? "（红中辅助）" : "");
            }
        }
    }

    /**
     * 评估听牌强度 - 高级版
     * 综合考虑多种因素进行精确的听牌强度评估
     * @param analysis 手牌分析结果对象
     * @return 听牌强度评分（0-100）
     */
    private int evaluateTingStrength(HandAnalysis analysis) {
        int strength = 0;
        Set<Integer> tingCards = analysis.tingCards;
        int tingCardCount = tingCards.size();

        // 基础分：根据听牌数量（非线性增长）
        if (tingCardCount == 1) {
            strength += 20;
        } else if (tingCardCount == 2) {
            strength += 35;
        } else if (tingCardCount == 3) {
            strength += 50;
        } else if (tingCardCount == 4) {
            strength += 60;
        } else if (tingCardCount == 5) {
            strength += 70;
        } else if (tingCardCount >= 6) {
            strength += 80;
        }

        // 加分：中张听牌（3-7）- 更易胡牌
        for (int card : tingCards) {
            int rank = card % 100;
            if (rank >= 3 && rank <= 7) {
                strength += 3;
            } else if (rank == 2 || rank == 8) {
                strength += 1;
            } else if (rank == 1 || rank == 9) {
                strength -= 1;
            }
        }

        // 加分：已完成面子多
        strength += analysis.meldCount * 7;

        // 加分：对子数量适中
        if (analysis.pairCount == 1) {
            strength += 5;
        } else if (analysis.pairCount > 1) {
            strength -= analysis.pairCount - 1;
        }

        // 红中影响评估
        if (analysis.hongZhongCount == 0) {
            // 无红中听牌，难度较大，给予额外加分
            strength += 10;
        } else if (analysis.hongZhongCount == 1) {
            strength += 7;
        } else if (analysis.hongZhongCount == 2) {
            strength += 4;
        } else if (analysis.hongZhongCount >= 3) {
            // 红中过多可能限制牌型，给予少量减分
            strength -= Math.min(analysis.hongZhongCount - 2, 5);
        }

        // 减分：孤张多
        strength -= analysis.isolatedCards.size() * 4;

        // 加分：听牌中的新摸牌
        if (analysis.isTingPai && tingCards.contains(analysis.lastDrawnCard)) {
            strength += 5;
        }

        // 加分：听牌组的花色多样性（避免只听一种花色）
        Map<Integer, Integer> suitTingCount = new HashMap<>();
        for (int card : tingCards) {
            int suit = card / 100;
            suitTingCount.put(suit, suitTingCount.getOrDefault(suit, 0) + 1);
        }
        if (suitTingCount.size() > 1) {
            strength += 5;
        }

        // 确保分数在合理范围内
        return Math.max(0, Math.min(strength, 100));
    }

    /**
     * 获取手牌改进建议
     * @param analysis 手牌分析结果对象
     * @return 改进建议
     */
    private String getImprovementSuggestions(HandAnalysis analysis) {
        StringBuilder suggestions = new StringBuilder();

        if (analysis.shantenCount == 1) {
            suggestions.append("接近听牌，优先考虑打出孤张牌。");
        } else if (analysis.shantenCount == 2) {
            suggestions.append("需要整理手牌，形成更多对子或顺子。");
        } else {
            suggestions.append("手牌需要大幅调整，优先保留有潜力的牌组。");
        }

        if (analysis.isolatedCards.size() > 3) {
            suggestions.append(" 考虑打出多余的孤张牌。");
        }

        if (analysis.hongZhongCount > 3) {
            suggestions.append(" 红中数量过多，可以考虑杠牌或保留。");
        }

        return suggestions.toString();
    }

    /**
     * 分析牌的类型
     * @param card 牌
     * @param count 牌的数量
     * @param analysis 手牌分析结果对象
     * @return 牌类型描述
     */
    private String analyzeCardType(int card, int count, HandAnalysis analysis) {
        if (card == HONG_ZHONG) {
            return "红中（万能牌）";
        }

        if (analysis.pairs.contains(card)) {
            return "对子牌";
        }

        if (analysis.isolatedCards.contains(card)) {
            return "孤张牌";
        }

        if (count == 3) {
            return "刻子牌";
        }

        int rank = card % 100;
        if (rank == 1 || rank == 9) {
            return "幺九牌";
        } else if (rank >= 3 && rank <= 7) {
            return "中张牌";
        } else {
            return "边张牌";
        }
    }

    /**
     * 分析最佳出牌策略
     * @param discardToTingOptions 出牌听牌选项
     * @param analysis 手牌分析结果对象
     */
    private void analyzeBestDiscardStrategy(Map<Integer, Set<Integer>> discardToTingOptions, HandAnalysis analysis) {
        // 找出听牌组最多的出牌选项
        int maxTingCards = 0;
        int bestCardToDiscard = -1;

        for (Map.Entry<Integer, Set<Integer>> entry : discardToTingOptions.entrySet()) {
            int card = entry.getKey();
            Set<Integer> tingCards = entry.getValue();

            if (tingCards.size() > maxTingCards) {
                maxTingCards = tingCards.size();
                bestCardToDiscard = card;
            }
        }

        if (bestCardToDiscard != -1) {
            logInfo("最佳出牌策略: 打出 " + bestCardToDiscard + " 可以听 " + maxTingCards + " 张牌");
            logInfo("听牌组: " + discardToTingOptions.get(bestCardToDiscard));
        }

        // 分析不同出牌选项的优劣
        for (Map.Entry<Integer, Set<Integer>> entry : discardToTingOptions.entrySet()) {
            int card = entry.getKey();
            Set<Integer> tingCards = entry.getValue();

            // 评估这个出牌选项的价值
            int value = evaluateDiscardOption(card, tingCards, analysis);
            logInfo("出牌选项评估: 打出 " + card + " (价值: " + value + ") -> 听牌: " + tingCards);
        }
    }

    /**
     * 评估出牌选项的价值
     * @param card 要打出的牌
     * @param tingCards 听牌组
     * @param analysis 手牌分析结果对象
     * @return 价值评分
     */
    private int evaluateDiscardOption(int card, Set<Integer> tingCards, HandAnalysis analysis) {
        int value = 0;

        // 基础分：听牌数量
        value += tingCards.size() * 10;

        // 减分：如果是有价值的牌
        if (analysis.cardUsefulness.containsKey(card)) {
            value -= analysis.cardUsefulness.get(card) / 5;
        }

        // 加分：中张听牌多
        for (int tingCard : tingCards) {
            int rank = tingCard % 100;
            if (rank >= 3 && rank <= 7) {
                value += 2;
            }
        }

        // 加分：如果是孤张牌
        if (analysis.isolatedCards.contains(card)) {
            value += 10;
        }

        return value;
    }

    /**
     * 将刻子、顺子、红中单独拎出，然后分析剩余的牌
     * @param hand 当前手牌
     */
    public void separateAndAnalyzeHand(List<Integer> hand) {
        System.out.println("\n开始分离分析手牌...");

        // 分析手牌
        HandAnalysis analysis = analyzeHand(hand);

        // 统计原始手牌中每张牌的数量
        Map<Integer, Integer> originalCounts = new HashMap<>();
        for (int card : hand) {
            originalCounts.put(card, originalCounts.getOrDefault(card, 0) + 1);
        }

        // 分离出刻子
        List<Integer> kziCards = new ArrayList<>();
        Map<Integer, Integer> usedInKzi = new HashMap<>();
        for (List<Integer> meld : analysis.completedMelds) {
            if (meld.get(0).equals(meld.get(1)) && meld.get(1).equals(meld.get(2))) {
                kziCards.addAll(meld);
                int card = meld.get(0);
                usedInKzi.put(card, usedInKzi.getOrDefault(card, 0) + 3);
            }
        }

        // 分离出顺子
        List<Integer> shunziCards = new ArrayList<>();
        Map<Integer, Integer> usedInShunzi = new HashMap<>();
        for (List<Integer> meld : analysis.completedMelds) {
            if (!(meld.get(0).equals(meld.get(1)) && meld.get(1).equals(meld.get(2)))) {
                shunziCards.addAll(meld);
                // 统计顺子中每张牌的使用次数
                for (int card : meld) {
                    usedInShunzi.put(card, usedInShunzi.getOrDefault(card, 0) + 1);
                }
            }
        }

        // 分离出红中
        List<Integer> hongzhongCards = new ArrayList<>();
        for (int card : hand) {
            if (card == HONG_ZHONG) {
                hongzhongCards.add(card);
            }
        }

        // 计算剩余需要分析的牌（处理顺子中多余的牌）
        List<Integer> remainingCards = new ArrayList<>();
        for (Map.Entry<Integer, Integer> entry : originalCounts.entrySet()) {
            int card = entry.getKey();
            int totalCount = entry.getValue();

            // 跳过红中
            if (card == HONG_ZHONG) {
                continue;
            }

            // 减去刻子和顺子中使用的数量
            int usedCount = usedInKzi.getOrDefault(card, 0) + usedInShunzi.getOrDefault(card, 0);
            int remainingCount = totalCount - usedCount;

            // 将剩余的牌添加到remainingCards中
            for (int i = 0; i < remainingCount; i++) {
                remainingCards.add(card);
            }
        }

        // 输出分离结果
        System.out.println("分离结果：");
        System.out.println("- 刻子: " + kziCards);
        System.out.println("- 顺子: " + shunziCards);
        System.out.println("- 红中: " + hongzhongCards);
        System.out.println("- 剩余待分析的牌: " + remainingCards);

        // 更新analysis中的剩余牌
        analysis.remainingCards = remainingCards;

        // 分析剩余牌的结构
        analyzeRemainingCards(remainingCards, analysis);
    }

    /**
     * 分析剩余需要处理的牌的结构
     * @param remainingCards 剩余的牌
     * @param analysis 手牌分析结果
     */
    private void analyzeRemainingCards(List<Integer> remainingCards, HandAnalysis analysis) {
        if (remainingCards.isEmpty()) {
            System.out.println("没有剩余需要分析的牌，手牌结构完整");
            return;
        }

        // 统计剩余牌的数量
        Map<Integer, Integer> cardCounts = new HashMap<>();
        for (int card : remainingCards) {
            cardCounts.put(card, cardCounts.getOrDefault(card, 0) + 1);
        }

        // 识别对子、搭子和孤张
        List<Integer> pairs = new ArrayList<>();
        List<Integer> triples = new ArrayList<>(); // 三张（可拆分成刻子）
        List<Integer>搭子 = new ArrayList<>();
        Set<Integer> usedInPairsOrTriples = new HashSet<>();

        // 首先识别对子和三张
        for (Map.Entry<Integer, Integer> entry : cardCounts.entrySet()) {
            int card = entry.getKey();
            int count = entry.getValue();

            if (count >= 3) {
                triples.add(card);
                usedInPairsOrTriples.add(card);
            } else if (count == 2) {
                pairs.add(card);
                usedInPairsOrTriples.add(card);
            }
        }

        // 将剩余的牌按花色分组进行搭子分析
        Map<Integer, List<Integer>> suitGroups = new HashMap<>();
        for (Map.Entry<Integer, Integer> entry : cardCounts.entrySet()) {
            int card = entry.getKey();
            int count = entry.getValue();
            int suit = card / 100;

            // 只考虑未被用于对子或三张的牌，以及数量>1的情况
            if (!usedInPairsOrTriples.contains(card) || count > 2) {
                suitGroups.computeIfAbsent(suit, k -> new ArrayList<>()).add(card);
            }
        }

        // 对每个花色单独分析搭子
        Set<Integer> usedIn搭子 = new HashSet<>();
        for (List<Integer> suitCards : suitGroups.values()) {
            // 按点数排序
            suitCards.sort((a, b) -> Integer.compare(a % 100, b % 100));

            // 检查边搭（1-2, 8-9）
            for (int i = 0; i < suitCards.size() - 1; i++) {
                int card1 = suitCards.get(i);
                int card2 = suitCards.get(i + 1);
                int rank1 = card1 % 100;
                int rank2 = card2 % 100;

                // 边搭：1-2 或 8-9
                if (Math.abs(rank1 - rank2) == 1) {
                    if ((rank1 == 1 && rank2 == 2) || (rank1 == 8 && rank2 == 9)) {
                        if (!usedIn搭子.contains(card1) && !usedIn搭子.contains(card2)) {
                            搭子.add(card1);
                            搭子.add(card2);
                            usedIn搭子.add(card1);
                            usedIn搭子.add(card2);
                        }
                    }
                }
            }

            // 检查两面搭（中间的连续牌）
            for (int i = 0; i < suitCards.size() - 1; i++) {
                int card1 = suitCards.get(i);
                int card2 = suitCards.get(i + 1);
                int rank1 = card1 % 100;
                int rank2 = card2 % 100;

                // 两面搭：2-3, 3-4, ..., 7-8
                if (Math.abs(rank1 - rank2) == 1 &&
                        rank1 > 1 && rank1 < 8 && rank2 > 2 && rank2 < 9) {
                    if (!usedIn搭子.contains(card1) && !usedIn搭子.contains(card2)) {
                        搭子.add(card1);
                        搭子.add(card2);
                        usedIn搭子.add(card1);
                        usedIn搭子.add(card2);
                    }
                }
            }

            // 检查坎搭（间隔一张的牌）
            for (int i = 0; i < suitCards.size() - 1; i++) {
                for (int j = i + 1; j < suitCards.size(); j++) {
                    int card1 = suitCards.get(i);
                    int card2 = suitCards.get(j);
                    int rank1 = card1 % 100;
                    int rank2 = card2 % 100;

                    // 坎搭：间隔一张，如1-3, 2-4等
                    if (Math.abs(rank1 - rank2) == 2) {
                        if (!usedIn搭子.contains(card1) && !usedIn搭子.contains(card2)) {
                            搭子.add(card1);
                            搭子.add(card2);
                            usedIn搭子.add(card1);
                            usedIn搭子.add(card2);
                        }
                    }
                }
            }
        }

        // 找出孤张牌（未被用于对子、三张或搭子的单张）
        List<Integer> isolatedCards = new ArrayList<>();
        for (Map.Entry<Integer, Integer> entry : cardCounts.entrySet()) {
            int card = entry.getKey();
            int count = entry.getValue();

            // 单张且未被用于搭子
            if (count == 1 && !usedIn搭子.contains(card)) {
                isolatedCards.add(card);
            }
        }

        // 更新analysis中的孤张牌信息，确保顺子中多余的牌被正确识别为孤张
        analysis.isolatedCards = isolatedCards;

        System.out.println("剩余牌分析：");
        System.out.println("- 三张: " + triples);
        System.out.println("- 对子: " + pairs);
        System.out.println("- 搭子: " + 搭子);
        System.out.println("- 孤张: " + isolatedCards);

        // 计算剩余牌需要的张数来完成牌型
        int neededMelds = 4 - analysis.meldCount;
        int neededPairs = (analysis.pairCount > 0) ? 0 : 1;
        System.out.println("还需要完成的面子数: " + neededMelds);
        System.out.println("还需要的对子数: " + neededPairs);

        // 分析牌的冗余情况
        if (!isolatedCards.isEmpty()) {
            System.out.println("存在孤张牌，建议考虑打出：" + isolatedCards);
        }
    }

    /**
     * 分析打出哪张牌可以听牌
     * 在摸牌后、打牌前的关键步骤，找出最优出牌选择
     * 通过模拟打出每一张牌，检测是否能进入听牌状态
     *
     * @param currentHand 当前手牌（包含刚摸的牌）
     * @return 可以打出的牌列表，以及每张牌打出后可以听的牌组
     */
    public Map<Integer, Set<Integer>> findDiscardToTing(List<Integer> currentHand) {
        Map<Integer, Set<Integer>> discardToTingMap = new HashMap<>();
        logInfo("\n开始分析打出哪张牌可以听牌...");

        // 对手牌进行深度复制，避免修改原手牌
        List<Integer> handCopy = new ArrayList<>(currentHand);
        handCopy.sort(Integer::compareTo);

        // 统计每种牌的数量，避免重复分析相同的牌
        Map<Integer, Integer> cardCounts = new HashMap<>();
        for (int card : handCopy) {
            cardCounts.put(card, cardCounts.getOrDefault(card, 0) + 1);
        }

        // 尝试打出每一种不同的牌，进行模拟分析
        for (Map.Entry<Integer, Integer> entry : cardCounts.entrySet()) {
            int cardToDiscard = entry.getKey();
            int count = entry.getValue();

            // 红中通常不会打出，但仍然分析可能性
            if (cardToDiscard == HONG_ZHONG) {
                logInfo("- 通常不建议打出红中: " + cardToDiscard);
                continue;
            }

            // 模拟打出这张牌
            List<Integer> tempHand = new ArrayList<>(handCopy);
            tempHand.remove(Integer.valueOf(cardToDiscard));

            // 分析打出这张牌后的手牌是否听牌
            HandAnalysis analysis = analyzeHand(tempHand);

            // 如果听牌，记录这张牌和对应的听牌组
            if (analysis.isTingPai && !analysis.tingCards.isEmpty()) {
                discardToTingMap.put(cardToDiscard, analysis.tingCards);
                logInfo("- 打出牌: " + cardToDiscard + " 后可以听牌");
                logInfo("  听的牌组: " + analysis.tingCards);
            }
        }

        // 输出分析结果
        if (discardToTingMap.isEmpty()) {
            logInfo("- 当前没有可以打出后听牌的牌");
        } else {
            logInfo("\n可打出后听牌的牌数量: " + discardToTingMap.size());
            logInfo("建议打出的牌及其对应的听牌组:");
            for (Map.Entry<Integer, Set<Integer>> entry : discardToTingMap.entrySet()) {
                logInfo("- 牌: " + entry.getKey() + " -> 听牌组: " + entry.getValue());
            }
        }

        return discardToTingMap;
    }

    // 碰牌判断 - 实现碰牌规则
    public boolean shouldPong(int proposedCard, List<Integer> currentHand) {
        // 分析当前手牌
        HandAnalysis analysis = analyzeHand(currentHand);
        System.out.println("----"+analysis.pairCount);

        // 不能碰听牌组中的牌
        if (analysis.tingCards.contains(proposedCard)) {
            System.out.println("不能碰: 不能碰听牌组中的牌 " + proposedCard);
            return false;
        }

        if (analysis.isTingPai){
            System.out.println("听牌中不能碰" + proposedCard);
            return false;
        }

        // 规则2: 有5个对子时不能碰已成对子的牌
        if (analysis.hasLongQiDuiPotential==true && analysis.pairs.contains(proposedCard)) {
            System.out.println("不能碰: 已有5个或更多对子时不能碰已成对子的牌 " + proposedCard);
            return false;
        }

        // 规则3: 顺子的情况下不能碰
        if (isCardInSequence(proposedCard, analysis)) {
            System.out.println("不能碰: 牌在顺子中的情况下不能碰 " + proposedCard);
            return false;
        }

        // 基础碰牌条件: 手中已有两张相同的牌
        int cardCount = 0;
        for (int card : currentHand) {
            if (card == proposedCard) {
                cardCount++;
            }
        }

        boolean canPong = cardCount >= 2;
        System.out.println("是否可以碰牌 " + proposedCard + ": " + canPong);

        return canPong;
    }

    // 检查牌是否在顺子中
    private boolean isCardInSequence(int card, HandAnalysis analysis) {
        // 遍历已完成的顺子
        for (List<Integer> meld : analysis.completedMelds) {
            // 如果顺子中有这张牌，且不是刻子（刻子是三张相同的牌）
            if (meld.contains(card) && !(meld.get(0).equals(meld.get(1)) && meld.get(1).equals(meld.get(2)))) {
                return true;
            }
        }
        return false;
    }

    /**
     * 计算牌的潜力分数 - 评估一张牌在当前手牌中的价值和发展潜力
     * @param card 要评估的牌
     * @param analysis 手牌分析结果
     * @return 潜力分数，越高表示越有价值
     */
    private int calculateCardPotentialScore(int card, HandAnalysis analysis) {
        int score = 0;
        int rank = card % 100;
        int suit = card / 100;

        // 1. 中张牌（3-7）潜力更高
        if (rank >= 3 && rank <= 7) {
            score += 8;
        } else if (rank == 2 || rank == 8) {
            score += 4;
        }

        // 2. 红中的影响 - 每有一个红中增加一定潜力
        score += analysis.hongZhongCount * 5;

        // 3. 检查是否有半搭子（有一张相邻牌）
        boolean hasPrev = false;
        boolean hasNext = false;

        if (rank > 1) {
            int prevCard = suit * 100 + (rank - 1);
            hasPrev = analysis.cardCounts.getOrDefault(prevCard, 0) > 0;
        }

        if (rank < 9) {
            int nextCard = suit * 100 + (rank + 1);
            hasNext = analysis.cardCounts.getOrDefault(nextCard, 0) > 0;
        }

        if (hasPrev || hasNext) {
            score += 15;
        }

        // 4. 同花色牌数量越多，单张牌的潜力也越高
        if (analysis.cardsBySuit.containsKey(suit)) {
            int suitCardCount = analysis.cardsBySuit.get(suit).size();
            score += suitCardCount * 2;
        }

        // 5. 检查牌是否在可能的听牌组附近
        for (int tingCard : analysis.tingCards) {
            int tingRank = tingCard % 100;
            int tingSuit = tingCard / 100;

            if (tingSuit == suit) {
                // 如果牌和听牌组在同一花色且相邻，增加潜力
                if (Math.abs(tingRank - rank) <= 1) {
                    score += 20;
                    break;
                }
            }
        }

        return score;
    }








    /**
     * 测试单个听牌场景，包含异常处理
     */
    private void testSingleTingScenario(String scenarioName, List<Integer> handCards) {
        logInfo("\n测试场景: " + scenarioName);
        logInfo("测试手牌: " + handCards);

        try {
            long startTime = System.currentTimeMillis();
            HandAnalysis analysis = analyzeHand(handCards);
            long endTime = System.currentTimeMillis();

            logInfo("分析结果: 成功");
            logInfo("是否听牌: " + analysis.isTingPai);
            logInfo("听牌组: " + analysis.tingCards);
            logInfo("听牌数量: " + analysis.tingCards.size());
            logInfo("向听数: " + analysis.shantenCount);
            logInfo("红中数量: " + analysis.hongZhongCount);
            logInfo("红中贡献听牌: " + analysis.hongZhongContributedTingCards);
            logInfo("分析耗时: " + (endTime - startTime) + "ms");
        } catch (Exception e) {
            logInfo("分析结果: 异常 - " + e.getMessage());
            logInfo("异常类型: " + e.getClass().getSimpleName());
            e.printStackTrace();
        }
    }

    /**
     * 执行性能对比测试，比较优化前后的算法性能
     */
    private void performPerformanceComparison() {
        // 创建复杂的测试手牌
        List<Integer> complexHand = Arrays.asList(
                101, 102, 103, 104, 105, // 一至五万
                206, 207, 208, 209, 210, // 六至十条
                301, 302, 303, 412, 412  // 一至三筒和两个红中
        );

        // 测试多次取平均值
        int iterations = 100;
        long totalTimeOptimized = 0;

        logInfo("执行" + iterations + "次优化版听牌检测测试...");

        for (int i = 0; i < iterations; i++) {
            HandAnalysis analysis = new HandAnalysis();
            // 准备分析数据
            for (int card : complexHand) {
                if (card == HONG_ZHONG) {
                    analysis.hongZhongCount++;
                } else {
                    int suit = card / 100;
                    analysis.cardsBySuit.computeIfAbsent(suit, k -> new ArrayList<>()).add(card);
                    // 统计每种牌的数量
                    analysis.cardCounts.put(card, analysis.cardCounts.getOrDefault(card, 0) + 1);
                }
            }
            analysis.shantenCount = 0;

            // 测量优化版算法时间
            long start = System.nanoTime();
            findTingCardsOptimized(analysis);
            long end = System.nanoTime();
            totalTimeOptimized += (end - start) / 1000; // 转换为微秒
        }

        double avgTimeOptimized = totalTimeOptimized / (double) iterations;

        logInfo("优化版算法平均耗时: " + avgTimeOptimized + " μs");
        logInfo("优化版算法总耗时: " + (totalTimeOptimized / 1000.0) + " ms");
    }

    /**
     * 分析手牌是否为听牌状态
     * @param handCards 当前手牌
     * @return 返回一个Map，其中key为是否听牌，value为听牌的集合
     * @throws IllegalArgumentException 当输入参数无效时抛出
     */
    public Map<Boolean, Set<Integer>> analyzeTingPaiStatus(List<Integer> handCards,   HandAnalysis analysis) {
        // 输入验证
        if (handCards == null) {
            throw new IllegalArgumentException("手牌列表不能为空");
        }

        Map<Boolean, Set<Integer>> result = new HashMap<>();
        Set<Integer> tingCards = new HashSet<>();
        boolean isTing = false;

        try {
            // 边界条件检查：空的手牌列表
            if (handCards.isEmpty()) {
                logInfo("警告：手牌列表为空，无法分析听牌状态");
                result.put(false, tingCards);
                return result;
            }

            // 验证手牌中的牌值是否有效
            if (!validateHandCards(handCards)) {
                logInfo("警告：手牌中包含无效的牌值");
                result.put(false, tingCards);
                return result;
            }

            // 对手牌进行分析
//            HandAnalysis analysis = analyzeHand(handCards);

            // 防止analysis为null
            if (analysis == null) {
                logInfo("错误：手牌分析结果为null");
                result.put(false, tingCards);
                return result;
            }

            // 检查是否听牌
            checkTingPai(analysis);

            // 查找听的牌
            findTingCards(analysis);

            // 执行备用的听牌分析，确保全面检查
            performBackupTingAnalysis(analysis);

            // 分析红中对听牌的影响
            analyzeHongZhongImpactOnTingCards(analysis);

            // 提取听牌信息
            isTing = analysis.isTingPai;

            // 防止tingCards为null
            if (analysis.tingCards != null) {
                tingCards = analysis.tingCards;
            }

            // 如果手牌加上任何一张可能的牌能胡牌，也应该认为是听牌
            if (!isTing) {
                try {
                    // 尝试所有可能的牌，检查是否有补牌能让手牌胡牌
                    for (int potentialCard : getAllPossibleCards()) {
                        List<Integer> testHand = new ArrayList<>(handCards);
                        testHand.add(potentialCard);

                        HandAnalysis testAnalysis = analyzeHand(testHand);
                        if (testAnalysis != null) {
                            checkTingPai(testAnalysis);

                            if (testAnalysis.isTingPai) {
                                isTing = true;
                                tingCards.add(potentialCard);
                            }
                        }
                    }
                } catch (Exception e) {
                    logInfo("检查潜在听牌时出错: " + e.getMessage());
                    // 继续执行，不影响主要结果
                }
            }
        } catch (IllegalArgumentException e) {
            // 重新抛出参数异常，这是一个需要调用者处理的错误
            throw e;
        } catch (Exception e) {
            logInfo("分析听牌状态时出错: " + e.getMessage());
            e.printStackTrace();
            // 即使出错也要返回一个有效的结果
        } finally {
            // 确保结果map总是包含布尔值和集合
            if (!tingCards.isEmpty()) {
                result.put(isTing, tingCards);
            } else {
                result.put(false, Collections.emptySet());
            }
        }

        return result;
    }

    /**
     * 验证手牌中的牌值是否有效
     * @param handCards 手牌列表
     * @return 牌值是否全部有效
     */
    private boolean validateHandCards(List<Integer> handCards) {
        // 基本的牌值范围检查
        for (int card : handCards) {
            // 检查牌值是否在合理范围内
            if (card < 100 || card > 503) {
                logInfo("无效的牌值: " + card);
                return false;
            }

            int suit = card / 100;
            int rank = card % 100;

            // 验证花色和点数是否有效
            if (suit < 1 || suit > 5) {
                logInfo("无效的花色: " + suit);
                return false;
            }

            // 万、筒、条（花色1-3）的点数应为1-9
            if (suit >= 1 && suit <= 3) {
                if (rank < 1 || rank > 9) {
                    logInfo("无效的点数: " + rank + " 对于花色: " + suit);
                    return false;
                }
            }
            // 风牌（花色4）的点数应为1-4
            else if (suit == 4) {
                if (rank < 1 || rank > 4) {
                    logInfo("无效的风牌点数: " + rank);
                    return false;
                }
            }
            // 箭牌（花色5）的点数应为1-3
            else if (suit == 5) {
                if (rank < 1 || rank > 3) {
                    logInfo("无效的箭牌点数: " + rank);
                    return false;
                }
            }
        }

        return true;
    }

    /**
     * 获取所有可能的麻将牌（万、筒、条、风牌、箭牌）
     * @return 所有可能的麻将牌的列表
     */
    private List<Integer> getAllPossibleCards() {
        List<Integer> allCards = new ArrayList<>();

        // 添加万、筒、条（花色1-3，数字1-9）
        for (int suit = 1; suit <= 3; suit++) {
            for (int rank = 1; rank <= 9; rank++) {
                allCards.add(suit * 100 + rank);
            }
        }

        // 添加风牌（东、南、西、北）
        for (int wind = 1; wind <= 4; wind++) {
            allCards.add(400 + wind);
        }

        // 添加箭牌（中、发、白）
        for (int dragon = 1; dragon <= 3; dragon++) {
            allCards.add(500 + dragon);
        }

        return allCards;
    }

    /**
     * 验证当手牌添加某张特定牌后是否能胡牌
     * @param handCards 当前手牌
     * @param targetCard 待验证的牌
     * @return 是否能胡牌
     */
    public boolean verifySingleCardCanWin(List<Integer> handCards, int targetCard) {
        if (handCards == null || handCards.isEmpty()) {
            return false;
        }

        try {
            // 创建测试手牌，添加目标牌
            List<Integer> testHand = new ArrayList<>(handCards);
            testHand.add(targetCard);

            // 分析测试手牌
            HandAnalysis analysis = analyzeHand(testHand);

            // 检查是否听牌（实际上在胡牌的情况下，应该是直接能胡）
            checkTingPai(analysis);

            // 如果听牌分析认为可以胡牌，返回true
            if (analysis.isTingPai) {
                return true;
            }

            // 额外检查：验证是否能通过不同的牌型组合方式胡牌
            // 检查是否符合基本胡牌条件（四组合一对）
            return checkBasicWinCondition(testHand, analysis);
        } catch (Exception e) {
            logInfo("验证单张牌是否能胡时出错: " + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 检查基本胡牌条件（四组合一对）
     * @param handCards 手牌
     * @param analysis 手牌分析结果
     * @return 是否符合基本胡牌条件
     */
    private boolean checkBasicWinCondition(List<Integer> handCards, HandAnalysis analysis) {
        // 对手牌进行排序，便于分析
        List<Integer> sortedHand = new ArrayList<>(handCards);
        Collections.sort(sortedHand);

        // 计算牌的数量分布
        Map<Integer, Integer> cardCounts = new HashMap<>();
        for (int card : sortedHand) {
            cardCounts.put(card, cardCounts.getOrDefault(card, 0) + 1);
        }

        // 检查是否可以形成一对将牌，其余为四组刻子或顺子
        return canFormValidMelds(sortedHand, cardCounts, analysis);
    }

    /**
     * 递归检查是否可以形成有效的牌组（刻子或顺子）和一对将牌
     * @param handCards 手牌
     * @param cardCounts 牌的数量分布
     * @param analysis 手牌分析结果
     * @return 是否可以形成有效的牌组
     */
    private boolean canFormValidMelds(List<Integer> handCards, Map<Integer, Integer> cardCounts, HandAnalysis analysis) {
        // 尝试将每一张有至少两张的牌作为将牌
        for (Map.Entry<Integer, Integer> entry : cardCounts.entrySet()) {
            int card = entry.getKey();
            int count = entry.getValue();

            if (count >= 2) {
                // 创建临时的牌数量分布，减去一对将牌
                Map<Integer, Integer> tempCounts = new HashMap<>(cardCounts);
                tempCounts.put(card, count - 2);

                // 检查剩余的牌是否可以形成四组刻子或顺子
                if (checkRemainingCards(tempCounts)) {
                    return true;
                }
            }
        }

        // 没有找到合适的将牌和牌组组合
        return false;
    }

    /**
     * 检查剩余的牌是否可以形成刻子或顺子
     * @param cardCounts 牌的数量分布
     * @return 是否可以形成有效的牌组
     */
    private boolean checkRemainingCards(Map<Integer, Integer> cardCounts) {
        // 递归终止条件：所有牌都被使用
        if (cardCounts.values().stream().allMatch(count -> count == 0)) {
            return true;
        }

        // 尝试每一张还有剩余的牌
        for (Map.Entry<Integer, Integer> entry : new HashMap<>(cardCounts).entrySet()) {
            int card = entry.getKey();
            int count = entry.getValue();

            if (count == 0) {
                continue;
            }

            // 获取牌的花色和点数
            int suit = card / 100;
            int rank = card % 100;

            // 尝试组成刻子（3张相同的牌）
            if (count >= 3) {
                Map<Integer, Integer> tempCounts = new HashMap<>(cardCounts);
                tempCounts.put(card, count - 3);

                if (checkRemainingCards(tempCounts)) {
                    return true;
                }
            }

            // 对于万、筒、条，尝试组成顺子（3张连续的牌）
            if (suit >= 1 && suit <= 3 && rank <= 7) {
                int nextCard = suit * 100 + (rank + 1);
                int nextNextCard = suit * 100 + (rank + 2);

                if (cardCounts.getOrDefault(nextCard, 0) > 0 &&
                        cardCounts.getOrDefault(nextNextCard, 0) > 0) {

                    Map<Integer, Integer> tempCounts = new HashMap<>(cardCounts);
                    tempCounts.put(card, count - 1);
                    tempCounts.put(nextCard, tempCounts.get(nextCard) - 1);
                    tempCounts.put(nextNextCard, tempCounts.get(nextNextCard) - 1);

                    if (checkRemainingCards(tempCounts)) {
                        return true;
                    }
                }
            }
        }

        return false;
    }

    /**
     * 综合测试函数：验证单张牌是否能让手牌胡牌
     * @param handCards 玩家手牌
     * @param testCard 要测试的单张牌
     * @param hongZhongCount 红中数量
     * @param tableCards 桌面已打出的牌（用于检查是否点炮等特殊规则）
     * @return 胡牌结果信息对象
     */
    public WinResult verifySingleCardCanWin(List<Integer> handCards, int testCard, int hongZhongCount, List<Integer> tableCards) {
        WinResult result = new WinResult();
        result.testCard = testCard;
        result.canWin = false;
        result.winTypes = new ArrayList<>();
        result.handCards = new ArrayList<>(handCards);
        result.hongZhongCount = hongZhongCount;

        // 开始计时，用于性能统计
        long startTime = System.currentTimeMillis();

        try {
            // 创建测试手牌（将测试牌加入手牌）
            List<Integer> testHandCards = new ArrayList<>(handCards);
            testHandCards.add(testCard);

            // 1. 检测是否为正常胡牌（标准型）
            boolean normalWin = checkNormalWin(testHandCards, hongZhongCount);
            if (normalWin) {
                result.canWin = true;
                result.winTypes.add("NORMAL");
            }

            // 2. 检测是否为七对子胡牌
            boolean sevenPairsWin = checkSevenPairsWin(testHandCards, hongZhongCount);
            if (sevenPairsWin) {
                result.canWin = true;
                result.winTypes.add("SEVEN_PAIRS");
            }

            // 3. 检测是否为十三幺胡牌
            boolean thirteenOrphansWin = checkThirteenOrphansWin(testHandCards);
            if (thirteenOrphansWin) {
                result.canWin = true;
                result.winTypes.add("THIRTEEN_ORPHANS");
            }

            // 4. 检测是否为特殊牌型胡牌（如清一色、一条龙等）
            List<String> specialWinTypes = checkSpecialWinTypes(testHandCards, hongZhongCount);
            if (!specialWinTypes.isEmpty()) {
                result.canWin = true;
                result.winTypes.addAll(specialWinTypes);
            }

            // 5. 如果可以胡牌，计算胡牌分数
            if (result.canWin) {
                result.winScore = calculateWinScore(result.winTypes, hongZhongCount);
            }

        } catch (Exception e) {
            logInfo("验证胡牌时出错: " + e.getMessage());
            result.error = e.getMessage();
        }

        // 记录执行时间
        result.executionTime = System.currentTimeMillis() - startTime;

        return result;
    }

    /**
     * 检查正常胡牌（标准型）
     */
    private boolean checkNormalWin(List<Integer> handCards, int hongZhongCount) {
        // 这里应该调用WinSplitCard类的方法进行检测
        // 简化实现，实际需要调用已有胡牌检测逻辑
        try {
            // 对输入参数进行预处理，将手牌转换为正确的格式
            // 然后调用WinSplitCard的检测方法
            // 简化返回，实际需要正确实现
            return handCards.size() % 3 == 2 || hongZhongCount > 0;
        } catch (Exception e) {
            logInfo("检查正常胡牌出错: " + e.getMessage());
            return false;
        }
    }

    /**
     * 检查七对子胡牌
     */
    private boolean checkSevenPairsWin(List<Integer> handCards, int hongZhongCount) {
        // 七对子需要7个对子（14张牌），或有红中时的特殊情况
        if (handCards.size() + hongZhongCount < 14) {
            return false;
        }

        // 统计每种牌的数量
        Map<Integer, Integer> cardCounts = new HashMap<>();
        for (int card : handCards) {
            cardCounts.put(card, cardCounts.getOrDefault(card, 0) + 1);
        }

        // 七对子的基本要求：成对的牌数量 + 红中可能组成的对子数 >= 7
        int pairCount = 0;
        int oddCount = 0;

        for (int count : cardCounts.values()) {
            pairCount += count / 2;
            if (count % 2 != 0) {
                oddCount++;
            }
        }

        // 红中可以作为对子或代替单张牌
        // 简化实现，红中可以灵活使用
        return (pairCount + hongZhongCount) >= 7;
    }

    /**
     * 检查十三幺胡牌
     */
    private boolean checkThirteenOrphansWin(List<Integer> handCards) {
        // 十三幺牌型：东南西北中发白 + 三种花色的1和9
        Set<Integer> requiredCards = new HashSet<>();
        // 添加东南西北中发白（简化表示，实际需要根据游戏具体规则）
        requiredCards.add(301); // 东
        requiredCards.add(302); // 南
        requiredCards.add(303); // 西
        requiredCards.add(304); // 北
        requiredCards.add(305); // 中
        requiredCards.add(306); // 发
        requiredCards.add(307); // 白
        // 添加万、筒、条的1和9（简化表示）
        requiredCards.add(101); requiredCards.add(109);
        requiredCards.add(201); requiredCards.add(209);
        requiredCards.add(401); requiredCards.add(409);

        // 检查是否包含所有必要的幺九牌
        Set<Integer> handCardSet = new HashSet<>(handCards);
        boolean hasAllOrphans = true;
        for (int required : requiredCards) {
            if (!handCardSet.contains(required)) {
                hasAllOrphans = false;
                break;
            }
        }

        // 十三幺要求至少13种不同的幺九牌，再加上其中任意一张组成对子
        if (!hasAllOrphans) {
            return false;
        }

        // 统计是否有至少一对
        Map<Integer, Integer> cardCounts = new HashMap<>();
        for (int card : handCards) {
            cardCounts.put(card, cardCounts.getOrDefault(card, 0) + 1);
            if (cardCounts.get(card) >= 2) {
                return true; // 找到对子，符合十三幺条件
            }
        }

        return false;
    }

    /**
     * 检查特殊牌型胡牌
     */
    private List<String> checkSpecialWinTypes(List<Integer> handCards, int hongZhongCount) {
        List<String> specialTypes = new ArrayList<>();

        // 检查清一色（所有牌同一花色，红中不计入）
        boolean isPureColor = checkPureColor(handCards);
        if (isPureColor) {
            specialTypes.add("PURE_COLOR");
        }

        // 检查一条龙（包含同一花色的1-9）
        boolean isOneDragon = checkOneDragon(handCards);
        if (isOneDragon) {
            specialTypes.add("ONE_DRAGON");
        }

        // 检查碰碰胡（全是刻子和一对将牌）
        boolean isAllTriplets = checkAllTriplets(handCards, hongZhongCount);
        if (isAllTriplets) {
            specialTypes.add("ALL_TRIPLETS");
        }

        return specialTypes;
    }

    /**
     * 检查清一色
     */
    private boolean checkPureColor(List<Integer> handCards) {
        if (handCards.isEmpty()) {
            return false;
        }

        // 获取第一张牌的花色
        int firstSuit = handCards.get(0) / 100;

        // 检查所有牌是否同花色
        for (int card : handCards) {
            if (card / 100 != firstSuit) {
                return false;
            }
        }

        return true;
    }

    /**
     * 检查一条龙
     */
    private boolean checkOneDragon(List<Integer> handCards) {
        // 按花色分组
        Map<Integer, Set<Integer>> cardsBySuit = new HashMap<>();
        for (int card : handCards) {
            int suit = card / 100;
            int value = card % 100;

            cardsBySuit.putIfAbsent(suit, new HashSet<>());
            cardsBySuit.get(suit).add(value);
        }

        // 检查每种花色是否包含1-9
        for (Set<Integer> values : cardsBySuit.values()) {
            boolean hasFullSequence = true;
            for (int i = 1; i <= 9; i++) {
                if (!values.contains(i)) {
                    hasFullSequence = false;
                    break;
                }
            }
            if (hasFullSequence) {
                return true;
            }
        }

        return false;
    }

    /**
     * 检查碰碰胡
     */
    private boolean checkAllTriplets(List<Integer> handCards, int hongZhongCount) {
        // 统计每种牌的数量
        Map<Integer, Integer> cardCounts = new HashMap<>();
        for (int card : handCards) {
            cardCounts.put(card, cardCounts.getOrDefault(card, 0) + 1);
        }

        int tripletCount = 0;
        int pairCount = 0;

        for (int count : cardCounts.values()) {
            tripletCount += count / 3;
            int remainder = count % 3;
            if (remainder == 2) {
                pairCount++;
            } else if (remainder == 1) {
                // 有单张牌，可能无法形成碰碰胡
                // 但可以用红中代替
            }
        }

        // 碰碰胡需要4个刻子和1个对子
        // 红中可以作为刻子或对子使用
        int possibleTripletsFromHongZhong = hongZhongCount / 3;
        int remainingHongZhong = hongZhongCount % 3;

        int totalTriplets = tripletCount + possibleTripletsFromHongZhong;
        int neededTriplets = Math.max(0, 4 - totalTriplets);

        // 检查是否可以通过剩余红中满足需求
        return (neededTriplets <= remainingHongZhong / 2) && (pairCount == 1 || (pairCount == 0 && remainingHongZhong >= 2));
    }

    /**
     * 计算胡牌分数
     */
    private int calculateWinScore(List<String> winTypes, int hongZhongCount) {
        int baseScore = 1;

        // 根据胡牌类型增加分数
        for (String winType : winTypes) {
            switch (winType) {
                case "NORMAL":
                    baseScore *= 1;
                    break;
                case "SEVEN_PAIRS":
                    baseScore *= 2;
                    break;
                case "THIRTEEN_ORPHANS":
                    baseScore *= 16;
                    break;
                case "PURE_COLOR":
                    baseScore *= 4;
                    break;
                case "ONE_DRAGON":
                    baseScore *= 2;
                    break;
                case "ALL_TRIPLETS":
                    baseScore *= 2;
                    break;
            }
        }

        // 红中奖励
        baseScore += hongZhongCount;

        return baseScore;
    }

    /**
     * 胡牌结果信息类
     */
    public static class WinResult {
        public int testCard; // 测试的牌
        public boolean canWin; // 是否可以胡牌
        public List<String> winTypes; // 胡牌类型列表
        public int winScore; // 胡牌分数
        public List<Integer> handCards; // 玩家手牌
        public int hongZhongCount; // 红中数量
        public long executionTime; // 执行时间（毫秒）
        public String error; // 错误信息（如果有）

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append("WinResult{testCard=").append(testCard)
                    .append(", canWin=").append(canWin)
                    .append(", winTypes=").append(winTypes)
                    .append(", winScore=").append(winScore)
                    .append(", executionTime=").append(executionTime).append("ms")
                    .append(", hongZhongCount=").append(hongZhongCount);

            if (error != null) {
                sb.append(", error='").append(error).append("'");
            }

            sb.append("}");
            return sb.toString();
        }
    }





}