【JavaDemo】③.控制台跑得快

要求

  • 实现跑得快的所有规则(已实现部分)
  • 完成一局游戏后,能够回放整局过程(下次一定,其实就差一个入口了)
  • 实现记牌器功能(下次一定)
  • 写好文档注释,并生成API文档(下次一定)
  • 人机模式(下次一定)

效果图

更新记录

2020-04-22:最初版本(洗牌发牌√,看牌出牌√,判断牌组的类型√,判断要不要得起√,自动结束游戏√)

总结

对于洗牌发牌出牌最开始的思路设计,导致最后写逻辑结构的时候出现了很多空指针异常,Debug了两天把会出现空指针异常的地方找了一遍,终于能够完整的完成一局游戏了。可能还没有完全找完,但是实在是不想自己和自己打牌了,所以就先这样吧,重构是不会重构的,永远也不会重构的,只能好好学一下Debug的方法思路提高Debug的效率这样子。其次就是对于引用变量的处理上面思路还需要更加的严谨,Java虽然是值传递模式,但是在引用变量的传递上如果不注意细节的处理,还是很容易破坏封装性,积累经验慢慢来。最后就是注释,说到底还是懒,最好还是能够养成写完类和方法的声明之后,马上写上注释,同时写注释时候也可以好好反省一下接下来要写的类/方法的框架,这次注释写的有点随意,下次更新把注释补上。

代码

文件结构

  • RunFast
    • game
      • CardType.java
      • Game.java
      • Poker.java
    • player
      • Player.java
    • RunFast.java

RunFast.java

import java.io.IOException;

import game.*;

public class RunFast {
    public static void main(String[] args) throws IOException {
        Game game = Game.getGame();
        game.startGame();

    }
}

Game.java

package game;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;

import player.*;

public class Game {
    private Player[] players = new Player[3];
    Poker[] poker = Poker.values();
    private static Game game = new Game();
    private ArrayList<Poker[]> playedCardsList = new ArrayList<>();
    private ArrayList playedRoundList = new ArrayList<>();
    private int roundTag = 0;
    private int roundCount = 1;
    // private int playerFisrtTag = 1;

    private Game() {
        players[0] = new Player();
        players[1] = new Player();
        players[2] = new Player();
    }

    public static Game getGame() {
        return game;
    }

    public void startGame() throws IOException {
        roundTag = 1;

        System.out.println("\n\n------------\n*游戏开始!*\n------------");
        this.deal();
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String inputStr = null;

        Round: do {
            System.out.println("\n\n------------------玩家" + roundTag + "的牌为-------------------");
            players[roundTag - 1].readCard();
            switch (roundCount) {
                case 1: {
                    System.out.print("请玩家" + roundTag + "输入指令执行操作(1.看牌 2.出牌):");
                    break;
                }
                case 2: {
                    if (CardType.canCardPlay(playedCardsList.get(0), players[roundTag - 1].getHandCards())) {
                        System.out.print("请玩家" + roundTag + "输入指令执行操作(1.看牌 2.出牌):");
                    } else {
                        System.out.print("请玩家" + roundTag + "输入指令执行操作(1.看牌 3.要不起):");
                    }
                    break;
                }
                case 3: {
                    int i = 1;
                    if (playedCardsList.get(i) == null) {
                        i = 0;
                    }
                    if (CardType.canCardPlay(playedCardsList.get(i), players[roundTag - 1].getHandCards())) {
                        System.out.print("请玩家" + roundTag + "输入指令执行操作(1.看牌 2.出牌):");
                    } else {
                        System.out.print("请玩家" + roundTag + "输入指令执行操作(1.看牌 3.要不起):");
                    }
                    break;

                }
                default: {
                    int i = playedCardsList.size() - 1;
                    do {
                        if (playedCardsList.get(i) == null) {
                            i--;
                        } else {
                            break;
                        }
                    } while (i > playedCardsList.size() - 3);

                    if (i == (playedCardsList.size() - 3)
                            || CardType.canCardPlay(playedCardsList.get(i), players[roundTag - 1].getHandCards())) {
                        System.out.print("请玩家" + roundTag + "输入指令执行操作(1.看牌 2.出牌):");
                    } else {
                        System.out.print("请玩家" + roundTag + "输入指令执行操作(1.看牌 3.要不起):");
                    }
                    break;
                }
            }

            while ((inputStr = br.readLine()) != null) {
                if (inputStr.matches("[1-3]")) {
                    if (inputStr.equals("1")) {
                        continue Round;
                    } else if (inputStr.equals("2")) {
                        System.out.print("请输入需要出的牌,以“,”分隔:");
                        PlayCards: while ((inputStr = br.readLine()) != null) {
                            inputStr = inputStr.replaceAll(" ", "");// 删除字符串中多余的空格
                            if (inputStr.matches("(([0-9]{1,2}|(A|J|K|Q)),)*([0-9]{1,2}|(A|J|K|Q))")) {
                                String[] playCardsStr = inputStr.split(",");
                                Poker[] playedCards = new Poker[playCardsStr.length];
                                String playInfo = new String();
                                if (players[roundTag - 1].haveCards(playCardsStr, playedCards)) {
                                    if (playedCardsSuccess(playedCards.clone(), playInfo)) {
                                        players[roundTag - 1].playCards(playedCards);
                                        System.out
                                                .println("-----------------玩家" + roundTag + "所出的牌为-----------------\n");
                                                System.out.print(CardType.judgeCardType(playedCards) + ":");
                                                for (Poker poker : playedCards) {
                                            System.out.print(poker.getCardName() + " ");
                                        }
                                        System.out.println("\n\n-------------------------------------------------");
                                        
                                        //System.out.print(playInfo);
                                        if (this.isGameEnd(players[roundTag - 1])) {
                                            this.endGame();
                                        }
                                    } else {
                                        System.out.println(
                                                "------------------------------------\n*出牌失败,您所选择的牌不符合规则!*\n------------------------------------");
                                        continue Round;
                                    }

                                } else {
                                    System.out.print("*出牌失败,您的手牌没有完整包含这些牌* 请重新输入您需要出的牌:");
                                    continue PlayCards;
                                }
                                break PlayCards;
                            } else {
                                System.out.print("*牌组输入不合法*,请重新输入您需要出的牌:");
                                continue PlayCards;
                            }
                        }
                        if (roundTag == 3) {
                            roundTag = 1;
                        } else {
                            roundTag++;
                        }
                        continue Round;
                    } else {
                        playedCardsSuccess(null, null);
                        if (roundTag == 3) {
                            roundTag = 1;
                        } else {
                            roundTag++;
                        }
                        continue Round;
                    }
                } else {
                    System.out.print("*指令输入无效* 请重新输入:");
                }
            }
        } while (roundTag != 0);
    }

    private void endGame() {
        System.out.println("*游戏结束,玩家" + roundTag + "获得胜利!*");
        System.exit(0);
    }

    private boolean isGameEnd(Player player) {
        Poker[] playerCards = player.getHandCards();
        for (Poker poker : playerCards) {
            if (poker != null) {
                return false;
            }
        }
        return true;
    }

    /** 此方法用于遍历一个玩家的手牌是否有炸弹 */
    private void goThroughPlayerCards(Player player) {
        double fourTag = 0.0;
        double dealCount = 0.0;
        int fourCount = 0;
        do {
            this.deal();
            int poker = (player.getHandCards())[0].getCardSize();
            for (int i = 1; i < (player.getHandCards()).length; i++) {
                if ((player.getHandCards())[i].getCardSize() == poker) {
                    fourCount++;
                } else {
                    fourCount = 1;
                    poker = (player.getHandCards())[i].getCardSize();
                }
                if (fourCount == 4) {
                    fourTag++;
                }
            }
            System.out.println("这是第" + ((int) (++dealCount)) + "次洗牌,现在出现过" + (int) fourTag + "次炸弹,概率为"
                    + (fourTag / dealCount * 100) + "%");
        } while (fourTag != 10000.0);
    }
    private void deal() {
        Poker[][] playerCards = { new Poker[16], new Poker[16], new Poker[16] };
        Poker.shuffleCards(poker);
        for (int i = 0, j = 0; i < poker.length; i = i + 3, j++) {
            playerCards[0][j] = poker[i];
            playerCards[1][j] = poker[i + 1];
            playerCards[2][j] = poker[i + 2];
        }
        players[0].takeHandCards(playerCards[0]);
        players[1].takeHandCards(playerCards[1]);
        players[2].takeHandCards(playerCards[2]);
    }

    private boolean playedCardsSuccess(Poker[] playedCards, String playInfo) {

        if (playedCards == null) {// 不要
            this.playedCardsList.add(playedCards);
            this.playedRoundList.add(roundTag);
            roundCount++;
            return true;
        } else {
            if (playCardsRule(playedCards, playInfo)) {
                this.playedCardsList.add(playedCards);
                this.playedRoundList.add(roundTag);
                roundCount++;
                return true;
            } else {
                return false;
            }
        }

    }

    private boolean playCardsRule(Poker[] playedCards, String playInfo) {
        boolean result = false;
        CardType cardType;
        int cardTypSize, cardCompNum;

        switch (playedCards.length) {
            case 3: {
                // 三张且手牌只剩三张牌时
                if ((cardType = CardType.judgeCardType(playedCards)) != null) {
                    // System.out.println(cardType);
                    if (players[roundTag - 1].getHandCardsNum() == 3) {
                        result = true;
                    }
                }
                break;
            }
            case 4: {
                if ((cardType = CardType.judgeCardType(playedCards)) != null) {
                    // System.out.println(cardType);
                    result = true;
                    // 排除掉三张且手牌不只剩四张牌的情况
                    if (cardType == CardType.三带二 && players[roundTag - 1].getHandCardsNum() != 4) {
                        result = false;
                    }
                }
                break;
            }
            default: {
                if ((cardType = CardType.judgeCardType(playedCards)) != null) {
                    // System.out.println(cardType);
                    result = true;
                }
            }
        }

        if (cardType != null) {
            cardTypSize = cardType.getTypeSize();
            cardCompNum = cardType.getCompNum();
            playInfo = cardType.toString();
        } else {
            playInfo = "不符合出牌规则";
            return result;
        }

        // 如果上游或者上上游出了牌就要进行大小判断
        switch (roundCount) {
            case 1: {// 第一轮出牌不要比较大小
                return result;
            }
            case 2: {// 第二轮直接比较大小
                // 首先判断牌的种类是否相等
                if (CardType.judgeCardType(playedCardsList.get(roundCount - 2)) != cardType) {
                    result = false;
                } else {
                    // 种类相等的情况下,判断牌的只数是否相等
                    if (CardType.judgeCardType(playedCardsList.get(roundCount - 2)).getCompNum() != cardCompNum) {
                        result = false;
                    } else {
                        // 接下来,判断牌的大小
                        if (CardType.judgeCardType(playedCardsList.get(roundCount - 2)).getTypeSize() >= cardTypSize) {
                            result = false;
                        }
                    }
                }
                break;
            }
            default: {// 第三轮以及之后则要看上游或上上游有没有出牌
                if (playedCardsList.get(roundCount - 2) != null) {
                    // 首先判断牌的种类是否相等
                    if (CardType.judgeCardType(playedCardsList.get(roundCount - 2)) != cardType) {
                        result = false;
                    } else {
                        // 种类相等的情况下,判断牌的只数是否相等
                        if (CardType.judgeCardType(playedCardsList.get(roundCount - 2)).getCompNum() != cardCompNum) {
                            result = false;
                        } else {
                            // 接下来,判断牌的大小
                            if (CardType.judgeCardType(playedCardsList.get(roundCount - 2))
                                    .getTypeSize() >= cardTypSize) {
                                result = false;
                            }
                        }
                    }
                } else if (playedCardsList.get(roundCount - 3) != null && playedCardsList.get(roundCount - 2) == null) {
                    // 首先判断牌的种类是否相等
                    if (CardType.judgeCardType(playedCardsList.get(roundCount - 3)) != cardType) {
                        result = false;
                    } else {
                        // 种类相等的情况下,判断牌的只数是否相等
                        if (CardType.judgeCardType(playedCardsList.get(roundCount - 3)).getCompNum() != cardCompNum) {
                            result = false;
                        } else {
                            // 接下来,判断牌的大小
                            if (CardType.judgeCardType(playedCardsList.get(roundCount - 3))
                                    .getTypeSize() >= cardTypSize) {
                                result = false;
                            }
                        }
                    }
                } else if (playedCardsList.get(roundCount - 3) == null && playedCardsList.get(roundCount - 2) == null) {
                    // 上游和上上游都不要的情况下,则不用判断,直接出牌
                }
            }
        }
        return result;
    }
}

Poker.java

package game;

public enum Poker {
    黑桃A("黑桃A", "Spade", 14), 红心A("红心A", "Heart", 14), 梅花A("梅花A", "Club", 14), 红心2("红心2", "Heart", 15),
    黑桃3("黑桃3", "Spade", 3), 红心3("红心3", "Heart", 3), 梅花3("梅花3", "Club", 3), 方块3("方块3", "Diamond", 3),
    黑桃4("黑桃4", "Spade", 4), 红心4("红心4", "Heart", 4), 梅花4("梅花4", "Club", 4), 方块4("方块4", "Diamond", 4),
    黑桃5("黑桃5", "Spade", 5), 红心5("红心5", "Heart", 5), 梅花5("梅花5", "Club", 5), 方块5("方块5", "Diamond", 5),
    黑桃6("黑桃6", "Spade", 6), 红心6("红心6", "Heart", 6), 梅花6("梅花6", "Club", 6), 方块6("方块6", "Diamond", 6),
    黑桃7("黑桃7", "Spade", 7), 红心7("红心7", "Heart", 7), 梅花7("梅花7", "Club", 7), 方块7("方块7", "Diamond", 7),
    黑桃8("黑桃8", "Spade", 8), 红心8("红心8", "Heart", 8), 梅花8("梅花8", "Club", 8), 方块8("方块8", "Diamond", 8),
    黑桃9("黑桃9", "Spade", 9), 红心9("红心9", "Heart", 9), 梅花9("梅花9", "Club", 9), 方块9("方块9", "Diamond", 9),
    黑桃10("黑桃10", "Spade", 10), 红心10("红心10", "Heart", 10), 梅花10("梅花10", "Club", 10), 方块10("方块10", "Diamond", 10),
    黑桃J("黑桃J", "Spade", 11), 红心J("红心J", "Heart", 11), 梅花J("梅花J", "Club", 11), 方块J("方块J", "Diamond", 11),
    黑桃Q("黑桃Q", "Spade", 12), 红心Q("红心Q", "Heart", 12), 梅花Q("梅花Q", "Club", 12), 方块Q("方块Q", "Diamond", 12),
    黑桃K("黑桃K", "Spade", 13), 红心K("红心K", "Heart", 13), 梅花K("梅花K", "Club", 13), 方块K("方块K", "Diamond", 13);

    private final String cardName;
    private final String cardSuit;
    private final int cardSize;

    private Poker(String name, String suit, int size) {
        this.cardName = name;
        this.cardSuit = suit;
        this.cardSize = size;
    }

    public String getCardName() {
        return cardName;
    }

    public String getCardSuit() {
        return cardSuit;
    }

    public int getCardSize() {
        return cardSize;
    }

    public static void shuffleCards(Poker[] poker) {
        Poker canum = null;// 交换数值时的缓存变量
        // 乱序排序
        
        for (int i = 0; i < poker.length - 1; i++) {
            double rand = Math.random() * (poker.length - 1);
            int j = (int) rand;
            canum = poker[j];
            poker[j] = poker[j + 1];
            poker[j + 1] = canum;
        }

        for (int i = 0; i < poker.length - 1; i=i+3) { double rand = Math.random() * (poker.length - 1); int j = (int) rand; canum = poker[j]; poker[j] = poker[j + 1]; poker[j + 1] = canum; } for (int i = poker.length - 1; i >= 0; i--) {
            double rand = Math.random() * (poker.length - 1);
            int j = (int) rand;
            canum = poker[j];
            poker[j] = poker[j + 1];
            poker[j + 1] = canum;
        }

        for (int i = poker.length - 1; i >= 0; i=i-3) {
            double rand = Math.random() * (poker.length - 1);
            int j = (int) rand;
            canum = poker[j];
            poker[j] = poker[j + 1];
            poker[j + 1] = canum;
        }
    }

}

CardType.java

package game;

import java.util.ArrayList;

public enum CardType {

    单张(1, 1), 对子(1, 1), 顺子(1, 1), 连对(1, 1), 飞机(1, 1), 三带二(1, 1), 四带三(1, 1), 炸弹(1, 1);

    private int typeSize, compNum;

    private CardType(int typeSize, int compNum) {
        this.typeSize = typeSize;
        this.compNum = compNum;

    }

    public int getTypeSize() {
        return typeSize;
    }

    private void setTypeSize(int typeSize) {
        this.typeSize = typeSize;
    }

    public int getCompNum() {
        return compNum;
    }

    private void setCompNum(int compNum) {
        this.compNum = compNum;
    }

    public static boolean canCardPlay(Poker[] playedCards, Poker[] handCards) {
        CardType cardType = judgeCardType(playedCards);
        int cardTypeSize = cardType.getTypeSize(), cardCompNum = cardType.getCompNum();
        switch (cardType) {
            case 单张: {
                int i = handCards.length - 1;
                do {
                    if (handCards[i] == null) {
                        i--;
                        continue;
                    }
                    if (handCards[i].getCardSize() > cardTypeSize) {
                        return true;
                    } else {
                        break;
                    }
                } while (true);
                break;
            }
            case 对子: {
                if (CardType.findDiepai(handCards, new ArrayList<>(), 2) > cardTypeSize) {
                    return true;
                }
                break;
            }
            case 顺子: {
                if (CardType.findShunzi(handCards, new ArrayList<>(), cardCompNum) > cardTypeSize) {
                    return true;
                }
                break;
            }
            case 连对: {
                if (CardType.findLiandui(handCards, new ArrayList<>(), cardCompNum) > cardTypeSize) {
                    return true;
                }
                break;
            }
            case 飞机: {
                if (CardType.findFeiji(handCards, new ArrayList<>(), cardCompNum) > cardTypeSize) {
                    return true;
                }

                break;
            }
            case 三带二: {
                if (CardType.findDiepai(handCards, new ArrayList<>(), 3) > cardTypeSize) {
                    return true;
                }

                break;
            }
            case 四带三: {
                if (CardType.findDiepai(handCards, new ArrayList<>(), 4) > cardTypeSize) {
                    return true;
                }

                break;
            }
            case 炸弹: {
                if (CardType.findDiepai(handCards, new ArrayList<>(), 4) > cardTypeSize) {
                    return true;
                }
                break;
            }
        }
        return false;

    }

    /**
     * 寻找玩家手牌中的数量为指定值的飞机
     * 
     * @param cards   玩家的手牌
     * @param list    存放遍历到的飞机列表
     * @param compNum 每一个飞机的数量
     * @return 返回遍历到最大的飞机的最小牌的值
     */
    public static int findFeiji(Poker[] cards, ArrayList<Poker[]> list, int compNum) {
        ArrayList<Poker[]> sanzhangList = new ArrayList<>();
        if (CardType.findDiepai(cards, sanzhangList, 3) == 0 | sanzhangList.size() < compNum) {
            return 0;
        }

        int count = 1, sanzhangTag = 3, startTag = 1;
        Poker poker = (sanzhangList.get(0))[0];
        Poker[] sanzhang = new Poker[compNum * 3];
        sanzhang[0] = sanzhangList.get(0)[0];
        sanzhang[1] = sanzhangList.get(0)[1];
        sanzhang[2] = sanzhangList.get(0)[2];
        do {
            for (int i = startTag; i < sanzhangList.size(); i++) {
                if ((sanzhangList.get(i))[0].getCardSize() == poker.getCardSize() + 1) {
                    count++;
                    sanzhang[sanzhangTag++] = sanzhangList.get(i)[0];
                    sanzhang[sanzhangTag++] = sanzhangList.get(i)[1];
                    sanzhang[sanzhangTag++] = sanzhangList.get(i)[2];
                    poker = sanzhangList.get(i)[0];
                    if (count == compNum) {
                        startTag = i - compNum + 3;
                        list.add(sanzhang.clone());
                        poker = sanzhangList.get(startTag - 1)[0];
                        sanzhang[0] = sanzhangList.get(startTag - 1)[0];
                        sanzhang[1] = sanzhangList.get(startTag - 1)[1];
                        sanzhang[2] = sanzhangList.get(startTag - 1)[2];
                        sanzhangTag = 3;
                        count = 1;
                        break;
                    }
                } else {
                    poker = sanzhangList.get(i)[0];
                    if (i == sanzhangList.size() - 1) {
                        startTag = sanzhangList.size();
                    } else {
                        startTag = i + 1;
                    }
                    sanzhang[0] = sanzhangList.get(i)[0];
                    sanzhang[1] = sanzhangList.get(i)[1];
                    sanzhang[2] = sanzhangList.get(i)[2];
                    sanzhangTag = 3;
                    count = 1;
                }
            }
        } while (startTag != sanzhangList.size());

        if (list.isEmpty()) {
            return 0;
        } else {
            return list.get(list.size() - 1)[0].getCardSize();// 返回最大的飞机的最小的三张的值
        }

    }

    /**
     * 寻找玩家手牌中的数量为指定值的连对
     * 
     * @param cards   玩家的手牌
     * @param list    存放遍历到的连对列表
     * @param compNum 每一个连对的数量
     * @return 返回遍历到最大的连对的最小牌的值
     */
    public static int findLiandui(Poker[] cards, ArrayList<Poker[]> list, int compNum) {
        ArrayList<Poker[]> duiziList = new ArrayList<>();
        if (CardType.findDiepai(cards, duiziList, 2) == 0 | duiziList.size() < compNum) {
            return 0;
        }

        int count = 1, lianduiTag = 2, startTag = 1;
        Poker poker = (duiziList.get(0))[0];
        Poker[] liandui = new Poker[compNum * 2];
        liandui[0] = duiziList.get(0)[0];
        liandui[1] = duiziList.get(0)[1];
        do {
            for (int i = startTag; i < duiziList.size(); i++) {
                if ((duiziList.get(i))[0].getCardSize() == poker.getCardSize() + 1) {
                    count++;
                    liandui[lianduiTag++] = duiziList.get(i)[0];
                    liandui[lianduiTag++] = duiziList.get(i)[1];
                    poker = duiziList.get(i)[0];
                    if (count == compNum) {
                        startTag = i - compNum + 3;
                        list.add(liandui.clone());
                        poker = duiziList.get(startTag - 1)[0];
                        liandui[0] = duiziList.get(startTag - 1)[0];
                        liandui[1] = duiziList.get(startTag - 1)[1];
                        lianduiTag = 2;
                        count = 1;
                        break;
                    }
                } else {
                    poker = duiziList.get(i)[0];
                    if (i == duiziList.size() - 1) {
                        startTag = duiziList.size();
                    } else {
                        startTag = i + 1;
                    }
                    liandui[0] = duiziList.get(i)[0];
                    liandui[1] = duiziList.get(i)[1];
                    lianduiTag = 2;
                    count = 1;
                }
            }
        } while (startTag != duiziList.size());

        if (list.isEmpty()) {
            return 0;
        } else {
            return list.get(list.size() - 1)[0].getCardSize();// 返回最大的连对的最小的对子的值
        }

    }

    /**
     * 寻找玩家手牌中数量为指定值的顺子
     * 
     * @param cards   玩家的手牌
     * @param list    存放遍历到的顺子列表
     * @param compNum 每一个顺子的数量
     * @return 返回遍历到最大的顺子的最小牌的值
     */
    public static int findShunzi(Poker[] cards, ArrayList<Poker[]> list, int compNum) {
        if (cards.length < 5 | compNum < 5) {
            return 0;
        }
        int count = 1, cardCompTag = 0, startTag = 1;
        Poker[] shunziComp = new Poker[compNum];
        Poker poker = null;
        for (int i = 0; i < cards.length; i++) {
            if (cards[i] != null) {
                poker = shunziComp[cardCompTag++] = cards[i];
                startTag = i + 1;
                break;
            }
        }

        while (startTag != cards.length - 1) {
            for (int i = startTag; i < cards.length; i++) { if (cards[i] == null) { continue; } // 牌的大小重复则跳过 if (cards[i].getCardSize() == poker.getCardSize()) { if (i == cards.length - 1) { startTag = cards.length - 1; } else { startTag = i + 1; } continue; } if (cards[i] != Poker.红心2 && cards[i].getCardSize() == poker.getCardSize() + 1) { count++; poker = cards[i]; shunziComp[cardCompTag++] = poker; if (count == compNum) { list.add(shunziComp.clone()); for (int j = cards.length - 1; j >= 0; j--) {
                            if (cards[j] == null) {
                                continue;
                            }
                            if (cards[j].getCardSize() == shunziComp[0].getCardSize()) {
                                startTag = j + 2;
                                break;
                            }
                        }
                        poker = cards[startTag - 1];
                        shunziComp[0] = poker;
                        cardCompTag = 1;
                        count = 1;
                        break;
                    }
                } else {
                    poker = cards[i];
                    if (i == cards.length - 1) {
                        startTag = cards.length - 1;
                    } else {
                        startTag = i + 1;
                    }
                    shunziComp[0] = cards[i];
                    cardCompTag = 1;
                    count = 1;
                }
            }

        }
        if (list.isEmpty()) {
            return 0;
        } else {
            return list.get(list.size() - 1)[0].getCardSize();
        }

    }

    /**
     * 此方法用于遍历玩家手牌寻找对应数量的叠牌
     * 
     * @param cards    玩家的手牌
     * @param list     存放遍历到的叠牌
     * @param aimCount 叠牌的数量
     * @return 返回遍历到组合的最大值
     */
    public static int findDiepai(Poker[] cards, ArrayList<Poker[]> list, int aimCount) {
        int maxSize = 0, count = 1, cardCompTag = 0;
        Poker[] cardComp = new Poker[aimCount];
        Poker poker = null;
        for (int i = 0; i < cards.length; i++) {
            if (cards[i] != null) {
                poker = cardComp[cardCompTag++] = cards[i];
                break;
            }
        }
        for (int i = 1; i < cards.length; i++) {
            if (cards[i] == null) {
                continue;
            }
            if (poker.getCardSize() == cards[i].getCardSize() && poker != cards[i]) {
                count++;
                cardComp[cardCompTag++] = poker = cards[i];
                if (count == aimCount) {
                    cardCompTag = 0;
                    maxSize = poker.getCardSize();
                    list.add(cardComp.clone());
                }
            } else {
                poker = cards[i];
                count = 1;
                cardCompTag = 0;
                poker = cardComp[cardCompTag++] = cards[i];
            }
        }
        return maxSize;
    }

    public static CardType judgeCardType(Poker[] cards) {
        switch (cards.length) {
            case 1: {
                单张.setTypeSize(cards[0].getCardSize());
                return 单张;
            }
            case 2: {
                if (CardType.goThroughCards(cards) == 2 && cards[0].getCardSize() == cards[1].getCardSize()) {
                    对子.setTypeSize(cards[0].getCardSize());
                    return 对子;
                }
                break;
            }
            case 3: {
                // 三张且手牌只剩三张牌时
                if (CardType.goThroughCards(cards) == 3) {
                    三带二.setTypeSize(cards[0].getCardSize());
                    return 三带二;
                }
                break;
            }
            case 4: {
                if (CardType.isLiandui(cards)) {
                    连对.setTypeSize(cards[0].getCardSize());
                    连对.setCompNum(2);// 返回有几个对子
                    return 连对;
                }
                // 三张且手牌只剩四张牌时
                if (CardType.goThroughCards(cards) == 3) {
                    Poker card = cards[0];
                    for (int i = 1; i < cards.length; i++) {
                        if (card.getCardSize() == cards[i].getCardSize()) {
                            三带二.setTypeSize(card.getCardSize());
                            break;
                        } else {
                            card = cards[i];
                        }
                    }
                    return 三带二;
                }
                if (CardType.goThroughCards(cards) == 4) {
                    炸弹.setTypeSize(cards[0].getCardSize());
                    return 炸弹;
                }
                break;
            }
            case 5: {
                if (CardType.goThroughCards(cards) == 3) {
                    Poker card = cards[0];
                    for (int i = 1; i < cards.length; i++) {
                        if (card.getCardSize() == cards[i].getCardSize()) {
                            三带二.setTypeSize(card.getCardSize());
                            break;
                        } else {
                            card = cards[i];
                        }
                    }
                    return 三带二;
                }
                if (CardType.isShunzi(cards)) {
                    顺子.setTypeSize(cards[0].getCardSize());
                    顺子.setCompNum(cards.length);// 返回有几个顺子
                    return 顺子;
                }
                break;
            }
            default: {
                if (CardType.isLiandui(cards)) {
                    连对.setTypeSize(cards[0].getCardSize());
                    连对.setCompNum(cards.length / 2);// 返回有几个对子
                    return 连对;
                }
                if (CardType.isShunzi(cards)) {
                    顺子.setTypeSize(cards[0].getCardSize());
                    return 顺子;
                }

                Integer minThree = 0, threeCount = 0;
                if (CardType.isFeiji(cards, minThree, threeCount)) {
                    飞机.setTypeSize(minThree);
                    飞机.setCompNum(threeCount);
                    return 飞机;
                }

                Integer fourSize = 0;
                if (CardType.isSidaisan(cards, fourSize)) {
                    四带三.setTypeSize(fourSize);
                    return 四带三;
                }

            }
        }

        return null;

    }

    public static int goThroughCards(Poker[] cards) {
        int result = 1, count = 1;
        Poker poker = cards[0];
        for (int i = 1; i < cards.length; i++) { if (poker.getCardSize() == cards[i].getCardSize()) { count++; if (count > result) {
                    result = count;
                }
            } else {
                count = 1;
                poker = cards[i];
            }
        }
        return result;
    }

    public static boolean isShunzi(Poker[] cards) {
        if (cards.length < 5 | cards[cards.length - 1] == Poker.红心2) {
            return false;
        }
        if (CardType.goThroughCards(cards) == 1) {
            for (int i = 0; i < cards.length - 1; i++) {
                // 只要一个不连续,则说明不包含顺子
                if (cards[i].getCardSize() != cards[i + 1].getCardSize() - 1) {
                    return false;
                }
            }
            return true;
        } else {
            return false;
        }
    }

    public static boolean isLiandui(Poker[] cards) {
        if (cards.length % 2 != 0) {
            return false;
        } else {
            for (int i = 0; i < cards.length - 2; i = i + 2) {
                // 只要一个不连续,则说明不包含顺子
                if (cards[i].getCardSize() != cards[i + 1].getCardSize()) {
                    return false;
                }
                if (cards[i + 1].getCardSize() != cards[i + 2].getCardSize() - 1) {
                    return false;
                }
            }
            return true;
        }
    }

    /**
     * 判断牌是不是飞机
     * 
     * @param cards      要判断的牌组
     * @param minThree   记录飞机中最小三张的值
     * @param threeCount 记录飞机中有多少个三张
     */
    public static boolean isFeiji(Poker[] cards, Integer minThree, Integer threeCount) {
        int count = 1;
        Poker poker = cards[0];
        minThree = 0;
        threeCount = 0;
        for (int i = 1; i < cards.length; i++) {
            if (poker.getCardSize() == cards[i].getCardSize()) {
                count++;
                if (count == 3) {
                    threeCount++;
                    // 记录飞机中最小的三张的值
                    if (threeCount == 1) {
                        minThree = poker.getCardSize();
                    }
                    // 如果一个三张的下面三张牌不是三张,说明飞机结束,直接退出此循环
                    if (i < cards.length - 4 && cards[i].getCardSize() != cards[i + 3].getCardSize() - 1) { break; } count = 1; } } else { count = 1; poker = cards[i]; } } if (threeCount >= 2) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 判断是不是四带三
     * 
     * @param cards    要判断的牌组
     * @param fourSize 炸弹的值
     */
    public static boolean isSidaisan(Poker[] cards, Integer fourSize) {
        if (CardType.goThroughCards(cards) == 4 && cards.length == 7) {
            int count = 1;
            Poker poker = cards[0];
            for (int i = 1; i < cards.length; i++) {
                if (poker.getCardSize() == cards[i].getCardSize()) {
                    count++;
                    if (count == 4) {
                        fourSize = poker.getCardSize();
                        return true;
                    }
                } else {
                    count = 1;
                    poker = cards[i];
                }
            }
        }
        return false;
    }

}

Player.java

package player;

import game.*;

public class Player {
    protected Poker[] handCards;

    public Player() {

    }

    public Player(Poker[] handCards) {
        this.handCards = handCards;
    }

    public void takeHandCards(Poker[] cards) {
        this.handCards = cards;
        this.sortCard(cards, "ASC");
    }

    public Poker[] getHandCards() {
        return handCards.clone();
    }

    public void sortCard(Poker[] cards, String sortOrder) {
        Poker canum = null;// 交换数值时的缓存变量
        // 冒泡排序
        if (sortOrder == "ASC") {
            for (int i = 0; i < cards.length - 1; i++) {
                for (int j = 0; j < cards.length - 1; j++) { if (cards[j].getCardSize() > cards[j + 1].getCardSize()) {
                        canum = cards[j];
                        cards[j] = cards[j + 1];
                        cards[j + 1] = canum;
                    }
                }
            }
        } else if (sortOrder == "DES") {
            for (int i = 0; i < cards.length - 1; i++) {
                for (int j = 0; j < cards.length - 1; j++) {
                    if (cards[j].getCardSize() < cards[j + 1].getCardSize()) {
                        canum = cards[j];
                        cards[j] = cards[j + 1];
                        cards[j + 1] = canum;
                    }
                }
            }
        }
    }

    public void readCard() {
        System.out.println("------------------------------------------------");
        for (int i = 0; i < handCards.length; i++) {
            if (handCards[i] != null) {
                switch (handCards[i].getCardSuit()) {
                    case "Spade":
                        System.out.print("黑 ");
                        break;
                    case "Heart":
                        System.out.print("红 ");
                        break;
                    case "Club":
                        System.out.print("梅 ");
                        break;
                    case "Diamond":
                        System.out.print("方 ");
                        break;
                }
            }
        }
        System.out.println();
        for (int i = 0; i < handCards.length; i++) {
            if (handCards[i] != null) {
                switch (handCards[i].getCardSuit()) {
                    case "Spade":
                        System.out.print("桃 ");
                        break;
                    case "Heart":
                        System.out.print("心 ");
                        break;
                    case "Club":
                        System.out.print("花 ");
                        break;
                    case "Diamond":
                        System.out.print("块 ");
                        break;
                }
            }
        }
        System.out.println();
        for (int i = 0; i < handCards.length; i++) {
            if (handCards[i] != null) {
                switch (handCards[i].getCardSize()) {
                    case 10:
                        System.out.print("10 ");
                        break;
                    case 11:
                        System.out.print("J  ");
                        break;
                    case 12:
                        System.out.print("Q  ");
                        break;
                    case 13:
                        System.out.print("K  ");
                        break;
                    case 14:
                        System.out.print("A  ");
                        break;
                    case 15:
                        System.out.print("2  ");
                        break;
                    default:
                        System.err.print(handCards[i].getCardSize() + "  ");
                }
            }
        }
        System.out.println();
        System.out.println("------------------------------------------------");
    }

    public boolean haveCards(String[] playCardsStr, Poker[] playedCards) {
        int[] playCardsSize = new int[playCardsStr.length];
        for (int i = 0; i < playCardsSize.length; i++) { // 如果是数字牌,但是不在2-10之间的牌则不存在 if (playCardsStr[i].matches("[0-9]{1,2}") && (Integer.parseInt(playCardsStr[i]) > 10 || Integer.parseInt(playCardsStr[i]) < 2)) {
                return false;
            }
            switch (playCardsStr[i]) {
                case "J":
                    playCardsSize[i] = 11;
                    break;
                case "Q":
                    playCardsSize[i] = 12;
                    break;
                case "K":
                    playCardsSize[i] = 13;
                    break;
                case "A":
                    playCardsSize[i] = 14;
                    break;
                case "2":
                    playCardsSize[i] = 15;
                    break;
                case "10":
                    playCardsSize[i] = 10;
                    break;
                default:
                    playCardsSize[i] = (Integer.parseInt(playCardsStr[i]));
            }
        }
        Poker[] handCardsNew=this.handCards.clone();
        PlayCardsSize: for (int i = 0; i < playCardsSize.length; i++) {
            HandCardsNew: for (int j = 0; j < handCardsNew.length; j++) {
                if (handCardsNew[j] == null) {
                    continue HandCardsNew;
                }
                if (playCardsSize[i] == handCards[j].getCardSize()) {
                    playedCards[i] = handCardsNew[j];
                    handCardsNew[j]=null;
                    continue PlayCardsSize;
                }
                if (j == handCards.length - 1) {
                    playedCards = null;
                    return false;
                }
            }
        }
        this.sortCard(playedCards, "ASC");
        return true;
    }

    public void playCards(Poker[] playCards) {
        PlayCards: for (int i = 0; i < playCards.length; i++) {
            HandCards: for (int j = 0; j < handCards.length; j++) {
                if (handCards[j] == null) {
                    continue HandCards;
                }
                if (playCards[i] == handCards[j]) {
                    handCards[j] = null;
                    continue PlayCards;
                }
            }
        }
    }

    /**
     * 拿回不符合规则的牌
     * 
     * @param playerCards 为打算出但是不符合规则的牌
     */
    public void handCardsBack(Poker[] playedCards) {
        for (int i = 0, j = -1; i < playedCards.length; i++) {

            while (true) {
                if (handCards[++j] == null) {
                    handCards[j] = playedCards[i];
                    break;
                }
            }
        }
        this.sortCard(this.handCards, "ASC");
    }

    /** 返回剩余手牌数 */
    public int getHandCardsNum() {
        int i = 0;
        for (Poker poker : handCards) {
            if (poker != null) {
                i++;
            }
        }
        return i;
    }

}

人已赞赏
Java编程语言

【Java学习笔记(五-1)】对象与垃圾回收

2020-4-15 22:33:22

数据结构编程语言

数据结构之链表

2020-5-26 12:01:35

2 条回复 A文章作者 M管理员
  1. 下次一定给你的文章点个“喜欢”

    • 哈哈哈哈,那还是这次把

个人中心
今日签到
有新私信 私信列表
搜索