CSC111 Homework 11 solution 2011

From dftwiki3
Revision as of 21:13, 16 December 2011 by Thiebaut (talk | contribs)
Jump to: navigation, search

--D. Thiebaut 21:10, 16 December 2011 (EST)


CSC111BusTrafficLightClouds.png

Main Program


# Valerie Cook and Emily Kim
# 111a-bq and 111a-as
# This program imports the information we wrote from the class hw11clas.py
# and uses it to create a scene in which clouds, trees, a traffic light, and
# buses can be drawn. The buses are programmed to stop within 50 pixels of the
# traffic light if it is not green and wait until it turns green again to continue.
# Our buses are set up so that the color of the body will be chosen at random from
# the list of colors we create and if more than one bus is drawn, they will go at
# different speeds

from hw11class import * 
from graphics import *
import random
import time

W = 600    # width of the graphics window
H = 400    # height of the graphics window

def main():

    win = GraphWin( "111a-bq 111a-as Traffic Light", W, H ) 

    # create a blue sky
    sky = Rectangle(Point(0,0),Point(W,H)) # rectangle has the same W and H as the
                                        # graphic window
    sky.setFill("lightblue") # it is lightblue like the sky
    sky.setWidth(0) # no border
    sky.draw(win) # draws the rectangle

    # colors for buses
    colors = ["purple", "green", "red", "blue", "magenta", "pink", "darkblue",
              "lightgreen", "darkgreen", "beige", "lavender", "violet"]

    clouds = [] # holds all of the clouds
    trees = []  # holds all of the trees
    buses = []  # holds all of the buses

    
    """ controls the clouds in the background of the window """
    for i in range (6): # change range to desired number of clouds
        cloud = Cloud(Point(random.randrange(0,W), # random x value
                            random.randrange(0,round(H*2/3)))) # random y value
        cloud.draw(win)# draw the cloud in graphics window
        clouds.append(cloud)# append the cloud to list clouds
        
    """ controls the trees in the background of the window """
    for i in range(4): # change the range to desired number of trees
        tree = Tree( Point( random.randrange(10,W), H ), # random x, y = win height
                     H*2/3,) # height of tree = 2/3 height of the window
        tree.draw( win ) # draw the tree in graphics window
        trees.append( tree ) # append the tree to the list of trees
        
    """ raws and positions the traffic light in the window """
    position = Point( W/3, H ) # position of traffic light
    light = TrafficLight(position,H) # create traffic light with the given position
                                     # and height of the window
    light.draw( win ) # draw the traffic light in the graphics window
    
    """ controls the buses in the window """
    for i in range(2): # change the range for the desired number of buses
        bus = Bus( Point( W, H*4/5 ), W/4, H/6 , W ) # create bus by giving it the
            # top left point, width, height, and width of the graphics window
        bus.setFill(random.choice(colors),# random body color
                    "lightblue", "black", "white") # window, outer tire, inner tire
        buses.append(bus) # appened bus to list of buses
        bus.draw(win) # draw bus in the graphics window

 
    # =========================== ANIMATION LOOP =============================
    while  True:

        # update traffic light
        light.update()
        
        if win.checkMouse() != None: # if the user clicks, program will close
            break
        
        """ this loop controls the movement of the buses in the window """
        for i in range(len(buses)): # move the buses

            # if the light isn't green and the front of the bus is in
            # front of and 50 pixels or closer to the traffic light 
            if not ( (light.isGreenOn() != True and
                ( 0<= buses[i].distanceFrontTo(light.getPosition()) <= 50)) ):

                buses[i].move(-4*(i+1), 0)   # moves buses in the -x direction
                                             # at different speeds
            
        # slow down the loop 
        time.sleep( 0.1 )

    # close the window
    win.close()
 
main()


Module


# Valerie Cook and Emily Kim
# 111a-bq and 111a-as
# This is a class which uses graphics to create our own unique objects
# In it, we have defined a traffic light which automatically changes
# color from green to yellow to red and then back to green.
# A wheel which we later use to create the bus ( incuding three wheels,
# a window, and a body) which can move and if it goes out of the graphic
# window it will loop around. It can also find out how close it is to
# another point. And a tree and clouds which make the background more
# interesting and realistic.
""" 
    The traffic light contains a long vertical pole,
    a rectangular box at the top, three circles (red, yellow, green)
    for the lights.
    Methods supported:
        greenIsOn():    tells if the green light is on or not
        getPosition():  gets the position of the basepoint of the pole
        draw(win):      draws the whole light on the graphic window
        switchState():  changes from red to green to yellow back to red
        update():       update the internal counter and decide when to change state

    The Wheel contains two circles of different radii but the same center
    Methods supported:
        setFill():      colors the outer then the inner cirlce 
        draw(win):      draws the entire wheel on the graphic window
        move():         moves the two circles at the same speed

    The bus contains a rectangular body, three wheels,
    and a rectangular window
    Methods supported:
        setFill():         colors the body, window, wheel outer, wheel inner
        distanceFrontTo(): gets the distance from the front of the bus to another object
        draw(win):         draws the whole bus on the graphic window
        move():            moves the entire bus and loops it around when it goes off the window
        getX():            gets the X value of the front of the bus

   The tree contains a trunk and a head
    Methods supported:
        draw(win):      draws the entire tree on the graphic window
    
    The cloud contains six white circles with the same radius but 
    different centers 
    Methods supported:
        draw(win):      draws the entire cloud on the graphic window
    

"""
from graphics import *
import random
import time

""" defines the window and draws the sky background on the window"""

     
class TrafficLight:

    """ The traffic light contains a long vertical pole,
    a rectangular box at the top, three circles (red, yellow, green)
    for the lights.
    Methods supported:
        greenIsOn():    tells if the green light is on or not
        getPosition():  gets the position of the basepoint of the pole
        draw(win):      draws the whole light on the graphic window
        switchState():  changes from red to green to yellow back to red
        update():       update the internal counter and decide when to change state
    """

    def __init__( self, basePoint, H):
        """builds the graphical obect.
        basePoint is a point on the ground, in the middle of the pole
        w is the width of the top box
        h is the height of the pole plus the box at top"""
 
        # save the geometry of the traffic light and the pole
        self.w = H/10
        self.h = H/2
        self.basePoint = basePoint
        self.isRed = True # red light is on
        self.isYellow = False # yellow light is off
        self.isGreen = False # green light is off

        # create the pole
        x = self.basePoint.getX()
        y = self.basePoint.getY()
        x1 = x - self.w/5
        x2 = x + self.w/5
        y1 = y - self.h
        y2 = y
        self.pole = Rectangle( Point( x1, y1), Point( x2, y2 ) )
        self.pole.setFill( "gray" )
 
        # create the top box where the lights are
        x1 = x - self.w/2
        x2 = x + self.w/2
        y1 = y - self.h *5/3
        y2 = y - self.h + self.w
        self.top = Rectangle( Point( x1, y1), Point( x2, y2 ) )
        self.top.setFill( "orange" )


        # create the lights in the box
        xc1 = (x1+x2)/2
        yc1 = (y1+y2)/3
        radius = self.w * 4 / 5 / 2
        self.red = Circle( Point( xc1, yc1 ), radius )

        xc2 = (x1+x2)/2
        yc2 = (y1+y2)/2
        self.yellow = Circle( Point( xc2, yc2 ), radius )
        
        xc3 = (x1+x2)/2
        yc3 = (y1+y2)* 2/3
        self.green = Circle( Point( xc3, yc3 ), radius )

        # initialize the counter to a random start  
        self.counter = random.randrange( 10 )
    
    def isGreenOn(self):
        """ figures out if the green light is on"""
        
        if self.isGreen:
            self.green.setFill("green")
            return True


    def getPosition(self):
        """ gets and returns the position of the basepoint"""
        position = self.basePoint
        return position

            
    def draw( self, win ):
        """draws the whole traffic light on the graphics window"""
        self.win = win
        self.pole.draw(win)
        self.top.draw(win)
        self.red.draw(win)
        self.yellow.draw(win)
        self.green.draw(win)

 
    def switchState( self ):
        """changes the state of the light to green from red, yellow from
        green, and red from yellow """
        if self.isRed == True: # if red is on, makes green turn on 
            self.isRed = False
            self.isYellow = False
            self.isGreen = True
            self.red.setFill( "black" )
            self.yellow.setFill( "black" )
            self.green.setFill( "green" )

        elif self.isYellow == True: # if yellow is on, makes red go on
            self.isYellow = False
            self.isGreen = False
            self.isRed = True
            self.red.setFill( "red" )
            self.yellow.setFill( "black")
            self.green.setFill( "black" )
            
        elif self.isGreen == True: # if green is on, makes yellow go on
            self.isGreen = False
            self.isRed = False
            self.isYellow = True
            self.red.setFill( "black" )
            self.yellow.setFill( "yellow")
            self.green.setFill( "black" )
             
    def update( self ):
        """called once through the animation loop, every 10
        calls, changes the state of the light to the opposite"""
        self.counter = ( self.counter + 1 ) % 10
        if self.counter == 0:
            self.switchState()

            
class Wheel:
    """ The Wheel contains two circles of different radii but the same center
    Methods supported:
        setFill():      colors the outer then the inner cirlce 
        draw(win):      draws the entire wheel on the graphic window
        move():         moves the two circles at the same speed
    """
    def __init__(self, center, r1, r2 ):
        """builds the graphical obect.
        center is the center of both circles
        r1 is the radius of the smaller cirlce
        r2 is the radius of the bigger circle"""
        self.center = center
        r1, r2 = min(r1, r2), max(r1, r2)
        self.radius1 = r1
        self.radius2 = r2
        self.c1 = Circle( center, r1 )
        self.c2 = Circle( center, r2 )
 
    def setFill( self, col1, col2 ):
        """ sets the colors of the two cirlces"""
        self.c2.setFill( col1 )
        self.c1.setFill( col2 )
 
    def draw( self, win):
        """ draws the whole wheel in the graphic window"""
        self.c2.draw( win )
        self.c1.draw( win )
 
    def move( self, dx, dy ):
        """ moves the whole wheel"""
        self.c2.move( dx, dy )
        self.c1.move( dx, dy )


class Bus:
    """ The bus contains a rectangular body, three wheels,
    and a rectangular window
    Methods supported:
        setFill():         colors the body, window, wheel outer, wheel inner
        distanceFrontTo(): gets the distance from the front of the bus to another object
        draw(win):         draws the whole bus on the graphic window
        move():            moves the entire bus and loops it around when it goes off the window
        getX():            gets the X value of the front of the bus
        """
    def __init__( self, topLeftPoint, width, height, W):
        """builds the graphical obect.
        W is the width of the graphic window
        width is the width of the bus
        x1 is the x value of the top left point of the bus
        body is the rectangle that makes the body of the bus
        wheels are the wheels on the bus
        window is the window on the bus"""
        self.W = W
        self.width = width
        x1 = topLeftPoint.getX()
        y1 = topLeftPoint.getY()
        x2 = x1 + width
        y2 = y1 + height
        self.x1 = x1
        self.body = Rectangle( topLeftPoint, Point( x2, y2 ))
        self.wheels = []
        self.wheels.append( Wheel( Point( x1+width*2/12,y2 ), width/12/2, width/12 ) )
        self.wheels.append( Wheel( Point( x1+width*9/12,y2 ), width/12/2, width/12 ) )
        self.wheels.append( Wheel( Point( x1+width*11/12,y2), width/12/2, width/12 ) )
        self.window = Rectangle( Point( x1+width/12/2, y1+height/4/2 ),
                                 Point( x1+width/12*3, y1+height/4*3*2/3 ) )

 
    def setFill( self, bodyCol, windowCol, wheelCol1, wheelCol2 ):
        """colors the body, window, outer wheel, inner wheel"""
        self.window.setFill( windowCol )
        self.body.setFill( bodyCol )
        for wheel in self.wheels:
            wheel.setFill( wheelCol1, wheelCol2 )

    def distanceFrontTo(self, light):
        """finds the distance from the front of the bus to another object""" 
        x = self.body.getP1().getX()
        xlight = light.getX()
        y = self.body.getP1().getY()
        ylight = light.getY()
        
        distance = eval(str(x)) - eval(str(xlight)) 
        
        return distance

        
    def draw( self, win ):
        """ draws the whole bus in the graphic window"""
        self.body.draw( win )
        self.window.draw( win )
        for wheel in self.wheels:
            wheel.draw( win )
 
    def move( self, dx, dy):
        """moves the entire bus and loops it around when it goes off the window"""
        x = self.body.getP1().getX()+self.width*2
        if x  > self.width: # if it's in the window move normally
            self.body.move( dx, dy )
            self.window.move( dx, dy )
            for wheel in self.wheels:
                wheel.move( dx, dy )
        else: # if bus goes off window, wrap it around to the other end
            self.body.move( self.W +self.width, 0 )
            self.window.move( self.W +self.width, 0 )
            for wheel in self.wheels:
                wheel.move( self.W +self.width, 0 )
    
 
    def getX( self ):
        """ gets and returns the x value of the top left point of the bus"""
        return self.body.getP1().getX()
 

class Tree:
    """ The tree contains a trunk and a head
    Methods supported:
        draw(win):      draws the entire tree on the graphic window
    """
    
 
    def __init__( self, point, height):
        """The tree is defined by the point at the base of its trunk,
        and its height.  The width of the window is passed for later
        use by the move method"""
 
        x = point.getX()
        y = point.getY()
        p1 = Point( x-(height/20), y )
        p2 = Point( x+(height/20), y - height *3/4 )
        self.trunk = Rectangle( p1, p2 )
        self.trunk.setFill( "brown" )
        self.head = Circle( Point( x, y - height * 5/ 6 ), height/4 )
        self.head.setFill( "darkgreen" )
 
    def draw( self, win ):
        """draws the trunk and head of the tree"""
        self.trunk.draw( win )
        self.head.draw( win )
        
class Cloud:
    """ The cloud contains six white circles with the same radius but 
    different centers 
    Methods supported:
        draw(win):      draws the entire cloud on the graphic window
    """
    def __init__(self, point):
        """builds the graphical obect.
        point is the point which the rest of the cloud is drawn around """
        x = point.getX() # x value of given point
        y = point.getY() # y value of given point
        self.c1 = Circle(point,20)
        self.c1.setWidth(0) # width of border is 0
        self.c1.setFill("white") # color is white
        self.c2 = Circle(Point(x + 20, y + 12),20)
        self.c2.setWidth(0)
        self.c2.setFill("white")
        self.c3 = Circle(Point(x + 20, y - 13),20)
        self.c3.setWidth(0)
        self.c3.setFill("white")
        self.c4 = Circle(Point(x + 50, y + 16),20)
        self.c4.setWidth(0)
        self.c4.setFill("white")
        self.c5 = Circle(Point(x + 50, y - 10),20)
        self.c5.setWidth(0)
        self.c5.setFill("white")
        self.c6 = Circle(Point(x + 70, y ),20)
        self.c6.setWidth(0)
        self.c6.setFill("white")
        
    def draw(self,win):
        """draws the cloud in the graphic window"""
        self.c1.draw(win)
        self.c2.draw(win)
        self.c3.draw(win)
        self.c4.draw(win)
        self.c5.draw(win)
        self.c6.draw(win)