CS 105 - Understanding Our Algorithmic World

CS 105 - Exercise Twelve

Goals

  • Write a simple simulation
  • Experiment with some simple statistics
  • Learn about cloning

Prerequisite

For this exercise, I am providing you with starter code, which adds some relevant costumes to our sprite. Open the starter code and then save it to make your own version.

Objective

In this exercise, you are going to simulate coin flipping. As you will see in the starter code, I have provided you with two costumes representing the two sides of a coin.

Flipping the coin

We will start by making a block that flips the coin: flip block.

"Flipping" the coin basically means picking between two equally possible options and calling one outcome "heads" and the other "tails". We will start very simply by using pick random block and setting the inputs to 0 and 1. If you click this block, you should see that about half the time it reports 0, the rest of the time it is 1.

To show the flip, we can change the costume with switch costume.

Combine these blocks with if-else block and equality block so that a different costume is chosen based on the random number.

Test out your block. When you flip the coin, sometimes it will be heads, sometimes it will be tails.

Improving the "flip"

While our flip simulation works, it isn't very satisfying. Many times it doesn't look like the coin flips at all. We are going to improve it with some animation.

Using repeat block and wait block, Make a loop that switches to heads, waits 0.05 seconds, switches to tails, and then waits 0.05 seconds again. Do this 5 times. This creates a strobe effect where the coin flashes back and forth between the two faces.

Add this before your "if" block in your flip block, so the coin flickers and then makes a selection.

Collect data

If we are going to look at the statistics, we need some way to keep track of when the coin has been flipped and when it came up heads.

Add two new variables flips and heads (these should not be script variables). Make these 'Sprite only'.

Edit your flip block to update these two variables after a flip using change by block.

The flips variable should change every time.

To check if you should update the heads variable, you can use of block. Set the right hand input to 'Sprite', and then you can select 'costume name' from the left hand input. If the costume name is 'heads', then update the heads variable.

Show the two variables on the stage (if they aren't already there), and flip the coin a bunch of times and make sure that they update.

Put a flip block in a forever block and let it run for a while. You should see that comes up heads about 50% of the time. An interesting thing about this process is that it will take a fairly large number of flips before the odds really start equally out (in my tests, I had to get more than 50 flips before they balanced). This tells you something about how our perceptions work in the moment. If you just flipped a coin a couple of times you would see what appeared to be a bias in the coin (in truth, coins are biased -- most are not cast to have even mass on both sides, but the difference tends to be minor on most coins).

Multiple coins

If our intuition isn't great with a single coin, it gets even worse with multiple coins. So, let's run some experiments with multiple coins. In particular, we will look at how probabilities combine. Given N coins, what is the probability that all of them will come up heads?

But how do we get multiple coins?

Cloning

Snap! has a trick that we haven't made use of yet called "cloning". In essence, it allows you to make independent copies of your sprite.

Find the create clone block. Set the input to 'myself' and try clicking it. It will appear that nothing has happened, but if you drag your clone in the stage, you will see there is a second coin underneath.

Interacting wth clones

There are a couple of different ways to interact with clones. They do not run any of the steps in the script that created them. However, they will respond to any of the events like clicks or key presses. A notable exception to this, however, is the stop button and the the green flag button, which will clear the clones.

Another way is to send the clones messages. In the Control palette, you will find there are a collection of blocks concerned with sending, broadcasting and receiving messages. Messages can be targeted to a particular sprite (sent) or they can be broadcast to everyone.

Create the clones

Pull out a green flag hat block.

Under it, move the sprite to (-200, 0). Then use repeat to create three clones. After each, change the X position by 75. This should give you a row of four coins.

It is going to be easier for us to just deal with the clones and ignore the original, so add a hide block at the end of the script. Of course, to make the code repeatable, we need a show block at the beginning of the script.

Now, when you run the script you should get three coins in a row.

Flip the coins

To flip the coins, we will broadcast a signal. Pull out the broadcast and wait block. Click on the input and select 'new' from the menu. This allows us to create our own signals. Type 'flip' in the dialog box that comes up. This block will now send out the signal "flip" and wait until any receivers have received the message and performed whatever action is associated with it.

To make the sprites receive the message, we need a received hat block. Pull it out, and set the input to 'flip'. Attach a flip block to it.

Click on the broadcast and wait block block, and all of the clones should flip.

Collect statistics

Our goal is to figure out the frequency with which all of the coins come up heads experimentally. In order to do that, we need to figure out if the clones have come up heads. We will build up to this one block at a time.

Our starting place is the my block, which gives us access to the sprite's attributes. Click the input and select 'clones'. If you click on the block now, it will give you a list of all of the clones.

Of course, we want the current costume of the clones, not the clones themselves. We will do this the same way we did before. Find the of block. Set the first input to 'costume name'. Then, use the item of block to get the first item of the list of clones and set that as the second argument. Note, you must set the inputs in this order. Snap! isn't bright enough to realize that you have a clone, and won't give you the option to select 'costume name' after you have set the right hand input.

If you click this, it should come up with the name of the clone's current costume. Make sure it does before moving on.

We want the total number of heads. There are a couple of ways to do that, but we will use one of our higher order blocks. Pull out the keep block. Recall that this block is essentially a filter. We pass it a predicate and it reports all items in the list for which the predicate was true. Remove the item of block from the of block, leaving the right input blank. Add the equals block to test of the costume is 'heads'. Put this predicate in the keep block, and set the from to the list of clones. It should look like this:

keep the heads

Run the block and make sure it gives you the list the clones that are currently showing heads.

What we really care about is if all of the clones show heads. So, use the equals block to test if the length of this new list is the same as the length of all clones.

Create a new variable called all heads. If all of the clones are heads, change all heads by 1.

Snap this condition under the broadcast and wait block block.

Add a wait block under these blocks that waits for half of a second.

Wrap this all in a repeat block that runs the broadcast and wait block and the tests for three heads 100 times.

Finally, put everything together. Snap the loop on the bottom of the green flag hat block script after the sprite has hidden itself.

At the top of the script, add two blocks to set flips and all heads to 0.

Move the show block to the end of the script so that the original sprite shows up again after the test.

Gather statistics

Run the simulation three times, and write down the number of times you got all heads in each run. Put these three values into a comment. How close are your experimental results to the analytic expectations (if there is a 50% chance of any one coin coming up heads, then there is a .5 X .5 X .5 = .125 or 12.5% chance of all three coming up heads at the same time)?

What I will be looking for

  • There should be a flip block that flips the coins and keeps track the number of flips and the number of heads
  • When the 'flip' signal is sent, any visible coins should flip
  • When the green flag button is clicked, three coins should appear and they should run a trial of 100 flips, keeping track of the number of times all coins show heads
  • The statistics should reset at the start of each run
  • The original sprite should be hidden during the trial, but visible at the end
  • There should be a comment with the results of three experiments

Submitting

Share the project using the instructions from exercise 1.

Visit the exercise page on Canvas to submit the URL.