Python 两个随机行走的海龟的无限循环

Python 两个随机行走的海龟的无限循环,python,python-3.x,turtle-graphics,Python,Python 3.x,Turtle Graphics,在我掌握了我上一个节目的诀窍(海龟随机行走并从墙上反弹,直到撞到它们4次)之后,我尝试在指南中做以下练习,这就要求两只乌龟在屏幕上随意走动,然后从墙上弹下来,直到它们撞到对方——没有反变量来决定它们什么时候应该停下来。我成功地编写了整个程序,除了它们碰撞并停止的部分:我认为如果海龟的X和Y坐标相同,则返回True的布尔函数,如果海龟的X和Y坐标不相同,则返回False即可,但相反,他们继续前行,而终止节目的唯一办法就是迫使口译员退出。我做错了什么 import turtle import ran

在我掌握了我上一个节目的诀窍(海龟随机行走并从墙上反弹,直到撞到它们4次)之后,我尝试在指南中做以下练习,这就要求两只乌龟在屏幕上随意走动,然后从墙上弹下来,直到它们撞到对方——没有反变量来决定它们什么时候应该停下来。我成功地编写了整个程序,除了它们碰撞并停止的部分:我认为如果海龟的X和Y坐标相同,则返回
True
的布尔函数,如果海龟的X和Y坐标不相同,则返回
False
即可,但相反,他们继续前行,而终止节目的唯一办法就是迫使口译员退出。我做错了什么

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
例程中添加了打印语句,得到了以下结果:

-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
def碰撞(t,u):
如果abs(t.xcor()-u.xcor())小于1且abs(t.ycor()-u.ycor())小于1:
返回真值
返回错误

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

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

while not collide(t, u):
    randomWalk(t, w)
    if collide(t, u):
        break
    randomWalk(u, w)
还有一件事要考虑;海龟们总是右转,或者撞到墙上时转180度。这引入了与上述类似的奇偶性问题,如果海龟不能右转,或者必须等到右壁碰撞时才能将它们指向正确的方向,则可能会阻止或延迟碰撞。你可以通过让海龟随机选择四个方向来解决这个问题:

def throwCoin(t):
    # 4-sided Ruritanian nickel
    t.left(90*random.randrange(4))
使用较大的海龟

如果你现在只称之为碰撞,如果两个海龟的x和y坐标完全匹配,那将是一个很难满足的条件


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

我甚至还没有看过代码,但问题是它们会在碰撞检查发生之前停止相交吗?例如,一只海龟在
(0,0)
处转到
(1,0)
,另一只海龟从
(1,0)
,转到
(0,0)
,然后冲突逻辑认为它们没有相互碰撞?我认为根据Python的逻辑,一只海龟是从,
0,1
0,0
,紧接着另一个从
1,0
0,0
,所以我认为坐标应该是相同的,但是第一只乌龟会再次行走,而另一只乌龟也会再次行走,而不是两只乌龟都停在原地。只有当它们开始彼此相距偶数步时,才会发生这种情况。如果它们从
(0,0)
(0,1)
开始,碰撞检测器将永远不会注意到它们发生碰撞。您的代码是否在某些时间停止?如果是,大约多久一次?一半时间?更少?发现了问题。看看我的编辑。一枚三面硬币?:)@jwygralak67:10边。:)它们一次只移动100步,它们的起始坐标总是100的倍数,这使得它们相遇的几率要大得多(事实上,我见过它们相遇好几次)。如果我将条件更改为
(abs(t.xcor()-u.xcor),可能会发生什么情况<10
等等。我更改了它,使它们在每次距离小于10时发生碰撞,它们走了100步才停下来,尽管它们彼此相距很远。每次我运行它时,它们都会在每转一圈后停下来。你知道为什么会发生这种情况吗?你还必须检查y坐标。你真的应该做一些类似sqrt(xx+yy)的事情其中x是x-coords和y之间的差值-两只海龟y-coords之间的差值。我只试了一次,它成功了,所以我又试了两次,看看它是否每次都有效,但都没有。我认为区别在于第一次两只海龟都没有撞到墙,但第二次它们撞到了,但我不知道这是怎么回事完成冲突检测,我很惊讶它不起作用,因为您的代码似乎很有意义。@reggaelizard:发布了另一个问题。我不确定它是否真的可以防止冲突,但修复它可能会使冲突发生得更快,如果您没有等待足够长的时间来查看结果,这可能很重要。仍然不会当然,碰撞已经发生了好几次,但它们并没有停止。(虽然很好的Ruritanian镍币,和我的海龟很相配,它是以一个俄罗斯男孩乐队的名字命名的)。
def throwCoin(t):
    # 4-sided Ruritanian nickel
    t.left(90*random.randrange(4))