0

I have almost everything ready for my poker game. What I want to do next is to sort cards in players hand by rank value. You know "two" is byte 2, "three" is byte 3 etc... This is my enum CardRank class

public enum CardRank {
    TWO((byte)2, "Two"),
    THREE((byte)3, "Three"),
    FOUR((byte)4, "Four"),
    FIVE((byte)5, "Five"),
    SIX((byte)6, "Six"),
    SEVEN((byte)7, "Seven"),
    EIGHT((byte)8, "Eight"),
    NINE((byte)9, "Nine"),
    TEN((byte)10, "Ten"),
    JACK((byte)11, "Jack"),
    QUEEN((byte)12, "Queen"),
    KING((byte)13, "King"),
    ACE((byte)14, "Ace");

    private final byte rankValue;
    private final String rankValueName;

    //Constructor
    private CardRank(byte rankValue, String rankValueName){
        this.rankValue=rankValue;
        this.rankValueName = rankValueName;
    }

    //reusable methods
    protected byte getRankValue(){
        return rankValue;
    }

    protected String getRankValueName(){
        return rankValueName;
    }
}

CardsOutput

CardRankOutput

I need to find a way to sort them using enum values but to be honest I don't really know how. This method returns enum values of player hand cards:

protected void sortHand(){
    for (Hand playerHand: players){
        i = 0;
        while(i<5){
            System.out.println(playerHand.cards.get(i).getRankValue());
            i++;
        }
    }
}

I can't use Collections from a very obvious reason: The method sort(List) in the type Collections is not applicable for the arguments (Hand)

And this is my Hand class

import java.util.ArrayList;

    public class Hand {

        protected ArrayList<Card> cards;
        private String handCards;

        // Constructor
        protected Hand() {
            cards = new ArrayList<Card>(5);
        }

        // reusable methods

        protected void add(Card card) {
            cards.add(card);
        }

        protected void emptyHand() {
            cards.clear();
        }

        protected void flipHandCards() {
            for (Card card : cards) {
                card.flipCard();
            }
        }

        protected String displayHand() {
            handCards = "";
            for (Card i : cards) {
                handCards += i.toString() + "\n";
            }
            return handCards;
        }

        protected boolean giveCard(Card card, Hand differentHand) {
            if (!cards.contains(card)) {
                return false;
            } else {
                cards.remove(card);
                differentHand.add(card);
                return true;
            }
        }
    }

And this is my Card class

public class Card {

    private CardSuit suit;
    private CardRank rank;
    private String cardName;
    private boolean visibility;

    //Constructor
    protected Card(CardRank rank, CardSuit suit){
        this.rank = rank;
        this.suit = suit;
    }

    //reusable methods
    protected String getCardSuit(){
        return suit.getCardSuit();
    }

    protected byte getRankValue(){
        return rank.getRankValue();
    }
    protected void flipCard(){
        visibility = !visibility;
    }

    public String toString(){
        if (visibility){
            cardName="";
            cardName+=rank.getRankValueName() + " of " + suit.getCardSuit();
        }
        else{
            cardName = "You cannot see your opponents card";
        }
        return cardName;
    }
}

Help. I appreciate for any help that will direct me into the right direction.

Matt
  • 27
  • 9

4 Answers4

0
protected void sortHand(){
    for (Hand playerHand: players){
        i = 0;
        int []arr = new int[5]; 
        while(i<5){
            System.out.println(playerHand.cards.get(i).getRankValue());
            arr[i] = playerHand.cards.get(i).getRankValue();
            i++;
        }
        Arrays.sort(arr);
    }
}

you can try adding it to an array and call Array.sort(). where i assume that getRankvalue will return an int . try this

Priyamal
  • 2,919
  • 2
  • 25
  • 52
  • Yes it will work I know but I need to sort cards using these values instead of sorting new created Array with integers. Any ideas? – Matt Apr 28 '16 at 15:57
  • so your `players` is it a list whats the type of its collection – Priyamal Apr 28 '16 at 15:59
0

Saying you can't use Guava (Google Collections) for this seems incorrect at face value. Just give hand a sort method that lets it interact with cards (which is an ArrayList).

protected void sortHand(){
    for (Hand playerHand: players){
        List<Card> sortedHand = playerHand.getSortedCards();
        // Do whatever
    }
}

Hand.java

public class Hand {
    ...

    public List<Card> getSortedCards() {
        Collections.sort(cards);
        return cards; // Consider deep copying.
    }
}

From there, making Card implement Comparable will let you sort the list.

Card.java

public class Card implements Comparable<Card>
{
    ...

    @Override
    public int compareTo(Card o) {
        if (this.rank.getRankValue() < o.rank.getRankValue()) {
            return -1;
        }
        else if (o.rank.getRankValue() < this.rank.getRankValue()) {
            return 1;
        }
        return 0;
    }
}
Ironcache
  • 1,719
  • 21
  • 33
  • The method sort(List) in the type Collections is not applicable for the arguments (ArrayList) returns the same problem as I had but for instead of – Matt Apr 28 '16 at 15:52
  • Card either needs to implement the Comparable interface and have an implementation for compareTo(), or you need to create a Comparator class and use the **Collections.sort(List, Comparator)** signature instead. – Ironcache Apr 28 '16 at 15:58
  • Updated the answer to clarify. – Ironcache Apr 28 '16 at 16:00
  • Hmmm I've never done Comparator before in my life. And this poker game is my most advanced program so far. So I don't really know how to do this. And the problem is that I am pretty new to programming because I started not that long ago so probably I have many gaps to fill. – Matt Apr 28 '16 at 16:00
  • Basically, **Collections.sort()** needs to know *how* to sort the list. By default (using the **Collections.sort(List)** signature), *T* needs to be comparable, and it will use the **compareTo()** method in *T* to determine how to sort the data. This is the best route to go; it provides a default comparison method. Creating a separate comparator is a better choice if you're looking to use a non-default sorting approach, or there are a few different ways you could want to sort the data. – Ironcache Apr 28 '16 at 16:05
  • In terms of what to put in the compareTo() method, recommend looking at this link, but basically all you need to do is return -1 if the card being compared is less than another card, 0 if it's the same, and 1 if it's greater. https://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html#compareTo(T) – Ironcache Apr 28 '16 at 16:10
  • So you are saying that I need to compare Card1RankValue to Card2 RankValue then Card1RankValue to Card3RankValue and so on? It seems reasonable to compare cards and then to use Collections.sort(). – Matt Apr 28 '16 at 16:13
  • You don't ever need to manually compare cards; when you make the class *Comparable*, you're telling **Collections.sort()** how to compare the cards for you. Once it knows how to tell if a card is higher or lower than another card, it'll do all the comparison work for you, and you just need to call the sort method. Check the default implementation for **compareTo()** that I put in the answer. – Ironcache Apr 28 '16 at 16:17
  • Ok I understand now. Sorry sometimes I just think about something and can't get my head around it....I'm quite new. You made it very clear to me. Thank You. I will try it and let You know of my results. – Matt Apr 28 '16 at 16:21
  • You made my day. Thank You very much once again. – Matt Apr 28 '16 at 16:27
0

ArrayLists can be easily sorted using a Comparator.
You would then get something like this:

cards.sort(new Comparator<Card>() {
    @Override
    public int compare(Card card1, Card card2) {
         // return -1 if card1 should come before card2
         // return 0 if card1 and card2 have equal values
         // return 1 if card1 should come after card2
    }
});
0

I suggest you use a static array to store cards in hand:

public class Hand {
    private static final int MAX_CARD = 5;//modify with your value

    protected Card[] cards;
    private int currentCardNumber;
    private String handCards;

    // Constructor
    protected Hand() {
        cards = new Card[MAX_CARD];
        currentCardNumber = 0;
    }

    // reusable methods

    protected void add(Card card) {
        if (currentCardNumber == MAX_CARD - 1) { return; }
        cards[currentCardNumber] = card;
        currentCardNumber++;
    }

    protected void emptyHand() {
        for (int i = 0; i < MAX_CARD; i++) {
            cards[i] = null;
        }
        currentCardNumber = 0;
    }

    protected void flipHandCards() {
        for (int i = 0; i < currentCardNumber; i++) {
            cards[i].flipCard();
        }
    }

    protected String displayHand() {
        handCards = "";
        for (int i = 0; i < currentCardNumber; i++) {
            handCards += cards[i].toString() + "\n";
        }
        return handCards;
    }
    protected boolean giveCard(Card card, Hand differentHand) {
        int index = getCardIndex(card);
        if (index == -1) {
            return false;
        } else {
            differentHand.add(remove(index));
            return true;
        }
    }

    protected void sortHand() {
        for(int i = 0; i < currentCardNumber; i++) {
            for(int j = i + 1; j < currentCardNumber; j++) {
                if(cards[j].getRankValue() < cards[i].getRankValue()) {
                    Card tmp = cards[j];
                    cards[j] = cards[i];
                    cards[i] = tmp;
                 }
             }
         }
     }

    private int getCardIndex(Card card) {
        for (int i = 0; i < currentCardNumber; i++) {
            if(card.equals(cards[i]) {
                return i;
            }
        }
        return -1;
    }

    private Card remove(int cardIndex) {
        if (currentCardNumber == 0) { return null; }
        Card tmp = cards[cardIndex];
        for (int i = cardIndex + 1; i < currentCardNumber; i++) {
            cards[i - 1] = cards[i];
        }            
        cards[currentCardNumber - 1] = null;
        currentCardNumber--;
        return tmp;
    }
}

Or you can create your own List and apply a your own sort method.