CSC111 Homework 11 solution program
--D. Thiebaut 12:22, 28 April 2010 (UTC)
Zip file
The program and all the gif files associated with it can be found in this zip file.
Source
# hw11a.py
# 111c - aq
# Kristina Fedorenko
# (Edited by D. Thiebaut)
#
# This program is a simulation of swimming fish. Each fish is an object
# (the class defninition is included in the program). Moreover, the
# simulation includes bubbles, which are also objects.
#
# The program simulates 7 fish, each is a randomly selected image
# with a randomly selected horizontal speed. As the fish swims it also
# moves sightly up and down. The bubbles randomly appear near fish's
# mouths and float up. When the fish "swims out" of the window, after
# a while it reappears on the other side of the window.
#
from graphics import *
from random import randrange
import time
# ------------------------------------------------------------------------
# CONSTANTS
# ------------------------------------------------------------------------
# size of the window:
H = 481
W = 605
n = 7 # number of fish:
fRad = 45 # half width of the fish:
# ------------------------------------------------------------------------
# GLOBAL VARIABLE
# ------------------------------------------------------------------------
bubbles = []
# ------------------------------------------------------------------------
# CLASSES
# ------------------------------------------------------------------------
# --BUBBLE--
class bubble:
"""A class defining a bubble"""
def __init__(self, x, y):
"""constructor"""
self.x = x
self.y = y
self.radius = randrange(2,12)
self.bubble = Circle(Point(x,y), self.radius)
self.bubble.setOutline("antique white")
self.spot = Point(x+self.radius/2, y-self.radius/2)
self.spot.setFill("antique white")
def draw(self, win):
"""draws a circle and a dot that constitute a bubble"""
self.bubble.draw(win)
self.spot.draw(win)
def GetRad(self):
"""returns the radius of the bubble"""
return self.radius
def GetCoord(self):
"""returns coordinates of the center of the bubble"""
return self.x, self.y
def swim(self):
"moves bubble upwards and randomly to the side"""
dy = -3
ddx = [-3, -2, -1, 1, 2, 3 ] + 10 * [0]
index = randrange(len(ddx))
self.bubble.move(ddx[index], dy)
self.spot.move(ddx[index], dy)
# ------------------------------------------------------------------------
# --FISH--
class fish:
"""A class defining a fish"""
def __init__(self, filename, direction, x, y):
""""constructor"""
self.fish = Image( Point( x, y ), filename )
self.x = x
self.y = y
self.filename = filename
self.d = direction
def draw(self, win):
"""draws a fish"""
self.fish.draw(win)
def move(self, dx):
"""move fish horizontally the specified distance"""
self.fish.move(dx, 0)
def reappear(self):
"""returns a copy of the fish, but places it near the window
border, so that it will emerge from the side as it swims"""
if self.d:
self.fish.move( -W-fRad*2, 0 )
else:
self.fish.move( +W+fRad*2, 0 )
def getCenter(self):
"""return the center of the fish"""
return self.fish.getAnchor()
def mouth(self):
"""returns the coordinates of the fish' mouth"""
center = self.fish.getAnchor()
y = center.getY()
x = center.getX()
if self.d:
x += fRad
else:
x -= fRad
return x, y
def swim(self):
"""moves the fish horizontally and randomly up and down"""
ddy = [-3, -2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3]
index = randrange(len(ddy))
if self.d:
self.fish.move(randrange(5), ddy[index])
else:
self.fish.move(-randrange(5), ddy[index])
# ------------------------------------------------------------------------
# FUNCTIONS
# ------------------------------------------------------------------------
def waitForClick( win, message ):
""" waitForClick: stops the GUI and displays a message.
Returns when the user clicks the window. The message is erased."""
# wait for user to click mouse to start
startMsg = Text( Point( win.getWidth()/2, win.getHeight()/2 ), message )
startMsg.draw( win ) # display message
win.getMouse() # wait
startMsg.undraw() # erase
# ------------------------------------------------------------------------
# randomly generates a bubble at a specified point and
# appends it to the list of bubbles
def breathing(win, x, y, i):
if i%randrange(1,100) == 0:
b = bubble(x,y)
bubbles.append(b)
b.draw(win)
# ------------------------------------------------------------------------
# checks if the object with passed coordinates and radius is inside
# the window
def Outside(x,y,r):
Outside = False
if (x+r < 0 or x-r > W) or (y+r < 0):
Outside = True
return Outside
# ------------------------------------------------------------------------
# --MAIN FUNCTION--
# runs the simulation
# ------------------------------------------------------------------------
def main():
global H, W
win = GraphWin( "Fish Tank", W, H )
waitForClick( win, "click to start" )
# sets the background
background = Image( Point( W/2, H/2 ), "crlhead.gif" )
background.draw( win )
Fish = []
r = True
l = False
images = [["fish8.gif", r], ["fish20.gif", r], ["fish23.gif", r],
["fish24.gif", r], ["fish26.gif", r], ["fish5.gif", r],
["fish3.gif", r], ["fish18.gif", r], ["fish11.gif", l],
["fish0.gif", l], ["fish15.gif", l]]
# creates fish and append them to the list
for i in range(n):
index = randrange(len(images))
f = fish(images[index][0], images[index][1],\
randrange(W), randrange(H))
Fish.append(f)
# draws fish from the list
for f in Fish:
f.draw( win )
# simulation itself
for i in range(300):
breathing(win, W/2+150, H/2-150, i) # person is breathing too
# deals with fish:
for f in Fish:
f.swim() # -------------- moves fish
x, y = f.mouth() # ---------- generates bubbles
breathing(win, x, y, i)
fCenter = f.getCenter() # ------- checks if fish is out
fX, fY = fCenter.getX(), fCenter.getY()
if Outside(fX, fY, fRad):
f.reappear()
# deals with bubbles
for b in bubbles:
b.swim() # --------------- moves bubbles
Xcoord, Ycoord = b.GetCoord() # ----- checks if bubble is out
if Outside(Xcoord, Ycoord, b.GetRad()):
bubbles.remove(b) # --------- removes it if it is
waitForClick( win, "click to end" )
win.close()
main()