August 03, 2005

Laaast Guessss...

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....

Last guess!

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!"

Ah hah.

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.

Using pygame.mixer.Sound

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
Comments

Great parenting. As of now, my 23 month old is interested in cars, computers, and anything else electronic. He loves to 'type.' So much so that I let him pound away on an old keyboard with the cable removed.

Your story is an inspiration, and a proves just how much potential kids have if they're just given room to grow.

Can't wait to get the last bit of the story!

Posted by: Devin M at August 4, 2005 10:41 PM

Hi David, what a great story. Your son has quite an attention span. My son wants to make a game on the computer too, a haunted house with a skeleton that falls out of the ceiling. I haven't decided how we'll write that one :) I like the idea of using python.

My kids like to play some of the old BSD games; Rogue, the old dungeon crawling text game, and robot (Daleks).

Posted by: ScottLu at August 5, 2005 04:10 AM

Hi David!

Wow. I'm a bit behind. Your 6 year old knows how to program better than I do. He sounds like an awesome creative little guy. I hope someday I can be as cool a parent as you (with the help of Google of course!).

I'll probably start coding again soon if some changes occur at work, but I'll email you about it some time.

Tell your son, "Nice work!"

Posted by: mapgirl at August 14, 2005 09:39 PM

I'm just a random seo surfing with the last minutes of a friday afternoon, and your blog enties on your son's adventures with python are wonderful! I've really enjoyed reading, and you're doing a fantastic job - i'm so glad there are some kids out there really getting that kind of growth and learning. :)

Posted by: camilla todd at August 26, 2005 12:29 PM

I've found flash to be an excellent platform for easy coding (essentially javascript) and very simple to connect visual and audio assets to an event-based model - may be something to consider for some more in-depth forrays into the multimedia world :)

Posted by: Mike J at October 12, 2005 09:53 AM

I've really enjoyed reading about your adventures in programming with your son. It's a really sweet story. I'm impressed with his sense of adventure and your devotion to providing him a positive experience. Well done. :)

Posted by: Travis Cripps at October 14, 2005 09:45 PM

I am having some trouble with PyObjC (pygame at the Instalation will not acknolige it). If you did too, how did you solve the problem, and if you didn't, which versions of python, pygame and pyobjc did you use and where did you get them from?

Posted by: Alexander Lupas at April 26, 2006 12:16 PM

I don't remember any specific problem. I got my PyObjC package and other python-mac packages from Bob Ippolito's website here:

http://pythonmac.org/packages/

Posted by: David at April 26, 2006 11:03 PM

thank you

Posted by: at April 27, 2006 07:58 AM

So when do you start programming with your daughter?

Posted by: Dorothea at May 26, 2006 10:34 AM

Using Audacity was a great idea. I'm one webmaster for my choir, and I use it all the time to cut sound clips to post on the site. It's very easy to use.

Posted by: Joanna at July 29, 2007 11:00 PM
Post a comment









Remember personal info?