CS21 Lab 10: Classes

Due Sunday, December 3, before midnight


As always, run update21 to create your cs21/labs/10 directory and create your programs for lab 10 in this directory. Since this is a graphics assignment, make use of the Zelle Graphics Documentation.


Overview and Goals

So far in this course we have used many different types of objects (Circles, Points, lists, strings, etc), but we haven't defined our own types. The goal of this lab is to practice writing your own classes (with constructors, instance variables, and methods). In the file aquarium.py, you will create an aquarium of swimming fish, like the videos shown below. In a separate file called fish.py, you will have a Fish class with methods to control the fish behavior. Pick one fish and watch its movement - when it reaches one side of the tank it wraps around and comes back on the other side, continuing to swim in the same pattern indefinitely.

This aquarium is interactive - over time fish will get "sick" (and some fish may start out sick). Your job is to save the fish by clicking on sick fish to make them healthy. If you make all the fish healthy, or if all the fish get sick, the game is over.

Here is an example where sick fish turn red. In this case the user won by saving all the fish:

Enter the number of fish: 30

Here is an example where all the fish got sick:

Enter the number of fish: 30

Here is another example aquarium where the sick fish turn black. This example includes fish bobbing and bubbles (these steps are optional, see below for more details).

Each of the sections below describes a requirement and some suggestions for implementation. One high-level suggestion is to try to mirror existing methods for other graphics objects (.draw(win), etc). Feel free to modify your class, but check with your instructor if you make major modifications.

Fish Class

Your program should contain a Fish class (in a separate fish.py file) with the following:

Here is some example test code to try in the main of the fish.py file:

# create two fish

pt1 = Point(width/4,height/2)
size = width/13
onefish = Fish(pt1,size,"red")
onefish.draw(win)

pt2 = Point(width/2,height/4)
size = width/15
twofish = Fish(pt2,size,"blue")
twofish.draw(win)

Fish Properties

The user should be able to select the number of fish at the beginning of the game (you may assume the user enters a valid input). The fish should be different in at least the following ways:

Fish Movement

Each fish should swim in a "circle" around the tank, wrapping around one side and emerging on the other. This wrapping functionality should be done outside the Fish class, since fish do not know about the window they are swimming in. We recommend making a wrapping function that checks the position of each fish and sees if it needs to be "wrapped".

Setup and Main

In main (in the file aquarium.py), you should create a list of Fish, based on user input. Make sure to import the Fish class. Fish should be located randomly throughout the window. If setting up the fish constructor input becomes a bit long, feel free to move this to another helper function. In main, continue to loop over the fish, moving them one by one. Each time a fish moves, it has a small probability of becoming sick. When it gets sick it should change to a different color (red, black, gray, green, up to you).

To control the speed of the game, you can use time.sleep(seconds) at the beginning of each loop through the fish. Set seconds to whatever looks good to you (0.1, 0.5, etc). To use this functionality, also remember to import time at the top.

A note about RGB color schemes. When creating fish colors, it may be helpful to avoid fish colors that match the "sick" color. For example, if you had a light sick color, you could color the rest of your fish darker colors. When using RGB, higher values mean lighter colors. For example, (255,255,255) is white, and (0,0,0) is black. Or if you had sick fish that were red, you could set the red component for the rest of the fish to be close to 0 to avoid red fish.

Game Play

During the animation loop, the user should be able to click on a fish to make it healthy. Since we want the animation to progress even when the user is not clicking, we'll use the win.checkMouse() function. Unlike win.getMouse(), which pauses the program until the user clicks, win.checkMouse() will allow the program to keep running, and if the user doesn't click, it will return None. So if the user's click is not None, check how close the click point is to each of the fish (similar to Lab 6), and change the color if it is inside the body of the fish (no need to worry about the case when the click is on the tail).

Here is a template for using win.checkMouse():

click = win.checkMouse()
if click != None:
    # do something with the click

If the user makes all the fish healthy, they should win and the game should end. It might be helpful to have a separate function that loops through all the fish and returns True if they are all healthy. On the flip side, if all the fish get sick, the user loses and the game is over. You could have another function that returns True if all the fish are sick. Alternatively, you could have a function for getting the number of sick fish, and then test if that number is 0 vs. the total number of fish.

Top-Down Design

Although you will not be submitting your top-down design (TDD) this week, we strongly encourage you to write your full design first. Design your main() function, classes and methods, and any additional helper functions. Your main() function should be relatively short and easy to read. Implement and test the program one function or method at a time. A good program design and good use of functions is part of the grade.


Extensions

There are many ways to extend this assignment. A few suggestions are below, but feel free to come up with your own extension.

  1. Adding another class - the example below shows a bubble class (similar to the fish class). Bubbles float upwards and wrap around the bottom of the window. The example below does not include game play, but your version should still include that. You could create another type of fish or sea creature.

  2. You could modify the getting sick process to include a contagious element. So if fish comes in contact with a sick fish, that is what makes it sick (as opposed to completely random).

  3. Make the fish (and/or bubble) bob up and down. One hint for this is to use a trig function like sine or cosine.

Enter the number of fish: 40
Enter the number of fish: 20

Answer the Questionnaire

After you have turned in the full program, please edit the QUESTIONS-10.txt file in your cs21/labs/10 directory and answer the questions in that file.


Turning in your labs....

Don't forget to run handin21 to turn in your lab files! You may run handin21 as many times as you want. Each time it will turn in any new work. We recommend running handin21 after you complete significant work on any part of the program.


Idea for this lab: Joe O'Rourke