package chapter6.demo64;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;

public class Function {
    // 存储牌号和牌面的对应关系
    private static HashMap<Integer, String> cardMap = new HashMap<>();

    public static void main(String[] args) {
        // 1. 准备牌的基本元素
        ArrayList<String> colors = prepareColors();
        ArrayList<String> points = preparePoints();

        // 2. 组装54张牌
        createCards(colors, points);

        // 3. 洗牌准备
        ArrayList<Integer> cards = shuffleCards();

        // 4. 发牌
        ArrayList<ArrayList<Integer>> dealtCards = dealCards(cards);
        ArrayList<Integer> iPlayer = dealtCards.get(0);
        ArrayList<Integer> iPlayer2 = dealtCards.get(1);
        ArrayList<Integer> iPlayer3 = dealtCards.get(2);
        ArrayList<Integer> iSecretCards = dealtCards.get(3);

        // 5. 整理手牌
        sortCards(iPlayer, iPlayer2, iPlayer3);

        // 6. 转换并显示牌面
        showCards(iPlayer, iPlayer2, iPlayer3, iSecretCards);
    }

    /**
     * 准备扑克牌的4种花色
     * @return ArrayList<String> 包含4种花色符号的列表
     */
    private static ArrayList<String> prepareColors() {
        ArrayList<String> colors = new ArrayList<>();
        colors.add("♠");
        colors.add("♥");
        colors.add("♣");
        colors.add("♦");
        return colors;
    }

    /**
     * 准备扑克牌的13种点数
     * @return ArrayList<String> 包含2-10,J,Q,K,A的点数列表
     */
    private static ArrayList<String> preparePoints() {
        ArrayList<String> points = new ArrayList<>();
        for (int i = 2; i <= 10; i++) {
            points.add(i + "");
        }
        points.add("J");
        points.add("Q");
        points.add("K");
        points.add("A");
        return points;
    }

    /**
     * 创建54张扑克牌，并建立编号和牌面的映射关系
     * @param colors 花色列表
     * @param points 点数列表
     */
    private static void createCards(ArrayList<String> colors, ArrayList<String> points) {
        int index = 0;
        for (String number : points) {
            for (String color : colors) {
                cardMap.put(index++, color + number);
            }
        }
        cardMap.put(index++, "小☺");
        cardMap.put(index++, "大☻");
    }

    /**
     * 生成54张牌的编号并随机打乱顺序
     * @return ArrayList<Integer> 洗好的牌的编号列表(0-53)
     */
    private static ArrayList<Integer> shuffleCards() {
        ArrayList<Integer> cards = new ArrayList<>();
        for (int i = 0; i <= 53; i++) {
            cards.add(i);
        }
        Collections.shuffle(cards);
        return cards;
    }

    /**
     * 将54张牌分发给三个玩家和底牌
     * @param cards 洗好的牌的编号列表
     * @return ArrayList<ArrayList<Integer>> 包含四个列表的集合：
     *         索引0-2分别为三个玩家的牌，索引3为底牌
     */
    private static ArrayList<ArrayList<Integer>> dealCards(ArrayList<Integer> cards) {
        ArrayList<Integer> iPlayer = new ArrayList<>();
        ArrayList<Integer> iPlayer2 = new ArrayList<>();
        ArrayList<Integer> iPlayer3 = new ArrayList<>();
        ArrayList<Integer> iSecretCards = new ArrayList<>();

        for (int i = 0; i < cards.size(); i++) {
            if (i >= 51) {
                iSecretCards.add(cards.get(i));
            } else {
                if (i % 3 == 0) {
                    iPlayer.add(cards.get(i));
                } else if (i % 3 == 1) {
                    iPlayer2.add(cards.get(i));
                } else {
                    iPlayer3.add(cards.get(i));
                }
            }
        }

        ArrayList<ArrayList<Integer>> result = new ArrayList<>();
        result.add(iPlayer);
        result.add(iPlayer2);
        result.add(iPlayer3);
        result.add(iSecretCards);
        return result;
    }

    /**
     * 对玩家手中的牌进行排序
     * @param players 可变参数，接收多个玩家的牌列表
     */
    private static void sortCards(ArrayList<Integer>... players) {
        for (ArrayList<Integer> player : players) {
            Collections.sort(player);
        }
    }

    /**
     * 展示所有玩家的牌和底牌
     * @param iPlayer 玩家1的牌号列表
     * @param iPlayer2 玩家2的牌号列表
     * @param iPlayer3 玩家3的牌号列表
     * @param iSecretCards 底牌列表
     */
    private static void showCards(ArrayList<Integer> iPlayer, ArrayList<Integer> iPlayer2,
                                  ArrayList<Integer> iPlayer3, ArrayList<Integer> iSecretCards) {
        ArrayList<String> sPlayer = convertToCardFace(iPlayer);
        ArrayList<String> sPlayer2 = convertToCardFace(iPlayer2);
        ArrayList<String> sPlayer3 = convertToCardFace(iPlayer3);
        ArrayList<String> sSecretCards = convertToCardFace(iSecretCards);

        System.out.println("玩家1：" + sPlayer);
        System.out.println("玩家2：" + sPlayer2);
        System.out.println("玩家3：" + sPlayer3);
        System.out.println("底牌：" + sSecretCards);
    }

    /**
     * 将牌号转换为具体的牌面
     * @param cards 牌号列表
     * @return ArrayList<String> 转换后的牌面列表
     */
    private static ArrayList<String> convertToCardFace(ArrayList<Integer> cards) {
        ArrayList<String> result = new ArrayList<>();
        for (Integer key : cards) {
            result.add(cardMap.get(key));
        }
        return result;
    }
}
