August 03, 2005
Continuing the story of Anthony's Guess-A-Number game. This was my six-year-old son's first try at programming a game together with me. You would play the little python program by trying to guess a random number fom 1 to 100. And most importantly, the opponent was a Very Scary Vampire.
I was surprised that Anthony was so enthusiastic about programming such a simple game. In 2005, we are decades beyond a time when Zork was the coolest game ever - today's run-of-the-mill free online Flash game "La Casa de Dora" for 3-year-olds is an animated multimedia extravaganza.
But Anthony was psyched. He had a lot of ideas on how to make his Guess A Number Vampire into a worthy opponent, and they were easy to program in python. The vampire would just give you just five guesses. If you did not get it in five, you would lose. And when you were about to run out of guesses, the vampire would taunt you.
Let us take a look at his program....
This is what Anthony's program looked like when it was finally "finished." At least, this is when I thought it was finished.
#!/usr/bin/env python import time import random secret_number = random.randint(1, 100) print "HAAARG! I've got the secret" print "it's a number. 1-100" guesses_left = 5 time.sleep(2) print "GUESS!" while guesses_left != 0: guess = input() if guess == secret_number: print "you win!" break if guess > secret_number: print "(TOO BIG!)" else : print "(too small!)" guesses_left -= 1 if guesses_left == 0: print "I WIN!" print secret_number elif guesses_left == 1: print "LAST GUESS!" else: print "GUESS AGAIN!"
You can see that Anthony was able to understand all the basic programming concepts: variables, branches, loops. It seemed to come pretty naturally. Key enablers like importing and using a library were so easy in python that a six-year old could use it all without any trouble. Even the idosyncratic python syntax with indenting and the colons seemed okay.
There were only a couple mysteries, like the spelling of the strange word "elif". And there was the mixup between assignment "=" and equality "==". My son's intuition was that "=" should be used to test equality, and assignment shouldn't have any symbol at all. But at six, you are a sponge. He learned the actual syntax of Python quickly enough.
The game was very nicely balanced, beating you most of the time but letting you win quite often.
Here is a transcript of me battling it out with the vampire:
>./GuessANumber.py HAAARG! I've got the secret it's a number. 1-100 GUESS! 50 (TOO BIG!) GUESS AGAIN! 25 (TOO BIG!) GUESS AGAIN! 12 (too small!) GUESS AGAIN! 19 (TOO BIG!) LAST GUESS! 16 (too small!) I WIN! 18 >
Anthony would shout out along with the terminal printout "LAST GUESS!" whenever the Vampire was about to defeat me.
One secret to a great game is having fun when you win or lose.
What Games Do in 2005
"I love my game!" Anthony said, "But, the vampire needs to say, 'Laaaast guuuesssss!'" He said the words using his best, most mocking sing-song nyah-nyah you-are-going-to-lose schoolyard voice.
"Sure, Anthony, it already does." And he used all capital letters, too. What a great game.
"No, Dad. I mean, the vampire has got to say it, you know? I mean SAY it, so that you can hear it! Laaaast guuuessssss!"
Anthony was brought up in a world with Reader Rabbit, Talking Battleship and Nick Jr. Flash Games. Talking is a multimedia game feature that he took for granted. Of course the game should talk! What game doesn't?
But I had no idea how to make a python game talk. I did not even know if it would be possible.
"Let's look at it tomorrow, Anthony. The game is great right now. It is time to go to bed."
Pygame, Audacity, and The Secret to Being a Dad in 2005
6AM the next morning Anthony ran into my bedroom and shook me awake. There was only one thing on his mind.
"Can we make sounds for the vampire now?"
Have you noticed that Google can transform you from an Ordinary Witless Dope into the World's Best Dad? It happens all the time. Yesterday my kids asked me [how you fold a paper fortune teller] and I had no idea. All the elementary school girls had played with them growing up, but I had never made one. No matter, because, of course, Google pointed me to a website that shows how, so that meant I could show them. And soon our house filled up with wonderful little folded paper fortune tellers, all crayoned up with fortunes for every future possibility a child could imagine.
And overnight that previous evening Google had taught me how to make python talk. Here is what I found:
1. [sound in python games] brought me to pygame.org, a wonderful python game library by Pete Shinners that is layered on top of the SDL libraries by Sam Latinga. I soon learned how to use pygame.mixer.Sound to play WAV files.
2. [free sound recording on OS X] brought me straight to Audacity, a GPL sound recorder for Mac and Linux made freely available by Dominic Mazzoni and Vaughan Johnson and many other contributing programmers.
Pygame is easy to install on stock OS X, thanks to Bob Ippolito's pymac packages. If you are following along on your mac, you will want to install both pygame and pyObjC. Later I needed Numeric and py2app as well.
The open-source world is just great. Everything worked as advertised. So after running a couple simple tests I went to bed too, ready for the next morning.
Listening to Anthony's Inner Vampire
Here is what we did in the morning. Anthony and I counted the eight different prompts that would need voice clips - "too big," "too small," "i win," and so on. And then, using Audacity, we recorded Anthony reading each of the clips in his best vampire voice.
Here is an example - Anthony says Haaarg:
Anthony enjoyed recording the sound, but he was not happy with the playback.
"It sounds like a boy! It is not scary at all!" He was ready to give up. "Can you make the Vampire, Dad? You can sound like a vampire!" Of course, that would be no fun. It was Anthony's game, and it should be an Anthony vampire.
Audacity saved the day. The free program comes with dozens of great audio effects, and one of them was perfectly suited to what we needed: change pitch. To make a vampire, we just dropped Anthony's recording by a whole octave.
Meet our scary opponent - The Guess-A-Number Vampire:
Anthony was delighted. "That's me, that's my voice" he explained to his little sister who had come running when she heard the vampire.
Once we had the sounds recorded, we loaded them into the program and played them at the right spots. I typed in a few of the sounds, and Anthony followed the template. I am not sure if he understood what was going on - although the code was simple enough, we also had to insert time delays. It was important to wait for a sound to finish playing before starting the next sound.
But the beauty of it was it was simple. There was just not that much more code to write.
Here is the fully audio-enabled version of Anthony's vampire:
#!/usr/bin/env python import random import time import pygame pygame.mixer.init() intro_sound = pygame.mixer.Sound("intro.wav") guess_sound = pygame.mixer.Sound("guess.wav") you_win_sound = pygame.mixer.Sound("you_win.wav") big_sound = pygame.mixer.Sound("big.wav") small_sound = pygame.mixer.Sound("small.wav") i_win_sound = pygame.mixer.Sound("i_win.wav") last_guess_sound = pygame.mixer.Sound("last_guess.wav") guess_again_sound = pygame.mixer.Sound("guess_again.wav") secret_number = random.randint(1, 100) intro_sound.play() print "HARRRG! I've got the secret" print "it's a number. 1-100" guesses_left = 5 time.sleep(7) guess_sound.play() print "GUESS!" while guesses_left != 0: guess = input() if guess == secret_number: you_win_sound.play() print "you win!" time.sleep(5) break if guess > secret_number: big_sound.play() print "(TOO BIG!)" else : small_sound.play() print "(too small!)" time.sleep(2) guesses_left -= 1 if guesses_left == 0: i_win_sound.play() print "I WIN!" print secret_number time.sleep(5) elif guesses_left == 1: last_guess_sound.play() print "LAST GUESS!" else: guess_again_sound.play() print "GUESS AGAIN!"
At this point, the game was genuinely entertaining! The kids all wanted a turn playing, and I did too. Anthony was right. The sounds made a huge difference.
This is when I decided to write a few weblog entires about it.
The game was still not good enough for Anthony, however, because he wanted to see his vampire too. It took a couple weeks before we got back to the project, but with the help of some cutting and pasting, we finally finished it up.
I will write a bit more about it next time. We should have a download for you next time, too.Posted by David at August 3, 2005 07:40 PM
|Copyright 2005 © David Bau. All Rights Reserved.|