All my code is below.
Just started learning to program this week. I'm attempting to make a Monty Hall simulator (text only) where the player chooses a door by selecting 1, 2 or 3. For some reason, though, Python doesn't seem to be recognizing the input!
Here are links to the game for the uninitiated:
Monty Hall wikipedia page
Monty Hall simulation
What my program attempts to do is as follows. First the player chooses a door, either 1, 2 or 3. Then the program checks to make sure that the player did indeed enter one of those three numbers. If not, then the person needs to choose again.
After this, the game randomly chooses a winning door. Then, per the rules of the game, the program needs to reveal a dummy prize (the goat). So the program randomly chooses one of the doors to be the "goat door." The program first makes sure that this door is not the winning door nor is it the chosen door.
Here's the error I get when running my code:
line 52, in <module>
doors()
line 14, in doors
while goatDoor == chosenDoor or goatDoor == winningDoor:
NameError: name 'chosenDoor' is not defined
My issue is that I can't tell why it keeps saying that chosenDoor is not defined!
Here's the code:
import random
def chooseDoor(): # choose a door
chosenDoor = ''
while chosenDoor != 1 and chosenDoor != 2 and chosenDoor != 3:
print('Choose a door. (1, 2 or 3)')
chosenDoor = input()
return chosenDoor
print('You chose door number ' + str(chosenDoor) + '.')
def doors(): # the winning door and the dummy door are randomly selected
winningDoor = random.randint(1,3)
goatDoor = ''
while goatDoor == chosenDoor or goatDoor == winningDoor:
goatDoor = random.randint(1, 3)
def keepOrSwitch():
switchDoor = 1
if switchDoor == chosenDoor or switchDoor == winningDoor:
switchDoor = 2
if switchDoor == chosenDoor or switchDoor == winningDoor:
switchDoor = 3
print('Do you want to')
print('KEEP your choice of door number ' + str(chosenDoor) + '?')
print('...or...')
print('Do you want to')
print('SWITCH and choose door number ' + str(switchDoor) + '?')
print()
choice = ''
while True:
print('Type \'K\' for keep or type \'S\' for switch.')
choice = input()
if choice == 'K' or choice == 'k':
break
if choice == 'S' or choice == 's':
chosenDoor = switchDoor
break
def checkWin():
if chosenDoor == winningDoor:
print('You win!')
if chosenDoor != winningDoor:
print('You lose!')
# the rest of the code is the actual game
playAgain = 'yes'
while playAgain == 'yes' or playAgain == 'y':
chooseDoor()
doors()
keepOrSwitch()
checkWin()
print('Do you want to play again? (yes or no)')
playAgain = input()
In your function:
def checkWin():
if chosenDoor == winningDoor:
print('You win!')
if chosenDoor != winningDoor:
print('You lose!')
you try to compare chosenDoor to winningDoor, but they are not yet defined. The function checkWin() has no access to localy defined variables in other functions.
You have to refactor your code. Eventually you could assign some parameters to the function checkWin and return some values from the other functions.
Also:
# the rest of the code is the actual game
can be replaced by:
if __name__ == "__main__":
# your actual game
This is the standard way to run a Python program. If you import anything from this module in another file, the code won't run by accident.
EDIT:
the error is actually caused by this line:
while goatDoor == chosenDoor or goatDoor == winningDoor:
In your function doors() you define goatDoor and winningDoor, but chosenDoor is not declared.
In the function keepOrSwitch() you have the same problem.
Nevertheless the function checkWin() will cause an error, too.
You have to refactor your function chooseDoor() too. It has a print statement after the return statement. It enters the while loop and will finish the function call never reaching the last line.
The simplest way to fix this would be to assign the return value of chooseDoor to a variable:
choosenDoorByTheUser = chooseDoor()
and later call the other functions with that variable as argument.
You have posted a lot of code and it looks like a scope issue, the variables in your functions are not visible inside the other functions.
The quick and dirty way to fix this is to make that variable causing the error global like this:
def chooseDoor(): # choose a door
global chosenDoor = ''
while chosenDoor != 1 and chosenDoor != 2 and chosenDoor != 3:
print('Choose a door. (1, 2 or 3)')
chosenDoor = input()
return chosenDoor
print('You chose door number ' + str(chosenDoor) + '.')
I think that will probably fix it but it's not good coding practice.
Your variables are out of scope, you need to store the variables you're making down in the while loop and return the values from the methods you've made, then pass the values to checkWin
keepOrSwitch should return chosen
chooseDoor should return chosenDoor
doors should return winningdoor/goatdoor
checkwin should take chosenDoor + winnindoor + goatdoor
you'll then be able to reference your variables correctly
In a python program you've only defined chosenDoor in the chooseDoor() function and you haven't passed chosenDoor into the next function doors(). You can pass chosenDoor to doors() by doing doors(chosenDoor).
Related
Now, I just can't seem to figure it out
What i'm after I think is a global Boolean that'll be set to False unless door two has been accessed then it'll flip the Boolean to be True but because i'm invoking roomChoice() to go back to the start after entering room two it's all being restarted.
Just wondering the logic to achieve this.
try and ignore the horrible mess that is this code ha, I'm doing this program in an attempt to convert from Java to Python and learn Vim in the process, so just slowly learning here.
global key = False
def roomChoice():
print("It is now time to make a decision, so go on, 1, 2 or 3")
userinput = int(input())
while userinput != 1 or 2 or 3:
if(userinput == 1):
print("Doors locked")
roomChoice()
elif(userinput == 1 and key == True):
print(
"You've entered the room, it's now time to decide if you want to steal the wallet?")
userinput = input()
if(userinput == "yes"):
print("Nice move, quick lets get out of here")
elevator()
elif(userinput == "no"):
print("Well, on your way back to the elevator someone sees you coming out of the apartment, later they realise a wallet has been stolen, because you have been seen at the crime you are falsely imprisoned for burglary. 10 years, the judge really didn’t like you.")
exit()
else:
roomChoice()
elif(userinput == 2):
print("Oh look a key, I wonder if that'll get you into room one?")
key = True
roomChoice()
else:
roomChoice()
break
I figured it out, one of those fun kinds of answers, I just had to flip my if & elif around as it was meeting the requirements of the if statement so it was never getting to the elif section. Nice.
global key = False
def roomChoice():
print("It is now time to make a decision, so go on, 1, 2 or 3")
userinput = int(input())
while userinput != 1 or 2 or 3:
if(userinput == 1 and key == True):
print(
"You've entered the room, it's now time to decide if you want to steal the wallet?")
userinput = input()
if(userinput == "yes"):
print("Nice move, quick lets get out of here")
elevator()
elif(userinput == "no"):
print("Well, on your way back to the elevator someone sees you coming out of the apartment, later they realise a wallet has been stolen, because you have been seen at the crime you are falsely imprisoned for burglary. 10 years, the judge really didn’t like you.")
exit()
else:
roomChoice()
elif(userinput == 1):
print("Doors locked")
roomChoice()
elif(userinput == 2):
print("Oh look a key, I wonder if that'll get you into room one?")
key = True
roomChoice()
else:
roomChoice()
break
EDIT: You just have a logic error in your first if/elif statement, you have to check that the key is still false in the if statement, or it will always execute instead of the elif below it.
Did you try declaring the key as a global variable inside the function?
key = False
def roomChoice():
global key
userinput = int(input("It is now time to make a decision, so go on, 1, 2 or 3: ")) # you can pass the prompt string as a parameter to the input method
while userinput != 1 or userinput != 2 or userinput != 3:
if(userinput == 1 and key is False): # key has not yet been found
print("Doors locked")
roomChoice()
elif(userinput == 1 and key is True): # now key has been found
print()
userinput = input("You've entered the room, it's now time to decide if you want to steal the wallet? ")
if(userinput == "yes"):
print("Nice move, quick lets get out of here")
elevator()
elif(userinput == "no"):
print("Well, on your way back to the elevator someone sees you coming out of the apartment, later they realise a wallet has been stolen, because you have been seen at the crime you are falsely imprisoned for burglary. 10 years, the judge really didn’t like you.")
exit()
else:
roomChoice()
elif(userinput == 2):
print("Oh look a key, I wonder if that'll get you into room one?")
key = True
roomChoice()
else:
roomChoice()
break
def choose():
decision = input( 'Do you ' + colored('run', ('blue')) + ' or ' +
colored('attack?', ('blue')) )
return decision
while choose():
if choose() == "attack":
etc.
elif choose() == "run":
etc.
The interpreter then asks for the input and after it is inputted it asks again, and again, then the program proceeds normally. Why is this and how can I fix it?
You call the input routine only once and save the response.
Check that saved value repeatedly, rather than going back to your user each time.
choice = choose()
while choice:
if choice == "attack":
etc.
elif choice == "run":
etc.
...
choice = choose()
I've been working on a project in python for a while now and I can't call the main function. I searched for a while but I can't get it to work. Right now the problem is that I can't call the main function. It used to be that once the program went through the main function once it wouldn't go back to the main function, but now it won't even go into the main function and I can't call it from the shell. Could someone help me? Here's my code.
#!/usr/bin/python
# I only have the above part in case the
# end user does not have python
# Wizard's Quest Copyright (c) 2016 by GrayHat4Life
# This software is open source and may be distributed freely
# Prepare the program
import sys, random
# Set up some variables & begin the story
global health
health = 10
global enemiesKilled
enemiesKilled = 0
print("You are a wizard travelling through the kingdom")
print("Your quest: to save the kingdom by placing the Gem of Karn in its rightful place, the Tower of Souls")
# Main gameplay loop
def main():
# Battle code
# Set up the battle variables
enemyList = ["Goblin", "Witch", "Dark Mage", "Dark Knight", "Theif", "Troll", "Orc"]
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
# Prepare the battles
print("As you are walking through the Forest of Doom, a " + random.choice(enemyList) + " appears on the path in front of you!")
# This part isn't very usefull, it's only to give the
# player the illusion of free will. It's actually a kind of gambling game :s
input("What spell do you use to attack it? ")
# The attack strengths
attack = random.choice(numbers)
enemyAttack = random.choice(numbers)
# Let the battle begin!
if attack > enemyAttack:
health = health - 1
print("Your attack failed and you've been hit! You narrowly escape the enemy and continue your quest")
main()
elif enemyAttack > attack:
enemiesKilled = enemiesKilled + 1
# This loop gives the user the ability to win. And lose. :D
while True:
if enemiesKilled == 10:
print("You've finally made it to the end of your quest!")
print("You place the Gem of Karn in the soul sphere and save the kingdom!")
sys.exit()
elif health == 0:
print("The damage was too much.")
print("You bleed out in the middle of the forest, alone and friendless.")
print("GAME OVER")
sys.exit()
Thanks!
Python does not have a main function. Define your functions first so the interpreter knows about them. It will then execute the first statement after the last 'return' and following statements after that.
Correct syntax for python:
#!/usr/bin/python
# Function definition is here
def printme( str ):
"This prints a passed string into this function"
print str
return;
# Now you can call printme function
printme()
I don't see where you call the main() method initially.
Currently, you are entering a while True: and neither condition enemiesKilled == 10: or health == 0: are true
Your code should follow this structure if you are expecting to execute it
import somestuff
def main():
# do something here
if __name__ == '__main__':
# call the main function
main()
And if you want the while True: piece, then I would recommend something like this instead to stop the infinite loop
if __name__ == '__main__':
# call the main function
while enemiesKilled != 10 or health != 0:
main()
if enemiesKilled == 10:
print("You've finally made it to the end of your quest!")
print("You place the Gem of Karn in the soul sphere and save the kingdom!")
elif health == 0:
print("The damage was too much.")
print("You bleed out in the middle of the forest, alone and friendless.")
print("GAME OVER")
I am currently making a game in Python. It's command only.
Let's say there is a loced door in the game, and you need the key to open the door. I can all the basic about variables, but apparently not this.
My code looks like this:
def room_1():
door = 0
print
choice = raw_input('>: ')
if choice.lower() == 'open door':
if door == '0':
print
print 'Sorry, you need a key to open this door.'
room_1()
if door == '1':
room_2()
I am not quite sure why this is not working.
Could someone here please help me out? Thank you very much!
Thats because you initially declared the variable door as an int, but you are comparing it to a string '0' (and '1').
It should be,
if door == 0:
.....
and
if door == 1:
.....
you didnt open your string in the raw_input function call:
def room_1():
door = 0
print
choice = raw_input('>: ')
if choice.lower() == 'open door':
if door == '0':
print
print 'Sorry, you need a key to open this door.'
def room_1()
if door == '1':
room_2()
I am using python 2.6.6
I am simply trying to restart the program based on user input from the very beginning.
thanks
import random
import time
print "You may press q to quit at any time"
print "You have an amount chances"
guess = 5
while True:
chance = random.choice(['heads','tails'])
person = raw_input(" heads or tails: ")
print "*You have fliped the coin"
time.sleep(1)
if person == 'q':
print " Nooo!"
if person == 'q':
break
if person == chance:
print "correct"
elif person != chance:
print "Incorrect"
guess -=1
if guess == 0:
a = raw_input(" Play again? ")
if a == 'n':
break
if a == 'y':
continue
#Figure out how to restart program
I am confused about the continue statement.
Because if I use continue I never get the option of "play again" after the first time I enter 'y'.
Use a continue statement at the point which you want the loop to be restarted. Like you are using break for breaking from the loop, the continue statement will restart the loop.
Not based on your question, but how to use continue:
while True:
choice = raw_input('What do you want? ')
if choice == 'restart':
continue
else:
break
print 'Break!'
Also:
choice = 'restart';
while choice == 'restart':
choice = raw_input('What do you want? ')
print 'Break!'
Output :
What do you want? restart
What do you want? break
Break!
I recommend:
Factoring your code into functions; it makes it a lot more readable
Using helpful variable names
Not consuming your constants (after the first time through your code, how do you know how many guesses to start with?)
.
import random
import time
GUESSES = 5
def playGame():
remaining = GUESSES
correct = 0
while remaining>0:
hiddenValue = random.choice(('heads','tails'))
person = raw_input('Heads or Tails?').lower()
if person in ('q','quit','e','exit','bye'):
print('Quitter!')
break
elif hiddenValue=='heads' and person in ('h','head','heads'):
print('Correct!')
correct += 1
elif hiddenValue=='tails' and person in ('t','tail','tails'):
print('Correct!')
correct += 1
else:
print('Nope, sorry...')
remaining -= 1
print('You got {0} correct (out of {1})\n'.format(correct, correct+GUESSES-remaining))
def main():
print("You may press q to quit at any time")
print("You have {0} chances".format(GUESSES))
while True:
playGame()
again = raw_input('Play again? (Y/n)').lower()
if again in ('n','no','q','quit','e','exit','bye'):
break
You need to use random.seed to initialize the random number generator. If you call it with the same value each time, the values from random.choice will repeat themselves.
After you enter 'y', guess == 0 will never be True.