reggaelizard
reggaelizard

Reputation: 831

Randomly walking turtle function not doing what I want it to

I have to write a programme where a turtle takes 90 degree turns, chosen randomly as left or right, around the screen, until it hits a wall, takes a 180 degree turn and goes back to walking around the screen. When it's hit the wall 4 times, the loop terminates. The problem I'm having is that when it bounces off the wall it just stops walking, and the loop has clearly terminated as I can close the window by clicking on it (wn.exitonclick). Here's the full programme:

import turtle
import random

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 randomWalk(t,w):
    counter = 0

    while isInScreen(w,t) and counter < 4:
        coin = random.randrange(0,2)
        if coin == 0:
            t.left(90)
        else:
            t.right(90)
        t.forward(50)

    t.left(180)
    t.forward(50)
    counter = counter+1

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

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

randomWalk(steklovata,wn)

wn.exitonclick()

I'm confused as to why it stops, considering once the turtle bounces back, its x and y coordinates meet the requirements for isInScreen(w,t) to be true and thus go back to walking. Any ideas?

EDIT: Accepted Sukrit's answer as it was the easiest to relate to what I'd already programmed and gave me a few pointers on other stuff, but Brian's answer was very useful too and I'd accept both if it was possible. Thanks a lot to both of you!

Upvotes: 3

Views: 2352

Answers (3)

Brian
Brian

Reputation: 3131

As an alternative to the nested loops and to avoid some redundant statements, the following should produce the same result as Sukrit's answer.

def randomWalk(t,w):
    counter = 0

    while counter < 4:
        if not isInScreen(w,t):
            t.left(180)
            counter += 1
        else:
            coin = random.randrange(0,2)
            if coin == 0:
                t.left(90)
            else:
                t.right(90)
        t.forward(50)

The core issue is making sure that isInScreen returning false does not cause your while loop to terminate while also incrementing counter within the loop body.

Upvotes: 2

CBredlow
CBredlow

Reputation: 2840

Your big while loop there is the cause of failure and you know that. So what you can do is make the while loop just check the counter only and not do the isInScreen() as part of the while loop. Now for checking if you can go forward, you can cheat by looking before you leap, that is add the value of fifty to your current position and check to see if you will be in screen, if not go forward, otherwise go as close as you can, increment the collision counter, and then turn around. Alternatively, Sukrit Kalra's answer might be easier to implement.

Upvotes: 0

Sukrit Kalra
Sukrit Kalra

Reputation: 34493

Your counter = counter + 1 is wrong. When your isInScreen returns False, the while loop breaks and the code ends, since, the counter is being incremented but you don't loop over again. See the following code -

import turtle
import random

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

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

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

    return True

def randomWalk(t,w):
    counter = 0

    while True:
        while isInScreen(w,t):
            coin = random.randrange(0,2)
            if coin == 0:
                t.left(90)
            else:
                t.right(90)
            t.forward(50)
        t.left(180)
        t.forward(50)
        counter += 1
        if counter == 4:
            break

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

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

randomWalk(steklovata,wn)

wn.exitonclick()

P.S - You don't need a variable to store stillIn, if the if condition evaluates to True, just return False, and if it doesn't return True. (Changes reflected in the above code).

Upvotes: 3

Related Questions