亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在 Java 中對撲克手牌進行分類

在 Java 中對撲克手牌進行分類

鴻蒙傳說 2024-01-05 15:05:15
我目前正在研究一個對玩家的手進行分類的 CS 項目。我解決了項目的前半部分,打印出牌組、洗牌牌組以及玩家 1、玩家 2 和剩余牌組的手牌。當我必須評估手牌時,問題就出現了。我的代碼必須以某種方式評估手牌的分類,并打印出玩家 1 或玩家 2 是否獲勝。到目前為止我已經上了三門課:public class Card {    static String[] card_suit = {"hearts", "diamonds", "clubs", "spades"};    static int[] card_rank = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};// 11 is Jack, 12 is Queen, 13 is King and 14 is Ace     public int[] getRank() {        return card_rank;    }    public String[] getSuit() {        return card_suit;    }}public class Driver {    public static void main(String[] args) {        Card card = new Card();        Deck deck = new Deck();        deck.getDeck();        System.out.print("ORIGINAL DECK: ");        deck.printDeck();        deck.shuffleDeck();        System.out.print("SHUFFLED DECK: ");        deck.printDeck();        System.out.println();        System.out.print("PLAYER ONE: ");        System.out.println(java.util.Arrays.toString(deck.playerOneHands()));        System.out.print("PLAYER TWO: ");        System.out.println(java.util.Arrays.toString(deck.playerTwoHands()));        System.out.print("REMAINING DECK: ");        System.out.println(java.util.Arrays.toString(deck.remainingDeckCards()));                       }}我認為它會起作用是因為 Deck 類擴展自 Card 類,我可以使用 getRank 方法來比較每手牌,但我不確定如何構造條件。任何幫助是極大的贊賞。謝謝。
查看完整描述

3 回答

?
慕村225694

TA貢獻1880條經驗 獲得超4個贊

不想為你做作業...

這是個問題:

class Deck extends Card

牌組不是卡牌的子類型。一副牌牌,所以:

class Deck {
    List<Card> cards;
}

是一個更好的選擇。

另外,以下代碼對牌組沒有任何作用:

public void shuffleDeck() {
    Collections.shuffle(Arrays.asList(deck_card));
}

它會洗牌牌組的副本,使牌組保持不變。

另外,您不應該在循環中構建字符串。相反,在 Card 和 Deck 上實現(覆蓋) toString() 方法。

另外,制作西裝enum

另外,card_rank完全刪除 - 它沒有任何意義。相反,int rank;向 Card 添加一個字段,或者更好地使排名成為enum。

首先修復這些問題,然后通過編寫一個方法來重新解決問題,該方法傳遞一個具有 List 的 Hand (一個新類),以及一個通過評估該手牌是否是同花而返回 HandType (另一個枚舉)的方法,否則有四種,否則...一直到高牌 - 從最高到最低。


查看完整回答
反對 回復 2024-01-05
?
大話西游666

TA貢獻1817條經驗 獲得超14個贊

  1. 為了對游戲進行建模,首先要識別CardDeck等實體(大多數情況下您已經完成了)。我會添加更多內容,例如Player、Evaluator(如下所述)等。

  2. 排名和花色不是字符串/整數,但它們是預定義的(在游戲的生命周期中不會改變)卡牌中可能的變化。始終使用領域詞匯來獲得最佳模型。每張卡牌屬于一種花色和一種等級。(將 Rank 和 Suit 視為枚舉,這將避免未知值在運行時破壞代碼。

  3. 不給出 Card 中的套件和等級的設置方法是必要的(它們組合形成 Card 的標識)

  4. 全牌組(初始化時)由花色和等級的叉積形成。意思是牌組有(包含)多張牌。請記住,卡牌在牌組之外(在玩家手中時)也可以是活的,因此它不是組合。從 Card 繼承 Deck 是絕對錯誤的。它翻譯為陳述Deck 是一種 Card,這是不正確的。牌組將收集卡片。使用繼承,會導致違反里氏替換原則(SOLID之一)。

  5. 為了對 Deck 進行建模,請考慮以下事實:Deck 不包含重復的牌,Deck 一旦形成就不會改變其順序(除非洗牌)。這是 Set 和 List 之間的棘手選擇,我會選擇帶有添加編程約束的 List 以避免重復(僅在初始化時才需要完成)。

  6. 但是,最好不要將 Modeling Deck 作為 java 集合,而是讓類 Deck 包含合適選擇的 java 集合,并且通過定義所需的 API(從領域角度來看)如 shuffle、getTopCard() 等,Deck 類作為包裝器工作。這稱為對象適配器設計模式。這使得我們的設計平臺(實現)獨立。

  7. 您需要對更多的類進行建模,例如Player持有CardInHand等。

  8. 關于評估手中的卡片,最好將其建模為單獨的類,因為其不同的關注點和規則可以獨立于其他類而改變。

  9. 撲克游戲是學習面向對象編程的最佳作業。


查看完整回答
反對 回復 2024-01-05
?
holdtom

TA貢獻1805條經驗 獲得超10個贊

看來你的類Card只有靜態字段;我會更改它,以便 的實例Card代表 中的一張卡Deck。我也會把套房做成一種enum類型。您還可以為數字和 A 添加整數常量。該類可以實現Comparable<Card>:


public class Card implements Comparable<Card> {

    public enum Suite {CLUBS, DIAMONDS, HEARTS, SPADES};


    public static final int JACK = 11;

    public static final int QUEEN = 12;

    public static final int KING = 13;

    public static final int ACE = 14;


    public final Suite suite;

    public final int rank;


    public Card(Suite suite, int rank) {

        if (suite == null) {

            throw new IllegalArgumentException("Suite cannot be null");

        }

        if (rank < 2 || rank > 14) {

            throw new IllegalArgumentException(

                    "Value must be between 2 and 14");

        }

        this.suite = suite;

        this.rank = rank;

    }


    public Suite getSuite() {

        return suite;

    }


    public int getRank() {

        return rank;

    }


    @Override

    public String toString() {

        StringBuilder buf = new StringBuilder();

        if (rank >= 2 && rank <= 10) {

            buf.append(rank);

        } else {

            switch (rank) {

                case JACK:

                    buf.append("jack");

                    break;

                case QUEEN:

                    buf.append("queen");

                    break;

                case KING:

                    buf.append("king");

                    break;

                case ACE:

                    buf.append("ace");

                    break;

            }

        }

        buf.append(" of ");

        buf.append(suite.toString().toLowerCase());

        return buf.toString();

    }


    @Override

    public int compareTo(Card other) {

        if (rank > other.rank) {

            return 1;

        } else if (rank < other.rank) {

            return -1;

        } else {

            return suite.compareTo(other.suite);

        }

    }

}

請注意,您還可以有 的兩個子類Card:一個用于數字,一個用于數字。


這Deck是 52 張卡片的集合。它是通過將每張卡添加到列表中來初始化的。一個人可以使用shuffle一副牌或take牌組中的一張牌:


public class Deck {

    private final List<Card> cards = new ArrayList<>();


    public Deck() {

        for (Card.Suite suite: Card.Suite.values()) {

            for (int i = 2; i <= 14; ++i) {

                cards.add(new Card(suite,i));

            }

        }

    }


    public void shuffle() {

        Collections.shuffle(cards);

    }


    public boolean isEmpty() {

        return cards.isEmpty();

    }


    public Card take() {

        if (cards.isEmpty()) {

            throw new IllegalStateException("Deck is empty");

        }

        return cards.remove(0);

    }

}

您可以洗牌并從牌庫中取出 5 張牌,如下所示:


    Deck deck = new Deck();

    deck.shuffle();

    for (int i = 0; i < 5; ++i) {

        Card card = deck.take();

        System.out.println(card);

    }

現在 aHand是從 a 中取出的一組五張牌Deck。我們可以聲明Hand為實現Comparable<Hand>,這樣我們就可以知道兩只手中哪一只的價值最高:


public class Hand implements Comparable<Hand> {

    private final Card[] cards = new Card[5];


    public Hand(Deck deck) {

        for (int i = 0; i < 5; ++i) {

            cards[i] = deck.take();

        }

        Arrays.sort(cards);

    }


    @Override

    public int compareTo(Hand other) {

        ...

    }

}

現在有趣的部分來了:您必須將手牌類型識別為以下類型之一(枚舉類型):


public enum HandType {

    SINGLE, PAIR, TWO_PAIRS, THREE, STRAIGHT, FLUSH, FULL_HOUSE, FOUR,

    STRAIGHT_FLUSH, ROYAL_FLUSH;

}

請注意,常數是從最低到最高排列的。此外,牌的排列方式必須能夠在出現平局的情況下,您可以比較牌來確定獲勝者。


我建議你將相同等級的卡牌分組;如果您有五個不同的組,它仍然可以是同花或順子。


另一種方法是聲明Handfor every 的子類HandType,但我認為這樣做不會獲得太多好處。


public class Hand implements Comparable<Hand> {

    public enum HandType {

        SINGLE, PAIR, TWO_PAIRS, THREE, STRAIGHT, FLUSH, FULL_HOUSE, FOUR,

        STRAIGHT_FLUSH, ROYAL_FLUSH;

    }


    private final Card[] cards = new Card[5];

    private final int[] groupSize;

    private final HandType type;


    public Hand(Deck deck) {

        for (int i = 0; i < 5; ++i) {

            cards[i] = deck.take();

        }

        groupSize = group(cards);

        type = identifyType(groupSize, cards);

    }


    @Override

    public int compareTo(Hand other) {

        int r = type.compareTo(other.type);

        if (r != 0) {

            return r;

        }

        for (int i = cards.length; --i >= 0; ) {

            int r1 = cards[i].getRank();

            int r2 = other.cards[i].getRank();

            if (r1 < r2) {

                return -1;

            } else if (r1 > r2) {

                return 1;

            }

        }

        return 0;

    }


    @Override

    public String toString() {

        StringBuilder buf = new StringBuilder();

        buf.append(type);

        buf.append(": ");

        buf.append(cards[0]);

        for (int i = 1; i < 5; ++i) {

            buf.append(", ");

            buf.append(cards[i]);

        }

        return buf.toString();

    }


    private static int[] group(Card[] cards) {

        Arrays.sort(cards);

        List<List<Card>> groups = new ArrayList<>();

        int val = -1; // invalid rank

        List<Card> currentGroup = null;

        for (Card card: cards) {

            if (val == card.getRank()) {

                currentGroup.add(card);

            } else {

                if (currentGroup != null) {

                    groups.add(currentGroup);

                }

                currentGroup = new ArrayList<>();

                currentGroup.add(card);

                val = card.getRank();

            }

        }

        if (currentGroup != null) {

            groups.add(currentGroup);

        }

        // identify groups of cards of same value

        // sort groups by size and highest card

        Collections.sort(groups, (List<Card> group1, List<Card> group2) -> {

            int s1 = group1.size();

            int s2 = group2.size();

            if (s1 < s2) {

                return -1;

            } else if (s1 > s2) {

                return 1;

            } else {

                return group1.get(s1-1).compareTo(group2.get(s2-1));

            }

        });

        int[] groupSize = new int[groups.size()];

        int g = 0;

        int i = 0;

        for (List<Card> group: groups) {

            groupSize[g++] = group.size();

            for (Card card: group) {

                cards[i++] = card;

            }

        }

        assert sum(groupSize) == 5;

        return groupSize;

    }


    private static HandType identifyType(int[] groupSize, Card[] cards) {

        switch (groupSize.length) {

            case 2:

                // can be a full house or four cards

                if (groupSize[0] == 1) {

                    return HandType.FOUR;

                } else if (groupSize[0] == 2) {

                    return HandType.FULL_HOUSE;

                } else {

                    assert false;

                    return null;

                }

            case 3:

                if (groupSize[0] == 1) {

                    // three cards or double pair

                    if (groupSize[1] == 1) {

                        return HandType.THREE;

                    } else {

                        assert groupSize[1] == 2 && groupSize[2] == 2;

                        return HandType.TWO_PAIRS;

                    }

                } else {

                    assert false;

                    return null;

                }

            case 4:

                // one pair

                return HandType.PAIR;

            case 5:

                // all different values: check for flush

                Card prev = cards[0];

                boolean sameSuite = true;

                boolean straight = true;

                for (int i = 1; i < 5; ++i) {

                    Card card = cards[i];

                    straight &= card.getRank() == prev.getRank()+1;

                    sameSuite &= card.getSuite() == prev.getSuite();

                }

                if (sameSuite) {

                    if (straight) {

                        if (cards[4].getRank() == Card.ACE) {

                            return HandType.ROYAL_FLUSH;

                        }

                        return HandType.STRAIGHT_FLUSH;

                    } else {

                        return HandType.FLUSH;

                    }

                } else {

                    if (straight) {

                        return HandType.STRAIGHT;

                    } else {

                        return HandType.SINGLE;

                    }

                }


            default:

                assert false;

                return null;

        }

    }


    private static int sum(int[] groupSize) {

        int sum = 0;

        for (int s: groupSize) {

            sum += s;

        }

        return sum;

    }

}



查看完整回答
反對 回復 2024-01-05
  • 3 回答
  • 0 關注
  • 280 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號