2

我正在尝试使用 L 系统生成一棵简单的树。但是,当我运行我拥有的代码时:

import turtle


def generate(length):
    sentence = "F"
    for j in range(1, length):
        for i in sentence:
            if i == "F":
                sentence += "FF+[+F-F-F]-[-F+F+F]"

        print(sentence)


    gen = turtle.Turtle()
    window = turtle.Screen()
    gen.left(90)

    for k in sentence:
        if k == "F":
            gen.forward(10)
        elif k == "+":
            gen.right(10)
        elif k == "-":
            gen.left(10)
        elif k == "[":
            location = gen.position()
        elif k == "]":
            gen.setposition(location)

我在海龟窗口中得到一个奇怪的纹理图案:

龟窗

我怎样才能产生想要的结果?

4

1 回答 1

1

您的+=操作将产生式规则的应用附加到字符串,但其想法是用产生式规则的结果替换每个出现的"F"字符。

您可以使用 来执行此操作string#replace,它会替换每个出现的子字符串。您在编辑之前使用了它,但没有将函数的返回值分配回原始sentence变量(replace不能就地工作并且字符串是不可变的)。

无论哪种方式,额外的内部循环都是不必要的。

另一个重点:生产规则是递归的,因此单个location变量不足以“记住”可能已执行的推送序列。

sentence详细说明,这是在多次迭代中应用生产规则后变量的摘录:

...[-FF+[+F-F-F]-[-F+F+F]+...

很明显,这在遇到[a 之前有两个顺序操作]。这种嵌套可以任意深。堆栈数据结构是跟踪嵌套递归位置的最佳方式(只能location跟踪最后一个,并且当两个推送操作连续发生时状态将被破坏)。

每当[遇到操作时,将位置推入堆栈(在 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()
于 2020-01-22T20:13:46.123 回答