Can't use functions in Python - python

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")

Related

This function is not working and I can not figure out why

I am creating a text-based game for a school project. I am a novice and found a pretty good YouTube tutorial. I am following along in the beginning pretty closely so that I may understand better. I've entered this code almost identical to what the tutorial has stated and the code in the tutorial works but mine does not. What am I doing wrong? My output is as follows...
Would you like to start the game? Y/N: Y
<function intro at 0x000001F74F2DF040>
Process finished with exit code 0
def intro():
print('There are 8 buildings that consist of a Supermarket, a Restaurant, a Convenience Store,')
print('a Church, Library, and a Hardware Store. They are spread out within a city and you, a police officer')
print('has dropped one piece of your gear in each of them. You must retrieve the gear before apprehending')
print('the bad guy or he will overtake you and you will lose the game. The gear consists of')
print('handcuffs for restraining the bad guy, a gun in case the bad guy is armed, bullets for the gun, a')
print('bulletproof vest to protect you in case you are shot, a flashlight in the event that it is dark,')
print('your badge to prove that you are a police officer and a radio to call for assistance once the bad')
print('guy is in custody.')
firstPath = input('You are in the Police Station and can only move south. Enter 1: ')
if firstPath == '1':
print()
path1()
elif firstPath != '1':
print(firstPath)
def path1():
print()
def path2():
print()
def path3():
print()
startGame = input('Would you like to start the game? Y/N: ')
if startGame == 'n' or startGame == 'N':
print('Maybe next time')
elif startGame == 'y' or startGame == 'Y':
print(intro)
You are not calling the function intro in the last line. Instead, you are printing the function object. Change the last line to:
print(intro())
or really just
intro()
since the function prints text and does not return it.

How to add input into a text based program

I created a text based RPG using Python. At the moment when you execute the program it brings you through an introduction and at the end of it i have the user decide to go 1.Left 2. Right 3. Middle. Each place has a unique item needed to complete the game, meaning if you go to the right it will see if you have a specific item appended to your bag. If you do not have it you will return to the main part to decide where to go again. That being said the middle is the main part where i want the user to be able to attack a dragon right away so they can lose, or if prepared with the necessary items appended, win! Now you do not have the option to attack, you just get to the dragon and win, so there is no lose. Any tips of how to incorporate an input throughout the game would be helpful. If more information is needed i can gladly share :).
I tried implementing an input before attacking the dragon but it got caught inside the loop so even when you obtained all the items you would get returned to the main dungeon. Here is a snippet code for the final dungeon for an idea.
def valid_input(prompt, option1, option2):
while True:
response = input(prompt).lower()
if option1 in response:
print_pause("You use the " + str(Weapon) + " against the dragon")
print_pause("But it is not strong enough "
"to defeat the dragon, he uses Fire Breath"
" and, he incinerates you! ")
print_pause("You lose!")
play_again()
break
elif option2 in response:
print_pause("Smart Choice! You head back to the main dungeon")
dungeon_game()
break
else:
print("Sorry, try again")
return response
def middle_dungeon():
print_pause("You go to the middle dungeon.")
print_pause("After a few moments,"
" you find yourself in front of a " + Dragon + "!")
print_pause("This is why you need these magical powers.")
if "MagicRune" in bag:
print_pause("Luckily the Wizard trained you well, you now obtain "
" the power of the " + str(MagicRune) + "!")
print_pause("You attack the dragon! ")
if "MagicRune" not in bag:
print_pause("You do not obtain the necessary magical powers.")
print_pause("It looks like you need a scroll or more power!.")
print_pause("You head back to the main dungeon.")
dungeon_game()
dragon_health = 100
count = 0
while dragon_health > 0:
damage_by_player = random.randint(0, 60)
print_pause(f"You hit the dragon and caused {damage_by_player} damage")
dragon_health = dragon_health - damage_by_player
print_pause(f"dragon health is now {dragon_health}")
count = count + 1
print_pause(f"You successfully defeated the dragon in {count} attempts, you win!")
play_again()
def dungeon_game():
passage = ''
if 'started' not in Dungeon:
display_intro()
Dungeon.append('started')
while passage != '1' and passage != '2' and passage != '3':
passage = input("1. Left\n"
"2. Right\n"
"3. Middle\n")
if passage == '1':
left_dungeon()
elif passage == '2':
right_dungeon()
elif passage == '3':
middle_dungeon()
dungeon_game()
So essentially this output will deny you until you go to the left dungeon and right dungeon, where you see MagicRune in bag: this will let you go to the dragon while loop and win the game.
You need to rearrange your code a bit. Here's how you could change your input function:
def valid_input(prompt, option1, option2):
while True:
response = input(prompt).lower()
if option1 in response:
return option1
elif option2 in response:
return option2
else:
print("Sorry, try again")
Now it returns the option the user chose and lets the calling code determine what to do with that information. This makes it actually reusable. You'd call it like this:
chosen = valid_input("Wanna attack the dragon?", "yes", "no")
if chosen == "yes":
# do that stuff
else:
# do other stuff
You also have another problem that you really need to fix: you are treating function calls like goto statements. This will cause you pain when you're trying to debug your code, and also causes hard-to-track bugs.
For example, you should not call play_again() to restart your code. Instead, set up your code structure so that you don't have to do that. E.g.
def dungeon_game():
while True:
# set up initial game state here, e.g.
bag = ["sword", "potion"]
# call main game logic function
dungeon()
# that function returned, so the game is over.
want_to_play = input("play again?")
if want_to_play == "no":
# if we don't break, the While loop will start the game again
break
def dungeon():
# blah blah dragon attack
if (whatever):
print("You got killed. Game over.")
return # goes back to dungeon_game()
else:
print("You won the fight")
# code for the next thing that happens...
if __name__ == "__main__":
dungeon_game()

Python3 won't recognize a variable in code

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).

Scoring in Python game does not work

I am new to Python, trying to pick up the language outside of my school courses. This Rock Paper Scissors game I am working on functions correctly, although the score output does not show anything. Here is the code...
#!/usr/bin/env python2
# Extra modules used
import random
import time
# Set each move to a specific number
# Once a selection is made by the player,
# it will be equated to that specific variable.
rock = 1
paper = 2
scissors = 3
# Text representation of each move
names = { rock: "Rock", paper: "Paper", scissors: "Scissors" }
# Game Rules
rules = { rock: scissors, paper: rock, scissors: paper }
# Declare variables to be used to track scoring
player_score = 0
computer_score = 0
# Function to print a greeting and start
# a loop to allow the player to continue
#playing as many times as they wish
def start():
print ("Let's play a game of Rock, Paper, Scissors.")
while game():
pass # Allows the loop to stop when player is done
scores() # Call function when done playing
def game():
# Call move function to determine player move
player = move()
# Get computer move as random int between 1 and 3
computer = random.randint(1, 3)
# Send the move through the result function
result(player, computer)
return play_again()
# Function to obtain a move from the player
def move():
while True:
print
player = input("Rock = 1\nPaper = 2\nScissors = 3\nMake a move: ")
# Try to set the player move, or catch the error
try:
# Cast the user input as an integer
player = int(player)
# If entry is valid, set the variable
if player in (1,2,3):
return player
except ValueError:
pass
print ("Oops! I didn't understand that. Please enter 1, 2, or 3.")
# Function to determine the result of the game
# player move and computer move are passed in
def result(player, computer):
# Countdown to result display
print ("1...")
time.sleep(1)
print ("2...")
time.sleep(1)
print("3!")
time.sleep(0.5)
# Display the computer's move
# string.format() gets the text version
# of the move and inserts it where "0"
print ("Computer threw {0}!".format(names[computer]))
#Call the scores set earlier
global player_score, computer_score
# Check the results of the game
if player == computer:
print ("Tie game.")
# Check if the losing move to the player's move
# is equal to the computer's move
elif rules[player] == computer:
print ("Your victory has been assured.")
player_score += 1
else:
print ("The computer laughs as you realize you have been defeated.")
computer_score += 1
# Ask to play again
def play_again():
answer = input("Would you like to play again? y/n: ")
if answer in ("y", "Y", "yes", "Yes", "Of course!"):
return answer
else:
print ("Thank you very much for playing. See you next time!")
def scores():
global player_score, computer_score
print ("HIGH SCORES")
print ("Player: "), player_score
print ("Computer: "), computer_score
# Used to execute in command line or import
# into another Python script. This will prevent
# the code from being executed when being imported.
if __name__ == '__main__':
start()
Your print statements are a little off.
You should be including the arguments inside the print statement
print("Player: ", player_score)
Edit:
To speak a little more to printing. You could also use
print("Player: {}".format(player_score))
You need the variables inside the brackets so:
print ("Player: "), player_score
print ("Computer: "), computer_score
becomes
print ("Player: ", player_score)
print ("Computer: ", computer_score)
Alternatively,
print ("Player: {}".format(player_score))
print ("Computer: {}".format(computer_score))
Format is better to use as there is a whole lot more you can do with it (I'll let you find that out for yourself)!

Still new to python. So confused right now. How do I make this program work?

So I'm making a little game to teach myself how python works, and it's been okay up to this point, but now I'm completely stuck. I'm sure the logic and formatting of the if and while statement are all wrong, so I'd be happy if people could point me in the right direction - again, REALLY new to programming in general. I'll paste the code, then explain what I'm trying to make it do:
import random
import time
print("Welcome to the Dojo!")
print("You have three opponents; they are ready...")
print("Are you?")
print("*To view the rules, type 'rules' ")
print("*To view commands, type 'commands' ")
print("*To begin, type 'start' ")
while True:
userInput = (input())
# Rules
if userInput == "rules":
print("The rules in this Dojo are simple. Kill your opponent! Fight to the death! Show no mercy!")
print("Each opponent gets progressively more difficult, whether it be in terms of health or damage.")
print("To attack, type 'attack'")
print("May the better (luckier) warrior win")
# Commands - to be added
elif userInput == "commands":
print("Commands will be added soon!")
# Start
elif userInput == "start":
damage = random.randint(1, 50)
userHealth = int(100)
opponentHealth = int(100)
print("Your first opponent is Larry Schmidt. Don't sweat it, he'll be a piece of cake.")
time.sleep(3)
print("The battle will begin in")
time.sleep(1)
print("5")
time.sleep(1)
print("4")
time.sleep(1)
print("3")
time.sleep(1)
print("2")
time.sleep(1)
print("1")
time.sleep(1)
print("Fight!")
if userInput == "attack":
int(userHealth - damage)
print("You did %(damage) to Larry!")
# Invalid response
else:
print("Enter a valid response, young grasshopper.")
if userInput == "start" is True:
continue
If you run the program for yourself, everything is okay until you reach the "5, 4, 3, 2, 1, Fight!" part. Then when you type "attack," it gives you "Enter a valid response, young grasshopper." I understand why this is happening, because "attack" doesn't fall under "rules", "commands", or "start". I just don't get how I'm supposed to format it so that after I enter "attack", it actually proceeds and outputs the damage done, etc. I apologize if this is hard to understand, but I think if you run it for yourself, you'll understand what I'm having problems with. Honestly, something tells me I've messed up the if and while statements up entirely, but hey, I'm learning and having fun :P.
Thanks for any help.
You aren't asking for more input. It's guaranteed that the userInput will still be "start" at that point.
Your code would benefit greatly from the use of functions. You could really organize the code better that way.
def intro():
print("Welcome to the Dojo!")
print("You have three opponents; they are ready...")
print("Are you?")
print("*To view the rules, type 'rules' ")
print("*To view commands, type 'commands' ")
print("*To begin, type 'start' ")
def get_user_input():
user_input = (input())
while user_input not in ['rules', 'commands', 'start']:
print("valid commands are rules, commands and start")
user_input = (input())
return user_input
intro()
returned_user_input = get_user_input()
There are a lot of ways to do these things, and you'll get better with time. Mainly note that user_input only gets updated when you do this:
user_input = (input())
Which in your code was only done once.
The code you have in the "start" branch of the if conditional will only run once, and userInput will still be "start" at that point. The solution, wrap it in a loop. Maybe something like this:
elif userInput == "start":
userHealth = 100
opponentHealth = 100
print("Your first opponent is Larry Schmidt. Don't sweat it, he'll be a piece of cake.")
time.sleep(3)
print("The battle will begin in")
time.sleep(1)
print("5")
time.sleep(1)
print("4")
time.sleep(1)
print("3")
time.sleep(1)
print("2")
time.sleep(1)
print("1")
time.sleep(1)
print("Fight!")
while opponentHealth > 0 and userHealth > 0:
userInput = input()
if userInput == "attack":
damage = random.randint(1, 50)
opponentHealth = opponentHealth - damage
print("You did %d to Larry!" % damage)
The while loop will loop until the opponent has been defeated or until the user is defeated, but at the moment, there's no damage done to the user. I'll leave that part to you.

Categories