Странная L-система в графике Python Turtle

Я пытался использовать модуль черепах в Python 3, чтобы воссоздать фрактал, найденный здесь: https://en.wikipedia.org/wiki/L-system, но всякий раз, когда я пытаюсь это сделать, он дает мне очень странный результат..,

Вот мой код:

import turtle
wn = turtle.Screen()
wn.bgcolor("white")
wn.screensize(10000, 10000)

tess = turtle.Turtle()
tess.color("lightgreen")
tess.pensize(1)
tess.speed(0)
tess.degrees()

inst = 'X'
steps = 3

for counter in range(steps):
    _inst = ''
    for chtr in inst:
        if chtr == 'X':
            _inst += 'F−[[X]+X]+F[+FX]−X'
        elif chtr == 'F':
            _inst += 'FF'
        else:
            _inst += chtr
    inst = _inst
    print(inst)


for chtr in inst:
    if (chtr == 'F'):
        tess.forward(25)
    elif (chtr == '+'):
        tess.right(25)
    elif (chtr == '-'):
        tess.left(25)
    elif (chtr == '['):
        angle = tess.heading()
        pos = [tess.xcor(), tess.ycor()]
    elif (chtr == ']'):
        tess.setheading(angle)
        tess.penup()
        tess.goto(pos[0], pos[1])
        tess.pendown()
wn.exitonclick()

Я трижды проверил все, и у меня, кажется, нет ошибок - но это все еще не работает. Что я делаю ужасно неправильно?

Заранее благодарю за любую помощь!

2 ответа

Решение

В вашем коде есть две проблемы.

Во-первых, ваш код неправильно обрабатывает вложенные скобки. Внутренняя открывающая скобка сохраняет свое состояние поверх предыдущего состояния, сохраненного при просмотре внешней открывающей скобки. Это не имеет значения для сразу вложенных скобок, таких как [[X]+X] (поскольку оба имеют одинаковое начальное состояние), но как только вы получаете более сложное вложение (как вы это сделаете после нескольких циклов замещения), проблема начинает приводить к ошибкам.

Чтобы решить эту проблему, вы, вероятно, хотите сохранить ваши сохраненные значения состояния в стек (list сможет сделать). Нажмите на значения, которые вы хотите сохранить, и отбросьте их обратно, когда вы будете готовы восстановить их.

stack = [] # use a list for the stack
for chtr in inst:
    if (chtr == 'F'):
        tess.forward(25)
    elif (chtr == '+'):
        tess.right(25)
    elif (chtr == '-'):
        tess.left(25)
    elif (chtr == '['):
        angle = tess.heading()
        pos = [tess.xcor(), tess.ycor()]
        stack.append((angle, pos)) # push state to save
    elif (chtr == ']'):
        angle, pos = stack.pop()  # pop state to restore
        tess.setheading(angle)
        tess.penup()
        tess.goto(pos[0], pos[1])
        tess.pendown()

Второй вопрос более тривиален. Ваш парсер ищет символ "минус" (-). Но в вашем коде, генерирующем шаблоны, используется несколько более длинная черта (). Измените один из них, чтобы он соответствовал другому (не имеет значения, какой именно), и ваш код будет работать так, как ожидается.

Согласно странице Википедии, символ "[" означает сохранение текущего состояния (угол и положение). Соответствие ']' означает восстановление ранее сохраненной позиции. Поскольку '[' и ']' могут быть вложенными, необходим стек.

from collections import deque

...

stack = deque()

for chtr in inst:
    if (chtr == 'F'):
        tess.forward(25)

    elif (chtr == '+'):
        tess.right(25)

    elif (chtr == '-'):
        tess.left(25)

    elif (chtr == '['):
        angle = tess.heading()
        pos = [tess.xcor(), tess.ycor()]
        stack.append((angle, pos))         ### New statement

    elif (chtr == ']'):
        angle, pos = stack.pop()           ### New statement
        tess.setheading(angle)
        tess.penup()
        tess.goto(pos[0], pos[1])
        tess.pendown()

. . .
Другие вопросы по тегам