0

I know there are multiple ways of writing code for this type of question, but I'm trying to understand my Professor's way. He wrote a method that takes the value of an integer in an array and assigns it the value of another random integer in the array, i.e "shuffling a deck":

static void shuffle(int[ ] deck) {
//Randomize the order of the elements of deck
//Pick a random card to go in position 0, then position 1, etc.
for(int cardNum=0; cardNum<DECK_SIZE-1; cardNum++){
  //pick a random value randomCardNum from cardNum...DECK_SIZE-1
  int randomCardNum = cardNum+(int)(Math.random()*(DECK_SIZE-cardNum));
  //Swap card and randomCard
  .....

What I can't understand is why he would have the for loop go until DECK_SIZE - 1. There are 52 cards, and I know that an array's last index is n-1, but the last cardNum is already not inclusive, so it's going from 0 to 50. I tried taking the -1 out, I get 52 random cards either way.

I'm not sure if it has to do with int randomCardNum, but this seems right as the equation for randomizing numbers in a specific range is :

Min + (int)(Math.random() + (Max-Min))

kris
  • 375
  • 2
  • 12
  • possible duplicate of [Random shuffling of an array](http://stackoverflow.com/questions/1519736/random-shuffling-of-an-array) – Marv Dec 15 '14 at 17:04
  • See the code again, you might be using array as well and a reason for for loop. – SMA Dec 15 '14 at 17:05

2 Answers2

2

Your best bet is to ask your professor, but note that if cardNum could go all the way to 51 (the last index), then this line:

int randomCardNum = cardNum+(int)(Math.random()*(DECK_SIZE-cardNum));

...is guaranteed to result in a 51 in randomCardNum on the last iteration, because DECK_SIZE-cardNum will be 1, and so multiplying it by Math.random() will give you a value less than 1, and so casting that value to int will result in 0, and of course cardNum+0 is cardnum.

Since cardNum and randomCardNum would both be 51 on that last iteration, and there's no point in swapping a card with itself, he stopped one iteration early.


My question would have been: Why use DECK_SIZE rather than deck.length, since it introduces a possible maintenance error (changing the size of deck but not remembering to change the constant).

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Nice answer, +1. However, he wouldn't change the size of the deck as he is referring to a standard playing card deck, which has 52 cards in it no matter what. Therefor, he wouldn't change the size of the deck. – mirvine Dec 15 '14 at 17:10
  • 1
    @itrollin98: There are all kinds of standard decks. 52 is a common one, but it's not *by far* the only possibility. There's piquet (36 cards), tarot (78; yes, there are tarot games, it's not just for reading the future), canasta (108), ... Of course, `deck` is probably declared somewhere as `int deck[DECK_SIZE];`, so... :-) – T.J. Crowder Dec 15 '14 at 17:12
  • @Crowder however, if you read his entire question you will see this: "There are 52 cards, and I know..." – mirvine Dec 15 '14 at 17:14
  • @itrollin98: "There are" as in "right now." Always assume requirements will change. – T.J. Crowder Dec 15 '14 at 17:15
  • @Crowder Seeing that this is a class, I would say that they made DECK_SIZE to prevent mistyping or getting confused with `.length` (array) and `.length()` (List). – mirvine Dec 15 '14 at 17:19
  • @itrollin98: And seeing this is a class, I think teaching good practices is important, hence bringing it up in the first place. This is all massively by-the-bye, though. – T.J. Crowder Dec 15 '14 at 17:21
0

Your professor's code is correct. Look at the random call:

int randomCardNum = cardNum+(int)(Math.random()*(DECK_SIZE-cardNum));

When cardNum starts at 0, it chooses one of 52 cards, puts that random one at position 0. Next time through the loop it chooses one of the 51 remaining and puts it next. Then it chooses one of 50 remaining and puts it next, etc. The last time through the loop there are two cards remaining, it chooses one to be first, and then we're done. You add another iteration to the loop it just selects one of the remaining one card, and places it where it already is, to no effect whatsoever.

Lee Daniel Crocker
  • 12,927
  • 3
  • 29
  • 55
  • Yes, of course. So if I had just put: int randomCardNum = cardNum+(int)(Math.random()*(DECK_SIZE-cardNum + 1)), I wouldn't have had to add the minus one in the for loop would I? – kris Dec 15 '14 at 17:17
  • That would make the code wrong. A proper shuffle HAS to have exactly the sequence of choose one of 52, then one of 51, etc. Any other sequence at all will result in a shuffle that favors some final orderings of cards over others. – Lee Daniel Crocker Dec 15 '14 at 17:25