1. 程式人生 > >java實現麻將(集合的應用)

java實現麻將(集合的應用)

*實現功能點
實現麻將的準備牌、洗牌、發牌、看牌
知識點
集合知識
專案思路
思路介紹
Icon
麻將的功能需求分析
a:具體規則:

  1. 組裝136張麻將
    條、筒、萬加到一起的數目是108張
    東、西、南、北風、紅中、白皮、發財是28張,總共136張
  2. 將136張牌順序打亂
  3. 四個玩家參與遊戲,四人交替摸牌,每次4張,3次,之後莊家摸2張,兩張之間個索引相差4,其他人再摸一張,即莊家14張,其他每人13張,剩下的留作底牌。
  4. 檢視四人各自手中的牌(按照牌的大小排序)、底牌*
import java.util.*;

/**
 * Description: 條strip 筒canister 萬 ten thousand
 *
 * @Author Fann
 * @Data 2018/11/14
 */
public class Mahjong {
    //牌插入時候的序號,從1開始
    int n = 1;
    //插入的花色型別
    int[] num = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9};
    String[] typeOne = new String[]{"筒", "萬", "條"};
    String[] typeTwo = new String[]{"東風", "西風", "南風", "北風", "紅中", "白板", "發財"};

    LinkedList<Integer> idMahjong;          //儲存牌的順序,利用牌的Integer可以通過hashmap查詢到花色.
    HashMap<Integer, String> idWithValue;    //key:牌的序號,value:花色
    ArrayList<ArrayList<Integer>> player;   //儲存四位玩家的ArrayList,預設第一位莊

    /**
     * 預設構造方法
     */
    public Mahjong() {
        this.idMahjong = new LinkedList<Integer>();
        this.idWithValue = new HashMap<Integer, String>();
        this.player = new ArrayList<ArrayList<Integer>>( 4 );
        for (int i = 0; i < 4; i++) {
            player.add( new ArrayList<Integer>() );
        }
    }

    /**
     * 整理麻將,共136張 並且打亂.
     */
    public void arrangeMahjong() {
        //加入筒,萬,條
        for (int i = 0; i < num.length; i++) {
            for (int j = 0; j < typeOne.length; j++) {
                String s = num[i] + typeOne[j];
                for (int k = 0; k < 4; k++) {  //每張牌插入四次
                    idWithValue.put( n, s );
                    idMahjong.add( n );
                    n++;
                }
            }
        }
        //插入東,西,南,北風,紅中,白板,發財
        for (int i = 0; i < typeTwo.length; i++) {
            String s = typeTwo[i];
            for (int j = 0; j < 4; j++) {
                idWithValue.put( n, s );
                idMahjong.add( n );
                n++;
            }
        }
        //對牌進行打亂
        Collections.shuffle( idMahjong );
    }

    /**
     * 發牌的過程
     */
    public void dealMahjong() {
        //利用ArrayList--idMahjong迭代器進行摸牌
        //四個人交替摸牌的過程,  每次四張, 三次.
        Iterator<Integer> iteratorForId = idMahjong.iterator();
        for (int i = 0; i < 3; i++) {  //三次
            for (int j = 0; j < 4; j++) {  //輪到第幾號玩家
                for (int k = 0; k < 4; k++) {  //摸牌的張數
                    Integer data = iteratorForId.next();
                    player.get( j ).add( data );
                    iteratorForId.remove(); //同時在牌中刪除這個.
                }
            }
        }

        //之後是莊家摸兩張,兩張間索引差4,其他人再摸一張
        //意思就是再摸5張牌,莊家拿1和5號,其他人拿2 3 4號
        for (int i = 0; i < 4; i++) {
            Integer data = iteratorForId.next();
            player.get( i ).add( data );
            iteratorForId.remove();
        }
        player.get( 0 ).add( iteratorForId.next() );  //第五張,
        iteratorForId.remove();
    }

    /**
     * 展示四位玩家的牌,和底牌.四位玩家的牌是有順序的,底牌是亂序的
     */
    public void printMahjong() {
        for (int i = 0; i < 4; i++) {
            int t = 0;
            System.out.print("第"+(i+1)+"位player的牌:");
            Collections.sort( player.get( i ),comparator );
            Iterator<Integer> iteratorPlayer = player.get( i ).iterator();
            while (iteratorPlayer.hasNext()){
                Integer key = iteratorPlayer.next(); //迭代器裡面存的是牌的序號,也就是key
                System.out.print(idWithValue.get( key )+" ");
                t++;
            }
            System.out.println("一共"+t+"張");
        }
        /**
         * 打印出底牌
         */
        System.out.print("底桌上的牌:");
        int t = 0;
        Iterator<Integer> iteratorForDesk = idMahjong.iterator();
        while (iteratorForDesk.hasNext()){
            Integer key = iteratorForDesk.next();
            System.out.print(idWithValue.get( key )+" ");
            t++;
        }
        System.out.println("牌桌上一共剩下"+t+"張");
    }

    /**
     * 比較器類,根據玩家ArrayList中的Integer得到HashMap中的String,比較String
     * 按照 筒,萬,條,風,紅中,白板,發財  記錄優先順序為1-7
     */
    private Comparator<Integer> comparator = new Comparator<Integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
            String s1 = idWithValue.get( o1 );
            int levelForS1 = 0;
            String s2 = idWithValue.get( o2 );
            int levelForS2 = 0;

            switch (s1.charAt( 1 )) {
                case '筒': levelForS1 = 1;break;
                case '萬': levelForS1 = 2;break;
                case '條': levelForS1 = 3;break;
                case '風': levelForS1 = 4;break;
                case '中': levelForS1 = 5;break;
                case '板': levelForS1 = 6;break;
                case '財': levelForS1 = 7;break;
            }
            switch (s2.charAt( 1 )) {
                case '筒': levelForS2 = 1;break;
                case '萬': levelForS2 = 2;break;
                case '條': levelForS2 = 3;break;
                case '風': levelForS2 = 4;break;
                case '中': levelForS2 = 5;break;
                case '板': levelForS2 = 6;break;
                case '財': levelForS2 = 7;break;
            }

            if (levelForS1 < levelForS2) { //如果第一個的優先順序高,返回-1,讓第一張牌在前面
                return -1;
            } else if (levelForS1 > levelForS2) {
                return 1;
            } else {  //證明兩個優先順序相等,接著比較牌1-9
                //如果都是筒or萬 or條,比較數字.
                if (levelForS1 == 1 || levelForS1 == 2 || levelForS1 == 3) {
                    switch (s1.charAt( 0 )) {
                        case '1': levelForS1 = 1;break;
                        case '2': levelForS1 = 2;break;
                        case '3': levelForS1 = 3;break;
                        case '4': levelForS1 = 4;break;
                        case '5': levelForS1 = 5;break;
                        case '6': levelForS1 = 6;break;
                        case '7': levelForS1 = 7;break;
                        case '8': levelForS1 = 8;break;
                        case '9': levelForS1 = 9;break;
                    }
                    switch (s2.charAt( 0 )) {
                        case '1': levelForS2 = 1;break;
                        case '2': levelForS2 = 2;break;
                        case '3': levelForS2 = 3;break;
                        case '4': levelForS2 = 4;break;
                        case '5': levelForS2 = 5;break;
                        case '6': levelForS2 = 6;break;
                        case '7': levelForS2 = 7;break;
                        case '8': levelForS2 = 8;break;
                        case '9': levelForS2 = 9;break;
                    }
                    return levelForS1 - levelForS2; //如果第一個數字比較小,返回的是負值,保證第一張牌在前面.

                } else if (levelForS1 == 4) { //如果是風,比較東西南北
                    switch (s1.charAt( 0 )) {
                        case '東': levelForS1 = 1;break;
                        case '西': levelForS1 = 2;break;
                        case '南': levelForS1 = 3;break;
                        case '北': levelForS1 = 4;break;
                    }
                    switch (s2.charAt( 0 )) {
                        case '東': levelForS2 = 1;break;
                        case '西': levelForS2 = 2;break;
                        case '南': levelForS2 = 3;break;
                        case '北': levelForS2 = 4;break;
                    }
                    return levelForS1 - levelForS2;//如果第一個數字比較小,返回的是負值,保證了第一張牌在前面.

                } else {
                    return levelForS1 - levelForS2; //其他情況就是紅中,發財,白板.
                }
            }
        }
    };

    public static void main(String[] args) {
        Mahjong mahjong = new Mahjong();
        //整理牌
        mahjong.arrangeMahjong();
        //發牌
        mahjong.dealMahjong();
        //列印牌
        mahjong.printMahjong();
    }
}