Introduction to Computer Science
Union College
Spring 2009

Homework Week 7 - due Friday, May 22, before class

This homework is due on Friday instead of Wednesday because we are having our midterm exam on Wednesday. Nevertheless, get started early, that is, before the midterm exam. The homework exercises using lists and reading and writing files - things that are relevant for the exam.

The goal of this homework is to maintain a file of high scores. Whenever a new game is started the player is asked for his/her name. When the game is over, this players score is compared to the list of high scores read from a file. If the current score is greater than the smallest score in that file, the current score is either added to the file (if the file contains fewer than five high scores) or the smallest score is replaced by the current score.

Reading in the high score file

Here is the hiscores file to start from.

In a separate file (not a pygame program to make it easier to debug), write a function to read in and process the file. This function should take string parameter, which is the name of the file to be read. It should return a list of lists, where each of the inner lists has length 2 and just consists of a person's name and his/her score.

For example, when reading in the file give above, this function should return the following list:

[['Tom', 5], ['Dave', 15], ['Jane', 25], ['Abi', 18]]
Note that the names are strings and the scores are integers.

This is similar for what you had to do to read in the map file.

Find the index of the smallest score

In a separate file (not a pygame program to make it easier to debug), write a function that takes a list of the format produced by the previous step as parameter and returns that index of the entry with the lowest score.

For example, when given the list

[['Tom', 5], ['Dave', 15], ['Jane', 25], ['Abi', 18]]
the function should return 0, because that is the index of the entry ['Tom', 5], which has the lowest score.

When when given the list

[['Dave', 15], ['Jane', 25], ['Tom', 5], ['Abi', 18]]
the function should return 2.

Draw all scores onto the screen

Now, download the following pygame program: high_score_v0.py. And play it. You also need the following image and sound files: red_balloon.gif, green_balloon.gif, pop.wav.

This game is a variant of the pop-the-balloon game that we did a few weeks ago. You get points for popping the red balloon; you die if you miss the red balloon. When you first run the game, it asks you to input your name in the python shell. That is not the nicest way of getting the player's name, but it is the easiest and uses only code that you already know. Note how the name is used in the good bye message.

Add the first function you wrote (the one that reads in the high scores from a file and returns a list) to your program. Call this function before the game loop starts and assign the return value (i.e., the list of player name-score pairs) to a name.

Again, this is similar to what you needed to do for reading in the map file.

Now, draw all of the high scores on the screen in addition to the line that shows the current score. So, your window should look something like this when you are done:

Update the list of high scores

Now add the second function you wrote (the one that finds the index of the smallest score) to your program.

If the player clicks next to the balloon and dies, update the list of high scores if necessary.

That means, if the player misses the balloon (that condition is already there in the part of the code that handles events), check whether the list of high scores is shorter than five elements. If so, add a new element which has the name of the current player and his current score. If the list of high scores is longer than five or of length exactly five, find the index of the smallest score in the list. If that player's current score is greater than that score, replace that entry with a new entry that has the name and score of the current player.

For example, if the list of high scores is

[['Dave', 15], ['Jane', 25], ['Tom', 5], ['Abi', 18]]
when the current player dies (i.e., the length of the list is four), add that player's name and score to the list:
[['Dave', 15], ['Jane', 25], ['Tom', 5], ['Abi', 18], ['Kay', 6]]
If the list of high scores is
[['Dave', 15], ['Jane', 25], ['Tom', 5], ['Abi', 18], ['Kay', 6]]]
when the current player ('Kate') dies and the current player's score is 3, the list doesn't change because the smallest score in the list is greater than the current player's score. However, if the current player's score is 7, the list gets updated to
[['Dave', 15], ['Jane', 25], ['Kate', 7], ['Abi', 18], ['Kay', 6]]]
That is, the entry with the lowest score gets replaced with the current player's information.

Write the updated list back to the file of high scores

Finally, after updating the list of high scores, write the list back to the file.

For this, write a function that takes a string (the file name) and a list of name-score pairs as parameters and writes one line to the file for each pair. The format of the file should be like the original format of the high scores file.

For example, if the list of high scores is

[['Dave', 15], ['Jane', 25], ['Kate', 7], ['Abi', 18], ['Kay', 6]]]
the resulting file should look like this:
Dave:15
Jane:25
Kate:7
Abi:18
Kay:6

by Kristina Striegnitz