1. 程式人生 > >微信小遊戲開發-麻將洗牌演算法(二)

微信小遊戲開發-麻將洗牌演算法(二)

麻將一組有1-9筒,1-9條,1-9萬,中發白,東南西北,34張牌,共有四組。

可以通過一個數組來表示則一組牌,程式碼如下:

private final static String[] mahjong = { "1T", "2T", "3T", "4T", "5T",
            "6T", "7T", "8T", "9T", "1S", "2S", "3S", "4S", "5S", "6S", "7S",
            "8S", "9S", "1W", "2W", "3W", "4W", "5W", "6W", "7W", "8W", "9W",
            "DONG", "NAN", "XI", "BEI", "ZHONG", "FA", "BAI" };

麻將隨機洗牌演算法如下:

/**
     * pengweikang 20180716 隨機洗牌次數
     * @param cards 總牌數
     * @param times 洗牌次數
     */
    public static void shuffle(int [] cards,int times){

        for(int j = 0; j <= times; j ++)
            for(int i = cards.length; i > 1; i --){
                int temp_i = rd.nextInt(i);
                int value = cards[temp_i];
                cards[temp_i] = cards[i - 1];
                cards[i - 1] = value;
            }

    }

獲取一副洗好牌後的麻將程式碼如下:

/**
     * pengweiakng 20180714 獲取已經洗好牌的麻將
     */
    private static int[] getMajiang(){
        int majiang [] = new int[136];
        for(int i = 0; i < 4; i++){
            for(int j = 0; j < mahjong.length; j++){
                majiang[j+(i*mahjong.length)] =  j;
            }
        }

        /**
         * 預設洗牌5次
         */
        shuffle(majiang,5);
        return majiang;

    }

按照使用者人數進行洗麻將程式碼如下:

/**
     * pengweikang 20180714 通過使用者數量進行洗牌
     * @param users 使用者數
     * @return
     */
    public static  List<Block> getBlocks(int users) throws Exception{

        if(users > 4){
            throw new Exception("使用者數量不能大於4人");
        }

        List<Block> blockList = new ArrayList<>();

        int [] majiang = getMajiang();

        /**
         * blockSize為每個人分配的麻將數量
         */
        int blockSize = majiang.length/users;
        int [] leftData = new int[blockSize];
        for(int i = 0; i < majiang.length; i++){
            if((i+1)%blockSize == 0){
                leftData[i%blockSize] = majiang[i];
                Block block = new Block();
                block.setLeftData(leftData);
                blockList.add(block);
                leftData = new int[blockSize];
            }else{
                leftData[i%blockSize] = majiang[i];
            }
        }
        return blockList;

    }

執行結果如下:

初始化麻將:
2W,9W,9T,1W,6W,1W,2S,FA,1S,9T,5T,2T,3S,4T,9T,3W,6W,4S,5W,FA,2T,8T,XI,9S,BEI,6S,8W,7S,XI,XI,5T,9S,1S,5T,
8W,5T,5W,5W,8T,8T,6T,7T,4W,6S,XI,1T,4W,9W,BAI,FA,5S,1T,BEI,8S,1W,4W,2W,4S,6W,8W,9W,6T,7S,9W,DONG,BAI,8T,2T,
9S,2S,BEI,2S,9T,ZHONG,8S,5W,NAN,BAI,ZHONG,1W,6W,5S,7T,NAN,NAN,1T,7S,DONG,7W,DONG,6T,8S,5S,1S,4W,FA,DONG,6T,6S,ZHONG,3T,7T,
2S,7W,3T,NAN,BAI,8S,2T,5S,8W,1S,3S,9S,3W,7W,6S,7T,3W,7W,3T,1T,4T,2W,4T,4T,4S,3S,3T,ZHONG,2W,3W,4S,3S,BEI,7S,

本人是江西樂平人,分享一組老家的洗牌麻法:

振骰子玩法:莊家通過自己振骰子的點數找到第二次骰篩子的人,例如莊家振骰子點數為7,從莊家自己開始順時針數到7的使用者為第二次振骰子的人,顯然是莊家對面的玩家了,然後第二個人開始振骰子。

抓拍玩法:第二個人振完骰子後,將兩次振骰子的點數進行相加,然後莊家從第二次振骰子的玩家麻將區從左到右數完兩次振的骰子點數後開始抓拍,莊家抓完後有莊家下家進行抓拍,沒人每次抓4張。抓3次,每人一共抓12張牌,之後莊家抓兩張牌,其他玩家依次抓1張牌,抓完後莊家14張牌,其他玩家13張牌。

程式碼執行結果如下:

初始化麻將:
2W,9W,9T,1W,6W,1W,2S,FA,1S,9T,5T,2T,3S,4T,9T,3W,6W,4S,5W,FA,2T,8T,XI,9S,BEI,6S,8W,7S,XI,XI,5T,9S,1S,5T,
8W,5T,5W,5W,8T,8T,6T,7T,4W,6S,XI,1T,4W,9W,BAI,FA,5S,1T,BEI,8S,1W,4W,2W,4S,6W,8W,9W,6T,7S,9W,DONG,BAI,8T,2T,
9S,2S,BEI,2S,9T,ZHONG,8S,5W,NAN,BAI,ZHONG,1W,6W,5S,7T,NAN,NAN,1T,7S,DONG,7W,DONG,6T,8S,5S,1S,4W,FA,DONG,6T,6S,ZHONG,3T,7T,
2S,7W,3T,NAN,BAI,8S,2T,5S,8W,1S,3S,9S,3W,7W,6S,7T,3W,7W,3T,1T,4T,2W,4T,4T,4S,3S,3T,ZHONG,2W,3W,4S,3S,BEI,7S,
莊家是:3
第一次搖撒子點數:3
第二次搖撒子點數:11
寶為:2W
剩餘麻將:
2W,9W,9T,1W,6W,1W,2S,FA,1S,9T,5T,2T,3S,4T,9T,3W,6W,4S,5W,FA,2T,8T,XI,9S,BEI,6S,8W,7S,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,5S,7T,NAN,NAN,1T,7S,DONG,7W,DONG,6T,8S,5S,1S,4W,FA,DONG,6T,6S,ZHONG,3T,7T,
2S,7W,3T,NAN,BAI,8S,2T,5S,8W,1S,3S,9S,3W,7W,6S,7T,3W,7W,3T,1T,4T,2W,4T,4T,4S,3S,3T,ZHONG,2W,3W,4S,3S,BEI,7S,
使用者洗牌麻將:
-1,8T,8T,2S,2S,8S,9S,1W,4W,5W,5W,BEI,BEI,ZHONG,
-1,6T,7T,9T,4S,6S,8S,1W,2W,4W,5W,6W,8W,ZHONG,
1T,5T,6T,7S,9S,4W,6W,9W,9W,9W,NAN,XI,XI,XI,
-1,1T,2T,5T,5T,8T,1S,5S,8W,DONG,FA,BAI,BAI,BAI,

演算法如下:

/**
     * pengweikang 20180716 初始化麻將
     * @param blockList 洗好的麻將
     * @param banker 莊家索引
     */
    public static void matchCard(List<Block> blockList,int banker) {


        System.out.println("莊家是:"+(banker+1));

        /**
         * 搖一搖撒子,進行搖點數,第一次
         */
        int random1 = rd.nextInt(12) + 1;

        System.out.println("第一次搖撒子點數:"+random1);

        /**
         * 搖一搖撒子,進行搖點數,第二次
         */
        int random2 = rd.nextInt(12) + 1;
        System.out.println("第二次搖撒子點數:"+random2);

        /**
         * 第一次搖骰子選中的使用者序號
         */
        int usernum = (random1 + banker - 1) % blockList.size() ;

        /**
         * 正骰子總點數
         */
        int randomSum = random1 + random2;

        int start = banker; //莊家所屬位置
        int times = 0; //抓取次數問題
        int usertimes = 0; //使用者抓取次數抓取次數問題

        int bao = -1;

        int[] leftData = blockList.get(usernum).getLeftData(); //從哪個使用者麻將區域進行抓牌
        if (randomSum >= (leftData.length / 2)) {   //判斷骰子點數是否大於該人的麻將總數
            randomSum = randomSum - leftData.length / 2;


            blockList.get(usernum).setGhostIndex(randomSum*2); //設定寶的索引位置
            bao = leftData[randomSum*2];


            usernum++;
            if (usernum > 3) {
                usernum = 0;
            }



        }else{

            int tempindex = usernum;
            tempindex--;
            if(tempindex == -1){
                tempindex = blockList.size() - 1;
            }

            blockList.get(tempindex).setGhostIndex(randomSum*2); //設定寶的索引位置

            leftData = blockList.get(tempindex).getLeftData();

            bao = leftData[randomSum*2];


        }

        System.out.println("寶為:"+mahjong[bao]);

        while (true) {

            leftData = blockList.get(usernum).getLeftData(); //從哪個使用者麻將區域進行抓牌

                if(usertimes == 2){ //一個使用者抓取兩次
                    usertimes = 0;
                    start++;
                    if (start > blockList.size() - 1) {
                        start = 0;
                    }

                    if(start == banker){
                        times++;
                    }

                }

                if(times != 3){
                    int[] data = blockList.get(start).getData();
                    data[times * 4 + usertimes*2 ] = leftData[randomSum * 2];
                    data[times * 4 + usertimes*2 + 1] = leftData[randomSum * 2 + 1];

                    leftData[randomSum * 2] = -1;
                    leftData[randomSum * 2 + 1] = -1;
                    randomSum++;
                    usertimes++;
                }else{


                    if(randomSum == 15){

                        int[] data = blockList.get(start).getData();

                        int tempusernum = usernum + 1;
                        if (tempusernum > blockList.size() - 1) {
                            tempusernum = 0;
                        }

                        int[] leftData1 = blockList.get(tempusernum).getLeftData();

                        data[times * 4 + usertimes*2 ] = leftData[randomSum * 2];
                        leftData[randomSum * 2] = -1;//抓牌後麻將設定成-1
                        data[times * 4 + usertimes*2 + 1] = leftData1[0];
                        leftData1[0] = -1;//抓牌後麻將設定成-1
                        start++;
                        if (start > blockList.size() - 1) {
                            start = 0;
                        }
                        data = blockList.get(start).getData();
                        data[times * 4 + usertimes*2 ] = leftData[randomSum * 2 + 1];
                        leftData[randomSum * 2 + 1] = -1;
                        start++;
                        if (start > blockList.size() - 1) {
                            start = 0;
                        }
                        data = blockList.get(start).getData();
                        data[times * 4 + usertimes*2 ] = leftData[randomSum * 2 + 2];
                        leftData[randomSum * 2 + 2] = -1;

                        start++;
                        if (start > blockList.size() - 1) {
                            start = 0;
                        }
                        data = blockList.get(start).getData();
                        data[times * 4 + usertimes*2 ] = leftData[randomSum * 2 + 3];
                        leftData[randomSum * 2 + 3] = -1;

                        blockList.get(tempusernum).setCardIndex(1); //設定抓拍索引

                    }else if(randomSum == 16){


                        int[] data = blockList.get(start).getData();

                        int tempusernum = usernum + 1;
                        if (tempusernum > blockList.size() - 1) {
                            tempusernum = 0;
                        }

                        int[] leftData1 = blockList.get(tempusernum).getLeftData();


                        data[times * 4 + usertimes*2 ] = leftData[randomSum * 2];
                        leftData[randomSum * 2] = -1;
                        data[times * 4 + usertimes*2 + 1] = leftData1[2];
                        leftData1[2] = -1;
                        start++;
                        if (start > blockList.size() - 1) {
                            start = 0;
                        }
                        data = blockList.get(start).getData();
                        data[times * 4 + usertimes*2 ] = leftData[randomSum * 2 + 1];
                        leftData[randomSum * 2 + 1] = -1;
                        start++;
                        if (start > blockList.size() - 1) {
                            start = 0;
                        }
                        data = blockList.get(start).getData();
                        data[times * 4 + usertimes*2 ] = leftData1[0];
                        leftData1[0] = -1;

                        start++;
                        if (start > blockList.size() - 1) {
                            start = 0;
                        }
                        data = blockList.get(start).getData();
                        data[times * 4 + usertimes*2 ] = leftData1[1];
                        leftData1[1] = -1;

                        blockList.get(tempusernum).setCardIndex(3); //設定抓拍索引

                    }else{

                        int[] data = blockList.get(start).getData();
                        data[times * 4 + usertimes*2 ] = leftData[randomSum * 2];
                        leftData[randomSum * 2] = -1;
                        data[times * 4 + usertimes*2 + 1] = leftData[randomSum * 2 + 4];
                        leftData[randomSum * 2 + 4] = -1;
                        start++;
                        if (start > blockList.size() - 1) {
                            start = 0;
                        }
                        data = blockList.get(start).getData();
                        data[times * 4 + usertimes*2 ] = leftData[randomSum * 2 + 1];
                        leftData[randomSum * 2 + 1] = -1;
                        start++;
                        if (start > blockList.size() - 1) {
                            start = 0;
                        }
                        data = blockList.get(start).getData();
                        data[times * 4 + usertimes*2 ] = leftData[randomSum * 2 + 2];
                        leftData[randomSum * 2 + 2] = -1;

                        start++;
                        if (start > blockList.size() - 1) {
                            start = 0;
                        }
                        data = blockList.get(start).getData();
                        data[times * 4 + usertimes*2 ] = leftData[randomSum * 2 + 3];
                        leftData[randomSum * 2 + 3] = -1;
                        blockList.get(usernum).setCardIndex(randomSum * 2 + 5);//設定抓牌的索引
                    }

                    break;

                }





                if (randomSum > 16) { //判斷當前使用者的麻將是否分配完,如果分配完了就進行下一個人麻將進行分配
                    randomSum = 0;
                    usernum++;
                    if (usernum > 3) {
                        usernum = 0;
                    }
                }




        }



        for(Block block : blockList){
            Arrays.sort(block.getData());
        }


    }