2

First of all, this is an assignment but I'm really lost on this part of the system.

The assignment is to fill the methods for dealer and player classes. I am working on the dealer now and would appreciate any guidance.

Now my problem here is what should I return for my deal method in my dealer class. inside the main you can see it being called and that a return value is expected so that it may display the current 5 cards, but whatever I tried it returned as error.

I tried:

return dealCard and return Card;

Also in my:

dealCard[i] = tempCards.get(i);

I got a problem in which when it is already on its 10th loop it returns an error saying index 4 size 3, by 10th loop, I am referring to the main class where the play method will be looped 10 times, thus my deal method will be called 10 times also. I apologize in advance if this seems to be a trivial matter but I have not really dug deep into java yet and I am still learning, I am not that used to OOP.

Main:

public class Poker {
    private static final int NUMBER_OF_HANDS = 10;

    public static void main(String... args) {
        Dealer dealer = new DealerImpl();
        Player player = new PlayerImpl();
        Deck deck = new Deck();

        dealer.shuffle(deck);

        for (int i = 0; i < NUMBER_OF_HANDS; i++) {
            try {
                play(dealer, player, deck);
            } catch (OutOfCardsException e) {
                throw new IllegalStateException();
            }
        }
    }

    private static void play(Dealer dealer, Player player, Deck deck)
            throws OutOfCardsException {

        Hand hand = dealer.deal(deck);
        Result result = player.evaluate(hand);

        System.out.println(format("%s \u21d2 %s", hand, result));
    }
}

Hand class

public class Hand {
    public static final int NUMBER_OF_CARDS = 5;

    private Set<Card> cards;

    public Hand(Set<Card> cards) {
        if (cards.size() != NUMBER_OF_CARDS) {
            String message = format("%d cards needed in one hand",
                    NUMBER_OF_CARDS);

            throw new IllegalArgumentException(message);
        }

        this.cards = cards;
    }

    public Set<Card> getCards() {
        return cards;
    }

    @Override
    public String toString() {
        StringBuilder stringBuilder = new StringBuilder();

        for (Card card : cards) {
            stringBuilder.append(card.toString());
        }

        return stringBuilder.toString();
    }
}

Deck:

public class Deck {
    private List<Card> cards = new ArrayList<>();

    public Deck() {
        for (Card card : Card.values()) {
            cards.add(card);
        }
    }

    public List<Card> getCards() {
        return cards;
    }
}

Dealer:

public class DealerImpl implements Dealer {

    @Override
    public void shuffle(Deck deck) {
            Collections.shuffle(deck.getCards());
    }

    @Override
    public Hand deal(Deck deck) throws OutOfCardsException {
            List<Card> tempCards = deck.getCards();

            int n = 5;
            Card[] dealCard = new Card[n];
            if(tempCards.size() >= 5){
                for(int i = 0; i< n; i++){
                // what I'm trying to do here is to get 5 cards from the deck and remove them 
                // so that they cannot be repeated. I am doing it right?
                    dealCard[i] = tempCards.get(i);
                    tempCards.remove(0);
                }
            }
            return null;
    }
}

card:

public enum Card {
    ACE_OF_DIAMONDS(DIAMONDS, ACE, new String(new int[] {0x1f0c1}, 0, 1)),
    TWO_OF_DIAMONDS(DIAMONDS, TWO, new String(new int[] {0x1f0c2}, 0, 1)),
    THREE_OF_DIAMONDS(DIAMONDS, THREE, new String(new int[] {0x1f0c3}, 0, 1)),
    FOUR_OF_DIAMONDS(DIAMONDS, FOUR, new String(new int[] {0x1f0c4}, 0, 1)),
    FIVE_OF_DIAMONDS(DIAMONDS, FIVE, new String(new int[] {0x1f0c5}, 0, 1)),
    SIX_OF_DIAMONDS(DIAMONDS, SIX, new String(new int[] {0x1f0c6}, 0, 1)),
    SEVEN_OF_DIAMONDS(DIAMONDS, SEVEN, new String(new int[] {0x1f0c7}, 0, 1)),
    EIGHT_OF_DIAMONDS(DIAMONDS, EIGHT, new String(new int[] {0x1f0c8}, 0, 1)),
    NINE_OF_DIAMONDS(DIAMONDS, NINE, new String(new int[] {0x1f0c9}, 0, 1)),
    TEN_OF_DIAMONDS(DIAMONDS, TEN, new String(new int[] {0x1f0ca}, 0, 1)),
    JACK_OF_DIAMONDS(DIAMONDS, JACK, new String(new int[] {0x1f0cb}, 0, 1)),
    QUEEN_OF_DIAMONDS(DIAMONDS, QUEEN, new String(new int[] {0x1f0cd}, 0, 1)),
    KING_OF_DIAMONDS(DIAMONDS, KING, new String(new int[] {0x1f0ce}, 0, 1)),
    ACE_OF_CLUBS(CLUBS, ACE, new String(new int[] {0x1f0d1}, 0, 1)),
    TWO_OF_CLUBS(CLUBS, TWO, new String(new int[] {0x1f0d2}, 0, 1)),
    THREE_OF_CLUBS(CLUBS, THREE, new String(new int[] {0x1f0d3}, 0, 1)),
    FOUR_OF_CLUBS(CLUBS, FOUR, new String(new int[] {0x1f0d4}, 0, 1)),
    FIVE_OF_CLUBS(CLUBS, FIVE, new String(new int[] {0x1f0d5}, 0, 1)),
    SIX_OF_CLUBS(CLUBS, SIX, new String(new int[] {0x1f0d6}, 0, 1)),
    SEVEN_OF_CLUBS(CLUBS, SEVEN, new String(new int[] {0x1f0d7}, 0, 1)),
    EIGHT_OF_CLUBS(CLUBS, EIGHT, new String(new int[] {0x1f0d8}, 0, 1)),
    NINE_OF_CLUBS(CLUBS, NINE, new String(new int[] {0x1f0d9}, 0, 1)),
    TEN_OF_CLUBS(CLUBS, TEN, new String(new int[] {0x1f0da}, 0, 1)),
    JACK_OF_CLUBS(CLUBS, JACK, new String(new int[] {0x1f0db}, 0, 1)),
    QUEEN_OF_CLUBS(CLUBS, QUEEN, new String(new int[] {0x1f0dd}, 0, 1)),
    KING_OF_CLUBS(CLUBS, KING, new String(new int[] {0x1f0de}, 0, 1)),
    ACE_OF_HEARTS(HEARTS, ACE, new String(new int[] {0x1f0b1}, 0, 1)),
    TWO_OF_HEARTS(HEARTS, TWO, new String(new int[] {0x1f0b2}, 0, 1)),
    THREE_OF_HEARTS(HEARTS, THREE, new String(new int[] {0x1f0b3}, 0, 1)),
    FOUR_OF_HEARTS(HEARTS, FOUR, new String(new int[] {0x1f0b4}, 0, 1)),
    FIVE_OF_HEARTS(HEARTS, FIVE, new String(new int[] {0x1f0b5}, 0, 1)),
    SIX_OF_HEARTS(HEARTS, SIX, new String(new int[] {0x1f0b6}, 0, 1)),
    SEVEN_OF_HEARTS(HEARTS, SEVEN, new String(new int[] {0x1f0b7}, 0, 1)),
    EIGHT_OF_HEARTS(HEARTS, EIGHT, new String(new int[] {0x1f0b8}, 0, 1)),
    NINE_OF_HEARTS(HEARTS, NINE, new String(new int[] {0x1f0b9}, 0, 1)),
    TEN_OF_HEARTS(HEARTS, TEN, new String(new int[] {0x1f0ba}, 0, 1)),
    JACK_OF_HEARTS(HEARTS, JACK, new String(new int[] {0x1f0bb}, 0, 1)),
    QUEEN_OF_HEARTS(HEARTS, QUEEN, new String(new int[] {0x1f0bd}, 0, 1)),
    KING_OF_HEARTS(HEARTS, KING, new String(new int[] {0x1f0be}, 0, 1)),
    ACE_OF_SPADES(SPADES, ACE, new String(new int[] {0x1f0a1}, 0, 1)),
    TWO_OF_SPADES(SPADES, TWO, new String(new int[] {0x1f0a2}, 0, 1)),
    THREE_OF_SPADES(SPADES, THREE, new String(new int[] {0x1f0a3}, 0, 1)),
    FOUR_OF_SPADES(SPADES, FOUR, new String(new int[] {0x1f0a4}, 0, 1)),
    FIVE_OF_SPADES(SPADES, FIVE, new String(new int[] {0x1f0a5}, 0, 1)),
    SIX_OF_SPADES(SPADES, SIX, new String(new int[] {0x1f0a6}, 0, 1)),
    SEVEN_OF_SPADES(SPADES, SEVEN, new String(new int[] {0x1f0a7}, 0, 1)),
    EIGHT_OF_SPADES(SPADES, EIGHT, new String(new int[] {0x1f0a8}, 0, 1)),
    NINE_OF_SPADES(SPADES, NINE, new String(new int[] {0x1f0a9}, 0, 1)),
    TEN_OF_SPADES(SPADES, TEN, new String(new int[] {0x1f0aa}, 0, 1)),
    JACK_OF_SPADES(SPADES, JACK, new String(new int[] {0x1f0ab}, 0, 1)),
    QUEEN_OF_SPADES(SPADES, QUEEN, new String(new int[] {0x1f0ad}, 0, 1)),
    KING_OF_SPADES(SPADES, KING, new String(new int[] {0x1f0ae}, 0, 1));

    private Suit suit;
    private Rank rank;
    private String string;

    private Card(Suit suit, Rank rank, String string) {
        this.suit = suit;
        this.rank = rank;
        this.string = string;
    }

    public Suit getSuit() {
        return suit;
    }

    public void setSuit(Suit suit) {
        this.suit = suit;
    }

    public Rank getRank() {
        return rank;
    }

    public void setRank(Rank rank) {
        this.rank = rank;
    }

    @Override
    public String toString() {
        return string;
    }
}
Andrew Tobilko
  • 44,067
  • 12
  • 74
  • 128
makingitwork
  • 149
  • 1
  • 9
  • What is the error/stack trace? I think I found a problem with the loop in `public Hand deal(Deck deck)`, A error trace would help me confirm. – kevingreen Mar 28 '16 at 17:32
  • You ask what to return, but the method signature is asking for you to return a Hand object. Just return a new Hand(tempCards) where you convert the List to a Set (not 100% sure thats necessary my java is a tad rusty) – Gordon Allocman Mar 28 '16 at 17:34
  • It only says index 4 size 3, I do believe it ran out of cards but that shouldn't ran out yet. – makingitwork Mar 28 '16 at 17:34
  • @GordonAllocman it gave this error java.util.ArrayList cannot be cast to java.util.Set, after i turned it into return new Hand((Set) tempCards); – makingitwork Mar 28 '16 at 17:38
  • @makingitwork you need to convert not just cast. see this [SO answer](http://stackoverflow.com/questions/1429860/easiest-way-to-convert-a-list-to-a-set-java) note the top comment that if the list passed in is null you get a NPE – Gordon Allocman Mar 28 '16 at 17:40
  • @GordonAllocman i'll look at this, what does NPE mean? – makingitwork Mar 28 '16 at 17:42
  • @makingitwork NullPointerException – Gordon Allocman Mar 28 '16 at 17:42

3 Answers3

2

The remove method shift all the remaining objects left, so when you get to index 4 it doesn't exist in the list anymore.

You can start the dealing from the end of the deck

for(int i = n - 1; i >= 0; i--) {
    dealCard[i] = tempCards.get(i);
    tempCards.remove(tempCards.size() - 1);
}

To return an Hand convert dealcards to Set and return new Hand

Set<Card> cards = new HashSet<Card>(Arrays.asList(dealCard));

return new Hand(cards);

The method deal will look like this

@Override
public Hand deal(Deck deck) throws OutOfCardsException {
    List<Card> tempCards = deck.getCards();

    int n = 5;
    Card[] dealCard = new Card[n];
    if(tempCards.size() >= 5) {
        for(int i = n - 1; i >= 0; i--) {
            dealCard[i] = tempCards.get(i);
            tempCards.remove(tempCards.size() - 1);
        }

        Set<Card> cards = new HashSet<Card>(Arrays.asList(dealCard));

        return new Hand(cards);
    }

    return null;
}
Guy
  • 34,831
  • 9
  • 31
  • 66
  • thanks it run without error, but the problem now is that the returned value is not being interpret properly by Hand class. – makingitwork Mar 28 '16 at 17:54
  • the expected output based on the requirements is some figures of the card, as you can see in the card class. but the output of my deal method are ?????. which means that it failed to identify what card to display. I wonder where I went wrong here. thank you so much for your guidance – makingitwork Mar 28 '16 at 18:01
  • it seems that netbeans has trouble with unicode as this "\u21d2" is also not presented properly – makingitwork Mar 28 '16 at 18:09
  • @makingitwork `new String(new int[] {0x1f0ae}, 0, 1)` returns odd symbols when you convert it int string. What exactly you are trying to print there? – Guy Mar 28 '16 at 18:29
  • I think its unicode problem as \u21d2 is displayed as ?, when it should be => – makingitwork Mar 28 '16 at 18:30
1

I do see a problem here. The dealCard array is 5 items big. In the for loop you are looking for 6 cards. Array indexes start at 0. The other problem is the list size changes each time you remove a card. Grab the 0 card instead of the (i). The 0 card becomes the 'next' card each time you do a remove.

@Override
    public Hand deal(Deck deck) throws OutOfCardsException {
            List<Card> tempCards = deck.getCards();

            int n = 5;
            Card[] dealCard = new Card[n];
            if(tempCards.size() >= 5){
                for(int i = 0; i< n; i++){
                // what I'm trying to do here is to get 5 cards from the deck and remove them 
                // so that they cannot be repeated. I am doing it right?
                    dealCard[i] = tempCards.get(i);
                    tempCards.remove(0);
                }
            }
            return null;
    }

Change this to:

@Override
public Hand deal(Deck deck) throws OutOfCardsException {
        List<Card> tempCards = deck.getCards();

        int n = 5;
        Card[] dealCard = new Card[n];
        if(tempCards.size() >= 5){
            for(int i = 0; i< n-1; i++){
            // what I'm trying to do here is to get 5 cards from the deck and remove them 
            // so that they cannot be repeated. I am doing it right?
                dealCard[i] = tempCards.get(0);
                tempCards.remove(0);
            }
        }
        //return a hand. Cast the Array to a set, and create a new hand.
        Set<Card> mySet = new HashSet<Card>(dealCard);
        return new Hand(Arrays.asList(mySet));

}

The for loop now goes to n-1.

kevingreen
  • 1,511
  • 1
  • 17
  • 40
  • That may solve his out of bounds exception, but it should be tempCards.get(0) instead, otherwise it won't do what he thinks it is doing. For example when _i_ is 1 he is grabbing what was originally in index 2 since the list shrunk. – Gordon Allocman Mar 28 '16 at 17:39
  • @GordonAllocman You're right. I didn't take into account the `remove(0)`. – kevingreen Mar 28 '16 at 17:40
  • @kevingreen the loop error is gone now all that remains is what to return – makingitwork Mar 28 '16 at 17:41
  • 1
    This answer is incorrect. `for(int i = 0; i< n; i++)` – Clark Kent Mar 28 '16 at 17:42
  • @makingitwork I added a return for the 'Hand' object. – kevingreen Mar 28 '16 at 17:44
  • @kevingreen I get a no suitable constructor for hashset(card[]) – makingitwork Mar 28 '16 at 17:49
  • 2
    And, perhaps, you should make that if statement conform to the amount of cards you are dealing, not hard code it to 5. ie. `int n = 5; if (tempCards.size() >= n) {...}` – Machtyn Mar 28 '16 at 17:50
  • @makingitwork oh yeah, it needs to be converted to an arraylist. via; Arrays.asList(dealCard); – kevingreen Mar 28 '16 at 17:50
  • Thank you, I sure missed a lot of important points in my code. – makingitwork Mar 28 '16 at 17:55
  • Thanks for understanding, now my problem is that the returned value is not being presented properly. as is just printed as ?????, wherein the expected outcome it should be pictures of the card. also \u21d2 is printed as ? – makingitwork Mar 28 '16 at 18:06
  • The ??? is a character encoding issue. The terminal can't make sense of the characters that the cards represent. Those characters are probably not in the ASCII set that the terminal uses. To solve that problem, you may need to write to a file, or use a different problem. – kevingreen Mar 28 '16 at 18:13
  • @makingitwork Here's some info about the unicode character sets for playing cards: https://en.wikipedia.org/wiki/Playing_cards_in_Unicode – kevingreen Mar 28 '16 at 18:15
  • @kevingreen I tried following this link [link](http://stackoverflow.com/questions/7219249/netbeans-console-does-not-display-bangla-unicode-characters) but I still can't display the unicode character properly – makingitwork Mar 28 '16 at 18:17
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/107568/discussion-between-kevingreen-and-makingitwork). – kevingreen Mar 28 '16 at 18:18
0

Since your method has a return type of Hand you have to return an object with the Hand type.

Also use kevingreen's solution for your array problems.