0

I'm writing a program that simulates a game of Bunko for my compSci class, but I'm having issues getting the function scoreCalc to modify the global variable playerScore. The game pits a player against the computer, so I wanted to be able to use one function to determine the score and just pass an in argument to increment the correct score respectively. However, the function is not saving the value of playerScore across multiple plays, resetting to 0 with each round. I'm new to functions, so I'm sure the issue is likely something trivial, but I appreciate any and all help!

dieList = []
sixCount = 0
playerScore = 0


def rollDice():    
    global sixCount
    sixCount = 0
    dieList.clear()

    die1 = random.randint(1,6)
    die2 = random.randint(1,6)
    die3 = random.randint(1,6)

    dieList.append(die1)
    dieList.append(die2)
    dieList.append(die3)

    print(dieList)

    for x in dieList:
        if x == 6:
            sixCount += 1
    print("sixCount:", sixCount)
    return


def scoreCalc(x):
    if sixCount == 1:
        x += 1
    elif sixCount == 2:
        x += 5
    elif sixCount == 3:
        x += 21
    return x


print()
print("Player's turn!")
print('*' * 30)
input("Press ENTER to roll the dice")
print()
rollDice()
print("Score:", scoreCalc(playerScore))
npburns224
  • 632
  • 7
  • 11

2 Answers2

6

If you pass playerScore as a parameter and then do operations on it inside a function, the global variable playerScore won't be changed.

Why? Numbers in Python are immutable.

Wait, what?? Yes, when you do any operation on a number and populate some variable with the result (e.g. i += 2), a new number object is created. So, when you pass playerScore to a function, a whole new object is getting passed, so, what scoreCalc gets is not the actual playerScore, but its copy. Needless to say that changing the copy doesn't change the original.

The following will do the trick:

def scoreCalc():
    global playerScore

    if sixCount == 1:
        playerScore += 1
    elif sixCount == 2:
        playerScore += 5
    elif sixCount == 3:
        playerScore += 21

    return playerScore
Community
  • 1
  • 1
ForceBru
  • 43,482
  • 10
  • 63
  • 98
  • Thank you for the tip! I wasn't aware of that property of numbers. You've got me a little closer to the goal, but I still would like to use the same function to modify the computer score – npburns224 Sep 23 '16 at 21:09
1

You clearly know how to modify a global variable, which you did for sixCount. You probably used to do that with playerScore, but changed it when trying to make the function useful for calculating anybody's score (stated goal in the OP).

In order to make the function work like a function, it needs to be ... a function. Meaning that it takes an input and gives an output, and nothing else matters. You then just need to use that output.

def scoreCalc(sixCount):
    x = 0
    if sixCount == 1:
        x += 1
    elif sixCount == 2:
        x += 5
    elif sixCount == 3:
        x += 21
    return x

# now use it
playerScore += scoreCalc(sixCount)

Notice how scoreCalc doesn't care about any global variables. It just gives the score for its input. You then apply that score where it belongs.

These functions might also be useful. It's better not to give them any global variables. Handle the results where they matter, and just let these functions do their job, and nothing else.

# return a list of d6 outputs
def rollDice(number_of_dice):
    return [random.randint(1,6) for _ in range(number_of_dice)]

# takes a list of d6 outputs and returns the count of sixes    
def countSixes(dieList):
    return sum([1 for x in dieList if x==6])
Kenny Ostrom
  • 5,639
  • 2
  • 21
  • 30