Teolul
Teolul

Reputation: 31

Python turtle: if statement with position sometimes works and sometimes doesn't

I'm making an adventure/board game where the player can collect an item if he steps on it. So I made the function check_item() to check this:

def check_is_inside_screen(check_x, check_y):
    if check_x < -450 or check_x > 450 or check_y < -350 or check_y > 300:
        return False
    return True

def check_item(player_x, player_y):

    global pick_armor, pick_key, pick_sword

    if not pick_armor and -395 < player_x < -405 and 270 < player_y < 280:
        armor.hideturtle()
        pick_armor = True
    elif not pick_sword and 395 < player_x < 405 and 270 < player_y < 280:
        sword.hideturtle()
        pick_sword = True
    elif not pick_key and 395 < player_x < 405 and -320 < player_y < -330:
        key.goto(400, 325)
        pick_key = True

def move(move_x, move_y):
    player.forward(-100)
    px, py = player.pos()
    if not check_is_inside_screen(px, py):
        player.forward(100)
        return
    check_item(px, py)

def movePlayer():
    player.onclick(move, 1)

The thing is, sometimes it works and sometimes it doesn't. I play test the game and sometimes the armor turtle is successfully hidden, sometimes it just isn't. Also the sword object usually isn't hidden and the key just doesn't work. I tried getting rid of the boolean parameters, but nothing works. It could be also useful to know that the function is called inside of the move() function, which is called from the onclick() event. Basically, whenever I click on the player object, it moves and after that it checks the position.

Upvotes: 0

Views: 718

Answers (1)

cdlane
cdlane

Reputation: 41872

First, turtles crawl a floating point plane so tests like this will sometimes work, and sometimes fail:

x == -400 and y == 275

as x could come back as -400.0001. You could coerce the points to integers:

int(x) == -400 and int(y) == 245

or test if the positions fall within a range of values.

Second, this code in your move() function is suspect:

    player.forward(100)
    return
    tx, ty = player.pos()
    check_item(tx, ty)

There shouldn't be code after a return at the same indentation level -- it will never be executed. I would have expected your code to be more like:

def check_item(x, y):

    global pick_armor, pick_key, pick_sword

    x = int(x)
    y = int(y)

    if not pick_armor and x == -400 and y == 275:
        armor.hideturtle()
        pick_armor = True
    elif not pick_sword and x == 400 and y == 275:
        sword.hideturtle()
        pick_sword = True
    elif not pick_key and x == 400 and y == -325:
        key.goto(400, 300)
        pick_key = True

def move(x, y):

    player.forward(-100)

    tx, ty = player.pos()

    if not -450 <= tx <= 450 or not -375 <= ty <= 325:
        player.backward(-100)
        return

    check_item(tx, ty)

def movePlayer():

    player.onclick(move, 1)

I couldn't test the above without more of your code to work with but hopefully you get the idea.

Upvotes: 1

Related Questions