0

I am creating a game of pick up sticks for a class. Our goal is to create a function that loops 4 other functions to run the game.

main():
  while numb_sticks > 1:
    func1()
    func2()
    func3()
    func4()
  else:
    print("Player {} wins!")

My problem is keeping the values I changed from one function onto the next. I have numb_sticks declared outside my functions, as well as the starting player.

numb_sticks = 20
player = 1

I have print() throughout my functions to keep track of what values are changing. I have determined that as a function is completed, the numb_stick and player values revert to their original value outside the function. This essentially creates an endless loop where the number of sticks always reverts to 20 and the turn is always for player 1. I am required to use these two variables as parameters for my functions. I do not know how to fix this. Below is the entirety of my code. I put comments along the entire program to explain what I am doing.

pick_up_sticks.py


import random

def not_quite_right(numb_sticks): #This function creates a chance to add sticks to the game.
    global sticks_added #Declaring variables global to be changed across program.
    global sticks_remaining
    print("Initial numb_sticks nqr:", numb_sticks) #Testing change.
    n = random.randint(1,10) #This and the next line set up the %30 chance for more sticks.
    if n > 7: 
        sticks_added = random.randint(1,4) #This sets up a random amount of sticks between 1-4 to be added.
        if numb_sticks + sticks_added <= 20: #Checks if cap is exceeded.
            numb_sticks += sticks_added #Adding sticks to pile.
            print(numb_sticks) #Testing change, will remove on final.
            return
        else:
            sticks_added = 20 - numb_sticks #This is a small work around if the sticks added would have been more than 20.
            numb_sticks = 20
            return
    else: #The following complets the 70% chance of no sticks being added.
        sticks_added = 0
        return
"""
---
"""
def take_sticks(player, numb_sticks):
    global sticks_taken #Setting variables as global for use across program.
    global sticks_remaining
    print("Initial numb_sticks ts:", numb_sticks) #Test before change.
    if numb_sticks > 1: #Checks if game is still going.
        sticks_taken = input("Player {}, choose how many sticks you would like to take: ".format(player)) #Lets player choose stick amount.
        try: #Next 4 lines check if the input is a number and restarts turn if it isn't.
            int(sticks_taken)
        except ValueError:
                print("Invalid input! Please type a number.")
                take_sticks(player, numb_sticks)
        sticks_taken = int(sticks_taken) #Sets input as integer.
        if sticks_taken <= 0 or sticks_taken >= 4: #Next 3 lines check if inputted number is legal move and restarts turn if it isn't.
            print("You can only take 1, 2, or 3 sticks.")
            take_sticks(player, numb_sticks)
        elif sticks_taken < 4 and sticks_taken > 0: #Determines legal move.
            numb_sticks -= sticks_taken #Sets sticks remaining by removing sticks taken from original 20 sticks.
            print("Numb_sticks:", numb_sticks) #Test change.
            if player == 1: #Next 5 lines changes players turn.
                player = 2
                print("Next turn is player", player,"'s turn.'") #Test player change.
                return
            else:
                player = 1
                return
            return
        else:
            return
    else:
        return
    
def display_board(numb_sticks): #This function states how many sticks there are at the start of the turn.
    print("There are", numb_sticks, " sticks on the board.")

def display_summary(player, sticks_taken, sticks_added, numb_sticks): #The following function simply displays the remaining sticks and the next players turn.
    print("Player", player,"took", sticks_taken, "sticks, pictsie added", sticks_added, "sticks back, leaving", numb_sticks, "sticks.")
            
def main(): #Creating a loop for the game.
    numb_sticks = 20 #Setting the number of sticks.
    player = 1 #Sets player 1 to start.
    while numb_sticks > 1:
        display_board(numb_sticks)
        take_sticks(player, numb_sticks)
        not_quite_right(numb_sticks)
        display_summary(player, sticks_taken, sticks_added, sticks_remaining)
    else:
        print("Player {} has won the game!".format(player)) #Declares a player the winner!

main() #Begins the game!
Luis
  • 3
  • 2
  • 1
    Does this answer your question? [Using global variables in a function](https://stackoverflow.com/questions/423379/using-global-variables-in-a-function) – Kolmar Nov 11 '20 at 06:05
  • 2
    A function has its own variable namespace. You should use arguments and return values for your functions to transfer values between them. Or use classes they have instance attributes which can be accessed in every instance method. Try not to use `global` it is considered less beautiful. – Klaus D. Nov 11 '20 at 06:08

2 Answers2

0

So, did you try passing your global values, declared in main() as parameters in the functions? This way your global values are always tied into the functions.

def main():
    numb_sticks = 20
    player = 1
    if numb_sticks > 1:
        func1(numb_sticks, player)
        func2(numb_sticks, player)
    else:
        print("Player {} wins!")

def func1(numb_sticks, player):

def func2(numb_sticks, player):
tym
  • 63
  • 8
  • I have, all of my functions use numb_sticks as a parameter. The issue lies in returning to the beginning of the loop. At the end of the loop, the correct number of sticks are shown by the function display_summary(). Immediately after, the number of sticks shown by the function display_board() is 20. I cannot figure out what is causing the value to revert to 20, as well as the player to 1. – Luis Nov 11 '20 at 06:47
0

The reason for your infinite loop is that wherever numb_sticks is being decremented or incremented, numb_sticks is a temporary local variable (well, it's a parameter, which is also a temporary variable, just as a local variable is). Once the function reaches the end of that particular invocation, the temporary variable numb_sticks (along with its decremented or incremented value) is gone.

There are many ways of fixing this.

I got rid of the infinite loop with the following changes:

  1. Modified the functions not_quite_right() and take_sticks() so that every return is changed to return numb_sticks. This will return the local variable's (incremented or decremented value) to the calling point where the function was invoked.

  2. Next, I modified the body of the while loop in your main() function as below:

    display_board(numb_sticks)
    numb_sticks = take_sticks(player, numb_sticks)
    numb_sticks = not_quite_right(numb_sticks)
    display_summary(player, sticks_taken, sticks_added, sticks_remaining)
    

The game ended in about 5 moves.

fountainhead
  • 3,584
  • 1
  • 8
  • 17
  • Thank you! With some tinkering, these and a couple other changes made the game play exactly as intended. I also moved the player change to the bottom of the main() function. – Luis Nov 12 '20 at 04:50