1

This program is a snakes and ladders program for my GCSE computer science (don't worry, this is just practice), and I'm having trouble breaking a while loop with a function that exists inside the loop. Here's the code:

win = False

while win == False:
    print("Player 1 goes first.")

    def dice():
        roll = random.randint(1,6)
        return roll

    roll = dice()
    print("They roll a...",roll)
    player1+=roll

    def check():
        if player1 in ladders or player2 in ladders:
            print("A ladder has moved the player to a new position.")
        elif player1 in snakes or player2 in snakes:
            print("A snake has moved the player to a new position.")
        elif player1 >= 36:
            print("Congratulations. Player 1 has won the game.")
            win = True
        elif player2 >= 36:
            print("Congratulations. Player 2 has won the game.")
            win = True

    check()

    print("Player 1 is on square",player1)

It's obviously not finished yet, and that's not all the code. After that bit, it does the same but with player2. There's a tuple above it that the check function checks to see if the player landed on a snake or a ladder, but I haven't added the code which actually moves the player up/down the ladder/snake.

The error is that the while loop is an infinite loop.

I've tried changing the whole win = False or True thing to just while True and then using break where I say win = True, but then it returns an error of 'break outside loop' even though the break is obviously inside the loop. I wonder if it's because I need to return something from the function, but I'm not quite sure how to do that. Simply putting 'return win' below both win = True doesn't change anything, and the while loop still continues indefinitely.

I've looked here and here for answers but neither worked for me; I think my situation is slightly different.

TaraF13
  • 13
  • 1
  • 4

2 Answers2

1

It happened because when you are assign variable in function it used local variable. So, for a fast fix you can add global win in check function:

def check():
    global win
    if player1 in ladders or player2 in ladders:
        print("A ladder has moved the player to a new position.")
    elif player1 in snakes or player2 in snakes:
        print("A snake has moved the player to a new position.")
    elif player1 >= 36:
        print("Congratulations. Player 1 has won the game.")
        win = True
    elif player2 >= 36:
        print("Congratulations. Player 2 has won the game.")
        win = True

You can read more about type of variables here - http://www.python-course.eu/python3_global_vs_local_variables.php

Also it's not a good idea to store function inside while because it will create function on each iteration which is not good. So better is define them outside of loop.

Mentos
  • 168
  • 12
1

Perhaps this is what you are looking for? Note how I took the functions out of the loop. Then I ditched using a boolean variable altogether, as there is cleaner ways around it. You can use while True and then simply break if a certain condition is met. If you want the loop go back to starting point when a certain condition is met, you can use continue.

def dice():
        return random.randint(1,6)


def check():
        if player1 in ladders or player2 in ladders:
            print("A ladder has moved the player to a new position.")
        elif player1 in snakes or player2 in snakes:
            print("A snake has moved the player to a new position.")
        elif player1 >= 36:
            print("Congratulations. Player 1 has won the game.")
            return True
        elif player2 >= 36:
            print("Congratulations. Player 2 has won the game.")
            return True

while True:
    print("Player 1 goes first.")

    roll = dice()
    print("They roll a...",roll)
    player1 += roll

    if check():
        break

    print("Player 1 is on square",player1)

I didn't really touch the logic but it would make sense to pass the player score into check.

Luke
  • 744
  • 2
  • 7
  • 23
  • 1
    I'm not sure how I would pass the player score into check, functions sort of confuse me, but what you've given seems to work fine as player1 and player2 variables aren't reset every time check is run. Thank you! – TaraF13 Aug 14 '17 at 10:27
  • @TaraF13 If functions confuse you then they are definitely something worth reading about and learning, they are one of the biggest fundamentals of programming, especially in functional programming languages like python – Nick is tired Aug 14 '17 at 10:32
  • @TaraF13 I'd definitely suggest watching [this video](https://www.youtube.com/watch?v=9Os0o3wzS_I). It will help you get a better understanding of functions in Python. – Luke Aug 14 '17 at 10:40