CSC111 Homework 11 solution program

From dftwiki3
Revision as of 08:34, 28 April 2010 by Thiebaut (talk | contribs) (Source)
Jump to: navigation, search

--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()