HDCerberus
HDCerberus

Reputation: 2143

New Value not being retained

I'm writing my first program which is a 'Trivia' style game. Questions are asked based on the round you've selected, so selecting round 1 gives you questions from list 1, round 2 questions from list 2 etc.

I've written a piece of code which allows you to change rounds mid game, but if you do this only the first question asked comes from the new round, any subsequent question asked reverts back to the previous round.

So:

  1. I select round 1.
  2. Get asked questions from round 1.
  3. Switch to round 2.
  4. Get asked a single question from round 2.
  5. All the questions after that revert back to round 1.

I'm not sure why, and I can't seem to find any reason it should do this.

A stripped down version of the code with the problem is:

round = raw_input ("Round?: ")

def turn(round):
    print "Current Round = " + round 
    if round == "1":
        print (choice (ssq1))
        play_again = raw_input("Again?: ")
        repeat(play_again)

    elif round == "2":
        print (choice (ssq2))
        play_again = raw_input("Again?: ")
        repeat(play_again)

def repeat(play_again): 

    if play_again == "Yes" or play_again == "Y":
        turn(round)

    elif play_again == "New":
        new_round = True
        new_turn(new_round)

def new_turn(new_round):
    round = raw_input("Okay, Which round?: ")
    turn(round)

from random import choice

ssq1 = ["Round1Q1", "Round1Q2", "Round1Q3"]
ssq2 = ["Round2Q1", "Round2Q2", "Round2Q3"]

turn(round)

Upvotes: 1

Views: 52

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1121346

round in repeat() is the global variable, the one set right at the start. You need to pass in the current round instead; the local name round used in turn():

repeat(play_again, round)

and use that in the repeat() function as an additional argument:

def repeat(play_again, round): 
    if play_again == "Yes" or play_again == "Y":
        turn(round)

    elif play_again == "New":
        new_round = True
        new_turn(new_round)

Your recursive functions are rather convoluted. Consider using a while loop instead:

def turn(round):
    print "Current Round = " + round 
    if round == "1":
        print (choice (ssq1))

    elif round == "2":
        print (choice (ssq2))

round = None

while True:
    if round is None:
        round = raw_input ("Round?: ")

    turn(round)

    play_again = raw_input("Again?: ")
    if play_again == 'New':
        # clear round so you are asked again
        round = None
    elif play_again not in ('Yes', 'Y'):
        # end the game
        break

Now the turn() function only handles a turn of the game. Repetition, asking for what round to play and ending the game is all handled in the one endless while loop. The break statement is used to end that loop.

Another improvement you could consider is using a dictionary or list to hold your rounds, instead of sequentially named variables:

round_questions = {
    "1": ["Round1Q1", "Round1Q2", "Round1Q3"],
    "2": ["Round2Q1", "Round2Q2", "Round2Q3"],
}

This removes the need to use a large set of conditionals; you simply retrieve the right list by key instead:

def turn(round):
    if round in round_questions:
        print "Current Round = " + round 
        ssq = round_questions[round]
        print choice(ssq)

    else:
        print "No such round", round

This makes handling erroneous input easier too; if the picked round is not a key in the dictionary, the first if statement will be false and you can print an error message instead.

Note that by using round as a variable name, you are masking the built-in function by the same name. That's fine here, you are not using any maths that requires rounding, but take that this into account if you ever did need to use that function.

Upvotes: 2

Related Questions