This Piper STEAM Project was contributed by Matthew Matz.
The Hour of Code is finally here! We are so excited to be joining millions of students and teachers in a worldwide movement to demystify STEAM and computer science for all!
Now, let's rock into Computer Science Education Week with a brand new PiperCode STEAM Project!
You may have played a game like Rock Band, Guitar Hero, or Dance Dance Revolution where a combination of buttons would appear, and to score points, you have to press the buttons shown (and not press the buttons that aren’t shown).
In this project, we will be creating our own version of that game. Instead of arrows, we’ll display which buttons should be pressed using 1’s or 0’s - so we’ll call this game Binary Hero!
Connect the Buttons
To make the game work, we need to connect all of our pushbuttons to the Raspberry Pi.
Get your parts ready - here’s what we’ll need:
Next, set up the keyboard by placing the buttons on the breadboard like so:
Now, it’s time to wire up the buttons.
Wire the buttons according to the pictures and the pin table below.
Next, wire up the buttons between the breadboard and Raspberry Pi as shown here.
Once everything is connected, open a new Piper Code project.
To find the correct GPIO pins, we can use the electronics tab in PiperCode. On that diagram, ground pins are outlined in black and multipurpose pins in grey. Their pin numbers are also shown.
**Note: The Raspberry Pi may turn off if a short circuit occurs between its ground and high-voltage GPIO pin to avoid head damage.
We can use the electronics tab to verify that the pins are hooked up correctly - when we press one of the buttons, the pin’s grey outline should turn green.
Even though we connected all 5 buttons, the game will only use the first 4. You can use the fifth button to add your own cool features to the game like changing the sounds or resetting the score.
Generating the random 1’s and 0’s
To make this game work, we will build some functions. Functions are smaller pieces of code that can be called, and when they are called they usually return a value. We want to build a function that returns a 4-digit binary (1’s and 0’s) number. A 4-digit binary number has a special name called a “nibble”.
First, grab a create text with block and drag it out into the workspace (1). Since we want our number to have 4 digits, we’ll need to “mutate” the block by clicking the blue gear icon on the block (2). Finally, drag an item block into the join block in the small window that popped up. Do this again to give the create text with block a total of 4 inputs (3). Click the blue gear icon again to close the small window.
From the Logic menu, grab a random number block (1) and connect it to the first input of the create text with block (2). Then, change the random numbers so that it chooses from 0 to 1. Finally, right-click the block and select “Duplicate” (3):
Use the Duplicate option to make a total of 4 random number from blocks and make sure each one is connected to the inputs of the create text with block.
We can use the shout block to test out our new “nibble generator”. Grab a shout block from the Chip menu (1), and connect it to the create test with block (2). Click the start button (3). You should see a random 4-digit binary number appear in the middle of the screen (4). Keep clicking start to see the number change randomly.
Disconnect the create text with block from the shout block, and delete the shout block by dragging it to the trash can or by right-clicking it and selecting “Delete”.
Next, open the Functions menu (1), drag the define function with return block out (2) and connect it to the create text with block:
Once it’s connected, click the words “do something” and replace them with “make nibble”:
Turning Button Presses into 1’s and 0’s
The next piece of the game we need to build is the part that turns button presses into 1’s and 0’s. We’ll need to check each button, and if it is on, turn the press into a “1”, and if it’s off, turn it into a “0”. To do this, we’ll need a function for each button that returns the 1 or 0.
Grab the two blocks shown from the Functions menu and drag them into the workspace:
Place the if __ return __ block inside of the define a function with a return block. Grab a pin __ is ON block from the Chip menu, place it in the if __ return __ block, and set it to Pin 40 (1). Grab two number blocks from the Variables menu and place them as shown below (2). Finally, rename the function to “check pin 40” (3):
Make 3 more of these blocks for pins 29, 19, and 13. Don’t forget to set the correct pin numbers and name the functions to match the pins:
Grab a create text with block from the Variables menu, and drag it into the workspace. Click the blue gear icon, and mutate the block so that it has 4 inputs. Then, grab the “check pin 40”, “check pin 29”, “check pin 19”, and “check pin 13” blocks from the Functions menu, and connect them to the create text with block as shown:
Grab a repeat forever block from the Loops menu and a shout block from the Chip menu, and connect them to the create text with block as shown. Click Start and test each of the buttons to make sure they are generating 1’s and 0’s correctly:
Putting the Pieces Together
Now that we are able to create a random nibble and also a nibble from our buttons, we need to store each of them into variables. Open the Variables menu, click the “create a variable” button. Name your new variable “buttons”. Create another variable called “sequence”.
Next, disconnect the create text with block from the shout block. Add a set __ to block from the Variables menu to the beginning of the repeat loop. Connect a “sequence” variable block to the shout block. Then, add a wait __ ms block, and, finally, add a set __ to block, and connect the create text with block to it. Set the wait block to 500 ms, and set the variable blocks as shown:
There are only a couple more things we need to do to make a playable game!
Grab an if __ else __ block from the Logic menu and add it below the set buttons to block inside of the repeat loop. Then, connect a __ = __ block to the if __ else __ block.
We are doing this to compare and see if the buttons and the random nibble (sequence) are the same. If they are, then the player pressed the buttons correctly, and we should make the Piper kit play a happy sound like a clap or snare drum. If they don’t match, then we’ll have the Piper kit play a low sound like a kick drum.
Grab the Play and synth blocks from the Sound menu and add them as shown:
Now, click the Start button to try it out. Try to match your key presses to the 1’s shown on the screen. Remember, you are only using the first 4 buttons.
You can make it a bit easier by increasing the time in the wait block to 1000 or 1500 ms.
Keeping Track of Your Score
It’s fun to play our new game - now let’s keep track of our score. To do this, we need two variables: one that keeps track of how many rounds there have been, and a second to keep track of how many attempts the player got correct.
Open the Variables menu, and click the “create a variable” button. Make a new variable named “score”. Click the variable again and make another variable named “round”.
Add two set ____ to blocks from the Variables menu to the beginning of your program. Use them to set the “round” and “score” variables to zero at the beginning of your program (1). Keeping track of how many rounds have been played is easy - just use a change ___ by block to add 1 to the variable “round” each time the program loops (2). Keeping track of the score is easy, too - just use a change ___ by block to add 1 to the variable “score” each time the player gets a button combo correct (3).
Finally - we can print out the round and the score in the console. Grab a create text with block from the Variables menu. Mutate the block so that it has four inputs. We will use it to make a single line of text that shows both what round we are on and what the score is. To do that, we need two “__” blocks, and the score and round blocks from the Variables menu.
In the first “__” block, type in round and add a space.
Then connect the round variable block.
In the next “__” block, type in a comma, a space, and then the word score.
In the last input, connect the score variable block.
Finally, grab a print block from the Chip menu and connect it.
Place this new block combination right after the wait 500 ms block inside of the loop forever block.
Open the console by clicking on the console tab at the bottom of the screen. Then, click the Start button to play the game again to see how high you can score.
How could you use the score and rounds variables to show what percentage of tries the player got correct instead of just the score?
When we described the game at the beginning of this project, we mentioned that you see the combos that are coming - but our game doesn’t do that...yet.
If we want to see what combinations are coming, we’ll need to store a set of combinations in a list. We can then grab items from the list or put items into the list.
Let’s start simple by making a list that holds two nibbles. When we make a new nibble, we’ll put it at the beginning of the list, and when we are ready to use a nibble, we’ll grab it from the end of the list. When we display the list, we can see which buttons we need to push now and which ones are coming next.
It’s also important that before our game starts, the list is filled with 2 nibbles.
The blocks you’ll need to add to or change in your program to make this work are shown here:
How could you add a display for two upcoming combos instead of just one?