I am writing a rock, paper, scissors game in Python but my code doesn't work as it should. I'm new to Python so please let me know if my code isn't formatted corectly. The game runs fine, assuming you enter one of the already existing answers. However, if you enter one that is different, the code seems to loop randomly after the 'end()' function is executed.
Here is my code:
# imports needed files
from random import randint
import time
# creates a function that ends the game
def end(cpuScore,playerScore):
time.sleep(1)
cont = input("Would you like to play again? (y or n)\n")
if cont=="y":
time.sleep(1)
start()
else:
print("Well... That's a bit rude.")
# creates a function to play the game
def rps(cpuScore,playerScore,num):
# loops code 3 times (unless 'num' is different)
for x in range(num):
num-=1
# creates options
options = ["rock","paper","scissors"]
# picks a random choice for cpu
cpu = options[randint(0,2)]
# asks the player to choose
player = input("rock, paper or scissors?\n")
# why not gun?
if player=="gun":
result = "w"
elif player==cpu:
result = "d"
elif player=="rock":
if cpu=="paper":
result = "l"
if cpu=="scissors":
result = "w"
elif player=="paper":
if cpu=="scissors":
result = "l"
if cpu=="rock":
result = "w"
elif player=="scissors":
if cpu=="rock":
result = "l"
if cpu=="paper":
result = "w"
# if they choose something other than rock, paper, scissors or gun
else:
print("That's an invalid input!")
# adds one to num so that this round is not counted as one of the 3
num+=1
# plays the game again with the amount of rounds remaining
rps(cpuScore,playerScore,num)
# tells the player how they did
if result=="w":
playerScore+=1
time.sleep(1)
print("Fine! You win! Your silly " + player + " beat my " + cpu + "!!!")
if result=="l":
cpuScore+=1
time.sleep(1)
print("Ha! Sucker!! My epic " + cpu + " smashed your measly " + player + "!!!")
if result=="d":
time.sleep(1)
print("Ah! We drew by both choosing %s! Like they say, great minds think alike!" % cpu)
# announces the scores
print("You are on %s and the computer is on %s!" % (playerScore,cpuScore))
# ends the game after 3 rounds
end(cpuScore,playerScore)
# creates the funtion that sets the variables and starts the game
def start():
result=""
cont=""
cpuScore=0
playerScore=0
rps(cpuScore,playerScore,3)
# begins the game
start()
Thanks
Basically your rps function loops num times, with num = 3 initially. If the user enters an incorrect input, you call back the function, which starts the whole process again, in a new context, for num+1 times.
Thus if you answer wrong the first time you have at least six games to play: four new added and the two initial ones you didn't try to play.
My advice try first to do a program that do one and only one iteration of the rock-paper-scissor game. Adding more iteration is a simple fact of adding a global loop.
Related
first time posting here on Stackoverflow. I am currently learning python and am trying to make a simple game where the player will be shown a random 2 decimal place number and have to add up to 10. I want the game to only last 30 seconds, hence I added a clock function as well.
However, I am facing some troubles running both the clock and the game together at the same time. I have tried using threading but sadly it didn't work out. Appreciate all the help I can get!
import random
import time
import threading
number = 10.0
print("Sum up to 10!")
def game():
global score
score = 0
while True:
question = round(random.uniform(0.01, 9.99), 2)
while True:
print("\nYour number is: " + str(question))
try:
answer = float(input("\nAnswer: "))
if question + answer != number:
print("\nWrong answer! Try again!")
elif answer + question == number:
score += 1
print("\nCorrect!")
break
except ValueError:
print("Please key in a number(2 decimals)!")
def clock(countdown=0):
while countdown > 0:
time.sleep(1)
countdown -= 1
print("\rTime Left: " + str(countdown), end="")
if countdown == 0:
print("Final score: " + str(score))
quit()
clock_thread = threading.Thread(target=clock(31))
game_thread = threading.Thread(target=game())
clock_thread.start()
game_thread.start()
Your problem is probably on that line
clock_thread = threading.Thread(target=clock(31))
What you are doing right now is launching the function cloack with the argument 31, what you want to do is give a pointer to the function lock, and then give the argument 31
so you'd need to do something like that:
clock_thread = threading.Thread(target=clock, args=(31,))
args is a keyword same as target leading to the arguments you wanna give to the function(note that it has to be a tuple, ence why I wrote (31,)), and note that I didn't put the "()" after clock because I'm giving a pointer to the function clock, not launching the function clock
same, game_thread = threading.Thread(target=game()) becomes:
game_thread = threading.Thread(target=game) for the same reasons
There is module files as well but they work perfectly, the main problem is when you enter a module and it just printing out There is 'none' in here for every module. Additionally, if I wanted to change the fuel gain from 50 to randomly chose between 20,30,40 or 50.
The rest of the code works well but when the npc in a room is outputted it should say there is a 'workers' in here instead of just none for each module.
#Telium - Game
import random
#Global Variables
num_modules = 17 #Number of modules in the space station
module = 1 #Module of space station we are in
last_module = 0 #Last module we were in
possible_moves = [] #List of possible moves we can make
alive = True #Whether player is alive or not
won = False #Whether player has won
power = 100 #Amount of power the space station has
fuel = 500 #Amount of fuel the player has in flamethrower
locked = 0 #Module that has been locked by the player
queen = 0 #Location of queen alien
vent_shafts = [] #Location of ventilation shaft entrances
info_panels = [] #Location of info panels
workers = [] #Location of worker aliens
#procedure declarations
#This loads the global module
def load_module():
global module, possible_moves
possible_moves = get_modules_from(module)
output_module()
def get_modules_from(module):
moves = []
text_file = open("Charles_Darwin\module" + str(module) + ".txt", "r")
for counter in range(0,4):
move_read = text_file.readline()
move_read = int(move_read.strip())
if move_read != 0:
moves.append(move_read)
text_file.close()
return moves
def output_module():
global module
print()
print("--------------------------------------------------------------
-----------------------")
print()
print("You are in module",module)
print()
npc = spawn_npcs()
print("There is a ", npc ,"here")
def output_moves():
global possible_moves
print()
print("From here you can move to modules: | ",end='')
for move in possible_moves:
print(move,'| ',end='')
print()
def get_action():
global module, last_module, possible_moves, power
valid_action = False
while valid_action == False:
print("What do you want to do next ? (MOVE, SCANNER)")
action = input(">")
if action == "MOVE" or action.lower() == 'move' or action.lower()
== 'm' or action.higher() == 'M':
move = int(input("Enter the module to move to: "))
if move in possible_moves:
valid_action = True
last_module = module
module = move
#power is decreased by 1 for every move
power =- 1
else:
print("The module must be connected to the current
module.")
def spawn_npcs():
global num_modules, queen, vent_shaft, greedy_info_panels, workers
module_set = []
for counter in range(2,num_modules):
module_set.append(counter)
random.shuffle(module_set)
i = 0
queen = module_set[i]
for counter in range(0,3):
i=i+1
vent_shafts.append(module_set[i])
for counter in range(0,2):
i=i+1
info_panels.append(module_set[i])
for counter in range(0,3):
i=i+1
workers.append(module_set[i])
def check_vent_shafts():
global num_modules, module, vent_shafts, fuel
if module in vent_shafts:
print("There is a bank of fuel cells here.")
print("You load one into your flamethrower.")
fuel_gained = 50
print("Fuel was",fuel,"now reading:",fuel+fuel_gained)
fuel = fuel + fuel_gained
print("The doors suddenly lock shut.")
print("What is happening to the station?")
print("Our only escape is to climb into the ventilation shaft.")
print("We have no idea where we are going.")
print("We follow the passages and find ourselves sliding down.")
last_module = module
module = random.randint(1,num_modules)
load_module()
#Main Program starts here
#Menu options
print("ENTER 1 for instructions")
print("ENTER 2 to play")
print("ENTER 3 to quit")
menu = int(input("Please enter a number corresponding to what you want to
do: "))
if menu == 1:
instructions = input("Do you want to read the instructions(Y/N): ")
if instructions == "Y":
print("You, the player are trying to navigate around a space
station named the 'Charles Darwin' which contains many modules")
print("The aim of the game is to find a and trap the queen alien
called 'Telium' who is located somewhere randomly in the station, the
queen will try to escape to connectinhg modules so beware")
print("To win - you have to lock the queen in one of the modules
so she is trapped, you can kill her with a flamethrower, there is also
objects to help on the way so keep a look out")
spawn_npcs()
#Outputs where the queen, shafts, panels and workers are located
print("Queen alien is located in module:",queen)
print("Ventilation shafts are located in modules:",vent_shafts)
print("Information panels are located in modules:",info_panels)
print("Worker aliens are located in modules:",workers)
#when the players is alive, the module will load
while alive and not won:
load_module()
if won == False and alive == True:
output_moves()
get_action()
#if power is 0 then the user will die and the game will end
if power == 0:
print("You ran out of life support, you died")
alive == False
#win message once you have trapped the queen or when you run out of life
support
if won == True:
print("The queen is trapped and you burn it to death with your
flamethrower.")
print("Game over. You win!")
if alive == False:
print("The station has run out of power. Unable to sustain life
support, you die.")
check_vent_shafts()
First the easy part. You can randomly get 20, 30, 40 or 50 by using random.randint like this:
random.randint(2, 5) * 10
The harder part:
As you discussed with #Random Davis in the comments, you want to assign the npcs to random modules and then print which one you encounter.
To append three random (possibly repeating) modules, use
for _ in range(0,3):
vent_shafts.append(random.choice(module_set))
Using global variables (and the global keyword) is generally considered bad practice as it can cause sideeffects due to other parts of the program modifying a variable you wouldn't expect it to / forgot about. Try to use them as function parameters where needed and return the results
queen, vent_shafts, info_panels, workers = spawn_npcs(5)
def spawn_npcs(num_modules):
module_set = []
for i in range(2, num_modules):
module_set.append(i)
for _ in range(0,3):
vent_shafts.append(random.choice(module_set))
for _ in range(0,2):
info_panels.append(random.choice(module_set))
for _ in range(0,3):
workers.append(random.choice(module_set))
queen_module = module_set[0]
return queen_module, vent_shafts, info_panels, workers
I would like to achieve the following.
I have a proof of concept I am working.
I have Individual "Named RFID"Cards, then I have "Action RFID Cards".
So I might have cards like this:
Names
John - 12345
Mary - 12346
Actions
Start Work - 111
Finish Work - 222
Lunch - 333
So John Swipes his own card, then swipes an action card, which logs his action.
-Start Script
-Wait for User Card Input
-Once Input Received and Validated
- Wait for Action Card Input
- Start Timer
- Wait until Action Card Input matches a valid Action
- If a match, exit back to the main loop
- If no match, wait for one minute, then exit
-Continue Main Loop
I am reusing code from :
How would I stop a while loop after n amount of time?
import time
timeout = time.time() + 60*5 # 5 minutes from now
while True:
test = 0
if test == 5 or time.time() > timeout:
break
test = test - 1
and a Python Game example which waits and loops forever playing the game
https://dbader.org/blog/python-intro-reacting-to-user-input
My code for testing is as follows (I am not doing a card or action lookup at this point, expecting the user to be 12345 and card to be 54321: (the requirement for four spaces for indent has possibly broken Python Indent)
#
# Guess My Number
#
import random
import time
# Set our game ending flag to False
game_running = True
while game_running:
# Greet the user to our game
print()
print("I'm thinking of a number between 1 and 10, can you guess it?")
# Have the program pick a random number between 1 and 10
#secret_number = random.randint(0, 10)
secret_number = 12345
card_number_list = 54321
# Set the player's guess number to something outside the range
guess_number = -1
# Loop until the player guesses our number
while guess_number != secret_number:
# Get the player's guess from the player
print()
guess = input("Please enter a number: ")
# Does the user want to quit playing?
if guess == "quit":
game_running = False
break
# Otherwise, nope, the player wants to keep going
else:
# Convert the players guess from a string to an integer
guess_number = int(guess)
# Did the player guess the program's number?
if guess_number == secret_number:
print()
print("Hi you have logged on, please swipe Card- if you don't Swipe - will timeout in 1 minute!")
timeout = time.time() + 60*1 # 1 minutes from now
while True:
test = 0
if test == 1 or time.time() > timeout:
card = input("Please enter your card number")
card_number = int(card)
if card_number == card_number_list:
print("Thanks for your card number")
test = 1
break
test = test - 1
# Otherwise, whoops, nope, go around again
else:
print()
print("You need to use your wrist band first...")
# Say goodbye to the player
print()
print("Thanks for playing!")
But instead of exiting, the script waits...
Any feedback appreciated - I have basic python skills and am trying to reuse existing code where possible (with thanks to the creators!).
The python input() function will always wait for response from the keyboard before returning. Take a look at this answer for a technique to accomplish what you want.
I have been working on a text-based adventure game. I've revised it a few times and can't seem to get the outcome I want, when I attempt to create EVENTS rather than simply relying on an abundance of PRINT strings. Whenever I choose the option I want (door 1 in this case), then the following options, the input is unresponsive or gives me an error. Below is a portion of the code for door 1. A little clarity would be appreciated!
def main():
import sys
from colorama import init
init()
init(autoreset=True)
from colorama import Fore, Back, Style
def run_event(event):
text, choices = event
text_lines = text.split("\n")
for line in text_lines:
print(Style.BRIGHT + line)
print()
choices = choices.strip()
choices_lines = choices.split("\n")
for num, line in enumerate(choices_lines):
print(Fore.GREEN + Style.BRIGHT + str(num + 1) + ". " + line)
print()
return colored_input()
def colored_input():
return input(Fore.YELLOW + Style.BRIGHT + "> ")
print ("")
print ("")
print (" WELCOME TO THE MAZE ")
print ("")
print ("")
print ("You have found yourself stuck within a dark room, inside this room are 5 doors.. Your only way out..")
print ("")
print ("Do you want to enter door 1,2,3,4, or 5?")
print ("")
EVENT_DOOR1 = ("""
Theres an alien eating what appears to be a human arm, though its so damaged it's hard to be sure. There is a knife next to the alien.
what do you want to do?
""","""
Go for the knife
Attack alien before it notices you
""")
EVENT_ALIEN = ("""
You approach the knife slowly, While the alien is distracted. You finally reach the knife, but as you look up, the alien stares back at you.
You make a move to stab the alien, but he is too quick. With one swift motion, the alien thrusts you into the air.
You land hard, as the alien makes it's way towards you again. What should you do?
""", """
Accept defeat?
Last ditch effort?
""")
EVENT_ALIEN2 = ("""
You catch the alien off-guard. He stumbled and hisses in your direction. You scream in terror before he grabs the knife, and punctures your throat as he rips off your limbs.")
You died.. GAME OVER.. Mistakes can't be made this soon.. OUCH
""")
door = colored_input()
if door == "1":
run_event(EVENT_DOOR1)
alien = colored_input()
if alien == "1":
run_event(EVENT_ALIEN)
elif alien == "2":
run_event(EVENT_ALIEN2)
restart=input("Start over? Yes or No? ").lower()
if restart == "yes":
sys.stderr.write("\x1b[2J\x1b[H")
main()
else:
exit()
main()
You run_event function unnecessarily makes another call to colored_input() when it returns, causing the unresponsiveness as the script waits for another input. Remove the return colored_input() line and your code would work.
Also note that you should add a comma to the single-item tuple assigned to EVENT_ALIEN2; otherwise it would be evaluated as a string:
EVENT_ALIEN2 = ("""
You catch the alien off-guard. He stumbled and hisses in your direction. You scream in terror before he grabs the knife, and punctures your throat as he rips off your limbs.")
You died.. GAME OVER.. Mistakes can't be made this soon.. OUCH
""",)
I am a programming beginner and I am trying to build a fill-in-the-blank quiz. I am almost finished but I am stuck on 2 problems I am not able to solve, whatever I do. I would really appreciate your help with this. Thank you for helping me with this!
If you try to run the code and play the game:
1) It prints the quiz according to the difficulty(easy-insane) and quiz you want to play(apple, bond and programming quiz) which is great but afterwards it prompts you to choose difficulty again (the player_level() function keeps going even though the player/user has already chosen the difficulty level. I don't really understand why it does it? The player_level() procedure seems perfectly okay and logical to me.
2) The errors:
a) local variable blanks_index referenced before assignment
b) global name list_of_answers is not defined.
I know that it is related to the initialize_game() function but I don't know how to change the code so it refers all the variables (blanks_index, answers_index, player_lives) correctly.
It could be solved by creating global variables(I guess) but that is not a good practice so I am trying to avoid it. Formerly, the whole function initialise_game() and play_game() were one function, but as there are over 25 lines of code in one function, it is not a good practice as it is long and messy and I know that I can separate it but I don't know how.
Here is the code:
"""3 diffferent quizzes : Apple quiz, James Bond quiz, Programming quiz"""
"""Quiz and answers about Apple"""
Apple_quiz = ("The most valuable company in terms of market cap in 2016 is, ___1___."
"It was founded in ___2___. Its flagship product is called ___3___."
"___1___ has many competitors, the biggest rival is ___4___,founded by"
" nobody but the richest man on the planet,___5___ ___6___.")
list_of_answers_Apple = ["Apple", "1976", "Iphone", "Microsoft", "Bill", "Gates"]
"""Quiz and answers about Bond"""
Bond_quiz = ("James Bond is agent ___1___. He serves his country,___2___ ___3___"
" against its enemies. His car of choice is usually ___4___ ___5___."
" His favorite drink is ___6___.")
list_of_answers_Bond = ["007", "United", "Kingdom", "Aston", "Martin", "Martini"]
"""Quiz and answers about programming basics"""
Programming_quiz = ("___1___ are created with the def keyword. ___1___ are also called ___2___"
" You specify the inputs a ___1___ take by adding ___3___ separated by commas"
" between the parentheses. ___3___ can be standard data types such as string, number"
" ,dictionary, tuple, and ___4___ or can be more complicated such as ___5___"
" and ___6___ functions.")
list_of_answers_Programming = ["Functions", "procedures", "arguments", "lists", "objects", "lambda"]
blank_space = ["___1___", "___2___", "___3___", "___4___", "___5___", "___6___]"]
#List of levels with corresponding lives/guesses that player can have
quiz_list = ["Apple", "Bond", "Programming"]
level_list = ["easy", "medium", "hard", "superhard", "insane"]
lives_easy = 5
lives_medium = 4
lives_hard = 3
lives_superhard = 2
lives_insane = 1
def choose_quiz():
""" Prompts player to pick a type of quiz and loads the quiz """
#Input = player_quiz (raw input from player)
#Output = loaded quiz, player chose
while True:
player_quiz = raw_input("Please, select a quiz you want to play: "
"(Apple, Bond or Programming): ")
if player_quiz == "Apple":
return Apple_quiz
elif player_quiz == "Bond":
return Bond_quiz
elif player_quiz == "Programming":
return Programming_quiz
else:
print "We don't have such quiz, pick again!"
def answers_for_quiz():
""" Loads appropiate answers to the quiz that player has chosen"""
#Input = player quiz (raw input from player)
#Output = loaded quiz answers from the quiz player chose
player_quiz_pick = choose_quiz()
if player_quiz_pick == Apple_quiz:
return list_of_answers_Apple
elif player_quiz_pick == Bond_quiz:
return list_of_answers_Bond
elif player_quiz_pick == Programming_quiz:
return list_of_answers_Programming
def player_level():
""" Loads a difficulty that player chooses """
#Input = player_level_input (raw input of player choosing a difficulty)
#Output = corresponding number of lives:
#Easy = 5 lives, Medium = 4 lives
#Hard = 3 lives, Superhard = 2 lives
#Insane = 1 life
while True:
player_level_input = raw_input("Please type in a difficulty level: "
"(easy, medium, hard, superhard, insane): ")
if player_level_input == "easy":
return lives_easy #Easy = 5 lives
elif player_level_input == "medium":
return lives_medium #Medium = 4 lives
elif player_level_input == "hard":
return lives_hard #Hard = 3 lives
elif player_level_input == "superhard":
return lives_superhard #Superhard = 2 lives
elif player_level_input == "insane":
return lives_insane #Insane = 1 life
else:
print "We do not have such difficulty! Pick again!"
def correct_answer(player_answer, list_of_answers, answers_index):
""" Checks, whether the the answer from player matches with the answer list. """
#Input: player_answer (raw input that player enters in order to fill in the blank)
#Output: "Right answer!" or "Wrong! Try again!" this output will be later used in the game
if player_answer == list_of_answers[answers_index]:
return "Right answer!"
return "Wrong! Try again!"
def initialize_game():
"""Functions that sets up a game so we can play it """
player_quiz_pick, player_level_pick, list_of_answers = choose_quiz(), player_level(), answers_for_quiz()
print player_quiz_pick
print "\nYou will get maximum " + str(player_level_pick) + " guesses for this game. Good luck.\n"
blanks_index, answers_index, player_lives = 0, 0, 0
#for elements in blank_space:
while blanks_index < len(blank_space):
player_answer = raw_input("Please type in your answer for " + blank_space[blanks_index] + ": ")
if correct_answer(player_answer,list_of_answers,answers_index) == "Right answer!":
print "Correct answer! Keep going!\n"
player_quiz_pick = player_quiz_pick.replace(blank_space[blanks_index],player_answer)
answers_index += 1
blanks_index += 1
print player_quiz_pick
if blanks_index == len(blank_space):
print "Congratulations! You nailed it! You are the winner!"
else:
player_level_pick -= 1
if player_level_pick == 0:
print "Game over! Maybe next time!"
break
else:
print "One life less, that sucks! Have another shot!"
print "You have " + str(player_level_pick) + " guesses left."
initialize_game()
Your main problem is that you keep calling the same functions over and over again and do not save the input into variables. Here are some tips about your code and questions:
You are not doing anything with your player_level() method call, so the player doesn't actually chooses a level in a way that affects the game. You should change the function call, so the returned value will be stored.
//the call to the method:
player_level_pick = player_level()
Afterwards, you keep calling the player_level() method, and not using the actual answer that the user supplied. Change all player_level() appearences to player_level_pick - the variable you use to save the answer (as I showed above). Same goes to all other unneeded function calls such as choose_level().
You should initialize number_of_guesses, player_lives, list_of_answers, and other vars to a matching value to player_level_pick as well, so it will hold the right value according to the level. Likewise, you should change this line:
# the line that checks if game is over
# change from:
if number_of_guesses == player_lives:
# to :
if number_of_guesses == 0:
In order to return multiple values, you have to use tuples. Using multiple return statements one after the other does not work anywhere.
so, instead of:
return list_of_answers
return number_of_guesses
return blanks_index
return answers_index
return player_lives
you should use tuples, and unpack them properly:
# the return statement:
return (list_of_answers, number_of_guesses, blanks_index, answers_index, player_lives)
# and the unpacking in the calling function:
list_of_answers, number_of_guesses, blanks_index, answers_index, player_lives = initialize_game()
this way, all of the returned values go into the wanted variables in the calling function. this way, you need to call the initialize_game() from play_game(). it will be the efficient way for you.
Just saying it again, as I said in the end of (4) - you should unit initialize_game() and play_game() into a single function (because a lot of data is the same needed data), or just call initialize_game() from play_game().
Better practice then using this recursivly: return choose_level(), you should use a while True: loop, and just brake when you get a proper answer.