CSC111 Lab10 Solution 1
--D. Thiebaut 15:12, 9 April 2010 (UTC)
# carLab10.py
# D. Thiebaut
# A solution program for the first part of Lab 10. The goal
# is to create a list of car objects constructed from the Car
# class. The Car class is made of a rectangular body, two
# wheels, a door, and a windshield.
# The cars are given a random direction (which cannot be
# 0) and move in that direction until all the cars have escaped
# the graphics window.
# This program uses Zelle's graphics library.
from graphics import *
import random
W = 400 # width of the graphics window
H = 400 # height of the graphics window
#----------------------------------------------------------------
class Wheel:
"""A class with two concentric circles"""
def __init__( self, center, r1, r2 ):
"""constructor"""
self.radius1 = min( r1, r2 )
self.radius2 = max( r1, r2 )
self.circ1 = Circle( center, self.radius1 )
self.circ2 = Circle( center, self.radius2 )
def draw( self, win ):
"""draws the wheel on the graphics window win"""
self.circ2.draw( win )
self.circ1.draw( win )
def move( self, dx, dy ):
self.circ1.move( dx, dy )
self.circ2.move( dx, dy )
def setFill( self, color1, color2 ):
self.circ1.setFill( color1 )
self.circ2.setFill( color2 )
def getRadius1( self ):
"""returns the smallest radius"""
return self.radius1
def getRadius2( self ):
"""returns the largest radius"""
return self.radius2
#----------------------------------------------------------------
class Car:
def __init__( self, P1, P2, dx ):
"""constructor. Receives top-left and bottom-right point, and speed"""
#--- create additional points needed for the car ---
pp1 = Point( min( P1.getX(), P2.getX() ), min( P1.getY(), P2.getY() ) )
pp2 = Point( max( P1.getX(), P2.getX() ), max( P1.getY(), P2.getY() ) )
pp3 = Point( (pp1.getX()+pp2.getX())/2, pp1.getY() )
pp4 = Point( pp3.getX(), pp1.getY()-30 )
pp5 = Point( (pp1.getX()+pp2.getX())/3, pp1.getY() )
pp6 = Point( (pp1.getX()+pp2.getX())*2/3, pp1.getY() )
#--- define the body ---
self.body = Rectangle( pp1, pp2 )
P1 = pp1
P2 = pp2
#--- the wheels ---
w =abs( P2.getX()-P1.getX() )
h =abs( P2.getY()-P1.getY() )
center1 = Point( w/4+P1.getX(), P2.getY() )
center2 = Point( P2.getX()-w/4, P2.getY() )
r2 = w/8
r1 = r2/2
self.w1 = Wheel( center1, r1, r2 )
self.w2 = Wheel( center2, r1, r2 )
#--- adjust speed if equal to 0 ---
if dx==0: dx = 2
self.dx = dx
#--- put windshield in direction of motion ---
if dx < 0:
self.shield = Polygon( pp1, pp3, pp4 )
else:
self.shield = Polygon( Point( pp2.getX(), pp1.getY() ), pp3, pp4 )
#--- create door ---
self.door = Rectangle( pp5, center2 )
def setFill( self, bodyc, tirec, insidec ):
"""set the color of the body, and tires"""
self.body.setFill( bodyc )
self.shield.setFill( "lightblue" ) # windshield color fixed
self.door.setFill( bodyc )
self.w1.setFill( tirec, insidec )
self.w2.setFill( tirec, insidec )
def draw( self, win ):
"""draw all the parts, in the right order so that wheel overlap everything"""
self.body.draw( win )
self.door.draw( win )
self.shield.draw( win )
self.w1.draw( win )
self.w2.draw( win )
def move( self ):
"""move the car by its own speed"""
self.body.move( self.dx, 0 )
self.shield.move( self.dx, 0 )
self.door.move( self.dx, 0 )
self.w1.move( self.dx, 0 )
self.w2.move( self.dx, 0 )
def IsOutside(self, W, H):
"""returns True if car is outside the window defined by W and H"""
#--- get leftmost and rightmost points ---
P1 = self.body.getP1()
P2 = self.body.getP2()
leftX = P1.getX()
rightX = P2.getX()
#--- are they out? ---
if leftX > W or rightX < 0:
return True
return False
#----------------------------------------------------------------
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
#----------------------------------------------------------------
def main():
"""demo program for a list of moving cars"""
global W, H
win = GraphWin( "wheel demo", W, H )
waitForClick( win, "click to start" )
#--- build a list of cars ---
List = []
for i in range( 3 ):
car = Car( Point( 120, 60+i*50 ), Point( 20, 20+i*50 ), 3-random.randrange( 6 ) )
car.setFill( "red", "yellow", "black" )
car.draw( win )
List.append( car )
waitForClick( win, "click to move" )
#--- move the cars ---
while True:
#--- as we move the cars, count the number of outside cars ---
outsideCount = 0
for car in List:
car.move( 3, 0 )
if car.IsOutside(W, H):
outsideCount += 1
#--- if they are all outside, we quit ---
if outsideCount >= len(List):
break
waitForClick( win, "click to end" )
main()