Reputation: 73
The program works but when it hits a wall the turtle undo's the last step and tries again. However, it keeps inputting the same forward distance and angle causing it to move in the same path in a loop. Is there a way to stop the turtle from taking the same value again?
from turtle import Turtle, Screen
import random
def createTurtle(color, width):
tempName = Turtle("arrow")
tempName.speed("fastest")
tempName.color(color)
tempName.width(width)
return tempName
def inScreen(screen, turt):
x = screen.window_width() / 2
y = screen.window_height() / 2
turtleX, turtleY = turt.pos()
if not (-x < turtleX < x) and (-y < turtleY < y):
return False
return True
def moveTurtle(screen, turt):
while True:
while inScreen(screen, turt):
turt.fd(random.randrange(100))
turt.left(random.randrange(360))
if (inScreen(screen, turt) == False):
turt.undo()
continue
wn = Screen()
alpha = createTurtle("red", 3)
moveTurtle(wn, alpha)
wn.exitonclick()
Upvotes: 0
Views: 251
Reputation: 41872
My belief is that the problem with your code is this logic:
while inScreen(screen, turt):
turt.fd(random.randrange(100))
turt.left(random.randrange(360))
if (inScreen(screen, turt) == False):
turt.undo()
When you invoke undo()
, you're only undoing the last thing that happened, so you're undoing the left()
but not the fd()
(forward). On error you keep going further and further off screen and take longer to get back. If we undo both operations (two undo()
calls), or reverse the order of operations and only undo the forward, then your random motion will correct itself much faster. No need to adjust the heading.
Here's a rework of your code to fix the above, and eliminate the while True:
logic which doesn't belong in an event-driven program and keeps exitonclick()
from working correctly:
from turtle import Turtle, Screen
import random
def createTurtle(color, width):
turtle = Turtle('arrow')
turtle.speed('fastest')
turtle.color(color)
turtle.width(width)
return turtle
def inScreen(screen, turtle):
x = screen.window_width() / 2
y = screen.window_height() / 2
turtleX, turtleY = turtle.pos()
return (-x < turtleX < x) and (-y < turtleY < y)
def moveTurtle():
turtle.left(random.randrange(360))
turtle.forward(random.randrange(100))
if not inScreen(screen, turtle):
turtle.undo() # undo forward()
screen.ontimer(moveTurtle, 50)
screen = Screen()
turtle = createTurtle('red', 3)
moveTurtle()
screen.exitonclick()
Note that you can now click on the screen at any time to exit. With your original code, clicking on the screen did nothing on my system.
Upvotes: 1
Reputation: 1714
I do not think that it keeps moving in the same path. I tried running your code and it keeps giving the turtle a new forward amount and rotation. If you wait long enough it will eventually move from that spot.
The reason it appears that it is not moving in the spot is that it keeps attempting to go to a new spot, but it has a very high chance of picking a random value which puts the turtle outside the screen bounds again.
I would maybe guide the turtle to the opposite angle direction of the bounds if it goes outside the bounds because right now it is just repeatedly choosing random values.
Upvotes: 1