Глава 19 · Архитектура
Render: модель → Turtle
Один и тот же пул Turtle-сегментов переиспользуется на каждом тике — новые создаются, только когда змейка выросла.
render() не создаёт новые сегменты на каждом тике
Змейка растёт, и напрашивается простое решение: создавать новый
turtle.Turtle() на каждое съеденное яблоко — ровно так и делал
первый прототип (раздел 19.6). Но объекты Turtle никуда не деваются: после
restart() их окажется столько же, сколько было в самой длинной
партии, и каждый из них экран продолжит обслуживать. Поэтому вводим пул
сегментов: один раз созданные черепашки переиспользуются от кадра к кадру, новые
добавляются только когда их действительно не хватает, а лишние прячутся, а не удаляются.
render.py
def render(self):
self.head.goto(*self.state.snake[0])
body = self.state.snake[1:]
self._ensure_segment_pool(len(body))
for i, segment in enumerate(self._segment_pool):
if i < len(body):
segment.showturtle()
segment.goto(*body[i])
else:
segment.hideturtle()
if self.state.food is not None:
self.food_turtle.showturtle()
self.food_turtle.goto(*self.state.food)
else:
self.food_turtle.hideturtle() # WON — свободных клеток не осталось
self._render_scoreboard()
self.screen.update()
Проверка food is not None здесь обязательна
Раздел 19.18 обещал, что отрисовка честно обработает случай, когда свободной клетки для еды не осталось, — вот это место. Без проверки
self.food_turtle.goto(*self.state.food) при food = None падает с TypeError: turtle.TNavigator.goto() argument after * must be an iterable, not NoneType — ровно в момент победы, в самом редком и самом обидном состоянии игры.Пул растёт, но никогда не уменьшается сам по себе
_ensure_segment_pool() добавляет новые Turtle-сегменты, только если их не хватает — уже существующие переиспользуются. Когда змейка становится короче (после restart()), лишние сегменты не удаляются, а просто прячутся через hideturtle() — на следующей долгой игре они снова понадобятся, и пересоздавать их не придётся.Практика: render() и пул сегментов
Модуль turtle открывает нативное окно Python — выполните локально в VS Code, PyCharm или Jupyter
Практика выполняется локально