1

I know, I know - there are hundreds of people on here asking how to shuffle and array 52 card objects in Java and I thought it would be simple enough. I've not used collections (based on advice on stack). I've tried the Fisher-Yates shuffle but I'm seeing what looks like really odd behaviour... Can anyone help?

I based my solution on this answer: Random shuffling of an array

And it works great... for numbers. This Class has two arrays, one containing the numbers from 0 to 51 and the other containing 52 Card objects with various instance variables like suit and number.

This code works flawlessly:

public void shuffleNums()
   {
       Random rnd = new Random();
       for (int i = this.numbers.length -1; i > 0; i--)
       {
          int index = rnd.nextInt(i + 1);
          // Simple swap
          int temp = this.numbers[index];
          this.numbers[index] = this.numbers[i];
          this.numbers[i] = temp;

       }
   }

But when I try to use the same approach on a deck of 52 Card objects, like this:

public void shuffleCards()
   {
       Random rnd = new Random();
       for (int i = this.cards.length - 1; i > 0; i--)
       {
          int index = rnd.nextInt(i + 1);
          // Simple swap
          Card temp = this.cards[index];
          this.cards[index] = this.cards[i];
          this.cards[i] = temp;

       }
   }

It doesn't work so nice. Most of the cards are shuffled successfully but apparently I've dropped half the deck because now the array has about 16 NULL values and only about 36 random cards. The NULLs seem to be randomly distributed throughout the array.

I could easily work around this but I want to understand why this is happening. Can anyone help me work out what's going on?

EDIT: Regarding how I initialised the array - I had checked that the array did in fact have 52 Card objects listed from 2 of clubs up to Ace of spades. Before executing shuffle() the array correctly contained 52 card objects. Afterwards it contained roughly 36 - give or take.

Community
  • 1
  • 1
Alex Yates
  • 436
  • 2
  • 9
  • 1
    Since your code is the same, it seems like what might be different is the initial state of the `cards` array. Could you post the code that initializes this array's `Card` values? – Dan Getz Jan 17 '15 at 19:24
  • 2
    `(4-1) * (13-1)` just happens to be 36...could you have off-by-one errors in that code? – Dan Getz Jan 17 '15 at 19:30
  • I'm afraid it wasn't an initialisation thing and I'm also afraid that it wasn't consistently 36 cards remaining. :-( I'm afraid I can't show you the code I used to initialise the array as I have editted it and the IDE that my uni want me to use doesn't have any straightforward source control integration. (I know!) However, it basically created 52 new card objects and looped through the numbers 1 to 13 and used a suit depending on whether the number was in the first block of thirteen or the second etc. – Alex Yates Jan 18 '15 at 11:12
  • Well, like I said, what you've posted doesn't show any possible mistake. Try creating a short example that can be run to demonstrate the problem, and then post it. If you succeed in demonstrating the problem, someone here will probably be able to find the reason. If your example doesn't demonstrate the problem... then you have written an example of correct code to use in your program. Win-win. Or did your last comment mean that you've already fixed it? – Dan Getz Jan 18 '15 at 14:01
  • Well, I've tried to recreate it but I can't. And now it seems to work. Sorry for wasting everyones' time. :( – Alex Yates Jan 20 '15 at 19:04

1 Answers1

1

It might be a problem with you initialized cards.

If you do

int[] cards = new int[52];

All inside the int array will be set 0 which means you can perform operations on it

However if you do

Card[] cards = new Card[52];

These are all set to null so if you to perform an operation on one of these cards, you get a null pointer exception. This may explain why you're getting all those null values.

committedandroider
  • 8,711
  • 14
  • 71
  • 126