package taurus.util;

import java.util.*;

public class test99 {

    // 长沙麻将特殊规则：二五八将
    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);
    }

    /**
     * 分析14张手牌的最佳打牌策略
     */
    public static void analyzeHandCards(List<Integer> handCards) {
        if (handCards == null || handCards.size() != 14) {
            System.out.println("错误：手牌必须是14张");
            return;
        }

        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));


    }









    /**
     * 找出所有刻子
     */
    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 boolean canFormShunzi(int card1, int card2, int card3) {
        if (getCardType(card1) != getCardType(card2) ||
                getCardType(card1) != getCardType(card3)) {
            return false;
        }

        List<Integer> values = Arrays.asList(
                getCardValue(card1),
                getCardValue(card2),
                getCardValue(card3)
        );
        Collections.sort(values);

        return values.get(0) + 1 == values.get(1) &&
                values.get(1) + 1 == values.get(2);
    }



    /**
     * 获取牌值
     */
    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 static void main(String[] args) {
        System.out.println("=== 长沙麻将手牌分析 ===\n");

        // 测试你提供的例子
        System.out.println("测试例子：201,202,203, 101,102,103, 303,303,303,105,108,307,309,308");
        List<Integer> hand = Arrays.asList(
                201, 202, 203,    // 1筒2筒3筒顺子
                101, 102, 103,    // 1万2万3万顺子
                303, 303, 303,    // 3条刻子
                105,              // 5万
                108,              // 8万
                307,              // 7条
                309,              // 9条
                308               // 8条
        );

        analyzeHandCards(hand);


    }
}