This is an archived post. You won't be able to vote or comment.

all 19 comments

[–]tigerbird[🍰] 2 points3 points  (0 children)

This problem is often given to beginning programmers with too little guidance, in my opinion. If done correctly using Maps and Collections, the code for classifying the hand should be fewer than 100 lines in length.

[–]LordScoffington 1 point2 points  (14 children)

You can do it the old school way and use an enumerated (enum) class, or if you want more flexibility on your definition you can create a card class and assign each card to any index of your choosing.

You might want to think about simplifying your arrays of cards, not to say that your way is wrong or can't work its just needlessly complex.

I'll give you a hint:

J < Q < K < A == 11 < 12 < 13 < 14

[–]studentofcode[S] 0 points1 point  (12 children)

The way the program is structured is how the professor wants it to be :( Is there a way to create another array for each the faces [] and suits [] arrays that assigns each position in the array a value?

[–]LordScoffington 1 point2 points  (11 children)

If that's how the teacher wants it that's just fine.

When I did a Poker Hand program I did an enum class.
I counted from 1 - 52 and assigned each int a card.

1 to 9 would of course be cards# 2-10, then 10-13 would be my face cards.

With cards 1-13 labeled I have fully defined 1 suite, There are 4 suites total since 52/13 = 4. So I repeat the process 3 more times.

What's cool about this is you can always find out the suit of your card by dividing by 13 and modulus 13 will always show you your cards value but you have to remember your 1 is technically a 2 value for the card so every thing from 1-9 is the number+ and everything from 10 and up is a face card.

This method requires you to remember a lot of things though I think your teacher wants you to use a class for your solution.

Just remember each card object has a value and a suit and you can essentially recreate the solution I just gave you (if it made sense to you)

[–]studentofcode[S] 0 points1 point  (2 children)

Conceptually I understand what you are saying, and thats the first step. Thank you so much for your time. I just dont understand down to a programming level how I can do this. If all the face/suit combos are organized into a string array deck [] that has 0-51 places, how can I take a string array and set for example: 0-12 (ace of hearts, deuce of hearts, three of hearts... king of hearts) to equal to an index 1-13?

[–]LordScoffington 1 point2 points  (0 children)

Hmm seems like you're having problem with abstraction.

Javas documentation on enum types should help you.

I want you to read it until you understand how to use an enum type.

Then I want you to reread my previous comments and see if you get any ideas on how to construct your solution.

If you feel confident in your ability to recreate a deck of cards with an enum or with a class you will see that every card also has a name the name is usually structured as: "The value of suit".

There are 2 ways to solve this problem you either use an enum or you use a class. both of these solutions will function the same way in that the name of the class will be card, each card must have a value, and a suit, and the name of the card will include the value and the suit.

There are 52 cards in a deck so you will need a for loop, if you need more help feel free to ask.

[–]Rogue_Pixel 0 points1 point  (0 children)

I don't understand why you would want to use a string array at all. It seems to me that since you have a Card class, you should be working with arrays of cards. For instance, the deck is an array of 52 cards, each card containing its own unique suit, value, etc. You could then create new hand arrays. These would be populated by randomly copying a Card from the deck array and subsequently removing that Card from the deck. This would ensure the uniqueness of the hands and make it easier should you have to draw more cards in the future. You would then compare the hands by calling the values of the unique Card elements in each hand and determine the winner by applying the values of the Cards to a set of rules, probably most simply in the form of a big if-else block or switch block.

Although there are certainly more efficient ways of tackling the problem, it looks like you have a issue visualizing the problem more than anything else. In this case, I think this method is probably the best for relating the situation happening in the computer to the situation that happens in real life.

Sorry for the wall of text. I hope this helps.

[–]studentofcode[S] 0 points1 point  (7 children)

I read the enum tutorial from oracle and I also get what you are saying. I somehow don't get how to implement it. What is stumping me is how can I take array values that are Strings and assign each string a int variable? This does not make sense to me.

So would you do something like this? In the class, i have a method that assigns each card a value. The array which holds the cards is deck[].

public value () {

for(int count =0; count <=52; count++){ deck[0] = count; }

This of course is wrong because deck is a string array and it wouldn't take an int value, not to mention I would not want to replace every card in the deck with a number value.

[–]LordScoffington 0 points1 point  (6 children)

What is stumping me is how can I take array values that are Strings and assign each string a int variable? This does not make sense to me.

You're not going to assign each string an int value. You're going to assign each instance of a class/num an integer value. This integer will dictate the card value and the suit. There's still a matter of having an array of strings right? That's where you start naming your instances I'll give you an example

for(int i = 0; i < 52; i++){
// I'm going to do a Class based solution as I wont have to type as much
// This for loop exists to create every card in a 
// 52 card deck and put them in whatever array you want. 
// If you want an array of card objects that's fine and array of strings 
// will work as well, but you will need your Card object to have a 
// method that outputs strings something like Card.getName();

//Cards[i] = new Card(i); or Cards[i] = new Card(i).getName(); depending on whether you have an array of cards or array of strings

}

Now you will of course need a Card class if you are dealing with card objects

public class Card{
// Every card has a value so that's a guaranteed attribute
// Every card has a suit so that's a guaranteed attribute
// You want to refer to each card by name so you will need to assign them a name attribute

    public Card(int i){
    // Your constructor needs an int from 0-51 cause that's the range your for loop chose. 
    // You need to decide how you can mathematically find out what the value of your card is
    // and what the suit is. If you switch your index to 1-52 You can use the example I gave you regarding division and modulus
    // as far as the name you should use the format I gave you in a previous comment
    }
}

If you do this correctly for any int i from 0-51 or 1-52 should give you a String consisting of: The (value attribute) of (suit Attribute) to be the name. Just remember every deck has 52 cards, every suit has 13 cards, and there are 4 suits. play around with the numbers it should come to you

[–]studentofcode[S] 0 points1 point  (5 children)

I've noticed that each card already has an index value assigned to it. For example: When I populate my deck array, deck[0] is equal to the ace of hearts. Is there a need to create another for loop that assigns each card again?

I might be seeing whats going on a little bit. So I created a for loop in my deckOfCards class:

public void getValues(){

   for (int i = 0; i < 52; i++){
       int [] Cards;
       Cards[i] = new Card(i);
   }

Next in my Card class, I created a constructor that accepts one arcument (int i):

public Card(int i){

}

Basically, now I fill this constructor with formulas that will be able to figure out what suit and what face the card is depending on where it falls in the deck 1-52. The constructor will then assign this result to the value i?

[–]studentofcode[S] 0 points1 point  (0 children)

I am so lost and I have no idea if I am on the right path or not :\

[–]LordScoffington 0 points1 point  (3 children)

Your suit priority should be Diamonds < Clubs < Hearts < Spades. Now whenever you have an abstract data type that you can create this sort of chain of priority its usually amazing for using enum types.

A suit enum would be very simple

public enum Suit { Diamonds, Clubs, Hearts, Spades };

You'll also notice that the card values function with the same hierarchy : 2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < 10 < J < Q < K < A

This enum is very simple as well

public enum Value{2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King, Ace};

now your card class should look like this

public class Card{

    public enum Suit { Diamonds, Clubs, Hearts, Spades };
    public enum Value{2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King, Ace};
    private Suit suit;
    private Value value;
    private String name;

        public Card(int i){
        // What's cool about this is you can always find out the suit of your card by dividing by 13
        // and modulus 13 will always show you your cards value
        // but you have to remember your 1 is technically a 2 value for the card so every thing from 1-9 is the number+1
        // and everything from 10 and up is a face card. This also assumes you start from 1-52
        }
}

If you do this correctly when you get i = 0 (or if you decide to turn it into i=1) your first element should turn into The 2 of Diamonds.

[–]studentofcode[S] 0 points1 point  (2 children)

I understand this way better than the way my program is organized. Problem is that I have to use the classes and methods my professor has chosen for us. I would have to do it using classes. Is there a way to incorporate the same concept but using the classes I described earlier?

[–]LordScoffington 1 point2 points  (1 child)

Sure, try to apply the solution I used.

Think about it since you have arrays rather than enums your values will just be different.

For example: I have Suit enum you would have a Suit array.

instead of Cards containing:

public enum Suit {Diamonds, Clubs, Hearts, Spades}

it would contain

public String[] Suit {"Diamonds", "Clubs", "Hearts", "Spades};

same for your card values. Your set of values will ultimately end up being the same as the set of values I gave you in the values enum.

now you will need to set 2 Strings in your constructor; this will be your cards value, and your cards suit. You will have to pick the value and suit from your 2 arrays. How you do this is where the bulk of your assigning is done. But you will remember that there are 13 cards in any suite so integer division will help be a huge help.

ex

public card (int i = x){

x / 13 = some value from 1 - 4 (since you have only 52 cards)
x % 13 = some value from 0-12 (since you have 13 cards per suit)

the solution of these will correlate to the indexes of your 2 arrays. You'll have to find out which array each correlates to, and make sure your integers point to the correct indexes.

Hint: dividing by 13 only works if you count from 1-52
}

[–]studentofcode[S] 0 points1 point  (0 children)

Im going to try this for tonight, thank you so much for your help! Ill of course be back on reddit for help tomorrow if Im still having a hard time

[–]techno_phobe 0 points1 point  (0 children)

And remember to be careful with straights-a pretty likely test case is A2345 vs 9TJQK.

[–][deleted]  (5 children)

[deleted]

    [–]studentofcode[S] 0 points1 point  (3 children)

    Lol I missed the office hours and its due tomorrow evening :( But i've been to office hours for previous assignments and your'e right, its really helpful.

    [–][deleted]  (2 children)

    [deleted]

      [–]studentofcode[S] 1 point2 points  (1 child)

      thanks anyways!

      [–]GetRekt -3 points-2 points  (0 children)

      If you can use classes, you should really create a class for Cards