无限循环与两个随机行走的乌龟

时间:2013-08-05 21:13:44

标签: python python-3.x turtle-graphics

在我掌握了我之前的程序(乌龟随机走动并从墙上反弹直到它击中它们4次)后,我尝试在指南中进行以下练习,要求两只乌龟随机起始位置在屏幕上走动并从墙壁反弹直到它们相互撞击 - 没有反向变量来决定它们何时应该停止。我设法写了整个事情,除了它们碰撞和停止的部分:我想了一个布尔函数,如果海龟的X和Y坐标是相同的,则返回True,如果它们不是False t会做这项工作,但他们继续走路,终止程序的唯一方法是强制解释器退出。我做错了什么?

import turtle
import random

def setStart(t):
    tx = random.randrange(-300,300,100)
    ty = random.randrange(-300,300,100)

    t.penup()
    t.goto(tx,ty)
    t.pendown()

def throwCoin(t):
    coin = random.randrange(0,2)

    if coin == 0:
        t.left(90)
    else:
        t.right(90)

def isInScreen(w,t):
    leftBound = w.window_width() / -2
    rightBound = w.window_width() / 2
    bottomBound = w.window_height() / -2
    topBound = w.window_height() / 2

    turtlex = t.xcor()
    turtley = t.ycor()

    stillIn = True

    if turtlex < leftBound or turtlex > rightBound or turtley < bottomBound or turtley > topBound:
        stillIn = False

    return stillIn

def collide(t,u):
    if t.xcor() == u.xcor() and t.ycor() == u.ycor():
        return True
    return False

def randomWalk(t,w):
        if not isInScreen(w,t):
            t.left(180)
        else:
            throwCoin(t)
        t.forward(100)

def doubleRandom(t,u,w):
    while not collide(t,u):
        randomWalk(t,w)
                if collide(t,u):
                   break
        randomWalk(u,w)

wn = turtle.Screen()
wn.bgcolor('lightcyan')

steklovata = turtle.Turtle()
steklovata.color('darkslategray')
steklovata.shape('turtle')
setStart(steklovata)

catshower = turtle.Turtle()
catshower.color('orangered')
catshower.shape('turtle')
setStart(catshower)

doubleRandom(steklovata,catshower,wn)

wn.exitonclick()

编辑:为了测试错误是在collide(t,u)函数中还是在调用它的while循环中,我写了另一个函数来发送两个乌龟到如果collide(t,u)返回True,那么同一个地方并打印出一些文字(如果有人想知道,这是一个内幕笑话,就像我提出的每个翻转名字一样)。当我运行它时,文本DID打印出来,这告诉我碰撞检测工作正常...但是循环不知何故告诉Python龟会在碰撞时停止。这是功能:

def raul(t,u,w):
    t.goto(1,1)
    u.goto(1,1)
    if collide(t,u):
        t.write('RAUL SUNTASIG')

这会给你们任何关于它为什么不起作用的想法吗?

3 个答案:

答案 0 :(得分:1)

编辑:完全改变了答案。

我在collide例程中添加了打印语句并得到了这个:

-300.0 -200.0 -100.0 -100.0
-300.0 -100.0 -100.0 -100.0
-300.0 -100.0 -200.0 -100.0
-300.0 -100.0 -200.0 -100.0
-300.0 1.13686837722e-13 -200.0 -100.0
-300.0 1.13686837722e-13 -200.0 1.27897692437e-13
-300.0 1.13686837722e-13 -200.0 1.27897692437e-13
-200.0 4.02080297728e-14 -200.0 1.27897692437e-13
-200.0 4.02080297728e-14 -200.0 100.0
-200.0 4.02080297728e-14 -200.0 100.0

以下是解决问题的方法:

def collide(t,u):
    if abs(t.xcor() - u.xcor()) < 1 and abs(t.ycor() - u.ycor()) < 1:
        return True
    return False

哦,你应该在每个collide()之后进行randomWalk()检查,而不仅仅是第一次检查。

答案 1 :(得分:0)

您的代码仅在两只乌龟移动后检查碰撞。大约一半的时间,海龟将开始奇数步距离,在这种情况下,当碰撞检测运行时,它们总是相距奇数步。即使其中一个移动到另一个位置,另一个也会在检查碰撞之前移开。要解决此问题,请在移动之间运行额外的碰撞检查:

while not collide(t, u):
    randomWalk(t, w)
    if collide(t, u):
        break
    randomWalk(u, w)

还有另外一件事要考虑;海龟总是右转,或者当它们撞到墙壁时会发出180秒。这引入了类似于上述的奇偶校验问题,如果海龟不能做出正确的转弯序列或者必须等到它们恰好产生正确的墙壁碰撞以将它们指向正确的方向,则可以防止或延迟碰撞。您可以通过让乌龟从所有4个方向随机选择进入来解决这个问题:

def throwCoin(t):
    # 4-sided Ruritanian nickel
    t.left(90*random.randrange(4))

答案 2 :(得分:0)

使用较大的海龟。

如果你目前只是在两只乌龟的x和y坐标完全匹配的情况下称它为碰撞,那将是一个非常难以满足的条件。

如果你想象你的海龟半径为5分,那么当两只海龟的中心点之间的距离小于10时,它们就会发生碰撞。