Есть несколько проблем с вашим кодом.Например, эта логика проверки границы полностью игнорирует текущий курс черепахи:
if t.xcor() + lengthOfTriangle > border or ... t.ycor() + lengthOfTriangle > border or ...
Т.е. она всегда принимает +45 градусов, поэтому не может работать.Вы можете либо выполнить тригонометрию, либо просто переместить черепаху в новое положение и проверить, не выходит ли она за пределы.Если за пределами, вы можете переместить его обратно, настроить и попробуйте снова.Здесь полезен метод turtle.undo()
.
Ваши drawFigure*()
функции иногда явно возвращают значения, иногда нет.Как только функция явно возвращает значение, она должна явно возвращать единицу со всех точек выхода, а не возвращать неявно иногда None
.
Ваша квадратная граница имеет пять сторон:
x = 0
while x <= 4:
, посколькупоследний перекрывает первый, это не очевидно визуально.
Давайте попробуем более простой итеративный подход, в котором мы используем turtle.circle()
для рисования наших треугольников, но думаем о каждом треугольнике как о круге при определении, находится ли он в границах,Мы также будем центрировать наш рисунок вместо того, чтобы использовать только верхний правый квадрант и положительные числа:
from turtle import Screen, Turtle
from random import randint
NUMBER_TRIANGLES = 80
PEN_SIZE = 3
BORDER = 300
def drawBorder(border):
turtle.pensize(PEN_SIZE)
turtle.penup()
turtle.goto(-border/2, -border/2)
turtle.pendown()
for _ in range(4):
turtle.forward(border)
turtle.left(90)
turtle.penup()
turtle.home()
def drawFigure(numTriangles):
if not 0 < numTriangles < 500:
exit("Number of triangles is out of range!")
for _ in range(numTriangles):
radius = randint(3, 20)
distance = randint(2, 60)
turtle.forward(distance)
while not(radius - BORDER/2 < turtle.xcor() < BORDER/2 - radius and radius - BORDER/2 < turtle.ycor() < BORDER/2 - radius):
turtle.undo() # undo last forward()
turtle.left(37) # rotate and try again (relative prime angle)
distance += 1 # increase distance slightly on failure
turtle.forward(distance)
angle = randint(1, 360)
turtle.setheading(angle)
turtle.right(90) # turtle represents center so need to adjust
turtle.forward(radius) # as turtle.circle() doesn't think that way
turtle.left(90)
turtle.pendown()
turtle.circle(radius, steps=3)
turtle.penup()
turtle.left(90) # undo adjustment to move turtle back to center
turtle.forward(radius)
turtle.right(90)
screen = Screen()
screen.tracer(False)
turtle = Turtle()
turtle.speed('fastest')
drawBorder(BORDER)
drawFigure(NUMBER_TRIANGLES)
turtle.hideturtle()
screen.tracer(True)
screen.mainloop()
Я не буду включать рекурсивэквивалентно, поскольку это действительно не рекурсивная проблема.Вы можете заставить его быть единым, как того требует ваше назначение.