Python 中使用字典、cTurtle 和递归来创建 L-系统

89 阅读1分钟

在 Python 中使用字典、cTurtle 和递归来创建 L-系统时,遇到以下问题:

  • 如何让规则字典将每个符号映射到一个替代字符串列表,以便在每次需要执行替换时随机选择其中一个字符串?
  • 如何获得字典中与字母 ch 关联的所有值,然后随机选择其中一个?
  • 在调整 applyProduction 函数后,运行 L-系统时出现错误:TypeError: object of type 'NoneType' has no len()

huake_00152_.jpg

2、解决方案

  • 将 applyProduction 函数修改为:
def applyProduction(axiom, rules, n):
http://www.jshk.com.cn/mb/reg.asp?kefu=xiaoding;//爬虫IP免费获取;
    for i in range(n):
        newString = ""
        for ch in axiom:
            listOfRules = rules.get(ch)
            if listOfRules is not None:
                doIt = random.choice(listOfRules)
                newString = newString + doIt
            else:
                newString = newString + ch
        axiom = newString
    return axiom
  • 使用 rules.get(ch) 获取与字母 ch 关联的值,如果找不到则返回 None。
  • 使用 random.choice(listOfRules) 从列表中随机选择一个元素。
  • 如果规则字典中没有找到与字母 ch 关联的值,则将字母 ch 保留不变。

修改后的代码可以正确运行,不会出现 TypeError: object of type 'NoneType' has no len() 错误。

以下是完整的代码:

import random
import turtle

def applyProduction(axiom, rules, n):
    for i in range(n):
        newString = ""
        for ch in axiom:
            listOfRules = rules.get(ch)
            if listOfRules is not None:
                doIt = random.choice(listOfRules)
                newString = newString + doIt
            else:
                newString = newString + ch
        axiom = newString
    return axiom

def drawLS(aTurtle, instructions, angle, distance):
    stateSaver = []
    for cmd in instructions:
        if cmd == 'F':
            aTurtle.forward(distance)
        elif cmd == 'G':
            aTurtle.up()
            aTurtle.forward(distance)
            aTurtle.down()
        elif cmd == 'B':
            aTurtle.backward(distance)
        elif cmd == '+':
            aTurtle.right(angle)
        elif cmd == '-':
            aTurtle.left(angle)
        elif cmd == '[':
            pos = aTurtle.position()
            head = aTurtle.heading()
            stateSaver.append((pos, head))
        elif cmd == ']':
            pos, head = stateSaver.pop()
            aTurtle.up()
            aTurtle.setposition(pos)
            aTurtle.setheading(head)
            aTurtle.down()

def lsystem(axiom, rules, depth, initialPosition, heading, angle, length):
    aTurtle = Turtle()
    aTurtle.speed(0)
    aTurtle.shape('blank')
    aTurtle.up()
    aTurtle.setposition(initialPosition)
    aTurtle.down()
    aTurtle.setheading(heading)
    instructions = applyProduction(axiom, rules, depth)
    drawLS(aTurtle, instructions, angle, length)
    aTurtle.exitOnClick()

if __name__ == '__main__':
    axiom = 'F-F-F'
    rules = {'F': ['F-F-F-GG', 'F+G++F', 'G': 'GG']}
    depth = 3
    initialPosition = (-100, -100)
    heading = 0
    angle = 120
    length = 25
    lsystem(axiom, rules, depth, initialPosition, heading, angle, length)