package taurus.util;

import com.game.Util;
import com.taurus.core.entity.ITArray;
import com.taurus.core.entity.ITObject;
import com.taurus.core.entity.TArray;
import com.taurus.core.entity.TObject;
import com.taurus.core.util.Logger;
import hunan.HandAnalysis;
import hunan.HuNanChangSha;
import org.w3c.dom.html.HTMLDOMImplementation;

import java.util.*;
import java.util.stream.Collectors;

public class ChangShaSuanFaTest {
    public int drawnCards; //摸牌
    public static List<Integer> tinCards = new ArrayList<>();
    public static boolean isTin = false;

    public static boolean isChi =false;

    public static boolean isPeng=false;

    public static List<Integer> chuguodepai = new ArrayList<>();


    // 长沙麻将特殊规则：二五八将
    private static final Set<Integer> JIANG_PAIS;

    static {
        Set<Integer> jiangSet = new HashSet<>();
        jiangSet.add(2);
        jiangSet.add(5);
        jiangSet.add(8);
        JIANG_PAIS = Collections.unmodifiableSet(jiangSet);
    }


    /**
     * 统一日志输出方法
     */
    private void logInfo(String message) {
        // 注释掉日志输出，减少测试时的信息干扰
//        System.out.println(message);
    }

    private final static Logger log;

    static {
        log = Logger.getLogger(ChangShaSuanFaTest.class);
    }



    public String teshuXuanPai(List<Integer> cardInhand, List<Integer> pengCard, List<Integer> chowGroup,List<Integer> gangdepai){
        String outcard = "";
        //特殊牌型处理
        //判断是否6对，是否快满足清一色
        //判断清一色
        //查询吃碰杠是否是同一色
        List<Integer> checkcpg = new ArrayList<>();
        checkcpg.addAll(pengCard);
        checkcpg.addAll(chowGroup);
        checkcpg.addAll(gangdepai);

        boolean qys = false;
        if (checkcpg.size()>0){
            int tmp1 = 0;
            int tmp2 = 0;
            for (int i=0;i<checkcpg.size()-1;i++) {
                tmp1 = checkcpg.get(i);
                tmp2 = checkcpg.get(i+1);
                if (Math.abs(tmp2-tmp1)>10){
                    //落地已经有了不同色，所以可以进行
                    qys = true;
                }
            }

            Map<String,List<Integer>> cardst2 = new HashMap<>();
            collectionCardse(cardInhand,cardst2);
            //检测手牌
            if (!qys){
                //检测同色牌有多少张
                for (Map.Entry<String,List<Integer>> entry : cardst2.entrySet()) {
                    List<Integer> values = entry.getValue();
                    if (values.size() > 0 && values.size() <= 2){
                        //如果只有一张同色，那就打这一张
                        return entry.getValue().get(0).toString();
                    }
                }
            }
        }else{
            //检测手牌
            if (cardInhand.size()==14){
                //检测同色牌有多少张
                Map<String,List<Integer>> cardst = new HashMap<>();
                collectionCardse(cardInhand,cardst);
                for (Map.Entry<String,List<Integer>> entry : cardst.entrySet()) {
                    if (entry.getValue().size()==1){
                        //如果只有一张同色，那就打这一张
                        return entry.getValue().get(0).toString();
                    }
                }
            }
        }
        return null;
    }

    public void collectionCardse(List<Integer> cardInhand,Map<String,List<Integer>>cardst){
        Map<Integer,List<Integer>> se = new HashMap<>();
        int wanzi = 0;
        int tongzi = 0;
        List<Integer> wanzicards = new ArrayList<>();
        List<Integer> tongzicards = new ArrayList<>();
        for (int i=0;i<cardInhand.size();i++){

            if (cardInhand.get(i)/100==1){
                wanzi++;
                wanzicards.add(cardInhand.get(i));
            }
            if (cardInhand.get(i)/100==2){
                tongzi++;
                tongzicards.add(cardInhand.get(i));
            }
        }
        cardst.put("wanzi",wanzicards);
        cardst.put("tongzi",tongzicards);
    }


    /**
     * 主算法入口：在摸牌后、打牌前进行全面分析，确定最优出牌策略
     * 核心流程：摸牌分析 -> 听牌检测 -> 策略制定 -> 出牌选择
     */
    public String outCardSuanFa(List<Integer> cardInhand, List<Integer> pengCard, List<Integer> chowGroup,List<Integer> gangdepai, List<Integer> resultList) {
        List<Integer> handCards = new ArrayList<>(cardInhand);

        List<Integer> pinghuhandCards = new ArrayList<>(cardInhand);


        List<Integer> pinghuhandCards1 = new ArrayList<>(cardInhand);


        chuguodepai.addAll(resultList);
        log.info("cardInhand:"+cardInhand);
        log.info("pengCard:"+pengCard);
        log.info("chowGroup:"+chowGroup);
        log.info("gangdepai:"+gangdepai);
        log.info("resultList:"+resultList);


        handCards.addAll(chowGroup);
        handCards.addAll(pengCard);

        handCards.sort(Integer::compareTo);

        int i = countPengGroups(handCards, pengCard); //刻子的数量
        int pisCardsCount = countPairs(handCards);//分析七小对
        //将将胡
        boolean jiangHu = isJiangHu(handCards);
        boolean isPengPengHu = hasThreeKeziAndTwoPairs(handCards, pengCard);
        //清一色碰碰胡
       // boolean hasBigSuit = isAllSameSuit(handCards, pengCard); // 分析是否有可能的清一色花色
       int  hasBigSuit =   checkDahu(handCards,chowGroup,pengCard,gangdepai);

        System.out.println("resultList22 +++++++++++++++++++++++================" + hasBigSuit);


        //特殊牌型处理
        String tscard = teshuXuanPai(cardInhand, pengCard, chowGroup, gangdepai);
        if (tscard!=null){
            System.out.printf("特殊牌型处理111 +++++++++++++++++++++++++++++++++++");
            return tscard;
        }


        //循环去一张是否能大胡听牌
        Map<Integer,List<Integer>> afterDahuOp = quyizhangDahuTingPai(cardInhand,chowGroup,pengCard,gangdepai);
        System.out.println("afterDahuOp:"+afterDahuOp);

        if (afterDahuOp.size()>0){
            //执行
            int xuanzecard1 = 0;
            int caozuonum1 = 0;
            List<Integer> tmpres  = new ArrayList<>();
            tmpres.addAll(resultList);
            tmpres.addAll(cardInhand);
            for (Map.Entry<Integer, List<Integer>> entry : afterDahuOp.entrySet()) {
                if (caozuonum1==0){
                    caozuonum1 = getTingPainum(entry.getValue(),tmpres);
                    xuanzecard1 = entry.getKey();
                }
                if (caozuonum1 < getTingPainum(entry.getValue(),tmpres)){
                    caozuonum1 = getTingPainum(entry.getValue(),tmpres);
                    xuanzecard1 = entry.getKey();
                }
            }
            //判断是否绝听
            if(caozuonum1>0){
                System.out.printf("大胡222 +++++++++++++++++++++++++++++++++++"+caozuonum1);
                return String.valueOf(xuanzecard1);
            }

        }

        //循环去一张还能听多牌
        Map<Integer,List<Integer>> afterOp = quyizhangTingPai(cardInhand);
        System.out.println("afterOp:"+afterOp);

        if (afterOp.size()>0){
            //执行
            int xuanzecard = 0;
            int caozuonum = 0;
            List<Integer> tmpres  = new ArrayList<>();
            tmpres.addAll(resultList);
            tmpres.addAll(cardInhand);
            for (Map.Entry<Integer, List<Integer>> entry : afterOp.entrySet()) {
                if (caozuonum==0){
                    caozuonum = getTingPainum(entry.getValue(),tmpres);
                    xuanzecard = entry.getKey();
                }
                if (caozuonum < getTingPainum(entry.getValue(),tmpres)){
                    caozuonum = getTingPainum(entry.getValue(),tmpres);
                    xuanzecard = entry.getKey();
                }
            }
            if(caozuonum>0){
                //绝听要换牌
                System.out.printf("特殊牌型处理222 +++++++++++++++++++++++++++++++++++");
                return String.valueOf(xuanzecard);
            }
        }


        //六对
        if (pisCardsCount >= 6 && pengCard.size() == 0 && chowGroup.size() == 0) {

            System.out.println("七小对数量大于等于6+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
            //单张牌
            List<Integer> danzhang = danzhang(handCards);
            isTin = true;


            Map<Integer, Integer> danzhangCountMap = new HashMap<>();

            for (Integer card2 : danzhang) {
                danzhangCountMap.put(card2, 0);

                tinCards.add(card2);
            }


            for (Integer card3 : resultList) {
                if (danzhangCountMap.containsKey(card3)) {
                    danzhangCountMap.put(card3, danzhangCountMap.get(card3) + 1);
                }
            }

// 找到最大的出现次数
            Integer maxCount = danzhangCountMap.values().stream()
                    .max(Integer::compareTo)
                    .orElse(0);

// 找出出现次数等于最大次数的牌
            List<Integer> maxCards = danzhangCountMap.entrySet().stream()
                    .filter(entry -> entry.getValue().equals(maxCount))
                    .map(Map.Entry::getKey)
                    .collect(Collectors.toList());


            //102/106
            // 找出maxCards中那些在handCards中出现3次的牌
            List<Integer> threeCardsFromMax = maxCards.stream()
                    .filter(card3 -> Collections.frequency(handCards, card3) == 3)
                    .collect(Collectors.toList());


            if (threeCardsFromMax.size() > 0) {
                List<Integer> zeroCountCards = threeCardsFromMax.stream()
                        .filter(card3 -> danzhangCountMap.getOrDefault(card3, 0) == 0)
                        .collect(Collectors.toList());
                System.out.println("出现次数为0的牌: " + zeroCountCards);
                // 从maxCards中移除
                if (!zeroCountCards.isEmpty()) {
                    maxCards.removeAll(zeroCountCards);
                    System.out.println("移除后maxCards: " + maxCards);
                }
            }

            System.out.println("maxCards中出现3次的牌: " + threeCardsFromMax);
            if (threeCardsFromMax.size() > 0) {
                return String.valueOf(threeCardsFromMax.get(0));
            }

            Integer maxCard = maxCards.isEmpty() ? null : maxCards.get(0);
            System.out.println("maxCard++++++++++++++++++++++++++++++" + maxCard);
            System.out.printf("特殊牌型处理333 +++++++++++++++++++++++++++++++++++");

            return String.valueOf(maxCard);

        }

//        if (isTin) {
//            System.out.println("   ");
//            System.out.println("==============听牌牌组-=-==========" + tinCards);
//            System.out.println("=========================drawnCards +++++++++++++++++++++++================" + drawnCards);
//            List<Integer> tin = new ArrayList<>(tinCards);
//            System.out.println("    ");
//            System.out.println("---------------tin--------------"+tin);
//            ai ai1 = new ai();
////        ChangshaMahjongAI ai = new ChangshaMahjongAI();
//            PlayerState playerState = new PlayerState();
//            playerState.handCards = pinghuhandCards;
//
//
//            for (int j = 0; j < chowGroup.size(); j += 3) {
//                List<Integer> chigroup = new ArrayList<>(chowGroup.subList(j, Math.min(j + 3, chowGroup.size())));
//                if (chigroup.size() == 3) {
//                    playerState.addChiGroup(chigroup);
//                }
//            }
//
//
//            for (int h = 0; h < pengCard.size(); h += 3) {
//                List<Integer> penggroup = new ArrayList<>(pengCard.subList(h, Math.min(h + 3, pengCard.size())));
//                if (penggroup.size() == 3) {
//                    playerState.addPongGroup(penggroup);
//                }
//            }
//
//
//            int bestDiscard = ai1.findBestDiscard(playerState);
//
//
//            if (bestDiscard != 0) {
//                if (ai1.isTinAi) {
//                    isTin = true;
//                }
//                if (tin.size()<tinCards.size()){
//                    System.out.println("----------听牌走ai出牌了-----");
//                    return String.valueOf(bestDiscard);
//                }else if (!tinCards.equals(tin)){
//                    tinCards.addAll(tin);
//                }
//            }
//
//
//
//            String tinOutCard = isTinOutCard(tinCards, resultList);
//            System.out.println("   ");
//            System.out.println("tinCards-----------" + tinCards);
//            System.out.println("tinOutCard-----------" + tinOutCard);
//            if (tinOutCard.equals("1")) {
//                // 1. 手牌分析 - 识别刻子、顺子、对子等牌型
//                HandAnalysis analysis = analyzeHand(handCards);
//
//                //最终出的牌
//                int outcard = selectCardToDiscard(pinghuhandCards, analysis);
//                return String.valueOf(outcard);
//            } else {
//                return tinOutCard;
//            }
//
//
//        }
//
//        if (isChi){
//            System.out.println("-----------吃牌听牌中-------");
//            ai ai1 = new ai();
////        ChangshaMahjongAI ai = new ChangshaMahjongAI();
//            PlayerState playerState = new PlayerState();
//            playerState.handCards = handCards;
//            System.out.println("吃牌听牌chowGroup +++++++++++++++++++++++" + chowGroup);
//            System.out.println("吃牌听牌pengCard +++++++++++++++++++++++" + pengCard);
//
//            for (int j = 0; j < chowGroup.size(); j += 3) {
//                List<Integer> chigroup = new ArrayList<>(chowGroup.subList(j, Math.min(j + 3, chowGroup.size())));
//                if (chigroup.size() == 3) {
//                    playerState.addChiGroup(chigroup);
//                }
//            }
//
//            System.out.println("吃牌听牌playerState.chiGroups +++++++++++++++++++   " + playerState.chiGroups);
//            System.out.println("吃牌听牌最新 ai出牌--------------------================");
//            for (int h = 0; h < pengCard.size(); h += 3) {
//                List<Integer> penggroup = new ArrayList<>(pengCard.subList(h, Math.min(h + 3, pengCard.size())));
//                if (penggroup.size() == 3) {
//                    playerState.addPongGroup(penggroup);
//                }
//            }
//
//
//            int bestDiscard = ai1.findBestDiscard(playerState);
//
//
//            if (bestDiscard != 0) {
//                if (ai1.isTinAi) {
//                    isTin = true;
//                    isChi =false;
//                }
//                System.out.println("吃牌听牌出牌长麻 ++++++++++++++++++++++++++++++++++++++");
//                log.info("吃牌听牌出牌长麻==============================="+bestDiscard);
//                return String.valueOf(bestDiscard);
//            }
//        }
//
//        if (isPeng){
//            System.out.println("-----------碰牌听牌中-------");
//            ai ai1 = new ai();
////        ChangshaMahjongAI ai = new ChangshaMahjongAI();
//            PlayerState playerState = new PlayerState();
//            playerState.handCards = handCards;
//            System.out.println("碰牌听牌中chowGroup +++++++++++++++++++++++" + chowGroup);
//            System.out.println("碰牌听牌中pengCard +++++++++++++++++++++++" + pengCard);
//
//            for (int j = 0; j < chowGroup.size(); j += 3) {
//                List<Integer> chigroup = new ArrayList<>(chowGroup.subList(j, Math.min(j + 3, chowGroup.size())));
//                if (chigroup.size() == 3) {
//                    playerState.addChiGroup(chigroup);
//                }
//            }
//
//            System.out.println("碰牌听牌中playerState.chiGroups +++++++++++++++++++   " + playerState.chiGroups);
//            System.out.println("碰牌听牌中最新 ai出牌--------------------================");
//            for (int h = 0; h < pengCard.size(); h += 3) {
//                List<Integer> penggroup = new ArrayList<>(pengCard.subList(h, Math.min(h + 3, pengCard.size())));
//                if (penggroup.size() == 3) {
//                    playerState.addPongGroup(penggroup);
//                }
//            }
//
//
//            int bestDiscard = ai1.findBestDiscard(playerState);
//
//
//            if (bestDiscard != 0) {
//                if (ai1.isTinAi) {
//                    isTin = true;
//                    isPeng =false;
//                }
//                System.out.println("碰牌听牌中出牌长麻 ++++++++++++++++++++++++++++++++++++++");
//                log.info("碰牌听牌中出牌长麻==============================="+bestDiscard);
//                return String.valueOf(bestDiscard);
//            }
//        }



        //将将胡
        if (jiangHu && chowGroup.size() == 0) {
            logInfo("将将胡");
            int outcard = selectCardToDiscardJiangHu(pinghuhandCards);
            System.out.printf("特殊牌型处理444 +++++++++++++++++++++++++++++++++++");

            return String.valueOf(outcard);
        }



        if (pisCardsCount >= 5 && pengCard.size() == 0 && chowGroup.size() == 0) {

            //大胡出牌逻辑 - 七小对
            int outcard = selectCardToDiscardBig(handCards, pisCardsCount);
            System.out.printf("特殊牌型处理666 +++++++++++++++++++++++++++++++++++");

            return String.valueOf(outcard);
        }

        System.out.println(hasBigSuit);
        if (hasBigSuit>0) {
            logInfo("执行清一色策略，尝试优化花色分布");
            // 调用清一色特定出牌策略
            int outcard = selectCardToDiscardForAllSameSuit(pinghuhandCards, chowGroup, pengCard);
            if (outcard != -1) {
                System.out.printf("特殊牌型处理555 +++++++++++++++++++++++++++++++++++");

                return String.valueOf(outcard);
            }
        }



//        List<Integer> checktingpai = TinHuChi.checktingpai(cardInhand);



        //碰碰胡
        List<Integer> checktingpai1 = TinHuChi.checktingpai(cardInhand);

        if (i >= 3 && chowGroup.size() == 0 && checktingpai1.size() == 0) {
            if (i == 4) {
                Map<String, List<?>> stringListMap = separateKeziAndRemaining(pinghuhandCards);
                List<?> remaining = stringListMap.get("remaining");
                Map<Integer, Integer> danzhangCountMap = new HashMap<>();
                //循环获取剩余的牌
                for (Object remaining1 : remaining) {
                    danzhangCountMap.put((Integer) remaining1, 0);
                }

                for (Integer card3 : resultList) {
                    if (danzhangCountMap.containsKey(card3)) {
                        danzhangCountMap.put(card3, danzhangCountMap.get(card3) + 1);
                    }
                }

                Integer maxCount = danzhangCountMap.values().stream()
                        .max(Integer::compareTo)
                        .orElse(0);


                List<Integer> maxCards = danzhangCountMap.entrySet().stream()
                        .filter(entry -> entry.getValue().equals(maxCount))
                        .map(Map.Entry::getKey)
                        .collect(Collectors.toList());

                Integer maxCard = maxCards.isEmpty() ? null : maxCards.get(0);
                System.out.printf("特殊牌型处理777 +++++++++++++++++++++++++++++++++++");

                return String.valueOf(maxCard);

            }

        }



        //七小对清一色
        List<Integer> qixiaoduiqingyise = qixiaoduiqingyise(handCards);
        boolean isqingyiseqixiaodui = hasFourOrMorePairs(qixiaoduiqingyise);
        if (isqingyiseqixiaodui && pengCard.size() == 0 && chowGroup.size() == 0) {
            logInfo("执行清一色七小对策略，尝试优化七小对分布");
            // 调用花色分析的清一色七小对出牌策略

            String discardCard = selectCardToDiscardAllSameSuitQiXiaoDuiBySuit(handCards);
            if (discardCard != null) {
                System.out.printf("特殊牌型处理888 +++++++++++++++++++++++++++++++++++");

                return discardCard;
            }
        }


        if (hasBigSuit>0 && i >= 3 && chowGroup.size() == 0) {
            logInfo("清一色碰碰胡");
            String discardCard = selectCardToDiscardPengPeng(pinghuhandCards);
            if (discardCard != null) {
                System.out.printf("特殊牌型处理999 +++++++++++++++++++++++++++++++++++");

                return discardCard;
            }
        }

        //调平胡递归
        List<Integer> integers = ChangshaWinSplitCard.analyzeBestDiscard(pinghuhandCards);
        System.out.println("integers:"+integers);
        if(integers.size()>0) {
            int integer = 0;

            integer = selectBestCardByPriority(integers);

            Map<String, List<Integer>> mapduijiang = new HashMap<>();

            int duijiangnum = checkduijiang(pinghuhandCards);

            if (integers.size() > 1 && duijiangnum == 0) {
                integer = selectBestCardRemove258(integers);
            }

            //判断是否可以开杠
            int cardnum = 0;
            if (integer > 0) {
                cardnum = Util.cardNum(integer, cardInhand);
            }


            if (integers.size() > 0 && cardnum < 4) {
                System.out.println("平胡最新出牌策略=============================================== 666   " + integer);

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

                for(int k : pinghuhandCards){
                    if(integer-1==k||integer+1==k||integer-2==k||integer+2==k){
                        //门子
                        guzhangc.add(integer);
                    }
                }
                //没有孤章门子
                if(guzhangc.size()==0) {
                    return String.valueOf(integer);
                }


                //处理拆对子问题
                //如果手牌没有对将则拆对子，等将下听
                //1、判断是否有对将
                int duijiangnum2 = checkduijiang(pinghuhandCards);
                //2拆对子
                //获取对子
                if(duijiangnum2==0) {
                    // 1. 统计牌型
                    Map<Integer, Integer> countMap = new HashMap<>();
                    for (int c : pinghuhandCards) {
                        countMap.put(c, countMap.getOrDefault(c, 0) + 1);
                    }
                    List<Integer> chaiduizi = new ArrayList<>();
                    for (Map.Entry<Integer, Integer> entry : countMap.entrySet()) {
                        if (entry.getValue() == 2) {
                            if (entry.getKey()%100==2||entry.getKey()%100==5||entry.getKey()%100==8){
                            }else{
                                chaiduizi.add(entry.getKey());
                            }
                        }
                    }

                    System.out.println("chaiduizi:" + chaiduizi);
                    List<Integer> kydongduizi = new ArrayList<>();

                    List<Integer> tmps = new ArrayList<>();
                    tmps.addAll(chaiduizi);

                    for (int c : chaiduizi) {
                        if(c%100!=2&&c%100!=5&&c%100!=8){
                            for(int k : pinghuhandCards){
                                if(c-1==k||c+1==k){
                                    //门子
                                    kydongduizi.add(c);
                                }
                            }
                        }

                    }
                    chaiduizi.removeAll(kydongduizi);
                    System.out.println("kydongduizi:" + chaiduizi);

                    if(chaiduizi.size()>0) {
                        return String.valueOf(chaiduizi.get(0));
                    }else{
                        if (tmps.size() > 0) {
                            for (int a : tmps) {
                                if (a%100==9||a%100==1){
                                    return String.valueOf(a);
                                }
                            }
                        }
                    }

                }else if(duijiangnum2==1){
                    int jiangcards = 0;
                    // 1. 统计牌型
                    Map<Integer, Integer> countMap = new HashMap<>();
                    for (int c : pinghuhandCards) {
                        countMap.put(c, countMap.getOrDefault(c, 0) + 1);
                    }
                    List<Integer> chaiduizi = new ArrayList<>();
                    for (Map.Entry<Integer, Integer> entry : countMap.entrySet()) {
                        if (entry.getValue() == 2) {
                            if (entry.getKey()%100==2||entry.getKey()%100==5||entry.getKey()%100==8){
                                jiangcards = entry.getKey();
                            }else{
                                chaiduizi.add(entry.getKey());
                            }
                        }
                    }

                    System.out.println("jiangcards:" + jiangcards);
                    if (jiangcards > 0&&chaiduizi.size()<2) {
                        //
                        //去掉将判断孤章
                        List<Integer> qudiaohou = new ArrayList<>();
                        qudiaohou.addAll(cardInhand);
                        Util.removeCard(qudiaohou,jiangcards,2);

                        Map<String, Object> map3 = new HashMap<>();
                        ChangshaWinSplitCard.checkNormalHu(qudiaohou, map3);
                        List<Integer> outs =(List<Integer>)  map3.get("cardResiue");
                        if (outs.size()>0){
                            return String.valueOf(outs.get(0));
                        }

                    }
                    //先过滤2，5，8

                    List<Integer> kydongduizi = new ArrayList<>();
                    for (int c : chaiduizi) {
                        for(int k : pinghuhandCards){
                            if(c-1==k||c+1==k){
                                //门子
                                if(!kydongduizi.contains(c)){
                                    kydongduizi.add(c);
                                }
                            }
                        }
                    }
                    if(kydongduizi.size()==chaiduizi.size()&&chaiduizi.size()>0) {
                        return String.valueOf(chaiduizi.get(0));
                    }
                    chaiduizi.removeAll(kydongduizi);

                    if(chaiduizi.size()>0) {
                        return String.valueOf(chaiduizi.get(0));
                    }else{

                        return String.valueOf(integer);
                    }
                }else{
                    return String.valueOf(integer);
                }


            }
        }


        //先拆对子

        //再拆门子


//        ai ai1 = new ai();
////        ChangshaMahjongAI ai = new ChangshaMahjongAI();
//        PlayerState playerState = new PlayerState();
//        playerState.handCards = pinghuhandCards;
//        System.out.println("chowGroup +++++++++++++++++++++++" + chowGroup);
//        System.out.println("pengCard +++++++++++++++++++++++" + pengCard);
//
//        for (int j = 0; j < chowGroup.size(); j += 3) {
//            List<Integer> chigroup = new ArrayList<>(chowGroup.subList(j, Math.min(j + 3, chowGroup.size())));
//            if (chigroup.size() == 3) {
//                playerState.addChiGroup(chigroup);
//            }
//        }
//
//        System.out.println("playerState.chiGroups +++++++++++++++++++   " + playerState.chiGroups);
//        System.out.println("最新 ai出牌--------------------================");
//        for (int h = 0; h < pengCard.size(); h += 3) {
//            List<Integer> penggroup = new ArrayList<>(pengCard.subList(h, Math.min(h + 3, pengCard.size())));
//            if (penggroup.size() == 3) {
//                playerState.addPongGroup(penggroup);
//            }
//        }


        //int bestDiscard = ai1.findBestDiscard(playerState);
       // System.out.println("bestDiscard:"+bestDiscard);

       /* if (bestDiscard != 0) {
            if (ai1.isTinAi) {
                isTin = true;
            }
            System.out.println("Ai出牌长麻 ++++++++++++++++++++++++++++++++++++++");
            log.info("Ai出牌长麻===============================");
            return String.valueOf(bestDiscard);
        }*/




        // 1. 手牌分析 - 识别刻子、顺子、对子等牌型
        HandAnalysis analysis = analyzeHand(pinghuhandCards1);

        //最终出的牌
        int outcard = selectCardToDiscard(pinghuhandCards1, analysis);


        logInfo("\n===== 手牌分析结果 =====");
        logInfo("按花色分组的牌: " + analysis.cardsBySuit);
        logInfo("已完成的刻子/顺子: " + analysis.completedMelds);
        logInfo("对子: " + analysis.pairs);
        logInfo("孤张牌: " + analysis.isolatedCards);
        logInfo("面子数量: " + analysis.meldCount);
        logInfo("对子数量: " + analysis.pairCount);
        logInfo("听牌状态: " + analysis.isTingPai);
        if (analysis.isTingPai) {
            logInfo("可胡牌: " + analysis.tingCards);
        }
        logInfo("向听数: " + analysis.shantenCount);
        logInfo("有龙七对潜力: " + analysis.hasLongQiDuiPotential);
        logInfo("有碰碰胡潜力: " + analysis.hasPengPengHu);
        logInfo("剩余需要分析的牌: " + analysis.remainingCards);

        //如果已经是听牌状态的情况
        if (analysis.isTingPai) {
            System.out.println("已经是听牌状态----" + drawnCards);
            return String.valueOf(drawnCards);
        }


        if (isJiangPai(outcard)&&integers.size()>0){
            return String.valueOf(integers.get(0));
        }
        System.out.println("最终出的牌------" + outcard);
        return String.valueOf(outcard);


    }

    // 从候选牌中选出最优的一张牌，优先去除258将牌
    public static Integer selectBestCardRemove258(List<Integer> cards) {
        if (cards == null || cards.isEmpty()) {
            return null;
        }

        // 如果只有一张牌，直接返回
        if (cards.size() == 1) {
            return cards.get(0);
        }

        // 创建非258牌的列表
        List<Integer> non258Cards = new ArrayList<>();
        List<Integer> is258Cards = new ArrayList<>();

        // 分类：258牌和非258牌
        for (Integer card : cards) {
            if (is258Jiang(card)) {
                is258Cards.add(card);
            } else {
                non258Cards.add(card);
            }
        }

        System.out.println("258将牌: " + is258Cards);
        System.out.println("非258牌: " + non258Cards);



        // 优先从非258牌中选
        if (!non258Cards.isEmpty()) {
            return selectBestSingleCard(non258Cards);
        }

        // 如果没有非258牌，从258牌中选
        if (!is258Cards.isEmpty()) {
            return selectBestSingleCard(is258Cards);
        }

        return null;
    }

    // 检测是否满足258做将的条件
    private static boolean is258Jiang(int card) {
        // 提取牌的类型和值
        int type = card / 100;  // 百位数：1-万，2-筒，3-条，4-风，5-箭
        int value = card % 100; // 个位数：牌面值

        // 只有万、筒、条有258做将的限制
        if (type >= 1 && type <= 3) {
            // 258做将：二万(102)、五万(105)、八万(108)
            //         二筒(202)、五筒(205)、八筒(208)
            //         二条(302)、五条(305)、八条(308)
            return value == 2 || value == 5 || value == 8;
        }
        return false;
    }

    // 从候选牌中选出最优的一张牌（优先边张1或9）
    public static Integer selectBestSingleCard(List<Integer> cards) {
        if (cards == null || cards.isEmpty()) {
            return null;
        }

        // 优先找边张（1或9）
        for (Integer card : cards) {
            int value = card % 100;
            if (value == 1 || value == 9) {
                return card;
            }
        }

        // 没有边张，找靠近边张的牌（2或8）- 注意这里2是258将牌，但我们已经去除了258
        for (Integer card : cards) {
            int value = card % 100;
            if (value == 2 || value == 8) {
                return card;
            }
        }

        // 都没有，返回第一张
        return cards.get(0);
    }

    public static Integer selectBestCardByPriority(List<Integer> cards) {
        if (cards == null || cards.isEmpty()) {
            return null;
        }

        Integer bestCard = null;
        int bestPriority = Integer.MAX_VALUE;

        for (Integer card : cards) {
            int value = card % 100;
            int priority = getCardPriority(value);

            if (priority < bestPriority) {
                bestPriority = priority;
                bestCard = card;
            } else if (priority == bestPriority) {
                // 优先级相同，比较牌值（小的优先）
                if (bestCard == null || value < (bestCard % 100)) {
                    bestCard = card;
                }
            }
        }

        return bestCard;
    }

    // 牌的优先级（数字越小优先级越高）
    private static int getCardPriority(int value) {
        if (value == 9) return 1;
        if (value == 1) return 2;
        if(value==2||value==5||value==8) {
            return 5;
        }
        if (value == 2 || value == 8) return 3;  // 靠近边张
        if (value >= 3 && value <= 7) return 4;  // 中间牌
        return 5;  // 其他
    }
    //听牌之后去分析出牌

    private String isTinOutCard(List<Integer> tinCards, List<Integer> resultList) {
        // 统计听牌组中每张牌在牌桌上的出现次数
        Map<Integer, Integer> tinCardCountMap = new HashMap<>();

        // 初始化听牌组中所有牌的出现次数为0
        for (Integer card : tinCards) {
            tinCardCountMap.put(card, 0);
        }

        // 统计听牌组中每张牌在牌桌上的实际出现次数
        for (Integer card : resultList) {
            if (tinCardCountMap.containsKey(card)) {
                tinCardCountMap.put(card, tinCardCountMap.get(card) + 1);
            }
        }

        // 找到最大的出现次数
        Integer maxCount = tinCardCountMap.values().stream()
                .max(Integer::compareTo)
                .orElse(0);

        // 判断所有听牌是否都大于等于3次
        boolean allGreaterOrEqualThree = !tinCardCountMap.isEmpty() &&
                tinCardCountMap.values().stream().allMatch(count -> count >= 3);

        if (allGreaterOrEqualThree) {
            isTin = false;
            // 如果所有听牌都出现大于等于3次，则随机出一张听牌
            Integer randomCard = tinCards.get(new Random().nextInt(tinCards.size()));
            System.out.println("所有听牌出现次数都>=3，随机出牌: " + randomCard);
            tinCards.remove(randomCard);
            return "1";


        }

        if (maxCount > 0 && maxCount < 3 && tinCards.size() > 1) {
            // 出现次数大于0但小于3，也直接出次数最多的牌
            List<Integer> maxCards = tinCardCountMap.entrySet().stream()
                    .filter(entry -> entry.getValue().equals(maxCount))
                    .map(Map.Entry::getKey)
                    .collect(Collectors.toList());

            if (!maxCards.isEmpty()) {
                isTin = false;
                Integer maxCard = Collections.max(maxCards);
                System.out.println("出现次数大于0，直接出牌: " + maxCard);
                tinCards.remove(maxCard);
                return "1";
            }
        } else {
            return String.valueOf(drawnCards);
        }

        // 如果所有听牌在牌桌上都没出现过（maxCount为0），或者需要调整听牌状态
        if (maxCount == 0) {
            //将tinCards转成map格式
            return String.valueOf(drawnCards);
        }


        // 返回一个默认值或处理逻辑（根据您的实际需求调整）
        return "0";
    }

    private List<Integer> danzhang(List<Integer> handCards) {
        // 统计每张牌出现的次数
        Map<Integer, Integer> cardCountMap = new HashMap<>();
        for (Integer card : handCards) {
            cardCountMap.put(card, cardCountMap.getOrDefault(card, 0) + 1);
        }

        System.out.println("统计结果: " + cardCountMap);

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

        // 遍历手牌，计算哪些是单张
        for (Map.Entry<Integer, Integer> entry : cardCountMap.entrySet()) {
            int card = entry.getKey();
            int count = entry.getValue();

            // 计算剩余单张的数量
            int remainder = count % 2;  // 取模2，奇数就有一个单张
            if (remainder == 1) {
                singleCards.add(card);
            }

        }
        return singleCards;
    }

    private int selectCardToDiscardJiangHu(List<Integer> handCards) {
        List<Integer> tempHand = new ArrayList<>(handCards);


        // 1. 统计牌型
        Map<Integer, Integer> countMap = new HashMap<>();
        for (int c : tempHand) {
            countMap.put(c, countMap.getOrDefault(c, 0) + 1);
        }

        // 2. 找出所有258对子（候选将牌）
        List<Integer> jiangCandidates = new ArrayList<>();
        for (Map.Entry<Integer, Integer> entry : countMap.entrySet()) {
            if (entry.getValue() >= 2 && isCard(entry.getKey())) {
                jiangCandidates.add(entry.getKey());
            }
        }

        // 3. 选择最优将牌（优先选择数量多的258对子）
        Integer bestJiang = selectBestJiang(jiangCandidates, countMap);

        // 4. 构建需要保留的牌（将牌 + 所有258牌）
        Set<Integer> keepCards = new HashSet<>();

        // 保留所有258牌（包括将牌）
        for (int c : tempHand) {
            if (is258Card(c)) {
                keepCards.add(c);
            }
        }

        // 5. 找出需要打出的牌（非258牌）
        List<Integer> discardCandidates = new ArrayList<>();
        for (int c : tempHand) {
            if (!isCard(c)) {
                discardCandidates.add(c);
            }
        }

        // 6. 如果有非258牌，优先打出
        if (!discardCandidates.isEmpty()) {
            return discardCandidates.get(0); // 可以优化选择策略
        }

        // 7. 如果全是258牌，但还没有将牌，需要拆牌做将
        if (bestJiang == null) {
            return selectCardToMakeJiang(tempHand, countMap);
        }

        // 8. 如果全是258牌且有将牌，打出多余的258牌
        return selectRedundant258Card(tempHand, countMap, bestJiang);
    }

    /**
     * 选择最优的将牌
     */
    private Integer selectBestJiang(List<Integer> jiangCandidates, Map<Integer, Integer> countMap) {
        if (jiangCandidates.isEmpty()) {
            return null;
        }

        // 策略：优先选择数量多的258对子（更容易碰成刻子）
        Integer bestJiang = null;
        int maxCount = 0;

        for (int candidate : jiangCandidates) {
            int count = countMap.get(candidate);
            if (count > maxCount) {
                maxCount = count;
                bestJiang = candidate;
            }
        }

        return bestJiang;
    }

    /**
     * 当没有将牌时，选择一张牌来促成将牌
     */
    private int selectCardToMakeJiang(List<Integer> handCards, Map<Integer, Integer> countMap) {
        // 策略：打出手牌中数量最少的258孤张
        for (int c : handCards) {
            if (countMap.get(c) == 1) {
                return c;
            }
        }

        // 如果没有孤张，打出手牌中数量最少的258
        int minCount = Integer.MAX_VALUE;
        int worstCard = handCards.get(0);

        for (int c : handCards) {
            int count = countMap.get(c);
            if (count < minCount) {
                minCount = count;
                worstCard = c;
            }
        }

        return worstCard;
    }

    /**
     * 选择多余的258牌打出
     */
    private int selectRedundant258Card(List<Integer> handCards, Map<Integer, Integer> countMap, int bestJiang) {
        // 策略：保留将牌，打出非将牌的258孤张

        // 1. 先找非将牌的孤张
        for (int c : handCards) {
            if (c != bestJiang && countMap.get(c) == 1) {
                return c;
            }
        }

        // 2. 找数量最少的非将牌
        int minCount = Integer.MAX_VALUE;
        int worstCard = handCards.get(0);

        for (int c : handCards) {
            if (c != bestJiang) {
                int count = countMap.get(c);
                if (count < minCount) {
                    minCount = count;
                    worstCard = c;
                }
            }
        }

        // 3. 如果所有牌都是将牌，只能拆将牌（这种情况很少）
        if (worstCard == bestJiang) {
            // 选择一张将牌打出（保留另一张）
            return bestJiang;
        }

        return worstCard;
    }

    /**
     * 判断是否是258牌
     */
    private boolean isCard(int card) {
        int cardValue = card % 10;
        int cardType = card / 100;

        if (cardValue == 2 || cardValue == 5 || cardValue == 8) {
            return true;
        }

        return false;
    }


    /**
     * 判断手牌中是否有碰牌（刻子）
     * 刻子定义：三张花色相同且点数相同的牌
     * 长沙麻将中碰牌需要满足至少三组刻子
     */
    /**
     * 统计手牌中的刻子数量
     * 刻子定义：三张花色相同且点数相同的牌
     *
     * @param handCards 手牌列表
     * @return 刻子数量
     */
    private int countPengGroups(List<Integer> handCards, List<Integer> pengCard) {
        List<Integer> handCards2 = new ArrayList<>();
        handCards2.addAll(handCards);
//        handCards2.addAll(pengCard);
        System.out.println("碰碰胡 handCards2 ++++++++++++++++" + handCards2);

        // 按花色分组
        Map<Integer, List<Integer>> suitGroupMap = new HashMap<>();
        for (Integer card : handCards2) {
            int suit = card / 100;
            suitGroupMap.computeIfAbsent(suit, k -> new ArrayList<>()).add(card);
        }

        logInfo("手牌花色分组: " + suitGroupMap.keySet().size() + " 种花色");

        int keziCount = 0;

        // 对每个花色分别统计刻子
        for (Map.Entry<Integer, List<Integer>> entry : suitGroupMap.entrySet()) {
            int suit = entry.getKey();
            List<Integer> suitCards = entry.getValue();

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

            // 找出该花色的刻子
            for (Map.Entry<Integer, Integer> valueEntry : valueCountMap.entrySet()) {
                if (valueEntry.getValue() >= 3) {
                    keziCount++;
                    int cardValue = suit * 100 + valueEntry.getKey();
                    logInfo("找到刻子: " + getCardName(cardValue) + " (花色:" + getSuitName(suit) +
                            ", 点数:" + valueEntry.getKey() + ", 数量:" + valueEntry.getValue() + ")");
                }
            }
        }

        logInfo("手牌中共找到 " + keziCount + " 组刻子");
        return keziCount;
    }


    //分析碰碰胡是否听牌
    public boolean hasThreeKeziAndTwoPairs(List<Integer> handCards, List<Integer> pengCard) {
        List<Integer> handCards2 = new ArrayList<>();
        handCards2.addAll(handCards);
//        handCards2.addAll(pengCard);

        // 统计每张牌出现的次数
        Map<Integer, Integer> cardCountMap = new HashMap<>();
        for (Integer card : handCards2) {
            cardCountMap.put(card, cardCountMap.getOrDefault(card, 0) + 1);
        }

        int keziCount = 0;  // 刻子数（三张相同）
        int pairCount = 0;  // 对子数（两张相同）

        // 统计刻子和对子
        for (int count : cardCountMap.values()) {
            if (count >= 3) {
                // 如果有3张或以上，可以算作一个刻子
                keziCount++;
                // 如果有4张，剩余的1张不能算对子，但可能算单张
                if (count >= 4) {
                    // 4张可以看作1个刻子+1张单牌，或者如果有需要可以调整
                    // 这里暂时不额外处理
                }
            } else if (count == 2) {
                pairCount++;
            }
        }

        // 检查是否有至少3个刻子和至少2个对子
        return keziCount >= 3 && pairCount >= 2;
    }


    //拿出剩余牌
    private static Map<String, List<?>> separateKeziAndRemaining(List<Integer> handCards) {
        List<List<Integer>> keziList = new ArrayList<>();
        Set<Integer> remainingCardsSet = new HashSet<>();  // 使用Set去重

        if (handCards == null || handCards.isEmpty()) {
            Map<String, List<?>> result = new HashMap<>();
            result.put("kezi", keziList);
            result.put("remaining", new ArrayList<>());
            return result;
        }

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

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

            if (count >= 3) {
                // 添加刻子
                List<Integer> kezi = new ArrayList<>();
                for (int i = 0; i < 3; i++) {
                    kezi.add(card);
                }
                keziList.add(kezi);

                // 如果还有剩余，加入Set去重
                if (count > 3) {
                    remainingCardsSet.add(card);
                }
            } else {
                // 全部加入剩余牌Set
                remainingCardsSet.add(card);
            }
        }

        // 将Set转换为List
        List<Integer> remainingCards = new ArrayList<>(remainingCardsSet);

        Map<String, List<?>> result = new HashMap<>();
        result.put("kezi", keziList);
        result.put("remaining", remainingCards);
        return result;
    }

    /**
     * 辅助方法：获取牌的名称
     */
    private String getCardName(int card) {
        int suit = card / 100;
        int value = card % 100;
        String suitName = getSuitName(suit);
        return suitName + value;
    }

    private boolean isJiangHu(List<Integer> handCards) {
        // 统计手牌中258牌的数量
        int count258 = 0;

        for (Integer card : handCards) {
            if (is258Card(card)) {
                count258++;
            }
        }

        // 判断258牌是否大于7张
        return count258 >= 10;
    }

    /**
     * 判断一张牌是否是258牌
     */
    private static boolean is258Card(int card) {
        // 假设牌型编码规则：
        // 101-109: 一万到九万
        // 201-209: 一筒到九筒
        // 301-309: 一条到九条

        // 获取牌的数字（个位数）
        int cardValue = card % 10;

        // 258牌的数字必须是2、5、8
        if (cardValue == 2 || cardValue == 5 || cardValue == 8) {
            // 确保是万、筒、条（排除风牌等）
            int cardType = card / 100;
            return true;
        }

        return false;
    }

    /**
     * 七小对大胡策略出牌
     * 当有5对以上时，按照七小对胡牌牌型进行出牌
     */
    public int selectCardToDiscardBig(List<Integer> handCards, int pisCardsCount) {
        if (pisCardsCount >= 5) {
            logInfo("执行七小对大胡策略，当前对子数量: " + pisCardsCount);

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

            // 收集单张牌（数量为1的牌）
            List<Integer> singleCards = new ArrayList<>();
            for (int card : handCards) {
                if (cardCounts.get(card) == 1) {
                    singleCards.add(card);
                }
            }

            // 如果有单张牌，优先打出这些牌
            if (!singleCards.isEmpty()) {
                // 优先打出边张（1和9）
                for (int card : singleCards) {
                    int value = card % 100;
                    if (value == 1 || value == 9) {
                        logInfo("打出七小对策略边张单牌: " + card);
                        return card;
                    }
                }

                // 其次打出中间不相关的牌（避开容易形成对子的中间牌）
                for (int card : singleCards) {
                    int value = card % 100;
                    if (value == 2 || value == 8) {
                        logInfo("打出七小对策略边张单牌: " + card);
                        return card;
                    }
                }

                // 最后随便选一张单牌
                logInfo("打出七小对策略单牌: " + singleCards.get(0));
                return singleCards.get(0);
            }

            // 如果没有单张牌（所有牌都是对子或刻子），需要拆牌
            // 优先拆刻子（保留对子）
            List<Integer> tripleCards = new ArrayList<>();
            for (int card : handCards) {
                if (cardCounts.get(card) >= 3) {
                    tripleCards.add(card);
                    // 只需要一张来代表这个刻子
                    break;
                }
            }

            if (!tripleCards.isEmpty()) {
                logInfo("七小对策略拆刻子: " + tripleCards.get(0));
                return tripleCards.get(0);
            }

            // 如果所有都是对子，理论上已经是七小对听牌状态
            // 但为了保险，随便选一张
            logInfo("七小对策略，所有牌都是对子，随便打出一张: " + handCards.get(0));
            return handCards.get(0);
        }

        // 不满足七小对条件时的默认返回
        return handCards.get(0);
    }


    private String selectCardToDiscardPengPengHu(List<Integer> handCards) {
        logInfo("开始执行碰碰胡出牌策略");
        // 1. 复制手牌，避免修改原始数据
        List<Integer> remainingCards = new ArrayList<>(handCards);

        // 2. 找出所有刻子（三张相同的牌），不重复利用
        List<Integer> keziList = extractAllKezi(remainingCards);
        int keziCount = keziList.size() / 3;
        logInfo("找到刻子: " + keziCount + "组 - " + getKeziNames(keziList));


        //去除刻子后的牌
        List<Integer> feiCandidates = findFeiJiangCandidates5(remainingCards);
        logInfo("去除刻子后的牌: " + (feiCandidates));
        int i = selectFromFeiCandidates4(feiCandidates);
        return String.valueOf(i);
    }

    /**
     * 找出非将牌候选（除了258将牌和刻子之外的牌）
     */
    private List<Integer> findFeiJiangCandidates5(List<Integer> cards) {
        Map<Integer, Integer> cardCount = new HashMap<>();
        List<Integer> feiJiangCandidates = new ArrayList<>();

        // 统计剩余牌的数量
        for (Integer card : cards) {
            cardCount.put(card, cardCount.getOrDefault(card, 0) + 1);
        }


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

            for (int i = 0; i < count; i++) {
                feiJiangCandidates.add(card);
            }
        }

        return feiJiangCandidates;
    }

    /**
     * 从非将牌候选中选择要打出的牌
     * 优先打孤张，否则再拆牌
     */
    private int selectFromFeiCandidates4(List<Integer> feiCandidates) {
        if (feiCandidates.isEmpty()) {
            return -1; // 或者抛出异常，根据实际情况处理
        }

        // 1. 优先找出非对子的牌
        Integer isolatedCard = findIsolatedCardInFei6(feiCandidates);
        logInfo("策略: 打出孤张牌 " + getCardName(isolatedCard));
        return isolatedCard;
    }

    private Integer findIsolatedCardInFei6(List<Integer> feiCandidates) {
        // 统计每张牌的出现次数
        Map<Integer, Integer> countMap = new HashMap<>();
        for (int card : feiCandidates) {
            countMap.put(card, countMap.getOrDefault(card, 0) + 1);
        }

        // 寻找出现次数为 1 的牌（非对子）
        for (int card : feiCandidates) {
            if (countMap.get(card) == 1) {
                return card;
            }
        }

        // 如果没有非对子的牌，返回 null 或选择第一张牌等策略
        return feiCandidates.get(0);
    }


    private String getKeziNames(List<Integer> keziList) {
        if (keziList.isEmpty()) return "无";

        Set<String> keziNames = new HashSet<>();
        for (int i = 0; i < keziList.size(); i += 3) {
            keziNames.add(getCardName(keziList.get(i)));
        }
        return String.join(", ", keziNames);
    }

    /**
     * 提取所有刻子（三张相同的牌），不重复利用
     */
    private List<Integer> extractAllKezi(List<Integer> cards) {
        List<Integer> keziList = new ArrayList<>();
        Map<Integer, Integer> cardCount = new HashMap<>();

        // 统计每张牌的数量
        for (Integer card : cards) {
            cardCount.put(card, cardCount.getOrDefault(card, 0) + 1);
        }

        // 找出所有数量>=3的牌，提取刻子
        List<Integer> cardsToRemove = new ArrayList<>();
        for (Map.Entry<Integer, Integer> entry : cardCount.entrySet()) {
            int card = entry.getKey();
            int count = entry.getValue();

            if (count >= 3) {
                // 计算可以组成几个刻子（比如4张相同的牌可以组成1个刻子+1张单牌）
                int keziGroups = count / 3;
                for (int i = 0; i < keziGroups; i++) {
                    // 添加3次相同的牌表示一个刻子
                    keziList.add(card);
                    keziList.add(card);
                    keziList.add(card);
                }
                // 标记需要从剩余牌中移除的牌（只移除刻子部分）
                for (int i = 0; i < keziGroups * 3; i++) {
                    cardsToRemove.add(card);
                }
            }
        }

        // 从剩余牌中移除刻子
        for (Integer card : cardsToRemove) {
            cards.remove(card);
        }

        return keziList;
    }


    /**
     * 最终出的牌
     * 优化后的分析逻辑：
     * 1. 分析剩余牌的搭子和卡隆情况
     * 2. 优先打出边张且不是将的牌
     * 3. 如果没有，优先打边张1、2，其次2、8，最后随便打
     */
    public int selectCardToDiscard(List<Integer> cardInhand, HandAnalysis analysis) {
        logInfo("\n===== 开始选择出牌策略 =====");
        int discardCard = 0;
        // 如果analysis为null，自动分析手牌
        if (analysis == null) {
            analysis = analyzeHand(cardInhand);
        }

        // 获取剩余牌
        List<Integer> remainingCards = new ArrayList<>(analysis.isolatedCards);
        logInfo("剩余需要分析的牌: " + remainingCards);

        // 识别搭子和卡隆
        List<List<Integer>> daAndKa = identifydaka(remainingCards);
        logInfo("识别到的搭子和卡隆: " + daAndKa);

        // 将搭子和卡隆中的牌收集起来
        Set<Integer> daka = new HashSet<>();
        for (List<Integer> card : daAndKa) {
            daka.addAll(card);
        }
        logInfo("搭子和卡隆中的牌: " + daka);

        // 找出所有可能的出牌候选，排除搭子和卡隆中的牌
        Set<Integer> candidates = new HashSet<>(remainingCards);
        candidates.removeAll(daka);
        logInfo("排除搭子和卡隆后的候选牌: " + candidates);

        // 1. 优先打出边张且不是将的牌
        List<Integer> ban = new ArrayList<>();
        for (int card : candidates) {
            int rank = card % 100;
            // 且不是将牌
            if ((rank != 5 && rank != 2 && rank != 8)) {
                ban.add(card);
            }
        }


        for (int card : candidates) {
            int rank = card % 100;
            // 边张是1或9，且不是将牌
            if ((rank == 1 || rank == 9) && !analysis.usedInPairs.contains(card)) {
                ban.add(card);
            }
        }

        if (!ban.isEmpty()) {
            if (ban.get(0) != 5 && ban.get(0) != 2 && ban.get(0) != 8) {
                return ban.get(0);
            }
        }


        // 4. 如果以上情况都没有，打出剩余随便哪张
        if (!candidates.isEmpty()) {
            discardCard = candidates.iterator().next();

            logInfo("最后选择任意剩余牌: " + discardCard);
            if (discardCard != 5 && discardCard != 2 && discardCard != 8) {
                return discardCard;
            }

        }


        // 检查已完成的牌组中是否有带有将的牌
        for (Integer meld : analysis.isolatedCards) {

            // 检查该牌组中是否有牌是将牌
            if (analysis.usedInPairs.contains(meld)) {
                if (meld == 5 || meld == 2 || meld == 8) {
                    return meld;
                }
            }
        }

        // 如果没有带有将的牌组，选择第一个牌组的第一张牌
        if (!analysis.pairs.isEmpty()) {
            int pcard = 0;
            for (Integer pair : analysis.pairs) {
                int card = pair % 100;
                if (card != 5 && card != 2 && card != 8) {
                    pcard = pair;
                }
            }
            if (pcard != 0) {
                return pcard;
            } else {
                return analysis.pairs.get(0);
            }
        }

        if (!analysis.remainingCards.isEmpty()) {
            for (Integer pair : analysis.remainingCards) {
                int card = pair % 100;
                if (card != 5 && card != 2 && card != 8) {
                    return pair;
                }
            }
        }

        if (!analysis.completedMelds.isEmpty()) {
            List<Integer> validMelds = new ArrayList<>();

            for (List<Integer> meld : analysis.completedMelds) {
                // 检查整个组合中是否包含要排除的牌
                boolean containsExcluded = false;
                for (Integer card : meld) {
                    int cardValue = card % 100;
                    if (cardValue == 5 || cardValue == 2 || cardValue == 8) {
                        containsExcluded = true;
                        break;
                    }
                }
                // 如果整个组合都不包含排除的牌，记录下来
                if (!containsExcluded && !meld.isEmpty()) {
                    validMelds.add(meld.get(0));
                }
            }

            // 如果有有效的组合，返回第一个
            if (!validMelds.isEmpty()) {
                return validMelds.get(0);
            }

            // 如果所有组合都包含排除牌，返回第一个组合的第一张牌作为备选
            return analysis.completedMelds.get(0).get(0);
        }


        if (!analysis.remainingCards.isEmpty()) {
            for (Integer pair : analysis.remainingCards) {
                int card = pair % 100;
                if (card == 5 || card == 2 || card == 8) {
                    return pair;
                }
            }
        }

        return discardCard;
    }

    /**
     * 识别搭子和卡隆
     * 搭子：两张连续的牌，例如1-2，2-3等
     * 卡隆：两张中间缺一张的牌，例如1-3（缺2），2-4（缺3）等
     */
    private List<List<Integer>> identifydaka(List<Integer> cards) {
        List<List<Integer>> daka = new ArrayList<>();

        // 按花色分组
        Map<Integer, List<Integer>> cardsBySuit = new HashMap<>();
        for (int card : cards) {
            int suit = card / 100;
            cardsBySuit.computeIfAbsent(suit, k -> new ArrayList<>()).add(card);
        }

        // 记录已经使用过的牌
        Set<Integer> usedCards = new HashSet<>();

        // 分析每个花色
        for (List<Integer> suitCards : cardsBySuit.values()) {
            Collections.sort(suitCards);

            // 优先找搭子（连续两张）
            for (int i = 0; i < suitCards.size() - 1; i++) {
                int card1 = suitCards.get(i);
                int card2 = suitCards.get(i + 1);

                if (usedCards.contains(card1) || usedCards.contains(card2)) {
                    continue; // 牌已被使用
                }

                int rank1 = card1 % 100;
                int rank2 = card2 % 100;

                // 搭子：连续两张牌
                if (rank2 - rank1 == 1) {
                    daka.add(Arrays.asList(card1, card2));
                    usedCards.add(card1);
                    usedCards.add(card2);
                    i++; // 跳过下一张牌
                }
            }

            // 再找卡隆（中间差一张）
            for (int i = 0; i < suitCards.size() - 1; i++) {
                int card1 = suitCards.get(i);

                if (usedCards.contains(card1)) {
                    continue;
                }

                for (int j = i + 1; j < suitCards.size(); j++) {
                    int card2 = suitCards.get(j);

                    if (usedCards.contains(card2)) {
                        continue;
                    }

                    int rank1 = card1 % 100;
                    int rank2 = card2 % 100;
                    int rankDiff = rank2 - rank1;

                    // 卡隆：中间差一张
                    if (rankDiff == 2) {
                        daka.add(Arrays.asList(card1, card2));
                        usedCards.add(card1);
                        usedCards.add(card2);
                        break;
                    } else if (rankDiff > 2) {
                        break;
                    }
                }
            }
        }

        return daka;
    }


    /**
     * 碰牌判断方法
     *
     * @param opcard    要碰的牌
     * @param handCards 当前手牌
     * @return 是否允许碰牌
     */
    public boolean shouldPong(int opcard, List<Integer> handCards) {
        // 1. 判断是否有至少两张相同的牌可以碰
        int count = 0;
        for (int card : handCards) {
            if (card == opcard) {
                count++;
            }
        }
        if (count < 2) {
            return false;
        }

        // 2. 如果是清一色花色，只能碰相同花色的牌
        if (isAllSameSuit1(handCards)) {
            Integer mainSuit = getMainSuit(handCards);
            int opcardSuit = opcard / 100;
            if (mainSuit != null && mainSuit != opcardSuit) {
                logInfo("清一色模式：不能碰不同花色的牌。目标牌花色：" + getSuitName(opcardSuit) + ", 主花色：" + getSuitName(mainSuit));
                return false;
            }
        }

        // 2. 复制手牌并模拟去掉要碰的两张牌
        List<Integer> tempHand = new ArrayList<>(handCards);
        tempHand.remove(Integer.valueOf(opcard));
        tempHand.remove(Integer.valueOf(opcard));

        // 3. 检查该牌是否是听牌组中的牌
        List<Integer> tingCards = calculateTingCards(tempHand);
        if (tingCards.contains(opcard)) {
            return false;
        }

        // 4. 检查该牌是否是顺子的一部分
        if (isPartOfSequence(opcard, handCards)) {
            return false;
        }

        // 5. 检查该牌是否是唯一的将牌
        if (isOnlyPair(tempHand, opcard)) {
            return false;
        }

        // 其他情况允许碰牌
        return true;
    }

    /**
     * 吃牌判断方法
     *
     * @param opcard    要吃的牌
     * @param handCards 当前手牌
     * @return 是否允许吃牌
     */
    public boolean shouldChow(int opcard, List<Integer> handCards) {
        logInfo("吃牌判断开始, 目标牌: " + opcard + ", 当前手牌: " + handCards);

        // 1. 如果是清一色花色，只能吃相同花色的牌
        if (isAllSameSuit1(handCards)) {
            Integer mainSuit = getMainSuit(handCards);
            int opcardSuit = opcard / 100;
            if (mainSuit != null && mainSuit != opcardSuit) {
                logInfo("清一色模式：不能吃不同花色的牌。目标牌花色：" + getSuitName(opcardSuit) + ", 主花色：" + getSuitName(mainSuit));
                return false;
            }
        }

        // 创建手牌的副本，避免修改原手牌
        List<Integer> handCopy = new ArrayList<>(handCards);

        // 分析手牌，识别刻子和顺子
        HandAnalysis analysis = analyzeHand(handCopy);

        // 获取剩余牌（未用于刻子或顺子的牌）
        List<Integer> remainingCards = analysis.remainingCards;

        // 检查剩余牌是否能与其他两张牌组成包含opcard的顺子
        boolean canChow = canFormChow(opcard, remainingCards);

        logInfo("吃牌判断结束, 结果: " + canChow);
        return canChow;
    }

    /**
     * 检查是否能形成包含目标牌的顺子
     * @param targetCard 目标牌
     * @param handCards 手牌
     * @return 是否能吃牌
     */

    /**
     * 判断是否应该杠牌（补牌）
     *
     * @param proposedCard 要杠的牌
     * @param currentHand  当前手牌
     * @param （1:暗杠,       2:明杠, 3:加杠, 4:补杠等）
     * @return 是否应该杠牌
     */
    public boolean shouldGang(int proposedCard, List<Integer> currentHand) {
        logInfo("判断是否应该杠牌: " + proposedCard);

        // 1. 如果是清一色花色，只能杠相同花色的牌
        if (isAllSameSuit1(currentHand)) {
            Integer mainSuit = getMainSuit(currentHand);
            int proposedCardSuit = proposedCard / 100;
            if (mainSuit != null && mainSuit != proposedCardSuit) {
                logInfo("清一色模式：不能杠不同花色的牌。目标牌花色：" + getSuitName(proposedCardSuit) + ", 主花色：" + getSuitName(mainSuit));
                return false;
            }
        }

        // 基础杠牌条件：手牌中至少有3张相同的牌
        int count = 0;
        for (int card : currentHand) {
            if (card == proposedCard) {
                count++;
            }
        }

        if (count < 3) {
            logInfo("手牌中没有足够的相同牌来杠");
            return false;
        }

        // 这里可以添加更多杠牌决策逻辑，目前只实现清一色优化
        return true;
    }


    private boolean canFormChow(int targetCard, List<Integer> handCards) {
        // 检查是否是字牌（风牌或箭牌），字牌不能组成顺子
        int suit = targetCard / 100;
        if (suit == 4 || suit == 5) { // 4是风牌，5是箭牌
            return false;
        }

        // 获取目标牌的点数
        int targetPoint = targetCard % 100;

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

        // 检查三种可能的顺子组合
        // 1. targetCard-2, targetCard-1, targetCard
        if (targetPoint >= 3) {
            int card1 = suit * 100 + (targetPoint - 2);
            int card2 = suit * 100 + (targetPoint - 1);
            if (cardCounts.containsKey(card1) && cardCounts.containsKey(card2)) {
                return true;
            }
        }

        // 2. targetCard-1, targetCard, targetCard+1
        if (targetPoint >= 2 && targetPoint <= 8) {
            int card1 = suit * 100 + (targetPoint - 1);
            int card2 = suit * 100 + (targetPoint + 1);
            if (cardCounts.containsKey(card1) && cardCounts.containsKey(card2)) {
                return true;
            }
        }

        // 3. targetCard, targetCard+1, targetCard+2
        if (targetPoint <= 7) {
            int card1 = suit * 100 + (targetPoint + 1);
            int card2 = suit * 100 + (targetPoint + 2);
            if (cardCounts.containsKey(card1) && cardCounts.containsKey(card2)) {
                return true;
            }
        }

        return false;
    }


    /**
     * 计算听牌
     *
     * @param handCards 手牌
     * @return 听牌列表
     */
    private List<Integer> calculateTingCards(List<Integer> handCards) {
        List<Integer> tingCards = new ArrayList<>();
        Map<Integer, Integer> cardCount = countCards(handCards);

        // 检查每种花色的牌
        for (int suit = 1; suit <= 3; suit++) { // 1:万, 2:筒, 3:索
            List<Integer> sameSuitCards = new ArrayList<>();
            for (int rank = 1; rank <= 9; rank++) {
                int card = suit * 100 + rank;
                int count = cardCount.getOrDefault(card, 0);
                for (int i = 0; i < count; i++) {
                    sameSuitCards.add(rank);
                }
            }

            // 检查是否有搭子需要补牌
            if (sameSuitCards.size() > 0) {
                // 简单检查：如果有单张牌，可能听它的相邻牌或相同牌
                Map<Integer, Integer> rankCount = new HashMap<>();
                for (int rank : sameSuitCards) {
                    rankCount.put(rank, rankCount.getOrDefault(rank, 0) + 1);
                }

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

                    // 如果是单张或对子，可能需要补牌
                    if (count == 1 || count == 2) {
                        // 添加当前牌（可能组成刻子）
                        tingCards.add(suit * 100 + rank);

                        // 添加相邻牌（可能组成顺子）
                        if (rank > 1) {
                            tingCards.add(suit * 100 + (rank - 1));
                        }
                        if (rank < 9) {
                            tingCards.add(suit * 100 + (rank + 1));
                        }
                    }
                }
            }
        }

        return tingCards;
    }

    /**
     * 判断是否是顺子的一部分
     *
     * @param card      要判断的牌
     * @param handCards 手牌
     * @return 是否是顺子的一部分
     */
    private boolean isPartOfSequence(int card, List<Integer> handCards) {
        int suit = card / 100;
        int rank = card % 100;

        // 检查是否存在顺子
        // 顺子是三个连续的牌，比如1-2-3，2-3-4等
        boolean hasPrevPrev = handCards.contains(suit * 100 + rank - 2);
        boolean hasPrev = handCards.contains(suit * 100 + rank - 1);
        boolean hasNext = handCards.contains(suit * 100 + rank + 1);
        boolean hasNextNext = handCards.contains(suit * 100 + rank + 2);

        // 检查是否是顺子的中间牌或边牌
        return (hasPrev && hasNext) || (hasPrevPrev && hasPrev) || (hasNext && hasNextNext);
    }

    /**
     * 判断是否是唯一的将牌
     *
     * @param tempHand 去掉两张要碰的牌后的手牌
     * @param opcard   要碰的牌
     * @return 是否是唯一的将牌
     */
    public boolean isOnlyPair(List<Integer> tempHand, int opcard) {
        Map<Integer, Integer> cardCount = countCards(tempHand);
        int pairCount = 0;

        for (Map.Entry<Integer, Integer> entry : cardCount.entrySet()) {
            if (entry.getValue() == 2) {
                pairCount++;
            }
        }

        // 如果去掉要碰的牌后没有对子，说明原来的牌是唯一的将牌
        return pairCount == 0;
    }

    /**
     * 统计每张牌的数量
     *
     * @param handCards 手牌
     * @return 牌的数量映射
     */
    private Map<Integer, Integer> countCards(List<Integer> handCards) {
        Map<Integer, Integer> cardCount = new HashMap<>();
        for (int card : handCards) {
            cardCount.put(card, cardCount.getOrDefault(card, 0) + 1);
        }
        return cardCount;
    }


    //大胡分析七小对
    public static int countPairs(List<Integer> handCards) {
        // 1. 先根据花色和点数排序
        List<Integer> sortedCards = new ArrayList<>(handCards);
        sortedCards.sort((a, b) -> {
            int suitA = a / 100;
            int suitB = b / 100;
            int rankA = a % 100;
            int rankB = b % 100;

            // 先按花色排序，再按点数排序
            if (suitA != suitB) {
                return suitA - suitB;
            }
            return rankA - rankB;
        });

        // 2. 统计对子
        int pairCount = 0;
        for (int i = 0; i < sortedCards.size() - 1; i++) {
            if (sortedCards.get(i).equals(sortedCards.get(i + 1))) {
                pairCount++;
                i++; // 跳过下一张
            }
        }

        return pairCount;
    }


    //分析七小对清一色
    public List<Integer> qixiaoduiqingyise(List<Integer> handCards) {
        // 合并所有牌
        List<Integer> allCards = new ArrayList<>();
        allCards.addAll(handCards);

        // 按花色分组
        List<Integer> wanCards = new ArrayList<>();   // 万: 101-109
        List<Integer> tongCards = new ArrayList<>();  // 筒: 201-209
        List<Integer> tiaoCards = new ArrayList<>();  // 条: 301-309

        for (Integer card : allCards) {
            if (card >= 101 && card <= 109) {
                wanCards.add(card);
            } else if (card >= 201 && card <= 209) {
                tongCards.add(card);
            } else if (card >= 301 && card <= 309) {
                tiaoCards.add(card);
            }
        }

        // 检查各花色数量
        if (wanCards.size() >= 8) {
            Collections.sort(wanCards);
            logInfo("检测到清一色花色: 万, 数量: " + wanCards.size());
            return wanCards;
        }

        if (tongCards.size() >= 8) {
            Collections.sort(tongCards);
            logInfo("检测到清一色花色: 筒, 数量: " + tongCards.size());
            return tongCards;
        }

        if (tiaoCards.size() >= 8) {
            Collections.sort(tiaoCards);
            logInfo("检测到清一色花色: 条, 数量: " + tiaoCards.size());
            return tiaoCards;
        }

        return new ArrayList<>();
    }

    public boolean hasFourOrMorePairs(List<Integer> qixiaoduiqingyise) {
        if (qixiaoduiqingyise == null || qixiaoduiqingyise.size() < 8) {
            return false; // 至少需要8张牌才能有4对
        }

        // 对牌进行排序
        List<Integer> sortedCards = new ArrayList<>(qixiaoduiqingyise);
        Collections.sort(sortedCards);

        // 统计对子数量
        int pairCount = 0;
        int i = 0;
        int n = sortedCards.size();

        while (i < n - 1) {
            if (sortedCards.get(i).equals(sortedCards.get(i + 1))) {
                // 找到一对对子
                pairCount++;
                i += 2; // 跳过这对对子
            } else {
                i += 1; // 继续检查下一张牌
            }
        }

        logInfo("清一色手牌中对子数量: " + pairCount);
        return pairCount >= 4;
    }

    //分析清一色
    public boolean isAllSameSuit(List<Integer> handCards, List<Integer> pengCard) {
        // 统计各花色的牌数量
        Map<Integer, Integer> suitCountMap = new HashMap<>();
        List<Integer> handCards2 = new ArrayList<>();
        handCards2.addAll(handCards);
//        handCards2.addAll(pengCard);

        for (Integer card : handCards2) {
            int suit = card / 100; // 获取花色，100=万，200=筒，300=条
            suitCountMap.put(suit, suitCountMap.getOrDefault(suit, 0) + 1);
        }

        // 检查是否有花色的牌数量超过8张
        for (Map.Entry<Integer, Integer> entry : suitCountMap.entrySet()) {
            int suit = entry.getKey();

            int count = entry.getValue();

            if (count >= 10) {
                String suitName = getSuitName(suit);
                logInfo("检测到可能的清一色花色: " + suitName + ", 数量: " + count);
                return true;
            }
        }

        return false;
    }

    /**
     * 检测当前牌 是否符合清一色
     * @param card
     * @param handCards
     * @param pengguopai
     * @param chipai
     * @param gangpai
     * @return
     */
    public static boolean checkAllSameSuitAll(int card, List<Integer> handCards, List<Integer> pengguopai, List<Integer> chipai, List<Integer> gangpai) {
        //判断 peng，chi ，gang是否有不同色
        //true 为可以 false 为不能
        List<Integer> cpg = new ArrayList<>();
        cpg.addAll(pengguopai);
        cpg.addAll(chipai);
        cpg.addAll(gangpai);
        if (cpg.size()>0){
            int tmp1 = 0;
            int tmp2 = 0;
            for (int i=0;i<cpg.size()-1;i++) {
                tmp1 = cpg.get(i);
                tmp2 = cpg.get(i+1);
                if (Math.abs(tmp2-tmp1)>10){
                    //落地已经有了不同色，所以可以进行
                    return true;

                }
            }
        }
        //加入之后
        cpg.add(card);
        if (cpg.size()>1){
            int tmp3 = 0;
            int tmp4 = 0;
            for (int i=0;i<cpg.size()-1;i++) {
                tmp3 = cpg.get(i);
                tmp4 = cpg.get(i+1);
                if (Math.abs(tmp4-tmp3)>10){
                    //牌 加入已经破坏手牌
                    return false;
                }
            }
        }
        cpg.clear();
        //判断手牌
        if(handCards.size()>3){
            //手牌判断
            // 统计各花色的牌数量
            Map<Integer, Integer> suitCountMap = new HashMap<>();
            for (Integer cards : handCards) {
                int suit = cards / 100; // 获取花色，100=万，200=筒，300=条
                suitCountMap.put(suit, suitCountMap.getOrDefault(suit, 0) + 1);
            }

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

                if (handCards.size()==4){
                    //手牌只有4张
                    if (count >= 2) {
                        //当手牌已经剩下4张时候，可以进行
                        return true;
                    }
                }

                if (count >= handCards.size()-3) {
                    int tmpsuit = card / 100;
                    if (suit == tmpsuit){
                        return true;
                    }
                }
            }
        }
        return  false;
    }



    //分析清一色
    public boolean isAllSameSuit1(List<Integer> handCards) {
        // 统计各花色的牌数量
        Map<Integer, Integer> suitCountMap = new HashMap<>();

        for (Integer card : handCards) {
            int suit = card / 100; // 获取花色，100=万，200=筒，300=条
            suitCountMap.put(suit, suitCountMap.getOrDefault(suit, 0) + 1);
        }


        for (Map.Entry<Integer, Integer> entry : suitCountMap.entrySet()) {
            int suit = entry.getKey();

            int count = entry.getValue();


            if (count >= 11) {
                String suitName = getSuitName(suit);
                logInfo("检测到可能的清一色花色: " + suitName + ", 数量: " + count);
                return true;
            }
        }

        return false;
    }


    // 获取主要花色（数量最多且≥9张的花色）
    public Integer getMainSuit(List<Integer> handCards) {
        Map<Integer, Integer> suitCountMap = new HashMap<>();

        for (Integer card : handCards) {
            int suit = card / 100;
            suitCountMap.put(suit, suitCountMap.getOrDefault(suit, 0) + 1);
        }

        Integer mainSuit = null;
        int maxCount = 0;

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

            if (count >= 10 && count > maxCount) {
                maxCount = count;
                mainSuit = suit;
            }
        }

        return mainSuit;
    }

    // 清一色特定出牌策略

    /**
     * 基于花色分析的清一色七小对出牌策略
     * 优先打出花色最少的牌，以优化七小对的形成
     *
     * @param handCards 当前手牌
     * @return 最优打出的牌
     */
    private String selectCardToDiscardAllSameSuitQiXiaoDuiBySuit(List<Integer> handCards) {
        // 1. 分析每个花色的牌数量
        Map<Integer, Integer> suitCount = new HashMap<>();
        Map<Integer, List<Integer>> cardsBySuit = new HashMap<>();

        for (int card : handCards) {
            int suit = card / 10; // 计算花色
            suitCount.put(suit, suitCount.getOrDefault(suit, 0) + 1);

            // 按花色分组存储牌
            cardsBySuit.computeIfAbsent(suit, k -> new ArrayList<>()).add(card);
        }

        logInfo("花色分布统计: " + suitCount);

        // 2. 找出花色数量最少的花色（排除主花色）
        Integer mainSuit = getMainSuit(handCards);
        Integer leastSuit = null;
        int minCount = Integer.MAX_VALUE;

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

            // 如果不是主花色，且数量更少
            if ((mainSuit == null || suit != mainSuit) && count < minCount) {
                minCount = count;
                leastSuit = suit;
            }
        }

        // 3. 从最少花色中选择要打出的牌
        if (leastSuit != null && cardsBySuit.containsKey(leastSuit)) {
            List<Integer> leastSuitCards = cardsBySuit.get(leastSuit);
            logInfo("优先从最少花色 " + getSuitName(leastSuit) + " 中选择打出的牌: " + leastSuitCards);

            // 统计最少花色中各牌的出现次数
            Map<Integer, Integer> cardCountsInLeastSuit = new HashMap<>();
            for (int card : leastSuitCards) {
                cardCountsInLeastSuit.put(card, cardCountsInLeastSuit.getOrDefault(card, 0) + 1);
            }

            // 优先打出单张牌（出现次数为1）
            for (Map.Entry<Integer, Integer> entry : cardCountsInLeastSuit.entrySet()) {
                if (entry.getValue() == 1) {
                    logInfo("选择打出最少花色中的单张牌: " + entry.getKey());
                    return String.valueOf(entry.getKey());
                }
            }

            // 如果没有单张，优先打对子的，优先保留刻子或四张一样的
            for (Map.Entry<Integer, Integer> entry : cardCountsInLeastSuit.entrySet()) {
                if (entry.getValue() == 2) {
                    return String.valueOf(entry.getKey());
                }
            }
        }

        // 4. 如果没有找到合适的牌（可能所有牌都是同一花色），使用七小对大胡策略
        logInfo("使用默认七小对大胡策略");
        int outcard = selectCardToDiscardBig(handCards, countPairs(handCards));
        return String.valueOf(outcard);
    }

    private String selectCardToDiscardPengPeng(List<Integer> handCards) {
        logInfo("开始执行清一色碰碰胡出牌策略");

        // 1. 分析每个花色的牌数量
        Map<Integer, Integer> suitCount = new HashMap<>();
        Map<Integer, List<Integer>> cardsBySuit = new HashMap<>();

        for (int card : handCards) {
            int suit = card / 100; // 计算花色（修正为除以100）
            suitCount.put(suit, suitCount.getOrDefault(suit, 0) + 1);

            // 按花色分组存储牌
            cardsBySuit.computeIfAbsent(suit, k -> new ArrayList<>()).add(card);
        }

        // 2. 找出主要花色（牌数量最多的花色）
        int mainSuit = findMainSuit(suitCount);
        logInfo("主要花色: " + getSuitName(mainSuit) + ", 数量: " + suitCount.get(mainSuit));

        // 3. 如果有非主要花色的牌，优先打出
        if (hasNonMainSuitCards(suitCount, mainSuit)) {
            logInfo("存在非主要花色牌，优先打出");
            return discardNonMainSuitCard(handCards, mainSuit);
        }

        // 4. 所有牌都是主要花色，使用清一色碰碰胡策略
        logInfo("所有牌都是主要花色，使用清一色碰碰胡策略");
        return discardFromSameSuitPengPeng(handCards, mainSuit);
    }

    /**
     * 打出非主要花色的牌
     */
    private String discardNonMainSuitCard(List<Integer> handCards, int mainSuit) {
        // 优先打出数量最少的非主要花色牌
        List<Integer> nonMainSuitCards = new ArrayList<>();
        for (int card : handCards) {
            int suit = card / 100;
            if (suit != mainSuit) {
                nonMainSuitCards.add(card);
            }
        }

        // 按数量排序，优先打出手牌数量少的牌
        Map<Integer, Integer> cardCount = countCardOccurrences(nonMainSuitCards);
        nonMainSuitCards.sort((a, b) -> {
            int countA = cardCount.get(a);
            int countB = cardCount.get(b);
            return Integer.compare(countA, countB);
        });

        int discardCard = nonMainSuitCards.get(0);
        logInfo("打出非主要花色牌: " + getCardName(discardCard));
        return String.valueOf(discardCard);
    }


    /**
     * 统计每张牌的出现次数
     */
    private Map<Integer, Integer> countCardOccurrences(List<Integer> cards) {
        Map<Integer, Integer> countMap = new HashMap<>();
        for (int card : cards) {
            countMap.put(card, countMap.getOrDefault(card, 0) + 1);
        }
        return countMap;
    }

    /**
     * 找出主要花色（牌数量最多的花色）
     */
    private int findMainSuit(Map<Integer, Integer> suitCount) {
        int mainSuit = -1;
        int maxCount = 0;

        for (Map.Entry<Integer, Integer> entry : suitCount.entrySet()) {
            if (entry.getValue() > maxCount) {
                maxCount = entry.getValue();
                mainSuit = entry.getKey();
            }
        }

        return mainSuit;
    }

    /**
     * 判断是否有非主要花色的牌
     */
    private boolean hasNonMainSuitCards(Map<Integer, Integer> suitCount, int mainSuit) {
        for (Map.Entry<Integer, Integer> entry : suitCount.entrySet()) {
            if (entry.getKey() != mainSuit && entry.getValue() > 0) {
                return true;
            }
        }
        return false;
    }

    /**
     * 从同花色牌中选择要打出的牌（清一色碰碰胡策略）
     */
    private String discardFromSameSuitPengPeng(List<Integer> handCards, int mainSuit) {
        // 统计每张牌的数量
        Map<Integer, Integer> cardCount = countCardOccurrences(handCards);

        // 找出刻子、将牌候选和剩余牌
        List<Integer> keziCards = new ArrayList<>();
        List<Integer> jiangCandidates = new ArrayList<>(); // 258将牌候选
        List<Integer> otherJiangCandidates = new ArrayList<>(); // 其他将牌候选
        List<Integer> remainingCards = new ArrayList<>(handCards);

        // 1. 先找出刻子（三张相同的牌）
        findAndRemoveKezi(remainingCards, cardCount, keziCards);


        findJiangCandidates(remainingCards, jiangCandidates, otherJiangCandidates);

        // 3. 选择要打出的牌
        int discardCard = selectDiscardCardPengPeng(remainingCards, otherJiangCandidates, cardCount, handCards);

        logInfo("清一色碰碰胡策略打出: " + getCardName(discardCard));
        return String.valueOf(discardCard);
    }

    /**
     * 找出将牌候选
     */
    private void findJiangCandidates(List<Integer> cards, List<Integer> jiangCandidates, List<Integer> otherJiangCandidates) {
        Map<Integer, Integer> cardCount = countCardOccurrences(cards);

        for (int card : cards) {

            int count = cardCount.get(card);
            if (count >= 2) {
                otherJiangCandidates.add(card);
            } else if (count == 1) {
                otherJiangCandidates.add(card);
            }
        }
    }

    /**
     * 选择要打出的牌（清一色碰碰胡策略）
     */
    private int selectDiscardCardPengPeng(List<Integer> remainingCards,
                                          List<Integer> otherJiangCandidates,
                                          Map<Integer, Integer> cardCount
            , List<Integer> handCards) {

        // 如果还有剩余牌，优先从剩余牌中选择
        if (!remainingCards.isEmpty()) {
            // 策略1: 优先打出孤张（没有相邻牌的牌）
            Integer isolatedCard = findIsolatedCard(remainingCards, cardCount);
            if (isolatedCard != null) {
                return isolatedCard;
            }

            // 策略2: 优先打出非258的牌
            Integer non258Card = findNon258Card(remainingCards);
            if (non258Card != null) {
                return non258Card;
            }

            // 策略3: 打出手牌数量最少的牌
            return findLeastCountCard(remainingCards, cardCount);
        }


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


        // 默认情况（理论上不会执行到这里）
        logInfo("警告：无法选择出牌，使用默认策略");
        return remainingCards.isEmpty() ? handCards.get(0) : remainingCards.get(0);
    }

    /**
     * 查找手牌数量最少的牌
     */
    private int findLeastCountCard(List<Integer> cards, Map<Integer, Integer> cardCount) {
        int minCount = Integer.MAX_VALUE;
        int resultCard = cards.get(0);

        for (int card : cards) {
            int count = cardCount.get(card);
            if (count < minCount) {
                minCount = count;
                resultCard = card;
            }
        }

        return resultCard;
    }

    /**
     * 查找非258的牌
     */
    private Integer findNon258Card(List<Integer> cards) {
        for (int card : cards) {
            int value = card % 100;
            if (value != 2 && value != 5 && value != 8) {
                return card;
            }
        }
        return null;
    }

    public int selectCardToDiscardForAllSameSuit(List<Integer> handCards, List<Integer> chowGroup, List<Integer> pengGroup) {
        Integer mainSuit = getMainSuit(handCards);
        if (mainSuit == null) {
            logInfo("未找到主要花色，使用默认策略");
            return -1;
        }
        List<Integer> chi = new ArrayList<>();
        chi.addAll(chowGroup);
        //如果吃和碰的牌 包含主要花色的牌，放弃走清一色
        if (chowGroup != null && pengGroup != null && chowGroup.size() > 0 && pengGroup.size() > 0) {
            chi.addAll(pengGroup);
            for (Integer integer : chi) {
                String str = integer.toString();
                if (!str.isEmpty()) {
                    int firstDigit = Character.getNumericValue(str.charAt(0));
                    if (!mainSuit.equals(firstDigit)) {
                        return -1;
                    }
                }
            }
        }

//        boolean allSameSuit = isAllSameSuit(handCards, mainSuit);

        String mainSuitName = getSuitName(mainSuit);
        logInfo("执行清一色策略，主要花色: " + mainSuitName);

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

        // 收集非主要花色的牌
        List<Integer> nonMainSuitCards = new ArrayList<>();
        for (Integer card : handCards) {
            int suit = card / 100;
            if (suit != mainSuit) {
                nonMainSuitCards.add(card);
            }
        }

        // 如果有非主要花色的牌，优先打出这些牌
        if (!nonMainSuitCards.isEmpty()) {
            logInfo("有非主要花色牌，优先打出");

            // 按优先级打出非主要花色牌
            Integer cardToDiscard = selectNonMainSuitCard(nonMainSuitCards, cardCountMap);
            if (cardToDiscard != null) {
                return cardToDiscard;
            }
        }

        // 如果所有牌都是主要花色，使用清一色优化策略
        logInfo("所有牌都是主要花色，使用清一色优化策略");
        return selectCardFromSameSuit(handCards, cardCountMap, mainSuit);
    }


    public boolean isAllSameSuit(List<Integer> handCards, Integer mainSuit) {
        // 提取主花色牌
        List<Integer> mainSuitCards = new ArrayList<>();
        for (Integer card : handCards) {
            int suit = card / 100;
            if (suit == mainSuit) {
                mainSuitCards.add(card);
            }
        }

        Map<String, List<List<Integer>>> stringListMap = analyzeMainSuitPatterns(mainSuitCards);

        List<List<Integer>> sequences = stringListMap.get("sequences");  // 顺子列表
        List<List<Integer>> triplets = stringListMap.get("triplets");    // 刻子列表
        List<List<Integer>> pairs = stringListMap.get("pairs");          // 对子列表

        // 获取数量
        int sequenceCount = sequences.size();
        int tripletCount = triplets.size();


// 判断顺子加上刻子的数量是否大于6
        boolean isSequenceAndTripletGreaterThan6 = (sequenceCount + tripletCount) > 6;

        return isSequenceAndTripletGreaterThan6;
    }


    /**
     * 分析主花色牌组中的顺子、刻子、对子
     *
     * @param mainSuitCards 主花色牌组
     * @return 包含顺子、刻子、对子信息的Map
     */
    private Map<String, List<List<Integer>>> analyzeMainSuitPatterns(List<Integer> mainSuitCards) {
        Map<String, List<List<Integer>>> patterns = new HashMap<>();
        patterns.put("sequences", new ArrayList<>());  // 顺子
        patterns.put("triplets", new ArrayList<>());   // 刻子
        patterns.put("pairs", new ArrayList<>());      // 对子

        if (mainSuitCards == null || mainSuitCards.isEmpty()) {
            return patterns;
        }

        // 提取所有点数
        List<Integer> points = new ArrayList<>();
        for (Integer card : mainSuitCards) {
            int point = card % 100;
            points.add(point);
        }
        Collections.sort(points);

        // 统计每个点数的数量
        Map<Integer, Integer> pointCountMap = new HashMap<>();
        for (Integer point : points) {
            pointCountMap.put(point, pointCountMap.getOrDefault(point, 0) + 1);
        }

        // 找出刻子（三张相同的牌）
        for (Map.Entry<Integer, Integer> entry : pointCountMap.entrySet()) {
            if (entry.getValue() >= 3) {
                List<Integer> triplet = new ArrayList<>();
                for (int i = 0; i < 3; i++) {
                    triplet.add(entry.getKey());
                }
                patterns.get("triplets").add(triplet);
            }
        }

        // 找出对子
        for (Map.Entry<Integer, Integer> entry : pointCountMap.entrySet()) {
            if (entry.getValue() >= 2) {
                List<Integer> pair = new ArrayList<>();
                for (int i = 0; i < 2; i++) {
                    pair.add(entry.getKey());
                }
                patterns.get("pairs").add(pair);
            }
        }

        // 找出顺子（需要从剩余牌中找）
        // 先复制一份牌用于顺子检测（避免刻子/对子使用的牌影响顺子检测）
        List<Integer> remainingPoints = new ArrayList<>(points);

        // 移除刻子使用的牌（如果有的话）
        for (List<Integer> triplet : patterns.get("triplets")) {
            int point = triplet.get(0);
            for (int i = 0; i < 3; i++) {
                remainingPoints.remove((Integer) point);
            }
        }

        // 检查顺子
        for (int start = 1; start <= 7; start++) {
            boolean canFormSequence = true;
            List<Integer> tempPoints = new ArrayList<>(remainingPoints);
            List<Integer> sequence = new ArrayList<>();

            // 检查是否有连续的3个点数
            for (int i = 0; i < 3; i++) {
                int currentPoint = start + i;
                if (!tempPoints.remove((Integer) currentPoint)) {
                    canFormSequence = false;
                    break;
                }
                sequence.add(currentPoint);
            }

            if (canFormSequence) {
                patterns.get("sequences").add(sequence);
                // 从剩余牌中移除这三个点数
                for (int i = 0; i < 3; i++) {
                    remainingPoints.remove((Integer) (start + i));
                }
            }
        }

        return patterns;
    }


    /**
     * 选择非主要花色牌打出
     */
    private Integer selectNonMainSuitCard(List<Integer> nonMainSuitCards, Map<Integer, Integer> cardCountMap) {
        // 1. 优先打出手牌中数量最少的单张牌
        List<Integer> singleCards = new ArrayList<>();
        for (Integer card : nonMainSuitCards) {
            if (cardCountMap.get(card) == 1) {
                singleCards.add(card);
            }
        }

        if (!singleCards.isEmpty()) {
            // 在单张牌中优先打边张(1和9)
            Integer edgeCard = findEdgeCard(singleCards);
            if (edgeCard != null) {
                logInfo("打出非主要花色的边张单牌: " + edgeCard);
                return edgeCard;
            }
            // 没有边张就打任意单张
            logInfo("打出非主要花色的单张牌: " + singleCards.get(0));
            return singleCards.get(0);
        }

        // 2. 拆数量最少的对子
        for (Integer card : nonMainSuitCards) {
            if (cardCountMap.get(card) == 2) {
                logInfo("拆非主要花色的对子: " + card);
                return card;
            }
        }

        // 3. 最后随便选一张非主要花色的牌
        logInfo("打出非主要花色的牌: " + nonMainSuitCards.get(0));
        return nonMainSuitCards.get(0);
    }

    /**
     * 从同花色牌中选择要打出的牌
     */
    private int selectCardFromSameSuit(List<Integer> handCards, Map<Integer, Integer> cardCountMap, int mainSuit) {
        // 分离出刻子、顺子、将牌和剩余牌
        List<Integer> kezi = new ArrayList<>();
        List<Integer> shunzi = new ArrayList<>();
        List<Integer> jiang = new ArrayList<>();
        List<Integer> remainingCards = new ArrayList<>(handCards);

        // 先找出刻子(三张相同的牌)
        findAndRemoveKezi(remainingCards, cardCountMap, kezi);

        // 再找出顺子
        findAndRemoveShunzi(remainingCards, mainSuit, shunzi);


        // 找出将牌(258对子)
//        findAndRemoveJiang(remainingCards, jiang);


        // 如果还有剩余牌，从剩余牌中选择要打出的牌
        if (!remainingCards.isEmpty()) {
            return selectFromRemainingCards(remainingCards, cardCountMap);
        }

        // 如果没有剩余牌，说明牌型很好，考虑拆散一组来优化
        return selectCardFromFormedGroups(handCards, cardCountMap, mainSuit);
    }

    /**
     * 找出并移除刻子
     */
    private void findAndRemoveKezi(List<Integer> cards, Map<Integer, Integer> cardCountMap, List<Integer> kezi) {
        // 创建临时副本避免修改遍历中的列表
        List<Integer> tempCards = new ArrayList<>(cards);
        Set<Integer> processedCards = new HashSet<>(); // 记录已处理的牌

        for (Integer card : tempCards) {
            // 如果这张牌已经处理过，或者数量不足3张，跳过
            if (processedCards.contains(card) || cardCountMap.get(card) < 3) {
                continue;
            }

            // 找到刻子，从原始cards列表中移除3张相同的牌
            int removeCount = 0;
            Iterator<Integer> iterator = cards.iterator();
            while (iterator.hasNext() && removeCount < 3) {
                Integer currentCard = iterator.next();
                if (currentCard.equals(card)) {
                    iterator.remove();
                    removeCount++;
                }
            }

            // 将刻子添加到结果列表（3次）
            kezi.add(card);
            kezi.add(card);
            kezi.add(card);

            // 标记这张牌已处理
            processedCards.add(card);

            logInfo("找到刻子: " + getCardName(card) + " (数量: " + cardCountMap.get(card) + ")");
        }
    }

    /**
     * 找出并移除顺子
     */
    private void findAndRemoveShunzi(List<Integer> cards, int mainSuit, List<Integer> shunzi) {
        List<Integer> sortedCards = new ArrayList<>(cards);
        Collections.sort(sortedCards);

        for (int i = 0; i <= sortedCards.size() - 3; i++) {
            int card1 = sortedCards.get(i);
            int card2 = sortedCards.get(i + 1);
            int card3 = sortedCards.get(i + 2);

            // 检查是否构成顺子
            if (isShunzi(card1, card2, card3, mainSuit)) {
                // 移除顺子
                cards.remove((Integer) card1);
                cards.remove((Integer) card2);
                cards.remove((Integer) card3);
                shunzi.add(card1);
                shunzi.add(card2);
                shunzi.add(card3);
                i += 2; // 跳过已处理的牌
            }
        }
    }

    /**
     * 判断三张牌是否构成顺子
     */
    private boolean isShunzi(int card1, int card2, int card3, int mainSuit) {
        int value1 = card1 % 100;
        int value2 = card2 % 100;
        int value3 = card3 % 100;

        return value2 == value1 + 1 && value3 == value2 + 1;
    }

    /**
     * 找出并移除将牌(258对子)
     */
    private void findAndRemoveJiang(List<Integer> cards, List<Integer> jiang) {
        Map<Integer, Integer> tempCount = new HashMap<>();
        for (Integer card : cards) {
            tempCount.put(card, tempCount.getOrDefault(card, 0) + 1);
        }

        // 优先找258对子作为将牌
        for (Integer card : cards) {
            int value = card % 100;
            if ((value == 2 || value == 5 || value == 8) && tempCount.get(card) >= 2) {
                // 找到将牌
                jiang.add(card);
                jiang.add(card);
                cards.remove(card);
                cards.remove(card);
                return;
            }
        }

        // 如果没有258对子，找任意对子作为将牌
        for (Integer card : cards) {
            if (tempCount.get(card) >= 2) {
                jiang.add(card);
                jiang.add(card);
                cards.remove(card);
                cards.remove(card);
                return;
            }
        }
    }

    /**
     * 从剩余牌中选择要打出的牌
     */
    private int selectFromRemainingCards(List<Integer> remainingCards, Map<Integer, Integer> cardCountMap) {
        // 优先打出孤张(没有相邻牌的牌)
        Integer isolatedCard = findIsolatedCard(remainingCards, cardCountMap);
        if (isolatedCard != null) {
            logInfo("打出孤张: " + isolatedCard);
            return isolatedCard;
        }

        // 其次打出手牌数量最多的牌(保留单张和刻子胚子)
        Integer mostCountCard = findMostCountCard(remainingCards, cardCountMap);
        if (mostCountCard != null) {
            logInfo("打出手牌数量多的牌: " + mostCountCard);
            return mostCountCard;
        }

        // 最后打边张(1和9)
        Integer edgeCard = findEdgeCard(remainingCards);
        if (edgeCard != null) {
            logInfo("打出边张: " + edgeCard);
            return edgeCard;
        }

        // 默认打出第一张
        logInfo("打出默认牌: " + remainingCards.get(0));
        return remainingCards.get(0);
    }

    /**
     * 从已组成的牌组中选择要拆打的牌
     */
    private int selectCardFromFormedGroups(List<Integer> handCards, Map<Integer, Integer> cardCountMap, int mainSuit) {
        // 这里可以实现更复杂的策略，比如拆散效率最低的顺子或刻子
        // 简单实现：打出手牌数量最少的牌
        int minCount = Integer.MAX_VALUE;
        Integer cardToDiscard = null;

        for (Integer card : handCards) {
            int count = cardCountMap.get(card);
            if (count < minCount) {
                minCount = count;
                cardToDiscard = card;
            }
        }

        logInfo("从已组成牌组中打出: " + cardToDiscard);
        return cardToDiscard;
    }

    /**
     * 查找孤张(没有相邻牌的牌)
     */
    private Integer findIsolatedCard(List<Integer> cards, Map<Integer, Integer> cardCountMap) {
        // 统计每张牌的出现次数
        Map<Integer, Integer> countMap = new HashMap<>();
        for (int card : cards) {
            countMap.put(card, countMap.getOrDefault(card, 0) + 1);
        }

        // 寻找出现次数为 1 的牌（非对子）
        for (int card : cards) {
            if (countMap.get(card) == 1) {
                return card;
            }
        }

        // 如果没有非对子的牌，返回 null 或选择第一张牌等策略
        return cards.get(0);
    }

    /**
     * 查找手牌数量最多的牌
     */
    private Integer findMostCountCard(List<Integer> cards, Map<Integer, Integer> cardCountMap) {
        int maxCount = 0;
        Integer result = null;

        for (Integer card : cards) {
            int count = cardCountMap.get(card);
            if (count > maxCount) {
                maxCount = count;
                result = card;
            }
        }

        return result;
    }

    /**
     * 查找边张(1和9)
     */
    private Integer findEdgeCard(List<Integer> cards) {
        for (Integer card : cards) {
            int value = card % 100;
            if (value == 1 || value == 9) {
                return card;
            }
        }
        return null;
    }

    /**
     * handCards :摸牌后的手牌
     * 分析手牌，将顺子，刻子，将 另存
     */
    public HandAnalysis analyzeHand(List<Integer> handCards) {
        logInfo("\n===== 开始手牌分析 =====");
        logInfo("待分析手牌: " + handCards);


        // 创建分析结果对象
        HandAnalysis analysis = new HandAnalysis();


        // 1. 统计每张牌的数量并按花色分组
        countCardsAndGroupBySuit(handCards, analysis);

        // 2. 识别刻子（三张相同）
        identifyTriplets(analysis);

        // 4. 识别顺子（三张连续，仅分析剩余的牌）
        identifySequences(analysis);

        // 3. 优先识别对子（两张相同）
        identifyPairs(analysis);


        // 5. 识别孤张牌
        identifyIsolatedCards(analysis);

        // 6. 检测听牌状态
        detectTingPai(analysis);

        return analysis;
    }


    /**
     * 统计每张牌的数量并按花色分组
     */
    private void countCardsAndGroupBySuit(List<Integer> handCards, HandAnalysis analysis) {
        Map<Integer, Integer> counts = new HashMap<>();
        Map<Integer, List<Integer>> bySuit = new HashMap<>();

        // 初始化花色分组（1:万, 2:筒, 3:条）
        bySuit.put(1, new ArrayList<>());
        bySuit.put(2, new ArrayList<>());
        bySuit.put(3, new ArrayList<>());

        // 统计数量并按花色分组
        for (int card : handCards) {
            counts.put(card, counts.getOrDefault(card, 0) + 1);

            int suit = card / 100;
            if (bySuit.containsKey(suit)) {
                bySuit.get(suit).add(card);
            }
        }

        // 对每个花色的牌进行排序
        for (List<Integer> suitCards : bySuit.values()) {
            suitCards.sort(Integer::compareTo);
        }

        analysis.cardCounts = counts;
        analysis.cardsBySuit = bySuit;
        analysis.remainingCards = new ArrayList<>(handCards);
        analysis.remainingCards.sort(Integer::compareTo);
    }

    /**
     * 识别刻子（三张相同的牌）
     */
    private void identifyTriplets(HandAnalysis analysis) {
        List<Integer> cardsToRemove = new ArrayList<>();

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

            // 如果某张牌有3张或以上，识别为刻子
            if (count >= 3) {
                // 添加刻子
                List<Integer> triplet = Arrays.asList(card, card, card);
                analysis.completedMelds.add(triplet);
                analysis.meldCount++;

                // 标记为已使用
                for (int i = 0; i < 3; i++) {
                    analysis.usedInMelds.add(card);
                }

                // 记录需要从剩余牌中移除的牌
                for (int i = 0; i < 3; i++) {
                    cardsToRemove.add(card);
                }
            }
        }

        // 从剩余牌中移除已识别为刻子的牌
        for (int card : cardsToRemove) {
            analysis.remainingCards.remove(Integer.valueOf(card));
        }
    }

    /**
     * 识别顺子（三张连续的牌，同一花色）
     */
    private void identifySequences(HandAnalysis analysis) {
        // 按花色分析顺子，只使用剩余的牌
        Map<Integer, List<Integer>> remainingCardsBySuit = new HashMap<>();
        for (int card : analysis.remainingCards) {
            if (!analysis.usedInMelds.contains(card)) {
                int suit = card / 100;
                remainingCardsBySuit.computeIfAbsent(suit, k -> new ArrayList<>()).add(card);
            }
        }

        for (Map.Entry<Integer, List<Integer>> entry : remainingCardsBySuit.entrySet()) {
            int suit = entry.getKey();
            List<Integer> suitCards = entry.getValue();

            if (suitCards.size() < 3) continue;

            suitCards.sort(Integer::compareTo);

            // 创建牌的计数映射，用于跟踪每张牌的数量
            Map<Integer, Integer> cardCount = new HashMap<>();
            for (int card : suitCards) {
                cardCount.put(card, cardCount.getOrDefault(card, 0) + 1);
            }

            // 遍历所有可能的顺子起始点
            for (int startCard : suitCards) {
                int secondCard = startCard + 1;
                int thirdCard = startCard + 2;

                // 检查是否同一花色且连续
                if (secondCard / 100 == suit && thirdCard / 100 == suit &&
                        cardCount.getOrDefault(startCard, 0) > 0 &&
                        cardCount.getOrDefault(secondCard, 0) > 0 &&
                        cardCount.getOrDefault(thirdCard, 0) > 0) {

                    // 添加顺子
                    List<Integer> sequence = Arrays.asList(startCard, secondCard, thirdCard);
                    analysis.completedMelds.add(sequence);
                    analysis.meldCount++;

                    // 从计数中移除（每张牌只用一次）
                    cardCount.put(startCard, cardCount.get(startCard) - 1);
                    cardCount.put(secondCard, cardCount.get(secondCard) - 1);
                    cardCount.put(thirdCard, cardCount.get(thirdCard) - 1);

                    // 更新剩余牌和已用牌
                    analysis.remainingCards.remove(Integer.valueOf(startCard));
                    analysis.remainingCards.remove(Integer.valueOf(secondCard));
                    analysis.remainingCards.remove(Integer.valueOf(thirdCard));
                    analysis.usedInMelds.add(startCard);
                    analysis.usedInMelds.add(secondCard);
                    analysis.usedInMelds.add(thirdCard);
                }
            }
        }
    }

    /**
     * 识别对子（两张相同的牌）
     */
    private void identifyPairs(HandAnalysis analysis) {
        // 统计剩余牌中每张牌的数量
        Map<Integer, Integer> remainingCounts = new HashMap<>();
        for (int card : analysis.remainingCards) {
            if (!analysis.usedInMelds.contains(card)) {
                remainingCounts.put(card, remainingCounts.getOrDefault(card, 0) + 1);
            }
        }

        // 识别对子
        for (Map.Entry<Integer, Integer> entry : remainingCounts.entrySet()) {
            int card = entry.getKey();
            int count = entry.getValue();

            if (count >= 2) {
                analysis.pairs.add(card);
                analysis.pairCount++;

                // 标记为已使用
                analysis.usedInPairs.add(card);

                // 将对子的牌从剩余牌中移除
                for (int i = 0; i < 2; i++) {
                    analysis.remainingCards.remove(Integer.valueOf(card));
                }

                // 检查是否为特殊对子（最后一位数字为2、5、8）
                int lastDigit = card % 10;
                if (lastDigit == 2 || lastDigit == 5 || lastDigit == 8) {
                    int suit = card / 100;
                    String suitName = getSuitName(suit);
                    logInfo("识别到特殊对子: " + card + " (" + suitName + lastDigit + ")");
                }
            }
        }

        // 检测是否有碰碰胡潜力（如果大部分牌都是刻子或对子）
        if (analysis.meldCount >= 3 && analysis.pairCount >= 1) {
            analysis.hasPengPengHu = true;
        }
    }

    /**
     * 获取花色名称
     */
    private String getSuitName(int suit) {
        switch (suit) {
            case 1:
                return "万";
            case 2:
                return "筒";
            case 3:
                return "条";
            default:
                return "未知";
        }
    }

    /**
     * 识别孤张牌（未组成任何牌型的单张牌）
     */
    private void identifyIsolatedCards(HandAnalysis analysis) {
        // 统计剩余牌中每张牌的数量
        Map<Integer, Integer> remainingCounts = new HashMap<>();
        for (int card : analysis.remainingCards) {
            remainingCounts.put(card, remainingCounts.getOrDefault(card, 0) + 1);
        }

        // 识别孤张牌
        for (Map.Entry<Integer, Integer> entry : remainingCounts.entrySet()) {
            int card = entry.getKey();
            int count = entry.getValue();

            // 如果牌未用于刻子或顺子，且不是对子，则为孤张
            if (!analysis.usedInPairs.contains(card)) {
                for (int i = 0; i < count; i++) {
                    analysis.isolatedCards.add(card);
                }
            }
        }

        // 检测是否有龙七对潜力（如果有多个对子和孤张）
        if (analysis.pairCount >= 4) {
            analysis.hasLongQiDuiPotential = true;
        }
    }

    /**
     * 检测听牌状态
     */
    private void detectTingPai(HandAnalysis analysis) {
        // 创建完整手牌列表
        List<Integer> fullHand = new ArrayList<>(analysis.remainingCards);
        for (int card : analysis.usedInMelds) {
            fullHand.add(card);
        }
        for (int card : analysis.usedInPairs) {
            fullHand.add(card);
            fullHand.add(card);
        }

        int totalCards = fullHand.size();

        // 对于14张牌的情况，需要去掉一张牌后检查是否为和牌牌型
        if (totalCards == 14) {
            // 尝试去掉每张牌，检查是否可以和牌
            for (int card : new HashSet<>(fullHand)) {
                List<Integer> tempHand = new ArrayList<>(fullHand);
                tempHand.remove(Integer.valueOf(card));

                if (canHu(tempHand, analysis)) {
                    analysis.tingCards.add(card);
                }
            }
        }
        // 对于13张牌的情况，检查摸到哪些牌可以和牌
        else if (totalCards == 13) {
            // 尝试添加每张可能的牌，检查是否可以和牌
            for (int suit = 1; suit <= 3; suit++) {  // 1:万, 2:筒, 3:条
                for (int rank = 1; rank <= 9; rank++) {
                    int card = suit * 100 + rank;

                    // 检查这张牌是否已经在手中有4张（麻将中每种牌最多4张）
                    int count = 0;
                    for (int c : fullHand) {
                        if (c == card) {
                            count++;
                        }
                    }
                    if (count >= 4) continue;

                    List<Integer> tempHand = new ArrayList<>(fullHand);
                    tempHand.add(card);

                    if (canHu(tempHand, analysis)) {
                        analysis.tingCards.add(card);
                    }
                }
            }
        }

        // 如果有可胡的牌，则为听牌状态
        analysis.isTingPai = !analysis.tingCards.isEmpty();

        // 计算向听数
        calculateShanten(analysis);
    }

    /**
     * 判断手牌是否符合和牌条件（基本牌型：四组合一对将）
     */
    private boolean canHu(List<Integer> hand, HandAnalysis analysis) {
        // 统计牌的数量
        Map<Integer, Integer> tempCounts = new HashMap<>();
        for (int card : hand) {
            tempCounts.put(card, tempCounts.getOrDefault(card, 0) + 1);
        }

        // 尝试找出一对将牌
        for (Map.Entry<Integer, Integer> entry : tempCounts.entrySet()) {
            int card = entry.getKey();
            int count = entry.getValue();

            if (count >= 2) {
                // 假设这对牌作为将牌
                Map<Integer, Integer> copyCounts = new HashMap<>(tempCounts);
                copyCounts.put(card, count - 2);

                // 检查剩余的牌是否可以组成四组合（刻子或顺子）
                if (checkAllMelds(copyCounts)) {
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * 检查剩余的牌是否可以全部组成刻子或顺子
     */
    private boolean checkAllMelds(Map<Integer, Integer> counts) {
        // 创建剩余牌的列表（排除数量为0的牌）
        List<Integer> remainingCards = new ArrayList<>();
        for (Map.Entry<Integer, Integer> entry : counts.entrySet()) {
            int card = entry.getKey();
            int count = entry.getValue();
            for (int i = 0; i < count; i++) {
                remainingCards.add(card);
            }
        }

        // 排序以便分析
        remainingCards.sort(Integer::compareTo);

        // 递归检查是否可以组成全部的刻子或顺子
        return checkMeldsRecursive(remainingCards);
    }

    /**
     * 递归检查是否可以组成刻子或顺子
     */
    private boolean checkMeldsRecursive(List<Integer> cards) {
        if (cards.isEmpty()) {
            return true; // 所有牌都已组成合法牌型
        }

        int firstCard = cards.get(0);

        // 尝试组成刻子（三张相同）
        if (cards.size() >= 3 && firstCard == cards.get(1) && firstCard == cards.get(2)) {
            List<Integer> newCards = new ArrayList<>(cards.subList(3, cards.size()));
            if (checkMeldsRecursive(newCards)) {
                return true;
            }
        }

        // 尝试组成顺子（三张连续）
        if (cards.size() >= 3) {
            int secondCard = firstCard + 1;
            int thirdCard = firstCard + 2;

            // 确保是同一花色
            int suit = firstCard / 100;
            if (suit == secondCard / 100 && suit == thirdCard / 100) {
                List<Integer> tempCards = new ArrayList<>(cards);
                tempCards.remove(Integer.valueOf(firstCard));

                // 查找第二张牌
                boolean foundSecond = false;
                for (int i = 0; i < tempCards.size(); i++) {
                    if (tempCards.get(i) == secondCard) {
                        tempCards.remove(i);
                        foundSecond = true;
                        break;
                    }
                }

                if (foundSecond) {
                    // 查找第三张牌
                    boolean foundThird = false;
                    for (int i = 0; i < tempCards.size(); i++) {
                        if (tempCards.get(i) == thirdCard) {
                            tempCards.remove(i);
                            foundThird = true;
                            break;
                        }
                    }

                    if (foundThird && checkMeldsRecursive(tempCards)) {
                        return true;
                    }
                }
            }
        }

        return false;
    }

    /**
     * 计算向听数（距离听牌还有几张牌）
     * 优化的向听数计算算法，考虑了面子、对子和搭子的组合
     */
    private void calculateShanten(HandAnalysis analysis) {
        // 如果已经听牌，向听数为0
        if (analysis.isTingPai) {
            analysis.shantenCount = 0;
            return;
        }

        // 创建完整手牌列表
        List<Integer> fullHand = new ArrayList<>(analysis.remainingCards);
        for (int card : analysis.usedInMelds) {
            fullHand.add(card);
        }
        for (int card : analysis.usedInPairs) {
            fullHand.add(card);
            fullHand.add(card);
        }

        int totalCards = fullHand.size();
        if (totalCards != 13 && totalCards != 14) {
            analysis.shantenCount = Integer.MAX_VALUE;
            return;
        }

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

        // 计算最小向听数
        int minShanten = Integer.MAX_VALUE;

        // 尝试每种可能的将牌（对子）
        Set<Integer> possiblePairs = new HashSet<>(counts.keySet());

        // 添加没有对子的情况（需要摸一张牌形成对子）
        possiblePairs.add(-1);

        for (int pairCard : possiblePairs) {
            Map<Integer, Integer> tempCounts = new HashMap<>(counts);
            int pairShanten = 0;

            // 如果选择了具体的将牌
            if (pairCard != -1) {
                int pairCount = tempCounts.get(pairCard);
                if (pairCount >= 2) {
                    tempCounts.put(pairCard, pairCount - 2);
                } else {
                    // 需要摸一张牌形成对子
                    pairShanten = 1;
                    tempCounts.put(pairCard, tempCounts.getOrDefault(pairCard, 0) + 1 - 2);
                }
            } else {
                // 需要摸一张牌形成对子
                pairShanten = 1;
            }

            // 计算剩余牌的向听数
            int meldShanten = calculateMeldShanten(tempCounts);
            int totalShanten = pairShanten + meldShanten;

            // 更新最小向听数
            if (totalShanten < minShanten) {
                minShanten = totalShanten;
            }
        }

        // 确保向听数不为负数
        analysis.shantenCount = Math.max(0, minShanten);
    }

    /**
     * 计算剩余牌（排除将牌后）的面子向听数
     */
    private int calculateMeldShanten(Map<Integer, Integer> counts) {
        // 创建剩余牌的列表
        List<Integer> cards = new ArrayList<>();
        for (Map.Entry<Integer, Integer> entry : counts.entrySet()) {
            int card = entry.getKey();
            int count = entry.getValue();
            for (int i = 0; i < count; i++) {
                cards.add(card);
            }
        }

        if (cards.isEmpty()) {
            return 0;
        }

        // 按花色和数值排序
        cards.sort(Comparator.comparingInt(card -> {
            int suit = card / 100;
            int rank = card % 100;
            return suit * 10 + rank;
        }));

        // 使用动态规划计算最小向听数
        return calculateMeldShantenRecursive(cards, 0);
    }

    /**
     * 递归计算面子向听数
     */
    private int calculateMeldShantenRecursive(List<Integer> cards, int index) {
        if (index >= cards.size()) {
            return 0;
        }

        int minShanten = Integer.MAX_VALUE;
        int currentCard = cards.get(index);

        // 尝试作为刻子
        if (index + 2 < cards.size() && currentCard == cards.get(index + 1) && currentCard == cards.get(index + 2)) {
            int shanten = calculateMeldShantenRecursive(cards, index + 3);
            if (shanten < minShanten) {
                minShanten = shanten;
            }
        } else if (index + 1 < cards.size() && currentCard == cards.get(index + 1)) {
            // 有对子，可以考虑刻子（需要摸一张）
            int shanten = 1 + calculateMeldShantenRecursive(cards, index + 2);
            if (shanten < minShanten) {
                minShanten = shanten;
            }
        } else {
            // 单张，可以考虑刻子（需要摸两张）
            int shanten = 2 + calculateMeldShantenRecursive(cards, index + 1);
            if (shanten < minShanten) {
                minShanten = shanten;
            }
        }

        // 尝试作为顺子
        if (index + 2 < cards.size()) {
            int secondCard = currentCard + 1;
            int thirdCard = currentCard + 2;

            // 检查是否同一花色
            int suit = currentCard / 100;
            if (secondCard / 100 == suit && thirdCard / 100 == suit) {
                // 检查后两张牌是否存在
                boolean hasSecond = false;
                boolean hasThird = false;
                int secondIndex = -1;
                int thirdIndex = -1;

                for (int i = index + 1; i < cards.size(); i++) {
                    if (cards.get(i) == secondCard && !hasSecond) {
                        hasSecond = true;
                        secondIndex = i;
                    } else if (cards.get(i) == thirdCard && !hasThird) {
                        hasThird = true;
                        thirdIndex = i;
                    }
                }

                if (hasSecond && hasThird) {
                    // 创建新的牌列表，移除组成顺子的三张牌
                    List<Integer> newCards = new ArrayList<>();
                    for (int i = 0; i < cards.size(); i++) {
                        if (i != index && i != secondIndex && i != thirdIndex) {
                            newCards.add(cards.get(i));
                        }
                    }

                    int shanten = calculateMeldShantenRecursive(newCards, 0);
                    if (shanten < minShanten) {
                        minShanten = shanten;
                    }
                } else {
                    // 缺少牌，需要计算所需的牌数
                    int needed = 0;
                    if (!hasSecond) needed++;
                    if (!hasThird) needed++;

                    // 创建新的牌列表，移除已有的牌
                    List<Integer> newCards = new ArrayList<>();
                    for (int i = 0; i < cards.size(); i++) {
                        if (i != index) {
                            if (hasSecond && i == secondIndex) continue;
                            if (hasThird && i == thirdIndex) continue;
                            newCards.add(cards.get(i));
                        }
                    }

                    int shanten = needed + calculateMeldShantenRecursive(newCards, 0);
                    if (shanten < minShanten) {
                        minShanten = shanten;
                    }
                }
            }
        } else if (index + 1 < cards.size()) {
            // 只有两张连续牌，需要一张牌组成顺子
            int nextCard = cards.get(index + 1);
            if (nextCard - currentCard == 1 && (currentCard / 100) == (nextCard / 100)) {
                List<Integer> newCards = new ArrayList<>(cards);
                newCards.remove(index);
                newCards.remove(index); // 移除第二张牌

                int shanten = 1 + calculateMeldShantenRecursive(newCards, 0);
                if (shanten < minShanten) {
                    minShanten = shanten;
                }
            }
        }

        return minShanten;
    }

    public static int analyzeHandCards(List<Integer> handCards) {
        if (handCards == null || handCards.size() != 14) {
            System.out.println("错误：手牌必须是14张");
            return  0;
        }

        System.out.println("当前手牌(14张): " + convertToReadable(handCards));
        System.out.println("======================================");



        // 2. 分析手牌结构
        List<Integer> sortedHand = new ArrayList<>(handCards);
        Collections.sort(sortedHand);

        System.out.println("\n=== 手牌结构分析 ===");

        // 找出所有刻子
        List<List<Integer>> kezis = findKezis(sortedHand);
        System.out.println("刻子(" + kezis.size() + "组):");
        for (List<Integer> kezi : kezis) {
            System.out.println("  " + convertToReadable(kezi));
        }

        // 找出所有顺子
        List<List<Integer>> shunzis = findShunzis(sortedHand);
        System.out.println("\n顺子(" + shunzis.size() + "组):");
        for (List<Integer> shunzi : shunzis) {
            System.out.println("  " + convertToReadable(shunzi));
        }

        // 找出所有258将牌
        List<Integer> jiangCandidates = findJiangCandidates(sortedHand);
        System.out.println("\n258将牌候选(" + jiangCandidates.size() + "张):");
        System.out.println("  " + convertToReadable(jiangCandidates));

        if (kezis.size()>0 || shunzis.size()>0 || jiangCandidates.size()>0){
            return kezis.size()+shunzis.size();
        }

        return 0;

    }



    /**
     * 找出所有刻子
     */
    private static List<List<Integer>> findKezis(List<Integer> handCards) {
        List<List<Integer>> kezis = new ArrayList<>();
        List<Integer> temp = new ArrayList<>(handCards);

        while (!temp.isEmpty()) {
            int card = temp.get(0);
            int count = Collections.frequency(temp, card);

            if (count >= 3) {
                List<Integer> kezi = new ArrayList<>();
                kezi.add(card);
                kezi.add(card);
                kezi.add(card);
                kezis.add(kezi);

                // 移除这3张牌
                for (int i = 0; i < 3; i++) {
                    temp.remove(Integer.valueOf(card));
                }
            } else {
                temp.remove(Integer.valueOf(card));
            }
        }

        return kezis;
    }

    /**
     * 找出所有顺子
     */
    private static List<List<Integer>> findShunzis(List<Integer> handCards) {
        List<List<Integer>> shunzis = new ArrayList<>();
        List<Integer> temp = new ArrayList<>(handCards);

        // 先移除已找到的刻子
        List<List<Integer>> kezis = findKezis(handCards);
        for (List<Integer> kezi : kezis) {
            for (int i = 0; i < 3; i++) {
                temp.remove(Integer.valueOf(kezi.get(0)));
            }
        }

        // 找顺子
        Collections.sort(temp);

        for (int i = 0; i < temp.size(); i++) {
            int card1 = temp.get(i);
            int type = getCardType(card1);
            int value = getCardValue(card1);

            if (type <= 3 && value <= 7) {
                int card2 = card1 + 1;
                int card3 = card1 + 2;

                if (temp.contains(card2) && temp.contains(card3)) {
                    List<Integer> shunzi = new ArrayList<>();
                    shunzi.add(card1);
                    shunzi.add(card2);
                    shunzi.add(card3);
                    shunzis.add(shunzi);

                    // 移除这3张牌
                    temp.remove(Integer.valueOf(card1));
                    temp.remove(Integer.valueOf(card2));
                    temp.remove(Integer.valueOf(card3));
                    i--; // 因为移除了元素
                }
            }
        }

        return shunzis;
    }

    /**
     * 找出258将牌候选
     */
    private static List<Integer> findJiangCandidates(List<Integer> handCards) {
        List<Integer> jiangs = new ArrayList<>();

        for (int card : handCards) {
            int value = getCardValue(card);
            if (JIANG_PAIS.contains(value)) {
                jiangs.add(card);
            }
        }

        return jiangs;
    }


    /**
     * 获取牌值
     */
    private static int getCardValue(int card) {
        return card % 10;
    }

    /**
     * 获取牌类型
     */
    private static int getCardType(int card) {
        return card / 100;
    }

    /**
     * 格式化单张牌
     */
    private static String formatCard(int card) {
        int type = getCardType(card);
        int value = getCardValue(card);
        switch (type) {
            case 1:
                return value + "万";
            case 2:
                return value + "筒";
            case 3:
                return value + "条";
            default:
                return "字牌" + value;
        }
    }

    /**
     * 转换为可读格式
     */
    private static String convertToReadable(List<Integer> cards) {
        if (cards == null || cards.isEmpty()) {
            return "空";
        }

        List<String> cardStrs = new ArrayList<>();
        for (int card : cards) {
            cardStrs.add(formatCard(card));
        }
        return String.join(" ", cardStrs);
    }


    public List<Integer> chuguodepai() {
        return chuguodepai;
    }

    public static boolean isJiangPai(int card) {
        if (card % 100 == 2 || card % 100 == 5 || card % 100 == 8) {
            return true;
        }
        return false;
    }
    public static int checkduijiang(List<Integer> cardInHand) {
        Map<Integer, Integer> countMap = new HashMap<>();
        for (Integer item : cardInHand) {
            countMap.put(item, countMap.getOrDefault(item, 0) + 1);
        }
        System.out.println("countMap: " + countMap);
        int jiangnum = 0;
        for (int key : countMap.keySet()) {
            if (isJiangPai(key) && countMap.get(key) == 2) {
                jiangnum++;
            }
        }
        return jiangnum;
    }

    public static int checkChiTingAction(int card,List<Integer> changShaCardInhand){
        //判断吃之后能否下听
        List<List<Integer>> lists = new ArrayList<>();
        lists.addAll(TinHuChi.checkChi(changShaCardInhand, card));
        int index = 0;
        int flag = 0;
        for (List<Integer> list : lists) {
            List<Integer> temphand = new ArrayList<>();
            temphand.addAll(changShaCardInhand);
            temphand.add(card);
            Util.removeCard(temphand, list.get(0), 1);
            Util.removeCard(temphand, list.get(1), 1);
            Util.removeCard(temphand, list.get(2), 1);
            List<Integer> checktingpai1 = TinHuChi.checktingpai(temphand);
            if (checktingpai1.size() > 0) {
                flag = index + 1;
            }
            index++;
            System.out.println("checktingpai1  吃牌 " + checktingpai1);
        }


        // TODO: 2026/1/1
        //  1.需要补充 没听牌也可以吃 但是吃之后要比吃之前的手牌强 也就是可听数量变多
        //  2.听牌后也能吃牌，要比吃之前的牌强
        //  3.碰也一样要加
        //吃之后不下听
        if (flag>0){
            return flag;
        }

        return 0;
    }



    public static int checkCanChiAction(int card,List<Integer> changShaCardInhand){
        //吃之后也不能听
        Map<String, Object> map = new HashMap<>();
        Map<String, Object> map2 = new HashMap<>();
        //吃之前的逻辑
        List<List<Integer>> lists1 = TinHuChi.checkChi(changShaCardInhand, card);

        int jiangnum = checkduijiang(changShaCardInhand);
        List<Integer> tmpChangSch = new ArrayList<>();
        tmpChangSch.addAll(changShaCardInhand);
        tmpChangSch.add(card);
        ChangshaWinSplitCard.checkNormalHu(tmpChangSch, map);

        System.out.println("checkNormalHu" + map.get("cardResiue"));
        System.out.println("checktingpai1" + lists1);

        int index1 = 0;
        int flag1 = 0;
        for (List<Integer> list : lists1) {
            List<Integer> temphand = new ArrayList<>();
            temphand.addAll(tmpChangSch);
            Util.removeCard(temphand, list.get(0), 1);
            Util.removeCard(temphand, list.get(1), 1);
            Util.removeCard(temphand, list.get(2), 1);
            ChangshaWinSplitCard.checkNormalHu(temphand, map2);
            //判断两个map是否找到更优
            System.out.println("map1:" + Integer.parseInt(map.get("remainingMelds").toString()));
            System.out.println("map2:" + Integer.parseInt(map2.get("remainingMelds").toString()));
            if (Integer.parseInt(map2.get("remainingMelds").toString()) < Integer.parseInt(map.get("remainingMelds").toString())) {
                flag1 = index1 + 1;
            } else if (Integer.parseInt(map2.get("remainingMelds").toString()) == Integer.parseInt(map.get("remainingMelds").toString())) {
                int size2 = ((List<Integer>) map2.get("cardResiue")).size();
                System.out.println("size2" + size2);
                int size1 = ((List<Integer>) map.get("cardResiue")).size();
                System.out.println("size1" + size1);
                if (size2 < size1) {
                    flag1 = index1 + 1;
                }
                //如果手里没有将，则可以吃
                if (jiangnum > 0) {
                    int chihoujiangnum = checkduijiang(temphand);
                    if (chihoujiangnum > 0) {
                        //吃之后还有将
                        flag1 = index1 + 1;
                    }
                } else {
                    System.out.println("没队将");
                    //孤章1张 差一手 不是将 而且card不是将
                    if (Integer.parseInt(map.get("remainingMelds").toString()) == 1 && size1 == 1 && !isJiangPai(((List<Integer>) map.get("cardResiue")).get(0)) && !isJiangPai(card)) {
                        //吃
                        break;
                    }
                    flag1 = index1 + 1;
                    // break;
                }
            }
            index1++;
        }

        if (flag1 > 0) {
            return flag1;
        }
        return 0;
    }

    /**
     *
     * @param handcards
     * @param chowGrop
     * @param pengGrop
     * @param gangGrop
     * @return
     * 1,清一色，2，7小对，3，碰碰胡，4，将将胡，5，门清
     */
    public static int checkDahu(List<Integer> handcards,List<Integer> chowGrop,List<Integer>pengGrop,List<Integer>gangGrop){
        //检测是否可以是大胡
        //1、青一色
        boolean qys = checkHandsQingYiSe(handcards,chowGrop,pengGrop,gangGrop);
        if (qys){
            return 1;
        }
        //2、7小对
        int cpairs = countPairs(handcards);
        if (cpairs>4){
            return 2;
        }
        boolean pph = false;
        //3、碰碰胡
        if (pengGrop.size()==3&&chowGrop.size()==0){
            if (cpairs>3){
                return 3;
            }
        }else if (pengGrop.size()==6&&chowGrop.size()==0){
            if (cpairs>2){
                return 3;
            }
        }else if (pengGrop.size()==9&&chowGrop.size()==0){
            if (cpairs>1){
                return 3;
            }
        }
        //4、将将胡
        boolean jjh = false;
        if (pengGrop.size() == 0){
            int count258 = 0;
            for (Integer card : handcards) {
                if (is258Card(card)) {
                    count258++;
                }
            }
            if (count258>=9){
                return 4;
            }
        }
        if (pengGrop.size() == 3){
            //碰都是将
           boolean tmpj = isJiangPai(pengGrop.get(0));
           if (tmpj){
               int count258 = 0;
               for (Integer card : handcards) {
                   if (is258Card(card)) {
                       count258++;
                   }
               }
               if (count258>6){
                   return 4;
               }
           }
        }
        if (pengGrop.size() == 6){
            //碰都是将
            boolean tmpj2 = isJiangPai(pengGrop.get(0));
            if (tmpj2){
                int count258 = 0;
                for (Integer card : handcards) {
                    if (is258Card(card)) {
                        count258++;
                    }
                }
                if (count258>3){
                    return 4;
                }
            }
        }

        return 0;
    }

    public static boolean checkHandsQingYiSe(List<Integer> handcards,List<Integer> chowGrop,List<Integer>pengGrop,List<Integer>gangGrop){
        //true 为可以 false 为不能
        List<Integer> cpg = new ArrayList<>();
        cpg.addAll(chowGrop);
        cpg.addAll(pengGrop);
        cpg.addAll(gangGrop);
        if (cpg.size()>0){
            int tmp1 = 0;
            int tmp2 = 0;
            for (int i=0;i<cpg.size()-1;i++) {
                tmp1 = cpg.get(i);
                tmp2 = cpg.get(i+1);
                if (Math.abs(tmp2-tmp1)>10){
                    //落地已经有了不同色，所以可以进行
                    return false;
                }
            }
        }



        Map<Integer, Integer> suitCountMap = new HashMap<>();
        for (Integer card : handcards) {
            int suit = card / 100; // 获取花色，100=万，200=筒，300=条
            suitCountMap.put(suit, suitCountMap.getOrDefault(suit, 0) + 1);
        }
        for (Map.Entry<Integer, Integer> entry : suitCountMap.entrySet()) {
            int suit = entry.getKey();

            int count = entry.getValue();

            if (handcards.size()==13){
                if (count >= 10) {
                    return true;
                }
            }else if (handcards.size()==10){
                if (count >= 7) {
                    List<Integer> cpg2 = new ArrayList<>();
                    cpg2.addAll(chowGrop);
                    cpg2.addAll(pengGrop);
                    cpg2.addAll(gangGrop);
                    if (cpg2.size()>0){
                        if(cpg2.get(0)/100!=suit){
                            return false;
                        }
                    }


                    return true;
                }
            } else if (handcards.size()==7) {
                if (count >= 4) {
                    List<Integer> cpg3 = new ArrayList<>();
                    cpg3.addAll(chowGrop);
                    cpg3.addAll(pengGrop);
                    cpg3.addAll(gangGrop);
                    if (cpg3.size()>0){
                        if(cpg3.get(0)/100!=suit){
                            return false;
                        }
                    }
                    return true;
                }
            }else if (handcards.size()==4) {
                if (count >= 2) {
                    List<Integer> cpg3 = new ArrayList<>();
                    cpg3.addAll(chowGrop);
                    cpg3.addAll(pengGrop);
                    cpg3.addAll(gangGrop);
                    if (cpg3.size()>0){
                        if(cpg3.get(0)/100!=suit){
                            return false;
                        }
                    }
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 通过结果计算最优分数并返回对应的选择id
     * @param map
     * @return
     */
    public static int suanfen(Map<Integer,ITObject>map){
        System.out.println("suanfen"+map);
        if (map.size()==0){
            return 0;
        }
        Map<Integer,Integer> fell = new HashMap<>();
        for (Map.Entry<Integer,ITObject> entry : map.entrySet()) {
            int tmp = 0;
            /*if (entry.getValue().getBoolean("isTing")){
                tmp= tmp+30;
            }*/
            if (entry.getValue().getBoolean("xiaoDahu")){
                tmp= tmp-20;
            }
           /* if (entry.getValue().getInt("isDaHu")>0){
                tmp= tmp-10;
            }*/
            if (entry.getValue().getBoolean("xiaoJiang")){
                tmp= tmp-13;
            }
            if (entry.getValue().getInt("tingNum")!=0){
                tmp= tmp+entry.getValue().getInt("tingNum")*4;
            }
            if (entry.getValue().getBoolean("sanTing")){
                tmp= tmp-50;
            }

            if (entry.getValue().getBoolean("canTing")&&!entry.getValue().getBoolean("isTing")){
                //从不能听牌到听牌，
                tmp= tmp+20;
            }
            if (entry.getValue().getInt("teshu")>0){
                tmp= tmp+entry.getValue().getInt("teshu")*1;
            }
            if (entry.getValue().getInt("lastHands")>0){
                tmp= tmp+entry.getValue().getInt("lastHands")*5;
            }
            if (entry.getValue().getInt("guzhang")>0){
                tmp= tmp+entry.getValue().getInt("guzhang")*1;
            }
            System.out.println("tmp:"+tmp);
            fell.put(entry.getKey(), tmp);
        }

        //找分数最高的id
        int dangqianfen = 0;
        int dangqianid = 0;
        for (Map.Entry<Integer, Integer> entry : fell.entrySet()) {
            if (dangqianid==0){
                dangqianid = entry.getKey();
                dangqianfen = entry.getValue();
            }
            if (entry.getValue()>dangqianfen){
                dangqianfen = entry.getValue();
                dangqianid = entry.getKey();
            }
        }
        if (dangqianfen>4){
            return dangqianid;
        }else{
            dangqianid = 0;
        }
        return dangqianid;
    }

    /**
     * 检测碰之后的结果
     * @param beforelisten
     * @param card
     * @param opcard
     * @param yupanhandcard
     * @param beforeIsDahu
     * @param allSeeCard
     * @param chowGroup
     * @param pengGrop
     * @param gangGrop
     * @return
     *
     *                boolean isTing    是否听牌
     *      *         boolean canTing   能否听牌
     *      *         boolean sanTing   是否散听
     *      *         int     tingNum   听多少张
     *      *         int     isDaHu    是否大胡
     *      *         boolean xiaoDahu  是否消掉大胡
     *      *
     *      *         int     guzhang   有多少孤章 相差
     *      *         int     lastHands 差多少手  相差
     *      *         boolean xiaoJiang 是否把将去没了
     *                int     teshu     特殊加分减分
     *
     *      *         int     id        tiplist id
     *      *         List<Integer>     opcard
     *      *         int     weight    tiplist weight
     *      *         int     card      tiplist card
     *      *         int     type      tiplist type
     *
     */
    public static ITObject pingguPeng(boolean beforelisten, int card, ITArray opcard, List<Integer> yupanhandcard, int beforeIsDahu, List<Integer> allSeeCard ,List<Integer>chowGroup,List<Integer>pengGrop,List<Integer>gangGrop,List<Integer>changShachuguopai){
        ITObject chiob = new TObject();
        chiob.putBoolean("isTing",beforelisten);
        chiob.putInt("isDaHu",beforeIsDahu);
        List checkCards = new ArrayList();
        checkCards.addAll(yupanhandcard);
        System.out.println("checkCards"+checkCards);
        //去掉三张牌是否还能听牌
        List<Integer> npeng = new ArrayList<>();

        for (int i=0;i<opcard.size();i++){
            Util.removeCard(checkCards,opcard.getInt(i),2);
        }
        npeng.add(card);
        npeng.add(card);
        npeng.add(card);
        npeng.addAll(pengGrop);

        // 操作之前和操作后有没有从有对将
        int beforedj = checkduijiang(yupanhandcard);
        System.out.println("beforedj:"+beforedj);
        if (beforedj>=1){
            int afterdj = checkduijiang(checkCards);
            System.out.println(checkCards);
            if (afterdj==0){
                chiob.putBoolean("xiaoJiang",true);
            }else{
                chiob.putBoolean("xiaoJiang",false);
            }
        }else{
            chiob.putBoolean("xiaoJiang",false);
        }

        //循环去三张还能听牌

        Map<Integer,List<Integer>> afterdaHuOp = quyizhangDahuTingPai(checkCards,chowGroup,npeng,gangGrop);
        if (afterdaHuOp.size()>0){
            chiob.putBoolean("canTing", true);
            chiob.putBoolean("sanTing", false);
        }else {

            Map<Integer, List<Integer>> afterOp = quyizhangTingPai(checkCards);

            if (afterOp.size() == 0 && beforelisten) {
                chiob.putBoolean("sanTing", true);
                chiob.putBoolean("canTing", false);
            }
            if (afterOp.size() > 0) {
                chiob.putBoolean("canTing", true);
                chiob.putBoolean("sanTing", false);
            } else {
                chiob.putBoolean("canTing", false);
                chiob.putBoolean("sanTing", false);
            }
        }

        //循环之后还能是大胡吗？1,清一色，2，7小对，3，碰碰胡，4，将将胡，5，门清
        if(beforeIsDahu>0){
            if (beforeIsDahu==2){
                chiob.putBoolean("xiaoDahu",true);
                chiob.putInt("teshu",0);
            }
            if (beforeIsDahu==3){
                //碰碰胡
                chiob.putBoolean("xiaoDahu",false);
                chiob.putInt("teshu",10);
            }else if (beforeIsDahu==4){
                //判断被碰的牌是否将
                if(!isJiangPai(card)){
                    chiob.putBoolean("xiaoDahu",true);
                }else{
                    chiob.putBoolean("xiaoDahu",false);
                    chiob.putInt("teshu",10);
                }
            }else if(beforeIsDahu==5){
                //门清
                chiob.putBoolean("xiaoDahu",true);
                chiob.putInt("teshu",0);
            }else{
                //毁掉清一色
                List<Integer> tmpchi = new ArrayList<>();
                List<Integer> chi = new ArrayList<>(); //新new 吃的牌 todo
                tmpchi.addAll(chowGroup);
                chi.addAll(chowGroup);
                List<Integer>pongGroup = new ArrayList<>();
                List<Integer> gangdepai = new ArrayList<>();
                gangdepai.addAll(gangGrop);
                pongGroup.add(card);
                for (int i=0;i<opcard.size();i++){
                    chi.add(opcard.getInt(i));
                }
                int afterdh = checkDahu(checkCards,chi,pongGroup,gangdepai);
                if (afterdh!=1){
                    chiob.putBoolean("xiaoDahu",true);
                    chiob.putInt("teshu",0);
                }else{
                    chiob.putBoolean("xiaoDahu",false);
                    chiob.putInt("teshu",0);
                }
            }
        }else{
            chiob.putBoolean("xiaoDahu",false);
            chiob.putInt("teshu",0);
        }

        //操作之前的孤章差手情况
        Map<String, Object> map = new HashMap<>();
        List<Integer> tmpChangSch = new ArrayList<>();
        tmpChangSch.addAll(yupanhandcard);
        ChangshaWinSplitCard.checkNormalHu(tmpChangSch, map);
        System.out.println("map:"+map);

        //操作后，去一张牌，分析求最优
        Map<String, Object> map2 = new HashMap<>();
        System.out.println(checkCards);
        Map<Integer,List<Integer>> xiatingList = new HashMap<>();
        List<Integer> peng = new ArrayList<>(); //新new
        peng.add(card);
        peng.add(card);
        peng.add(card);
        map2 = quyizhangChayou(checkCards,chowGroup,peng,gangGrop,xiatingList);
        Util.removeCard(peng,card,3);

        peng.add(card);
        peng.add(card);
        System.out.println("map2:"+map2);
        System.out.println("xiatingList:"+xiatingList);
        //比对
        if (map2.size()>0){
            //可以下听
            chiob.putInt("guzhang",((List<Integer>)map.get("cardResiue")).size()-((List<Integer>)map2.get("cardResiue")).size());
            chiob.putInt("lastHands",Integer.parseInt(map.get("remainingMelds").toString())-Integer.parseInt(map.get("remainingMelds").toString()));
        }else{
            chiob.putInt("guzhang",((List<Integer>)map.get("cardResiue")).size());
            chiob.putInt("lastHands",Integer.parseInt(map.get("remainingMelds").toString()));
        }


        //听多张问题：
        List<Integer> caozuoqian = handscardshifoutingpai(yupanhandcard,chowGroup,pengGrop,gangGrop);
        int caozuoqiannum = 0;//操作之前听牌张数
        List<Integer> allpai = new ArrayList<>();
        allpai.addAll(yupanhandcard);
        allpai.addAll(changShachuguopai);
        if (caozuoqian.size()>0){
            caozuoqiannum = getTingPainum(caozuoqian,allpai);
        }
        int caozuohounum = 0;
        if (xiatingList.size()>0){
            //获取能听牌数最多的
            for (Map.Entry<Integer, List<Integer>> entry : xiatingList.entrySet()) {
                if (caozuohounum==0){
                    caozuohounum = getTingPainum(entry.getValue(),allpai);
                }
                if (caozuohounum < getTingPainum(entry.getValue(),allpai)){
                    caozuohounum = getTingPainum(entry.getValue(),allpai);
                }
            }
        }

        chiob.putInt("tingNum",caozuohounum - caozuoqiannum);
        //先评分
        int tmp = 0;
            /*if (entry.getValue().getBoolean("isTing")){
                tmp= tmp+30;
            }*/
        if (chiob.getBoolean("xiaoDahu")){
            tmp= tmp-20;
        }
           /* if (entry.getValue().getInt("isDaHu")>0){
                tmp= tmp-10;
            }*/
        if (chiob.getBoolean("xiaoJiang")){
            tmp= tmp-13;
        }
        if (chiob.getInt("tingNum")>0){
            tmp= tmp+chiob.getInt("tingNum")*4;
        }

        if (chiob.getBoolean("sanTing")){
            tmp= tmp-50;
        }

        if (chiob.getBoolean("canTing")&&!chiob.getBoolean("isTing")){
            //从不能听牌到听牌，
            tmp= tmp+25;
        }
        if (chiob.getInt("teshu")>0){
            tmp= tmp+chiob.getInt("teshu")*1;
        }
        if (chiob.getInt("lastHands")>0){
            tmp= tmp+chiob.getInt("lastHands")*5;
        }
        if (chiob.getInt("guzhang")>0){
            tmp= tmp+chiob.getInt("guzhang")*2;
        }
        //如果评分大于0，且小于5
        if (tmp>0&&tmp<=5){
            //去掉将时候
            //判断是否有对将
            if(card%100==9||card%100==1){
                chiob.putInt("teshu",5);
            }
        }
        //检测是否有4对
        int duizi = countPairs(yupanhandcard);
        System.out.println("duizi:"+duizi);
        System.out.println(pengGrop);

        if (duizi==4&&pengGrop.size()>=0){
            chiob.putInt("teshu",5);
        }
        if (duizi==3&&pengGrop.size()>=2){
            chiob.putInt("teshu",8);
        }
        System.out.println(pengGrop.size());
        if (duizi>=2&&pengGrop.size()>=6){
            chiob.putInt("teshu",12);
        }


        System.out.println("peng:"+chiob);
        return chiob;
    }

    /**
     *
     * @param beforelisten
     * @param card
     * @param opcard
     * @param yupanhandcard
     * @param beforeIsDahu
     * @param allSeeCard
     * @return
     *         boolean isTing    是否听牌
     *         boolean canTing   能否听牌
     *         boolean sanTing   是否散听
     *         int     tingNum   听多少张
     *         int     isDaHu    是否大胡
     *         boolean xiaoDahu  是否消掉大胡
     *
     *         int     guzhang   有多少孤章 相差
     *         int     lastHands 差多少手  相差
     *         boolean xiaoJiang 是否把将去没了
     *
     *         int     id        tiplist id
     *         List<Integer>     opcard
     *         int     weight    tiplist weight
     *         int     card      tiplist card
     *         int     type      tiplist type
     */
    public static ITObject pingguChi(boolean beforelisten, int card, ITArray opcard, List<Integer> yupanhandcard, int beforeIsDahu, List<Integer> allSeeCard ,List<Integer>chowGroup,List<Integer>pengGrop,List<Integer>gangGrop,List<Integer>changShachuguopai){
        ITObject chiob = new TObject();
        chiob.putBoolean("isTing",beforelisten);
        chiob.putInt("isDaHu",beforeIsDahu);
        chiob.putInt("teshu",0);
        List checkCards = new ArrayList();
        checkCards.addAll(yupanhandcard);
        System.out.println("运行之前："+checkCards);
        //去掉三张牌是否还能听牌
        List<Integer> nchi = new ArrayList();

        for (int i=0;i<opcard.size();i++){
            Util.removeCard(checkCards,opcard.getInt(i),1);
            nchi.add(opcard.getInt(i));
        }
        nchi.add(card);
        nchi.addAll(chowGroup);
        // 操作之前和操作后有没有从有对将
        int beforedj = checkduijiang(yupanhandcard);
        if (beforedj>=1){
            int afterdj = checkduijiang(checkCards);
            if (afterdj==0){
                chiob.putBoolean("xiaoJiang",true);
            }else{
                chiob.putBoolean("xiaoJiang",false);
            }
        }else{
            chiob.putBoolean("xiaoJiang",false);
        }


        Map<Integer,List<Integer>> afterdaHuOp = quyizhangDahuTingPai(checkCards,nchi,pengGrop,gangGrop);
        if (afterdaHuOp.size()>0){

            chiob.putBoolean("canTing",true);
            chiob.putBoolean("sanTing",false);
        }else {
            //循环去一张还能听牌
            Map<Integer, List<Integer>> afterOp = quyizhangTingPai(checkCards);

            if (afterOp.size() == 0 && beforelisten) {
                chiob.putBoolean("sanTing", true);
                chiob.putBoolean("canTing", false);
            }
            if (afterOp.size() > 0) {
                chiob.putBoolean("canTing", true);
                chiob.putBoolean("sanTing", false);
            } else {
                chiob.putBoolean("canTing", false);
                chiob.putBoolean("sanTing", false);
            }
        }

        //循环之后还能是大胡吗？1,清一色，2，7小对，3，碰碰胡，4，将将胡，5，门清
        if(beforeIsDahu>0){
            if (beforeIsDahu>1){
                chiob.putBoolean("xiaoDahu",true);
            }else{
                //毁掉清一色
                List<Integer> tmpchi = new ArrayList<>();
                tmpchi.addAll(chowGroup);
                List<Integer>pongGroup = new ArrayList<>();
                List<Integer> gangdepai = new ArrayList<>();
                List<Integer> chi = new ArrayList<>();   // 新new

                chi.add(card);
                chi.addAll(chowGroup);
                for (int i=0;i<opcard.size();i++){
                    chi.add(opcard.getInt(i));
                }
                int afterdh = checkDahu(checkCards,chi,pongGroup,gangdepai);
                if (afterdh!=1){
                    chiob.putBoolean("xiaoDahu",true);
                }else{
                    chiob.putBoolean("xiaoDahu",false);
                }
            }
        }else{
            chiob.putBoolean("xiaoDahu",false);
        }
        //操作之前的孤章差手情况
        Map<String, Object> map = new HashMap<>();

        List<Integer> tmpChangSch = new ArrayList<>();
        tmpChangSch.addAll(yupanhandcard);
        ChangshaWinSplitCard.checkNormalHu(tmpChangSch, map);
        System.out.println("map:"+map);

        //操作后，去一张牌，分析求最优
        Map<String, Object> map2 = new HashMap<>();
        System.out.println(checkCards);
        Map<Integer,List<Integer>> xiatingList = new HashMap<>();
        List<Integer> chi = new ArrayList<>(); //新new
        chi.addAll(chowGroup);
        chi.add(card);
        for (int i=0;i<opcard.size();i++){
            chi.add(opcard.getInt(i));
        }
        map2 = quyizhangChayou(checkCards,chi,pengGrop,gangGrop,xiatingList);
        Util.removeCard(chi,card,1);
        for (int i=0;i<opcard.size();i++){
            Util.removeCard(chi,opcard.getInt(i),1);
        }


        System.out.println("map2:"+map2);
        System.out.println("xiatingList:"+xiatingList);
        //比对
        if (map2.size()>0){
            //可以下听
            chiob.putInt("guzhang",((List<Integer>)map.get("cardResiue")).size()-((List<Integer>)map2.get("cardResiue")).size());
            chiob.putInt("lastHands",Integer.parseInt(map.get("remainingMelds").toString())-Integer.parseInt(map2.get("remainingMelds").toString()));
        }else{
            chiob.putInt("guzhang",((List<Integer>)map.get("cardResiue")).size());
            chiob.putInt("lastHands",Integer.parseInt(map.get("remainingMelds").toString()));
        }

        //听多张问题：
        List<Integer> caozuoqian = handscardshifoutingpai(yupanhandcard,chowGroup,pengGrop,gangGrop);

        int caozuoqiannum = 0;//操作之前听牌张数
        List<Integer> allpai = new ArrayList<>();
        allpai.addAll(yupanhandcard);
        allpai.addAll(changShachuguopai);
        if (caozuoqian.size()>0){
            caozuoqiannum = getTingPainum(caozuoqian,allpai);
        }
        int caozuohounum = 0;
        if (xiatingList.size()>0){
            //获取能听牌数最多的
            for (Map.Entry<Integer, List<Integer>> entry : xiatingList.entrySet()) {
                if (caozuohounum==0){
                    caozuohounum = getTingPainum(entry.getValue(),allpai);
                }
                if (caozuohounum < getTingPainum(entry.getValue(),allpai)){
                    caozuohounum = getTingPainum(entry.getValue(),allpai);
                }
            }
        }
        chiob.putInt("tingNum",caozuohounum - caozuoqiannum);

        System.out.println("chiob:"+chiob);
        return chiob;
    }

    public static boolean shiFouJieTing(List<Integer> tingList,List<Integer> changShachuguopai ){


        return false;
    }

    public static int getTingPainum(List<Integer> caozq, List<Integer> changShachuguopai){
        int num = 0;
        for (int i=0;i<caozq.size();i++){
            int js = 4;
            for (int j=0;j<changShachuguopai.size();j++){
                if ((int)caozq.get(i) == (int)changShachuguopai.get(j)){
                    js = js-1;
                }
            }
            num = js+num;
        }
        return num;
    }



    /**
     * 判断手牌是否能听牌
     * @param cardhand
     * @return
     */
    public static List<Integer> handscardshifoutingpai(List<Integer> cardhand,List<Integer>chowGroup,List<Integer> pongGroup,List<Integer> gangdepai) {
        List<Integer> tpcards = new ArrayList<>();
        List<Integer> tmphc = new ArrayList<>();
        tmphc.addAll(cardhand);
        for (int j = 101; j <= 109; j++) {
            WinCard win = new WinCard(tmphc, j);
            if (win.tryWin()) {
                if (!tpcards.contains(j)) {
                    tpcards.add(j);
                }
            }

            Paixing px = new Paixing();
            List<Integer> pxc = new ArrayList<>();
            pxc.addAll(tmphc);
            //pxc.add(j);
            if(px.tingCheck(pxc,chowGroup,pongGroup,gangdepai)){
                if (!tpcards.contains(j)) {
                    tpcards.add(j);
                }
            }
        }
        for (int k = 201; k<= 209; k++) {
            WinCard win = new WinCard(tmphc, k);

            if (win.tryWin()) {
                if (!tpcards.contains(k)) {
                    tpcards.add(k);
                }
            }

            Paixing px = new Paixing();
            List<Integer> pxc2 = new ArrayList<>();
            pxc2.addAll(tmphc);
           // pxc2.add(k);
            if(px.tingCheck(pxc2,chowGroup,pongGroup,gangdepai)){
                if (!tpcards.contains(k)) {
                    tpcards.add(k);
                }
            }
        }
        //如果没有则检测大胡
        return tpcards;
    }

    public static Map<Integer,List<Integer>> quyizhangDahuTingPai(List<Integer> cardhand,List<Integer> chowGroup,List<Integer> pongGroup,List<Integer> gangdepai){
        Map<Integer,List<Integer>> map = new HashMap<>();
        List<Integer> tmphc = cardhand;

        for (int i = 0; i < cardhand.size(); i++) {
            int tmpcard = tmphc.get(0);
            tmphc.remove(0);
            List<Integer> huziting = new ArrayList<>();
            for (int j = 101; j <= 109; j++) {
                Paixing px = new Paixing();
                List<Integer> pxc = new ArrayList<>();
                pxc.add(j);
                pxc.addAll(tmphc);
                if(px.tingCheck(pxc,chowGroup,pongGroup,gangdepai)){
                    if (!huziting.contains(j)) {
                        huziting.add(j);
                    }
                }
            }
            for (int k = 201; k <= 209; k++) {
                Paixing px2 = new Paixing();
                List<Integer> pxc2 = new ArrayList<>();
                pxc2.add(k);
                pxc2.addAll(tmphc);
                if(px2.tingCheck(pxc2,chowGroup,pongGroup,gangdepai)){
                    if (!huziting.contains(k)) {
                        huziting.add(k);
                    }
                }
            }
            if (huziting.size()>0){
                map.put(tmpcard,huziting);
            }
            tmphc.add(tmpcard);

        }
        return map;
    }

    public static  Map<Integer, List<Integer>> quyizhangTingPai(List<Integer> cardhand) {
        Map<Integer, List<Integer>> quxiatingmap = new HashMap<>();

        List<Integer> tmphc = cardhand;

        for (int i = 0; i < cardhand.size(); i++) {
            int tmpcard = tmphc.get(0);
            tmphc.remove(0);
            List<Integer> huziting = new ArrayList<>();
            for (int j = 101; j <= 109; j++) {
                WinCard win = new WinCard(tmphc, j);
                if (win.tryWin()) {
                    if (!huziting.contains(j)) {
                        huziting.add(j);
                    }
                }
            }
            for (int k = 201; k <= 209; k++) {
                WinCard win = new WinCard(tmphc, k);
                if (win.tryWin()) {
                    if (!huziting.contains(k)) {
                        huziting.add(k);
                    }
                }
            }
            if (huziting.size()>0){
                quxiatingmap.put(tmpcard,huziting);
            }
            tmphc.add(tmpcard);

        }
        return quxiatingmap;
    }

    public static Map<String, Object>  quyizhangChayou(List<Integer> cardhand,List<Integer>chowGroup,List<Integer> pongGroup,List<Integer> gangdepai,Map<Integer,List<Integer>> xiatingList) {
        Map<String, Object> map = new HashMap<>();
        Map<Integer,Map<String, Object>> bigMap = new HashMap<>();

        List<Integer> tmphc = new ArrayList<>();
        tmphc.addAll(cardhand);
        System.out.println("tmphc1:"+tmphc);
        for (int i = 0; i < cardhand.size(); i++) {
            int tmpcard = tmphc.get(0);
            tmphc.remove(0);

            Map<String, Object> tmap = new HashMap<>();
            int res = ChangshaWinSplitCard.checkNormalHu(tmphc,tmap);
            bigMap.put(tmpcard,tmap);

            //检查是否能下听
            List<Integer> tmxt = new ArrayList<>();
            tmxt = handscardshifoutingpai(tmphc,chowGroup,pongGroup,gangdepai);
            if (tmxt.size()>0){
                xiatingList.put(tmpcard,tmxt);
            }

            tmphc.add(tmpcard);
        }
        System.out.println(bigMap);
        System.out.println("吃之后");
        //遍历找最优解
        if (bigMap.size()==0){
            return map;
        }

        Map<String, Object> bestmap = gaiBestCardInMap(bigMap);

        return bestmap;
    }
    private static Map<String, Object> gaiBestCardInMap(Map<Integer,Map<String, Object>> map){
        Map<String, Object> tmpmap = new HashMap<>();
        int bestcard = 0;
        for (Map.Entry<Integer, Map<String, Object>> entry : map.entrySet()) {
            if (tmpmap.isEmpty()){
                tmpmap = entry.getValue();
                bestcard = entry.getKey();
            }else{
                int tmpr = Integer.parseInt( tmpmap.get("remainingMelds").toString());
                int entr = Integer.parseInt( entry.getValue().get("remainingMelds").toString());
                if (tmpr>entr){
                    tmpmap = entry.getValue();
                }else if (tmpr==entr){
                    List<Integer> tl = (List<Integer>)tmpmap.get("cardResiue");
                    List<Integer> enl = (List<Integer>)entry.getValue().get("cardResiue");

                    if (tl.size()>enl.size()){
                        tmpmap = entry.getValue();
                    }
                    if(tl.size()==enl.size()){
                        //寻找是否有边张
                        for (int i=0;i<tl.size();i++){
                            if (tl.get(i)%100==9||tl.get(i)%100==1){
                            }else{
                                //不要取有边张
                                tmpmap = entry.getValue();
                            }
                        }
                    }
                }
            }
        }

        return tmpmap;
    }

    public static void main(String[] args) {
        // 测试用例：没有258将牌的情况
        List<Integer> test1 = new ArrayList<Integer>();

        test1.add(205);
        test1.add(204);
        test1.add(204);
        test1.add(203);

        test1.add(202);
        test1.add(201);
        test1.add(108);

        test1.add(107);
        test1.add(103);
        test1.add(103);

       // test1.add(106);
        //test1.add(104);
       // test1.add(103);

        int lg = countPairs(test1);
        System.out.println(lg);
        //int card = 206;
        //int flag = checkChiTingAction(card,test1);
        //System.out.println(flag);

        //测试吃：
        List<Integer> allcard = new ArrayList<>();
        allcard.add(105);
        allcard.add(101);
        allcard.add(209);
        allcard.add(209);
        allcard.add(104);
        allcard.add(104);
        allcard.add(104);
        //allcard.add(104);
        /*ITArray opcard = TArray.newInstance();
        opcard.addInt(209);
        opcard.addInt(208);*/

        List<Integer> chipai = new ArrayList<>();
        chipai.add(207);
        chipai.add(208);
        chipai.add(209);


       // chipai.add(101);
      //  chipai.add(102);
      //  chipai.add(103);
       // int card = 202;

        List<Integer>changShachuguopai = new ArrayList<>();
        //changShachuguopai.add(101);
        changShachuguopai.add(202);
        changShachuguopai.add(201);
        changShachuguopai.add(203);
        changShachuguopai.add(105);
        changShachuguopai.add(105);
        changShachuguopai.add(105);
        changShachuguopai.addAll(allcard);

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

       // gangguopai.add(108);0

        int card = 103;
        List<Integer>pengCard = new ArrayList<>();
        /*pengCard.add(203);
        pengCard.add(203);
        pengCard.add(203);

        pengCard.add(101);
        pengCard.add(101);
        pengCard.add(101);*/

        //出牌求优
        ChangShaSuanFaTest ct = new ChangShaSuanFaTest();
        test1.add(card);
        String outcard = ct.outCardSuanFa(test1,pengCard,chipai,gangguopai,changShachuguopai);

        System.out.println("outcard:"+outcard);

        // pingguChi(false,card,opcard,test1,0,allcard,chipai,changShachuguopai);

        //测试碰
       // int card = 102;
        ITArray opcardpeng = TArray.newInstance();
        opcardpeng.addInt(203);

        List<Integer> pengpai = new ArrayList<>();
        List<Integer> gangpai = new ArrayList<>();

        //pingguPeng(true,card,opcardpeng,test1,0,allcard,chipai,pengpai,gangpai,changShachuguopai);
        /*
       //List<Integer>tf = handscardshifoutingpai(test1);
       // System.out.println(tf);
        //Map<String, Object> map = new HashMap<>();
        //map = quyizhangChayou(test1);
       // System.out.println(map);

        /*Map<Integer,List<Integer>> maps = new HashMap<>();
        maps = quyizhangTingPai(test1);
        System.out.println(maps);*/
       // test1.add(202);
       // test1.add(209);
       // test1.add(201);

      //  test1.add(208);
     //   test1.add(207);
       // test1.add(209);

     //   test1.add(104);

       // test1.add(203);
       // test1.add(202);
       // test1.add(201);
//        test1.add(103);
//        test1.add(102);

        /*
        int card = 201;
        List<Integer> pengguopai = new ArrayList<>();
        pengguopai.add(204);
        pengguopai.add(204);
        pengguopai.add(204);
        List<Integer> chipai = new ArrayList<>();
        chipai.add(203);
        chipai.add(202);
        chipai.add(201);
        List<Integer> gangguopai = new ArrayList<>();
        gangguopai.add(206);
        gangguopai.add(206);
        gangguopai.add(206);
        gangguopai.add(206);

        System.out.println("手牌：" + test1);
       boolean c =  checkAllSameSuitAll(card,test1,pengguopai,chipai,gangguopai);
       System.out.println(c);
       */

//        if (!bestDiscard.isEmpty()) {
//            System.out.println("建议出牌：" + bestDiscard.get(0));
//        } else {
//            System.out.println("没有出牌建议");
//        }
    }
}
