Imagine we want to program a card game. We will need the ability to simulate a deck of cards and select a hand of cards for the player. If we store the deck as a list:
["Ace", "2", "3", …]
we can think of the start of the list as the “top” of the deck and the end of the list as the “bottom”. Dealing a player cards could be as simple as slicing the deck - make one slice that has the first 5 cards, that is the player’s hand, and a second slice with everything else that is the leftover cards.
To reduce the complexity, we will only deal with a deck with 13 cards. However, we will write the code so that it could work for any size deck. A good practice when problem solving is to whenever possible, solve a smaller version of the problem before scaling up to tackle the full version.
Subsection 28.5.2 Shuffle By Move To Back
The second algorithm we will try will be to pick one card at random from the deck (other than the last card) and move it to the end of the deck. On its own, that won’t do much, but maybe if we repeat it a bunch of times, it will work.
The exercises below will guide you through writing the algorithm.
Checkpoint 28.5.5.
The starter code makes selectIndex
and sets it to a random value between 0 and 2 less than the length of the deck. (Since the last card is length - 1 and we do not want to select it).
Copy the card at that location of
selectIndex
to a variable
removed
. Then use the
.pop(XXX)
function to remove that item from the
deck
. Here is the section on
Adding and Removing Items if you need to review.
Print removed
and deck
. Make sure the card you “removed” is no longer in the deck. At this point the first 3 tests should pass.
Append the removed card to the end of the deck. Print the deck and verify that one random card was moved to the end. At this point the last test should pass.
The checks for this program can’t verify it works because it is doing something random. They will just make sure you have some of the basic elements that are needed. Make sure to test your program until you are sure it is working. The checks do depend on you using the specified variable names in your code.
Now we will repeat the process. Since we are only moving one card at a time, doing 10 repetitions probably won’t be enough. But let’s start with that and see if the method looks like it is working before we scale it up to more repetitions.
Checkpoint 28.5.6.
Put your existing code in the loop below that repeats the whole process 10 times.
Checkpoint 28.5.7.
How does this new method seem to work?
Poorly. Items seem to drift back to their initial positions after being moved.
Things should be more jumbled up than that.
OK. But there are still really long runs of consecutive cards (like 2-6 all in order).
It is possible that you saw this, but only if you got unlucky. Try running the program again.
Well.
This is pretty effective, though it would help to repeat the process more than 10 times.
If we really wanted to prove which method was the better way to shuffle we would need to create a measurement of randomness and then test how “random” the results of the different algorithms are. We might also need to do this to figure out the optimum number of repetitions for any particular algorithm. But the “eye test” is good enough to identify that our second algorithm is superior.