Java中扑克手的分类

Java中扑克手的分类,java,arrays,oop,poker,Java,Arrays,Oop,Poker,我目前正在做一个CS项目,对玩家的手进行分类。我解决了项目的前半部分,以打印出牌组、洗牌牌组以及玩家1、玩家2和剩余牌组的手。当我必须评估手的时候,问题就出现了。我的代码必须以某种方式评估手的分类,并打印出player1还是player2获胜。到目前为止,我有三门课: public class Card { static String[] card_suit = {"hearts", "diamonds", "clubs", "spades"}; static int[] c

我目前正在做一个CS项目,对玩家的手进行分类。我解决了项目的前半部分,以打印出牌组、洗牌牌组以及玩家1、玩家2和剩余牌组的手。当我必须评估手的时候,问题就出现了。我的代码必须以某种方式评估手的分类,并打印出player1还是player2获胜。到目前为止,我有三门课:

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;
    }
}
导入java.util.array;
导入java.util.Collections;
公共类卡片{
卡片=新卡片();
私有字符串[]卡片组=新字符串[52];
公共字符串[]getDeck(){
int i=0;
对于(int s=0;s<4;s++){
对于(int r=0;r<13;r++){
牌组[i]=(牌组[s]+“+牌组[r]);
i++;
}
}
返回卡;
}
公共空白打印组(){
System.out.println(java.util.Arrays.toString(deck_card));
}
公共空间{
收集。洗牌(数组。asList(卡片组));
}
公共字符串[]PlayerHands(){
字符串[]第一手=新字符串[5];
对于(int a=0;a<5;a++){
第一手牌;
}
直接返回;
}
公共字符串[]playerTwoHands(){
字符串[]二手=新字符串[5];
对于(int a=0;a<5;a++){
二手[a]=信用卡[a+5];
}
二手货;
}
公共字符串[]剩余的DeckCards(){
字符串[]remainDeck=新字符串[42];
对于(int a=0;a<42;a++){
remainDeck[a]=卡片组[a+10];
}
返回重新标记;
}
}
我认为它会起作用的是,因为Deck类从Card类扩展而来,我可以使用getRank方法来比较每只手,但我不确定如何构造条件

非常感谢您的帮助。谢谢

  • 为了给游戏建模,首先要确定像牌、牌组等实体(大部分你都做过)。我想再加上几个,比如玩家、评估者(解释如下)等等
  • 等级和花色不是字符串/整数,但它们是预定义的(在游戏的生命周期中不会改变)可能的纸牌变体。始终使用领域词汇表以获得最佳模型。每张牌属于一套和一个等级。(考虑将Rank和Suit作为枚举,这将避免未知值在运行时破坏代码
  • 不给出卡片中的组别和等级的设置方法是必要的(它们组合形成卡片的标识)
  • 全副牌(初始化时)由套装和等级的叉积组成。这意味着副牌有(包含)多张牌。记住牌可以在副牌之外(当在玩家手中时)有效同样,因此它不是组合。从卡片继承卡片组是绝对错误的。它转换为语句卡片组是一种卡片,这是不正确的。卡片组将有卡片集合。使用继承,将导致违反Liskov的替换原则(实体之一)
  • 为了模拟甲板,考虑甲板不包含重复卡片的事实,甲板一旦形成就不会改变它的顺序(除非洗牌)。这是在集合和列表之间的棘手选择,我会选择附加的编程约束来避免重复(只需要在初始化时进行)。
  • 但与其将Deck建模为java集合,不如让类Deck包含适当选择的java集合,并通过定义所需的API(从域的角度)如shuffle、getTopCard()等,让Deck类作为包装器工作。这称为对象适配器设计模式。这使得我们的设计平台(实现)独立的
  • 你需要为更多的类建模,比如玩家持有卡丁等
  • 关于评估手中的卡片,最好将其建模为单独的类,因为其不同的关注点和规则可以独立于其他类进行更改
  • 扑克游戏是学习面向对象编程的最佳任务
  • 对于游戏的建模,首先要确定像卡、牌组等实体(大部分是你做的)。我会添加一些像玩家、评估者(解释如下)等
  • 等级和等级不是字符串/整数,但它们是预定义的(在游戏的生命周期内不会改变)卡牌中可能的变化。始终使用域词汇表以获得最佳模型。每张卡牌属于一个等级和一个等级。(将等级和等级设为枚举,这将避免未知值在运行时破坏代码。)
  • 不给出卡片中的组别和等级的设置方法是必要的(它们组合形成卡片的标识)
  • 全副牌(初始化时)由套装和等级的叉积组成。这意味着副牌有(包含)多张牌。记住牌可以在副牌之外(当在玩家手中时)有效同样,因此它不是组合。从卡片继承卡片组是绝对错误的。它转换为语句卡片组是一种卡片,这是不正确的。卡片组将有卡片集合。使用继承,将导致违反Liskov的替换原则(实体之一)
  • 为了模拟甲板,考虑甲板不包含重复卡片的事实,甲板一旦形成就不会改变它的顺序(除非洗牌)。这是在集合和列表之间的棘手选择,我会选择附加的编程约束来避免重复(只需要在初始化时进行)。
  • 但与其将Deck建模为java集合,不如让类Deck包含适当选择的java集合,并通过定义所需的API(从域的角度)如shuffle、getTopCard()等,让Deck类作为包装器工作。这称为对象适配器设计模式。这使得我们的设计平台(实现)独立的
  • 你需要为更多的类建模,比如玩家持有卡丁等
  • 关于评估手上的卡片,最好使用模式
    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()));               
            }
    
    }
    
    import java.util.Arrays;
    import java.util.Collections;
    
    public class Deck extends Card {
    
        Card card = new Card();
    
        private String[] deck_card = new String[52];
    
        public String[] getDeck() {
            int i = 0;
            for(int s = 0; s < 4; s++) {
                for(int r = 0; r < 13; r++) {
                    deck_card[i]=(card_suit[s] + " of " + card_rank[r]);
                    i++;
                    }
    
                }
            return deck_card;
        }
    
        public void printDeck() {
            System.out.println (java.util.Arrays.toString (deck_card));
        }
    
        public void shuffleDeck() {
            Collections.shuffle(Arrays.asList(deck_card));
        }
    
        public String[] playerOneHands() {
            String [] firsthand = new String[5];
            for(int a = 0; a < 5; a++) {
                firsthand[a] = deck_card[a];
            }
            return firsthand;
        }
    
        public String[] playerTwoHands() {
            String[] secondhand = new String[5];
            for(int a = 0; a < 5; a++) {
                secondhand[a] = deck_card[a+5];
            }
            return secondhand;
        }
    
        public String[] remainingDeckCards() {
            String[] remainDeck = new String[42];
            for(int a = 0; a < 42; a++){
                remainDeck[a] = deck_card[a+10];
            }
            return remainDeck;
        }
    
    }
    
    class Deck extends Card
    
    class Deck {
        List<Card> cards;
    }
    
    public void shuffleDeck() {
        Collections.shuffle(Arrays.asList(deck_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);
            }
        }
    }
    
    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);
        }
    }
    
        Deck deck = new Deck();
        deck.shuffle();
        for (int i = 0; i < 5; ++i) {
            Card card = deck.take();
            System.out.println(card);
        }
    
    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;
    }
    
    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;
        }
    }