java模擬實現鬥地主(超簡單的發牌理牌思路)

2020-08-12 12:25:16

java語言模擬實現鬥地主

用陣列以及亂數模擬實現,超簡單~~~

一、初始化牌

衆所周知,紙牌共有54張,將這54張牌放入到字串數組裏面,進行初始化操作,注意:這個順序很重要,後面理牌的時候要用。相當於一個模板 以下是我宣告的字串陣列。

String[] pai = {
                "3♠", "3♥", "3♦", "3♣",
                "4♠", "4♥", "4♦", "4♣",
                "5♠", "5♥", "5♦", "5♣",
                "6♠", "6♥", "6♦", "6♣",
                "7♠", "7♥", "7♦", "7♣",
                "8♠", "8♥", "8♦", "8♣",
                "9♠", "9♥", "9♦", "9♣",
                "10♠", "10♥", "10♦", "10♣",
                "J♠", "J♥", "J♦", "J♣",
                "Q♠", "Q♥", "Q♦", "Q♣",
                "K♠", "K♥", "K♦", "K♣",
                "A♠", "A♥", "A♦", "A♣",
                "2♠", "2♥", "2♦", "2♣",
                "大♚", "小♔"
        };

二、建陣列

//設定一個boolean陣列,來對應下標,檢查牌是否出現過
 boolean[] isTrue = new boolean[54];
 //用來存隨機生成的下標,最重要,理牌時候也用到
  int[] xiaBiao = new int[54];
  //建3個int陣列存下標,表示三個玩家,
   int[] zhao = new int[17];
   int[] liu = new int[17];
   int[] zhang = new int[17];
   //用一個int陣列存地主牌
   int[] diZhuPai = new int[3];

根據牌的下標去字串裏面取牌(值),如果這個值有了就對應的boolean陣列的對應的設爲true。

三、用亂數生成下標

用亂數生成一個(0,53]的亂數,其實生成的亂數就是字元陣列(pai陣列)的下標,根據生成的數去取值。

public void xiPai(String[] pai, boolean[] isTrue, int[] xiaBiao) {
        System.out.println("\n洗牌");
        int temp = 0;//用來計數,看是否夠54張牌,
        while (temp < 54) {
            ////隨機產生一個數(0,53]之間的數,賦值給p,這樣保證一次回圈只隨機產生一個
            int p = (int) (Math.random() * (53 - 0 + 1));
            //isTrue是一個boolean陣列,來對應下標,目的是檢查隨機生成的下標是否已經出現過
            if (!isTrue[p]) {//執行的話證明還沒有這個牌(下標)
                xiaBiao[temp] = p;//把值存到數組裏面
                temp++;//牌數加一
                System.out.print(pai[p] + "  ");
                //每27張牌換行一次
                if (temp % 27 == 0)
                    System.out.println();
                isTrue[p] = true;//對應的boolean陣列設爲true,證明這張牌已經有了
            }
        }
    }

發牌

發牌就是將存好的陣列下標分成4份(3份17個代表17張牌,一個3個,代表地主牌),可以直接用陣列拷貝方法,都可以,只要達到目的就行。

//發牌
    public void faPai(String[] pai, int[] xiaBiao, int[] zhang, int[] liu, int[] zhao, int[] dizhupai) {
        System.out.print("\n開始發牌:");
        int k = 0;
        int j = 0;
        while (j < 17) {
            zhao[j] = xiaBiao[k++];
            liu[j] = xiaBiao[k++];
            zhang[j] = xiaBiao[k++];
            j++;
        }
        System.out.print("\n張飛的牌爲:");
        for (int i =0; i<17 ; i++) {
            System.out.print(pai[zhang[i]] + "  ");
        }
        System.out.print("\n趙雲的牌爲:");
        for (int i =0; i<17 ; i++) {
            System.out.print(pai[zhao[i]] + "  ");
        }
        System.out.print("\n劉備的牌爲:");
        for (int i =0; i<17 ; i++) {
            System.out.print(pai[liu[i]] + "  ");
        }
        int q=0;
        System.out.print("\n底牌:");
        for (int i = 51; i < 54; i++) {
            dizhupai[q] = xiaBiao[i];
            System.out.print(pai[dizhupai[q]] + "  ");
            q++;
        }

    }

理牌

經過上面一個步驟以後,每個玩家手裏面都有了17張牌,只需要將他們排序(注意,從頭到尾用的都是下標,不是字串裏面的值,下標是int值,每一個int值對應字串數組裏面的一張牌,將隨機生成的下標排序,其實就是理牌,因爲下標有順序了,根據下標取的值自熱也就有了順序。),詳情如下程式碼:

//理牌
    public void liPai(String[] pai, int[] zhang, int[] zhao, int[] liu) {
        System.out.print("\n\n理牌");
        //把下標排序,根據下標取值
        Arrays.sort(zhang);
        Arrays.sort(zhao);
        Arrays.sort(liu);

        System.out.print("\n張飛的牌爲:");
        for (int i = 0; i < 17; i++) {
            System.out.print(pai[zhang[i]] + "  ");
        }
        System.out.print("\n趙雲的牌爲:");
        for (int i = 0; i < 17; i++) {

            System.out.print(pai[zhao[i]] + "  ");
        }
        System.out.print("\n劉備的牌爲:");
        for (int i = 0; i < 17; i++) {

            System.out.print(pai[liu[i]] + "  ");
        }
    }

全部程式碼如下:

/*4.在鬥地主當中,將54張牌隨機發給3位玩家,並且保留3張牌做爲底牌,分別展示三位玩家手中的牌和底牌。


    例如: 張飛手中隨機握有17張牌 ,趙雲手中隨機握有17張牌 ,劉備手中隨機握有17張牌 底牌還剩3張

    提示:撲克牌不只一張,很多張肯定要用陣列,因爲陣列的定義就是一羣元素

        那麼一副撲克牌54張肯定是陣列。17張撲克牌也是陣列。3張撲克牌也是陣列。*/


import java.util.Arrays;

public class DouDiZhu {

    public static void main(String[] args) {
        String[] pai = {
                "3♠", "3♥", "3♦", "3♣",
                "4♠", "4♥", "4♦", "4♣",
                "5♠", "5♥", "5♦", "5♣",
                "6♠", "6♥", "6♦", "6♣",
                "7♠", "7♥", "7♦", "7♣",
                "8♠", "8♥", "8♦", "8♣",
                "9♠", "9♥", "9♦", "9♣",
                "10♠", "10♥", "10♦", "10♣",
                "J♠", "J♥", "J♦", "J♣",
                "Q♠", "Q♥", "Q♦", "Q♣",
                "K♠", "K♥", "K♦", "K♣",
                "A♠", "A♥", "A♦", "A♣",
                "2♠", "2♥", "2♦", "2♣",
                "大♚", "小♔"
        };
        boolean[] isTrue = new boolean[54];//設定一個boolean陣列,來對應下標,
        int[] xiaBiao = new int[54];
        int[] zhao = new int[17];
        int[] liu = new int[17];
        int[] zhang = new int[17];
        int[] diZhuPai = new int[3];
        DouDiZhu d = new DouDiZhu();
        d.chushipai(pai);
        d.xiPai(pai, isTrue, xiaBiao);
        d.faPai(pai, xiaBiao, zhang, liu, zhao, diZhuPai);
        d.liPai(pai, zhang, zhao, liu);
    }

    //初始化牌,其實就是給輸出一下pai[]陣列
    public void chushipai(String[] p) {
        System.out.print("初始化新牌:");
        for (int i = 0; i < p.length; i++) {
            //每27張牌換行
            if (i % 27 == 0) {
                System.out.println();
            }
            System.out.print(p[i] + "\t");
        }
        System.out.println();
    }

    //洗牌
    public void xiPai(String[] pai, boolean[] isTrue, int[] xiaBiao) {
        System.out.println("\n洗牌");
        int temp = 0;//用來計數,看是否夠54張牌,
        while (temp < 54) {
            ////隨機產生一個數(0,53]之間的數,賦值給p,這樣保證一次回圈只隨機產生一個
            int p = (int) (Math.random() * (53 - 0 + 1));
            //isTrue是一個boolean陣列,來對應下標,目的是檢查隨機生成的個下標是否已經出現過
            if (!isTrue[p]) {//執行的話證明還沒有這個牌(下標)
                xiaBiao[temp] = p;
                temp++;
                System.out.print(pai[p] + "  ");
                if (temp % 27 == 0)
                    System.out.println();
                isTrue[p] = true;
            }
        }
    }

    //發牌
    public void faPai(String[] pai, int[] xiaBiao, int[] zhang, int[] liu, int[] zhao, int[] dizhupai) {
        System.out.print("\n開始發牌:");
        int k = 0;
        int j = 0;
        while (j < 17) {
            zhao[j] = xiaBiao[k++];
            liu[j] = xiaBiao[k++];
            zhang[j] = xiaBiao[k++];
            j++;
        }
        System.out.print("\n張飛的牌爲:");
        for (int i =0; i<17 ; i++) {
            System.out.print(pai[zhang[i]] + "  ");
        }
        System.out.print("\n趙雲的牌爲:");
        for (int i =0; i<17 ; i++) {
            System.out.print(pai[zhao[i]] + "  ");
        }
        System.out.print("\n劉備的牌爲:");
        for (int i =0; i<17 ; i++) {
            System.out.print(pai[liu[i]] + "  ");
        }
        int q=0;
        System.out.print("\n底牌:");
        for (int i = 51; i < 54; i++) {
            dizhupai[q] = xiaBiao[i];
            System.out.print(pai[dizhupai[q]] + "  ");
            q++;
        }

    }

    //理牌
    public void liPai(String[] pai, int[] zhang, int[] zhao, int[] liu) {
        System.out.print("\n\n理牌");
        //把下標排序,根據下標取值
        Arrays.sort(zhang);
        Arrays.sort(zhao);
        Arrays.sort(liu);

        System.out.print("\n張飛的牌爲:");
        for (int i = 0; i < 17; i++) {
            System.out.print(pai[zhang[i]] + "  ");
        }
        System.out.print("\n趙雲的牌爲:");
        for (int i = 0; i < 17; i++) {

            System.out.print(pai[zhao[i]] + "  ");
        }
        System.out.print("\n劉備的牌爲:");
        for (int i = 0; i < 17; i++) {

            System.out.print(pai[liu[i]] + "  ");
        }
    }
}

執行結果一
在这里插入图片描述
執行結果二
在这里插入图片描述
執行結果三
在这里插入图片描述

可以看出,每次玩家收到的牌都不一樣(亂數產生的效果),理牌最關鍵的是理下標,根據下標去字串數組裏面取值。下標有了順序,自然牌也就有了順序,這纔是爲什麼強調字串陣列的裏面字串位置很重要的原因。