我尝试使用Python 3中的turtles模块重新创建此处的分形: https://en.wikipedia.org/wiki/L-system#Example_7:_Fractal_plant 但每当我尝试它时,它给我一个非常奇怪的结果......
这是我的代码:
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()
我对所有内容进行了三重检查,但我似乎没有错误 - 但它仍然无效。我做错了什么?
提前感谢您的帮助!
答案 0 :(得分:1)
根据维基百科页面,符号'['表示保存当前状态(角度和位置)。匹配']'表示恢复先前保存的位置。因为'['和']'可以嵌套,所以需要堆栈。
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()
. . .
答案 1 :(得分:1)
您的代码中存在两个问题。
首先,您的代码无法正确处理嵌套括号。当看到外部开口支架时,内部开口支架将其状态保存在保存的先前状态的顶部上方。这对于像[[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()
第二个问题更为微不足道。您的解析器会查找“减号”字符(-
)。但是,您的模式生成代码使用了另一种稍长的破折号(−
)。更改其中一个以匹配另一个(这并不重要),您的代码将按预期工作。