# CS111 Lab 09 PART 02 SOLUTIONS
# Nested loops and turtle graphics
# Row houses that are inspired by Amsterdam row houses
#
#
#
#
#
from turtle import *
from turtleBeads import *
import random
import math
# Note: new turtleBeads functions randomPastelColor, randomVibrantColor,
# and randomMutedColor can be used to generate random colors.
def makeWindow(size, c1, c2):
'''Draws a square of size and color c1 with a
smaller square of size/2 in color c2 nested inside.
Maintains position and heading invariant. '''
color(c1)
begin_fill()
drawSquare(size)
end_fill()
color(c2)
begin_fill()
drawSquare(size/2)
end_fill()
# maintains position and heading invariant
def drawRoof(windowSize, numCols, rcolor):
'''Draws a triangular roof that spans column number of windows
with size. Triangular roof has 45 degree angles at two corners
that touch the building and the peak of the roof is a 90 degree
angle. Assumes this function is invoked when the
turtle at the upper left corner of the building, facing East.
Maintains position and heading invariant.'''
# draw the roof
color(rcolor)
begin_fill()
roofWidth = windowSize * numCols
sideLen = roofWidth/2.* math.sqrt(2)
fd(roofWidth)
rt(45)
bk(sideLen)
rt(90)
fd(sideLen)
lt(180-45)
end_fill()
# students might find this optional helper function useful
def getReadyForRoof(windowSize):
'''Assumes turtle starts in center of upper right most window,
and places turtle in roof starting position, at upper right most corner
of building. Works when the building is drawn in row major order.'''
pu()
rt(90)
fd(windowSize/2)
lt(90)
bk(windowSize/2)
pd()
def makeBuilding(rows, columns, size, buildingColor, windowColor):
'''Draws a grid of row x column size with outer square color
buildingColor and inner square color windowColor. Each square has the
same color combo. Starts drawing in lower left hand corner window.
Maintains position and heading invariant.'''
color(buildingColor)
for r in range(rows):
for c in range(columns):
makeWindow(size, buildingColor, windowColor)
leap(size)
leap(-size*columns)
# position turtle for next row, drawing from bottom up
pu()
lt(90)
fd(size)
rt(90)
pd()
getReadyForRoof(size)
# draw the roof
drawRoof(size, columns, windowColor)
# maintains position and heading invariant
pu()
rt(90)
fd(rows*size)
bk(size/2)
lt(90)
fd(size/2)
pd()
def makeRandomColorBuilding(rows, columns, size):
'''Draws a grid of row x column size with random colored
squares'''
for r in range(rows):
for c in range(columns):
buildingColor = randomMutedColor()
windowColor = randomPastelColor()
makeWindow(size, buildingColor, windowColor)
leap(size)
leap(-size*columns)
# position turtle for next row, drawing from bottom up
pu()
lt(90)
fd(size)
rt(90)
pd()
getReadyForRoof(size)
# draw the roof
roofColor = randomPastelColor()
drawRoof(size, columns, roofColor)
# maintain position and heading invariant
pu()
rt(90)
fd(rows*size)
bk(size/2)
lt(90)
fd(size/2)
pd()
def makeRowBuilding(rows, columns, size):
'''Draws a grid of row x column size with each row
randomly changing color'''
for r in range(rows):
buildingColor = randomMutedColor()
windowColor = randomPastelColor()
for c in range(columns):
makeWindow(size, buildingColor, windowColor)
leap(size)
leap(-size*columns)
# position turtle for next row, drawing from bottom up
pu()
lt(90)
fd(size)
rt(90)
pd()
getReadyForRoof(size)
roofColor = randomPastelColor()
drawRoof(size, columns, roofColor)
# maintain position and heading invariant
pu()
rt(90)
fd(rows*size)
bk(size/2)
lt(90)
fd(size/2)
pd()
def makeColumnBuilding(rows, columns, size):
'''Draws a grid of row x column size with each column
randomly changing color'''
for c in range(columns):
buildingColor = randomMutedColor()
windowColor = randomPastelColor()
lt(90) # draw a column first, from bottom to top
for r in range(rows):
makeWindow(size, buildingColor, windowColor)
leap(size)
if r == (rows-1) and c == 0: # leftmost column
# get ready to make roof
pu()
bk(size/2)
rt(90)
bk(size/2)
# actually draw the roof
roofColor = randomPastelColor()
drawRoof(size, columns, roofColor)
# revert to original position/heading at end of column
fd(size/2)
lt(90)
fd(size/2)
leap(-size*rows)
# position turtle for next column
pu()
rt(90)
fd(size)
pd()
# maintain position and heading invariant
pu()
bk(columns*size)
pd()
def getRandomBuildingSpecs():
'''Returns random rows, cols and size within these limits:
rows are between [1-8], cols between [1-8] and size between
[20-40]'''
rows = random.randint(1,8)
cols = random.randint(1,8)
size = random.randint(30,40)
return (rows, cols, size)
def transitionToNextBuilding(row, col, size):
'''Places turtle at lower right corner of building just
drawn, anticipating start of the next building.'''
pu()
fd(size*col)
bk(size/2)
lt(90)
bk(size/2)
rt(90)
pd()
def transitionToLowerLeftWindowCenter(size):
'''Moves turtle from lower right building corner
to lower left window center to start drawing building'''
pu()
fd(size/2)
lt(90)
fd(size/2)
rt(90)
pd()
def cityScape(numHouses):
'''Draws a city scape of randomly-sized and randomly-colored
buildings in a row. Houses should all be aligned on the bottommost
row. numHouses is the number of houses drawn.'''
for h in range(numHouses):
# get random specs
r, c, s = getRandomBuildingSpecs()
# move to starting place in center of lower left window
transitionToLowerLeftWindowCenter(s)
# draw a house
makeRowBuilding(r, c, s)
transitionToNextBuilding(r, c, s)
if __name__ =='__main__':
setupTurtle()
noTrace()
leap(-100)
hop(-100)
# # Testing makeBuilding (Task A)
#makeBuilding(5, 2, 50, 'SlateGray', 'LightSkyBlue')
#makeBuilding(2, 3, 50, 'SlateGray', 'LightSkyBlue')
makeBuilding(5, 2, 50, 'SlateGray', 'LightSkyBlue')
# # Testing makeRandomColorBuilding (Task B)
# makeRandomColorBuilding(8,1, 30)
# # Testing makeRowBuilding (Task C)
#makeRowBuilding(6, 3, 50)
# # Testing makeColumnBuilding (Task D)
#makeColumnBuilding(6,3, 50)
#makeColumnBuilding(2,5, 50)
#cityScape(4)
# ht() # hides the turtle
showPicture()
input('>')