我必须使用Turtle在Python中编写一个程序,该程序从文件中读取指令列表并根据输入绘制Turtle图。可能的输入是前进,左,右和分离。如果输入被拆分,我必须克隆列表中的所有海龟并将新的海龟附加到列表中。所有新克隆都应向右转x度。问题是,海龟无限期克隆。
setInterval("myFunction()", 1);
function myFunction() {
if document.getElementById("demo").hasFocus; {
document.getElementById('pic1').src='https://pbs.twimg.com/profile_images/701853789855346689/iKxIyGkO.png';
} else {
document.getElementById('pic1').src='https://pbs.twimg.com/profile_images/688766010837446657/2DgfpAQ6.png';
}
}
方向是一个元组列表,其中每个元组的第一个值是命令(例如向前,向左,向右或分离),第二个是度数(前进多远,转动多少度)。但乌龟继续永远克隆。如何调整此代码以便只克隆给定次数?这是我的示例输入文件:
<div style="border-style: solid;height:20px;" id="demo"></div>
<img id="pic1" src="https://pbs.twimg.com/profile_images/688766010837446657/2DgfpAQ6.png">
答案 0 :(得分:0)
首先,您遇到了逻辑错误。你的外循环遍历海龟,然后在循环内部,它分别处理所有每只乌龟的步骤。这是不正确的;即使它有效,它也会在之前将的指令应用于它之后创建的海龟。 (这将有效地将前面的指令两次应用于同一只乌龟,以及再次执行拆分 。)您需要在所有海龟上一次处理一个步骤。所以循环需要在方向上,而不是乌龟:
for step in directions:
# Process the step
现在我们已经交换了循环,解决方案变得更加明显。我们可以检查该步骤并对'split'
案例进行特殊处理:
for step in directions:
if step[0] == 'split':
# Clone all the turtles here
else:
for turt in turtles:
if step[0] == 'forward':
turt.forward(step[1])
elif step[0] == 'left':
...
我选择对运动案例使用单个循环,但如果您愿意,每个案例都有一个循环同样有效。
我们仍然遇到创建克隆并将其添加到列表中的问题。您已经看到不会工作:
for turt in turtles:
turtles.append(turt.clone())
因此我们需要存储所有这些新克隆而不修改我们正在循环的列表。我们可以用临时列表来做到这一点:
turtle_clones = []
for turt in turtles:
turtle_clones.append(turt.clone())
然后我们只需要将turtle_clones
放在turtles
的末尾。我将两个列表结合起来作为练习。
以下是一些使您的代码更清晰的建议:
使用解包,这样您就不必在任何地方都有索引。
您实际上不需要使用索引访问step
中的两个数据。您可以使用解包将每个元素放在自己的变量中:
for action, value in directions:
if action == 'split':
...
else:
...
turt.forward(value)
这使您的代码更简单易读,但您可能会想到value
更好的名称。
您实际上不必使用显式临时列表和for
循环来制作克隆。您可以使用列表理解:
turtle_clones = [t.clone() for t in turtles]
再次,更简单易读。
first
变量似乎不必要。您可以直接初始化包含第一只乌龟的列表:
turtles = [turtle.Turtle()]