"""
Python Exercise 18
for the class of
Data Processing and Visulisation with Python
2020-2021-1
"""# libraries to be usedimport turtle
import random
# initialize"""
feel free to change these settings and check the output,
or you could get these settings from user input
"""
maxHeight =700
maxWidth =1200
rowCount =70
columnCount =120
screenPaddingWidth =8
screenPaddingHeight =8
backGroundColor ='white'
lineColor ='black'"""
the following variables are calculated from the above settings
* rowSize is the integer part of maxHeight divided by rowCount
* colSize is the integer part of maxWidth divided by columnCount
* cellHeight and cellWidth are set to the smaller value of rowSize and colSize
* mazeWidth equals columnCount times cellWidth
* mazeHeight equals rowCount times cellHeight
* screenWidth is the sum of mazeWidth and screenPaddingWidth
* screenHeight is the sum of mazeHeight and screenPaddingHeight
"""#-----------------code section - finish the code below-----------------
rowSize = maxHeight // rowCount
colSize = maxWidth // columnCount
cellHeight = cellWidth = rowSize if rowSize < colSize else colSize
mazeWidth = columnCount*cellWidth+1
mazeHeight = rowCount*cellHeight+1
screenWidth = mazeWidth + screenPaddingWidth
screenHeight = mazeHeight + screenPaddingHeight
#-------------------------end of code section-------------------------# disjoint sets"""
the following code implements smart union algorithm
it will be useful in finding which wall to destroy in order to make a maze
you do not need to do anything with this part, it is ready for your later use
"""
s =[-1]* rowCount * columnCount
deffindRoot(x):if s[x]<0:return x
else:return findRoot(s[x])defunionSets(c1, c2):
r1 = findRoot(c1)
r2 = findRoot(c2)if s[r1]< s[r2]:
s[r2]= r1
else:if s[r1]== s[r2]:
s[r2]-=1
s[r1]= r2
defcellsConnected(x, y):return findRoot(x)== findRoot(y)# window and pen"""
settings of the screen window and turtle pen
the code finishes the following settings
* define a variable screen as a TurtleScreen instance via turtle.Screen() function
* set the window size as screenWidth and screenHeight by calling screen.setup()
* set the worldcoordinates as (0, 0, screenWidth-1, screenHeight-1) by calling screen.setworldcoordinates()
* set the title of the window to "Maze created by YOUR NAME" by calling screen.title()
(remember to replace YOUR NAME with your own name)
* set the screen.tracer() to False in order to speed up drawing maze
* define a variable pen as a Turtle instance via turtle.Turtle() function
* hide turtle in window using hideturtle() function
for more details of Turtle and Screen, please visit:
https://docs.python.org/3/library/turtle.html#turtle.screensize
or in Chinese:
https://docs.python.org/zh-cn/3/library/turtle.html#turtle.screensize
"""#-----------------code section - finish the code below-----------------
screen = turtle.Screen()
screen.setup(screenWidth, screenHeight)
screen.setworldcoordinates(0,0, screenWidth-1, screenHeight-1)
screen.title('Maze created by YE Huanzhuo')
screen.tracer(False)
pen = turtle.Turtle()# pen.speed(10)
pen.hideturtle()#-------------------------end of code section-------------------------# build walls## store all the walls available to be erased"""
store all the walls in a full grid into a list, name the list as wallErasable
* the cells in the grid are numbered from 0 to rowCount*columnCount-1 starting from
lowerleft of the grid arranged in coloumn first order
* normally, each cell has four walls, but in order not to miss any wall or recount any
one, we define each cell with two walls, the upper wall and the right wall, except:
- the upper most row, in which cells do not have upper walls
- the right most column, in which cells do not have right walls
* each wall is represented by a tuple (cellNo, position), in which
- cellNo is the serial number of the cell
- position show where the wall is to the cell, it has only two values:
# 0: the wall is the upper wall of the cell
# 1: the wall is the right wall of the cell
"""#-----------------code section - finish the code below-----------------
wallErasable =[]for i inrange(rowCount*columnCount):if i%columnCount != columnCount-1:
wallErasable.append((i,1))# right wall to the cellif i <(rowCount-1)*columnCount:
wallErasable.append((i ,0))# upper wall to the cell#-------------------------end of code section-------------------------## function to find the neighbor cell share the wall (cellNo, position)"""
this function returns the serial number of the cell which shares the wall
represented by (cellNo, position) with the cell numbered cellNo
"""defneighbor(cellNo, position):#-----------------code section - finish the code below-----------------return cellNo +1*position + columnCount*(1-position)#-------------------------end of code section-------------------------## function to set a wall"""
the following code calcultes and draws the correspongding line with the current pen color
this function draws the wall represented by (cellNo, position)
with the settings of columnCount, cellWidth and cellHeight, the pixels or line of
the wall (cellNo, position) can be easlily calculated
"""defsetWall(cellNo, position):#-----------------code section - finish the code below-----------------
row = cellNo // columnCount
column = cellNo % columnCount
if position:
startPoint =((column+1)*cellWidth, row*cellHeight)else:
startPoint =(column*cellWidth,(row+1)*cellHeight)
endPoint =((column+1)*cellWidth,(row+1)*cellHeight)
pen.up()
pen.goto(startPoint)
pen.down()
pen.goto(endPoint)#-------------------------end of code section-------------------------## randomly destroy rowCount*columnCount-1 walls to make rowCount*columnCount## cells connected, thus build a maze"""
* build an empty list named wallToBuild to store the walls that should not be destroyed
* each time randomly choose a destroyable / erasable wall from list wallErasable
- find out the two cells sharing this wall
- find out if the two cells are already connected using cellsConnected() function
# if they are not connected yet
+ pop this wall out of wallErasable
# otherwise (if they are already connected)
+ move this wall from wallErasable to wallToBuild
+ find another wall to destroy
* repeat the above steps rowCount*columnCount-1 times to destroy rowCount*columnCount-1 walls
in that way, rowCount*columnCount cells will be connected and the maze will be formed
* move all the rest walls in wallErasable to wallToBuild
"""#-----------------code section - finish the code below-----------------
numErased =0
wallToBuild =[]while numErased <(rowCount*columnCount-1):
numWall = random.randrange(len(wallErasable))
cellNo, position = wallErasable[numWall]
w = wallErasable.pop(numWall)
neighborCellNo = neighbor(cellNo, position)ifnot cellsConnected(cellNo, neighborCellNo):
unionSets(cellNo, neighborCellNo)
numErased +=1else:
wallToBuild.append(w)
wallToBuild.extend(wallErasable)#-------------------------end of code section-------------------------## build the maze### build outer frame"""
* set the pen color to lineColor
* draw the outline border of the maze, a rectangle set by
- rowCount
- columnCount
- cellWidth
- cellHeight
"""#-----------------code section - finish the code below-----------------
pen.color(lineColor)
pen.forward(cellWidth*columnCount)
pen.left(90)
pen.forward(cellHeight*rowCount)
pen.left(90)
pen.forward(cellWidth*columnCount)
pen.left(90)
pen.forward(cellHeight*rowCount)#-------------------------end of code section-------------------------### build inner walls"""
take each wall from wallToBuild and draw it with current pen color
"""#-----------------code section - finish the code below-----------------for w in wallToBuild:
setWall(*w)#-------------------------end of code section-------------------------### dig out entrance and exit"""
make an entrance and an exit on the outline border
* set the pen color to backGroundColor
* draw the upper wall of the upperleft cell
* draw the right wall of the lowerright cell
"""#-----------------code section - finish the code below-----------------
pen.color(backGroundColor)
setWall((rowCount-1)*columnCount,0)
setWall(columnCount-1,1)#-------------------------end of code section-------------------------# well done
screen.tracer(True)# screen.exitonclick()
turtle.done()
Project 2 : Using Turtle to Draw a Maze (Python Exercise 18)
Data Processing and Visulisation with PythonPython Exercise 18Data Processing and Visulisation with Python"""Python Exercise 18for the class ofData Processing and Visulisation with Python2020-2021-1"""# libraries to be usedimport turtleimport r