Выход на краю сетки
Вы можете выйти, когда черепаха достигнет края сетки, следующим образом:
while fun:
for k in range(5):
coin = random.randrange(0, 2)
if coin == 0:
count[k].left(90)
else:
count[k].right(90)
count[k].forward(40)
x = count[k].xcor() # new lines
y = count[k].ycor() # |
# |
if x < -300 or 300 < x or \ # |
y < -200 or 200 < y: # |
fun = False # |
break # |
Вы на правильном пути, поставив этулогика в функцию off_grid
, но эта функция не должна принимать self
в качестве аргумента (это не экземпляр класса).
Предложения по проектированию
У меня есть некоторыеобщие предложения по дизайну (простите за обзор импровизированного кода):
- Избегайте глобальных переменных;используйте параметры для передачи информации в функции.Это сохраняет функции для повторного использования и безопасными.Думайте о каждой функции как о черном ящике с регулируемыми ручками (параметрами);этот черный ящик должен работать независимо, а не ломаться или работать иначе, если внешнее состояние изменяется непредсказуемо.Это уменьшает количество ошибок и упрощает анализ вашей программы.
- Используйте точные имена переменных.
count
- это на самом деле не count
чего-либо, а список turtle
с.Значимые имена облегчают следование вашей логике и позволяют избежать ошибок и недоразумений.Переменная fun
может быть более понятной как running
.Переменная k
в for k in range(0, turtle_count):
не используется и обычно пишется как _
в Python. - Предпочитается
snake_case
для имен функций в Python (CamelCase
используется дляклассы). Вместо множества последовательных командных команд используйте цикл для рисования сетки и сохраняйте свой код DRY (не повторяйте себя).Например:
for _ in range(0, height + 1, grid_size):
turtle.pendown()
turtle.forward(width)
turtle.penup()
turtle.right(90)
turtle.forward(grid_size)
turtle.right(90)
turtle.forward(width)
turtle.right(180)
Избегайте жесткого кодирования чисел и строк;поместите все эти переменные вверху вашей main
программы и используйте их повсюду.В частности, в этой программе вам нужны параметры height
, width
и grid_size
, которые будут определены в одном месте и будут управлять работой всей программы (включая определение, когда черепаха покинула сетку),Теперь, если я решу, что я хочу размер сетки 30, высоту 200 и ширину 400, например, я могу изменить эти числа в одном месте, и все просто работает.
- Используйте Python'sпараметры по умолчанию или словари, чтобы уменьшить нагрузку чрезмерных параметров на функции.Разместите функции в верхней части скрипта и отделите их от
main
. Комментарии хороши, но комментарии, когда код уже очевиден, часто добавляют шум:
# Exit on close window
turtle.exitonclick()
Имейте в виду пользователя: я не знал, что мне нужно было возвращаться к терминалу, чтобы ввести скорость черепахи после того, как решетка была нарисована.Я бы предпочел попросить пользователя указать скорость черепахи, а затем запустить визуальную часть программы.
Возможный рефакторинг
Собрать все вместе,Вот предложенный первый рефакторинг (еще есть много возможностей для улучшения дизайна, но это должно дать пищу для размышлений):
import turtle
import random
def create_turtles(
turtle, turtle_count, colors, speed=10, shape="turtle"
):
turtles = []
for _ in range(turtle_count):
tur = turtle.Turtle()
tur.shape(shape)
tur.color(random.choice(colors))
tur.speed(speed)
tur.pendown()
turtles.append(tur)
return turtles
def draw_lines(turtle, turn, length_a, length_b, grid_size):
for _ in range(0, length_a + 1, grid_size):
turtle.pendown()
turtle.forward(length_b)
turtle.penup()
turn(90)
turtle.forward(grid_size)
turn(90)
turtle.forward(length_b)
turn(180)
def draw_grid(
turtle, width=600, height=400, grid_size=40,
speed=100, shape="classic", color="white"
):
tur = turtle.getturtle()
tur.shape(shape)
tur.color(color)
tur.speed(speed)
tur.penup()
tur.setposition(-width // 2, height // 2)
draw_lines(tur, tur.right, height, width, grid_size)
tur.setposition(-width // 2, height // 2)
tur.right(90)
draw_lines(tur, tur.left, width, height, grid_size)
turtle.penup()
turtle.ht()
def off_grid(turtle, width, height):
x = turtle.xcor()
y = turtle.ycor()
return x < -width // 2 or x > width // 2 or \
y < -height // 2or y > height // 2
if __name__ == "__main__":
grid_size = 40
height = 400
width = 600
all_colors = [
"red", "white", "blue", "hotpink",
"purple", "lightgreen", "yellow"
]
speed = int(input("Enter the speed of the turtles (1-10): "))
turtle.setup(800, 600)
window = turtle.Screen()
window.title("Turtles Walking through Grid")
window.bgcolor("black")
draw_grid(turtle, width, height, grid_size)
turtles = create_turtles(turtle, 5, all_colors, speed)
running = True
while running:
for tur in turtles:
random.choice([tur.left, tur.right])(90)
tur.forward(grid_size)
if off_grid(tur, width, height):
running = False
break
turtle.exitonclick()