Ваша операция +=
добавляет к строке применение производственного правила, но идея состоит в том, чтобы заменять каждое вхождение символа "F"
результатом производственного правила.
Вы можете сделать это с помощью string#replace
, который заменяет каждое вхождение подстрока. Вы использовали это перед редактированием, но не присвоили возвращаемое значение функции обратно исходной переменной sentence
(replace
не работает на месте, а строки неизменяемы).
В любом случае дополнительный внутренний цикл не нужен.
Еще один важный момент: производственное правило является рекурсивным, поэтому одной переменной location
недостаточно места для «запоминания» последовательности толчков, которые могли быть выполнены.
Чтобы уточнить, вот выдержка из вашей переменной sentence
после применения производственного правила на нескольких итерациях:
...[-FF+[+F-F-F]-[-F+F+F]+...
Понятно, что здесь есть две последовательные операции [
, прежде чем встретится ]
. Это вложение может расти сколь угодно глубоко. Структура данных стека — лучший способ отслеживать вложенные рекурсивные позиции. (location
может отслеживать только последнее, и состояние будет повреждено, если две операции push будут выполняться последовательно).
Всякий раз, когда встречается операция [
, помещайте позицию в стек (представленную в Python как список, который использует только append
(для отправки) и pop
без каких-либо аргументов, чтобы удалить конец списка). Всякий раз, когда встречается операция ]
, извлекайте стек и устанавливайте положение черепахи в это место.
В качестве второстепенного момента рекомендуется убрать жестко закодированные значения из кода; сгруппируйте все ваши настройки / конфигурации в верхней части блока. Если вы используете функцию, задайте эти параметры.
Вот рабочая версия:
import turtle
generations = 3
size = 10
rule = ("F", "FF+[+F-F-F]-[-F+F+F]")
sentence = "F"
positions = []
gen = turtle.Turtle()
gen.speed(10)
gen.left(90)
for i in range(generations):
sentence = sentence.replace(*rule)
for op in sentence:
if op == "F":
gen.forward(size)
elif op == "+":
gen.right(size)
elif op == "-":
gen.left(size)
elif op == "[":
positions.append(gen.position())
elif op == "]":
gen.setposition(positions.pop())
turtle.exitonclick()
person
ggorlen
schedule
22.01.2020
sentence.replace
не делает того, что вы думаете, - он заменяет каждое вхождение первого параметра вторым, а не делает это на месте. Кроме того, я не уверен, чего вы пытаетесь достичь. - person ggorlen   schedule 22.01.2020