CS21 Lab 6: Defining Functions

Due before midnight, Saturday October 25

This lab assignment requires you to write a program that uses multiple functions. As always, first run update21. This will create the cs21/labs/06 directory and the starting point program, called balloon.py. The starting point file contains function stubs for all of the functions you'll need to complete for this lab. For now each function that returns a value has been given a dummy value. As you write each function, replace these dummy values with appropriate values.

We have updated the graphics library and the documentation: Documentation for the Graphics Library


Coding with Functions

Our programs are starting to get bigger and resemble applications that you can actually use. However, in order to be able to write large programs effectively, we need to use functions to break up our code into more manageable chunks.

We start with what we'd like you to be able to accomplish for this assignment. Watch the following video. Turn on annotations to see the explanations.

High-level Specifications:

Basically, your job for this assignment is to write the above game. The rules are:

Breaking things up into functions

This looks pretty daunting at a first glance, so we'll break it up into functions. Edit the file balloon.py in your cs21/labs/06 subdirectory. Write the functions in the following order:

Step 1

Write the following functions:

def drawStar(centerPoint, size, color, window)
Accepts:
  • a Point representing the center of the star
  • one int representing the size of the star
  • one string representing the color of the star
  • the window object
This is what you did last week, wrapped up into a function! It draws a star at the specified location.
Returns the newly-drawn star.

def drawAllStars(window, numOfStars)
Accepts:
  • the window object
  • the number of stars to create.
Creates the specified number of stars (hint: call drawStar()) in the window.
Returns a list of the generated stars.

def drawAllBubbles(window, numOfBubbles)
Accepts:
  • the window object
  • the number of bubbles to create.
Creates the needed bubbles.
Returns a list of the generated bubbles.

Now that you have these functions, test them by writing programming statements in main() that creates a window, and draws lots of different numbers of bubbles and stars in the window. Something like this:

Step 2

Add the following functions:

def steerBalloon(balloon, window, keypress)
Accepts:
  • The balloon object
  • The window object
  • The keypress from the user (from checkKey())
This function moves the balloon up, down, left or right depending on the key pressed by the user. It should also call keepBalloonInWindow() to make sure that the balloon stays within the window.
This function does not have a return value.

def keepBalloonInWindow(balloon, window)
Accepts:
  • The balloon object
  • The window object
This function checks whether the entirety of the balloon is inside the window. (The radius of the balloon and the position of the center will give you that information -- draw a figure and you'll see why.) If part of the balloon is outside of the window, it should move the balloon so that it's back within the window.
This function does not have a return value.

Once you are done with these, add some programming statements to main() that will:

  1. Make a big balloon (make it big -- like 100 radius -- it'll be easier to test.)
  2. Create a while (True) loop in which you call checkKey(), and use the result to steer your balloon around.
  3. Make sure that steerBalloon() does its job. Pressing the "Up" arrow should move the balloon up, etc etc.
  4. Make sure that keepBalloonInWindow() does its job and doesn't let the balloon exit the window!

Step 3

Add the following functions:

def getDistance(point1, point2)
Accepts:
  • Two Point objects
This function calculates the distance between two given Points. The distance between two points, (x1, y1) and (x2, y2) can be found using the Pythagoras Theorem:

Returns: a float with the distance.

def balloonBubbleCollide(balloon, bubble)
Accepts:
  • Two Circle objects (the balloon and the bubble).
Checks the distance between two Circle objects (Hint: use getDistance() to check the distance between the centers, and compare with the sum of the radii).
Returns: True if the circles overlap (or touch), False if not.

def checkForBubblesAbsorbed(balloon, bubbles)
Accepts:
  • The balloon object
  • The list of bubbles.
This function checks whether any bubbles were just absorbed by the balloon (hint: call balloonBubbleCollide(). Bubbles that the balloon collides with should disappear from the window.
Returns an int specifying the number of bubbles that the balloon has collided with

Same as before, after you have implemented these functions, write some programming statements in main():

Steer the balloon around and hit some bubbles, and see if they disappear. Do not worry about "growing" the balloon yet. If your balloon is clearly running into bubbles but they are not disappearing, print out the results calculated by getDistance() and balloonBubbleCollide(), and make sure that they make sense.


Step 4

We're almost done! Add the following functions:

def balloonStarCollide(balloon, star)
Accepts:
  • One Circle object (the balloon)
  • One Polygon object (the star)
Checks the distance between the Circle and the Polygon to see if they touch (or collide). (Hint: use getDistance() to get the distance between the center of the Circle and each of the vertices (the points) of the Polygon, and compare with the radius of the Circle.)
Returns: True if the circle and the polygon collide or touch, and False if they do not.

def checkForStarCollision(balloon, stars)
Accepts:
  • The balloon object
  • The list of stars
Checks whether the balloon has collided with any of the stars (hint: call balloonStarCollide()).
Returns True if the balloon has collided with any of the stars, False if not.

After writing these functions, add programming statements to main():


Step 5

Now we're entering the home stretch. Add programming code to main() to do the following:


Useful Methods

For your reference -- Documentation for the Graphics Library

You will probably find these methods to be useful: In addition, you can also print out an object. Printing the object gives you its basic information -- e.g. what kind of object it is, the coordinates of its center point (or its corners), etc. It is very very very useful for debugging!
>>> win = graphics.GraphWin("hello", 500, 500)
>>> c = graphics.Circle(graphics.Point(250, 250), 50)
>>> c.draw(win)
>>> print c
Circle(Point(250.00, 250.00), 50.00)
>>> c.isDrawn()
True
>>> c.undraw()
>>> c.isDrawn()
False
>>> r = graphics.Rectangle(graphics.Point(20, 20), graphics.Point(200, 200))
>>> r.draw(win)
>>> print r
Rectangle(Point(20.00, 20.00), Point(200.00, 200.00))
>>>

Enhancements

Once you are done with the basic program, you can feel free to add enhancements to it. Some ideas of enhancements (kind of in order of increasing difficulty) are listed below. You may get up to 50% extra credit for enhancements.

You can also add other enhancements that you can think of. Some of these enhancements will require changes to the original specified functions -- for example, maybe a function will have to take in additional parameter, or a different type of parameter, etc. Therefore, to make life easier for us and our graders when we grade, we would like you to turn in additional file called documentation.txt that contains:

Please be clear and precise. The burden of making sure that the reader understands what you are saying rests on you.


Submit

Once you are satisfied with your programs, hand them in by typing handin21 at the unix prompt.

You may run handin21 as many times as you like. We will grade the most recent submission submitted prior to the deadline.