0

I have this shuffled card deck and I'm supposed to make it so that it hands out 5 cards to four players. I've been sitting here like an idiot for hours and I'm stuck.

public class Deck {
public static void main(String[] args) 
{
    String[] SUITS = {
        "Clubs", "Diamonds", "Hearts", "Spades"
    };

    String[] RANKS = {
        "2", "3", "4", "5", "6", "7", "8", "9", "10",
        "Jack", "Queen", "King", "Ace"
    };

    // initialize deck
    int n = SUITS.length * RANKS.length;
    String[] deck = new String[n];
    for (int i = 0; i < RANKS.length; i++) {
        for (int j = 0; j < SUITS.length; j++) {
            deck[SUITS.length*i + j] = RANKS[i] + " of " + SUITS[j];
        }
    }

    // shuffle
    for (int i = 0; i < n; i++) {
        int r = i + (int) (Math.random() * (n-i));
        String temp = deck[r];
        deck[r] = deck[i];
        deck[i] = temp;
    }
  // print shuffled deck
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 5; j++)
        System.out.println(deck[i])
    }
}

I am stuck on that last part. I am getting five similar cards for four players. It looks like this:

  • Queen of Hearts
  • Queen of Hearts
  • Queen of Hearts
  • Queen of Hearts
  • Queen of Hearts
  • 10 of Diamonds
  • 10 of Diamonds
  • 10 of Diamonds
  • 10 of Diamonds
  • 10 of Diamonds
  • 6 of Hearts
  • 6 of Hearts
  • 6 of Hearts
  • 6 of Hearts
  • 6 of Hearts
  • 10 of Spades
  • 10 of Spades
  • 10 of Spades
  • 10 of Spades
  • 10 of Spades

How am I supposed to go at it if my intent is to deal five different cards to four players?

I'm coding in Java, doing arrays and I can't use any java utils.

J.Doe
  • 13
  • 1
  • 3

5 Answers5

1

Math.random() * (n-i) is biased, but you can use shuffle:

Collections.shuffle(deck, new Random())

I don't know if that counts as "java utils" as I'm not sure if you mean the package java.utils or not.

Now on to your problem. An array is not a good representation of a deck of cards. A stack or queue would be better as they both allow you to take a card from the deck one card at a time. With the array, you are peeking into the deck at an index, which isn't how we should play cards in real life. Ideally, the act of dealing is the transfer of a card from the deck to the hand of a player, keeping in the deck array will make it pretty hard to keep track off.

Community
  • 1
  • 1
weston
  • 54,145
  • 21
  • 145
  • 203
  • It is clear that he is not allowed to use Collections. Moreover it does not solve his problem. It is probably an assignment... –  Jan 02 '17 at 21:12
  • @JawadLeWywadi Sorry that's not clear to me as they are already using `java.utils.Random` so I have to assume they don't mean the package, then I don't know what they do mean. – weston Jan 02 '17 at 21:14
  • 1
    I am pretty sure he means Collections but still your code does not solve his problem. It is not a problem of shuffling it is just an error of code. –  Jan 02 '17 at 21:16
  • @David yes, my mistake there. However, that link is the same one that's under the word "biased" in my question. – weston Jan 02 '17 at 21:23
1

It's just an error in printing your results. Use

// print shuffled deck
for (int i = 0; i < 4; i++) {
    System.out.println("** Person " + (i + 1) + " **");
    for (int j = 0; j < 5; j++) {
        System.out.println(deck[i + j * 4] + " (Card " + (i + j * 4) + ")");
    }
}

(Sysouts added to demonstrate card distribution)

Example output:

** Person 1 **
2 of Clubs (Card 0)
4 of Diamonds (Card 4)
9 of Diamonds (Card 8)
10 of Hearts (Card 12)
9 of Clubs (Card 16)
** Person 2 **
6 of Hearts (Card 1)
8 of Diamonds (Card 5)
9 of Spades (Card 9)
Jack of Hearts (Card 13)
Jack of Diamonds (Card 17)
** Person 3 **
Queen of Clubs (Card 2)
Ace of Diamonds (Card 6)
King of Hearts (Card 10)
8 of Clubs (Card 14)
5 of Spades (Card 18)
** Person 4 **
10 of Spades (Card 3)
10 of Clubs (Card 7)
Jack of Spades (Card 11)
10 of Diamonds (Card 15)
Ace of Clubs (Card 19)

Modus Tollens
  • 5,083
  • 3
  • 38
  • 46
  • 1
    Oh go-..it was that simple? God damn it. Thank you! Thank you all for the help, it has been very helpful! – J.Doe Jan 04 '17 at 16:03
1
for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 5; j++)
    System.out.println(deck[i])
}

Here you loop on the same card deck[i] since j is not considered. Besides, even if you considered j, it would not solve your problem since your embedded loop always starts with index j=0 as initialization when the outer loop iterates.
You should start the second loop from the index from the last card dealed.

Your loop should take into consideration first the number of players and then the number of cards to deal at each player.
So I propose you two loops : one and another one embedded.

I propose to you to declare the number of players and the number of cards in constants rather than hard coded them in order to have a more readable code.
If later these data may vary, you could replace constants by variables from method parameters for example.

public class Deck {
      ...
    private static final int NB_PLAYER = 4;
    private static final int NB_CARD_BY_PLAYER = 5;
      ...
    int playerNumber = 1;
    // you loop as much as the number of players
    // your increment step is the number of cards to deal by player
    // your end condition is the number of cards you have to
    // deal for all players
    for (int i = 0; i < NB_PLAYER * NB_CARD_BY_PLAYER; i = i + NB_CARD_BY_PLAYER) {

        System.out.println("player " + playerNumber + ", cards =");
        // you loop as much as the number of cards to deal by player
        // your start from the last dealed card 
        // your increment step is 1 as you want to deal card by card from the deck
        // your end condition is the number of cards to deal by player
        for (int j = i; j < i+NB_CARD_BY_PLAYER; j++) {
            System.out.println(deck[j]);
        }
        playerNumber++;
    }
 }
davidxxx
  • 125,838
  • 23
  • 214
  • 215
0

Change the last loop to this:

for (int i = 0; i < n; i++) {
    System.out.println(deck[i]);
}
hashmap
  • 400
  • 1
  • 9
-1

Your for loop is set up to deal each player the same card 5 times (i never changes as j does). Try this:

for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 5; j++)
    System.out.println(deck[j * 5 + i])
mln
  • 41
  • 4