why is my python code not running fully - python

Can anyone help me understand why my very simple rock paper scissors code gets stuck and exits at the end of line 18 please?
I´ve tested each part individually and it works, it might not be the prettiest code but it seems to do the job, however in it´s latest itteration it just exits at the en of line 18, exit code 0, so no error, does´nt say anything is wrong, it just doesn´t execute the next line, like there´s a break or an exit on that line, but there isn´t:
import random
def startgame():
print("Please choose rock - r, paper - p or scissors - s:")
pchoice = input(str())
if(pchoice.lower in ["r","rock"]):
pchoice = "0"
elif(pchoice.lower in ["s","scissors"]):
pchoice = "1"
elif(pchoice.lower in ["p","paper"]):
pchoice = "2"
cchoice = (str(random.randint(0,2)))
if(cchoice == "0"):
print("Computer has chosen: Rock \n")
elif(cchoice == "1"):
print("Computer has chosen: Scissors \n")
elif(cchoice == "2"):
print("Computer has chosen: Paper \n")
#runs perfect up to here, then stops without continuing
battle = str(pchoice + cchoice)
if(battle == "00" and "11" and "22"):
print("Draw! \n")
playagain()
elif(battle == "02" and "10" and "21"):
if(battle == "02"):
print("You Lose! \nRock is wrapped by paper! \n")
elif(battle == "10"):
print("You Lose! \nScissors are blunted by rock! \n")
elif(battle == "21"):
print("You Lose! \nPaper is cut by scissors! \n")
playagain()
elif(battle == "01" and "12" and "20"):
if(battle == "01"):
print("You Win! \nRock blunts scissors! \n")
elif(battle == "12"):
print("You Win! \nScissors cut paper! \n")
elif(battle == "20"):
print("You Win! \nPaper wraps rock! \n")
playagain()
def main():
print("\nWelcome to Simon´s Rock, Paper, Scissors! \n \n")
startgame()
def playagain():
again = input("Would you like to play again? y/n \n \n")
if(again == "y"):
startgame()
elif(again == "n"):
print("Thank you for playing")
exit()
else:
print("Please choose a valid option...")
playagain()
main()

In the lines like
if(battle == "00" and "11" and "22"):
use in operator
if(battle in ["00", "11", "22"]):
playagain() is not getting called since none of the conditions are true.

The error is in this:
if(battle == "00" and "11" and "22"):
this will evaluate to False in all cases but 00, you need to change it to:
if battle == "00" or battle == "11" or battle == "22":
And also the other two statements where you use and
Your statement gets interpreted as the following:
True/False 1- if battle == "00"
True 2- and "11" #<-- here it checks if the string is True which means string is not empty
True 3- and "22" is True #<-- here too
So your statement will only work if all statements are True because you are using and which requires all parts of the statement to be True. Second and third parts are always True so its checking if the choice is "00"
What you need is this:
1- if battle == "00" True/False
2- or battle == "11" True/False
3- or battle == "22" True/False
And you need only one part to be True here for the statement to run because of or

Related

only first if statement run, and unless it comes back true it will not continue. new to code

import random
user_wins = 0
computer_wins = 0
options = ["Rock", "Paper", "Scissors"]
while True:
user_input = input("Type Rock/Paper/Scissors or Q to quit: ")
if user_input == "q":
break
if user_input not in [options]:
continue
random_number = random.randint(0, 2)
# rock: 0, paper: 1, scissors: 2
computer_pick = options[random_number]
print("computer picked", computer_pick + ".")
if user_input == "rock" and computer_pick == "scissors":
print("You won!")
user_wins += 1
elif user_input == "scissors" and computer_pick == "paper":
print("You won!")
user_wins += 1
elif user_input == "paper" and computer_pick == "rock":
print("You won!")
user_wins += 1
else:
print("You lost!")
computer_wins += 1
print("You won", user_wins, "times.")
print("The cpu won", computer_wins, "times.")
print("Goodbye!")
I'm sorry if im not using this site the correct way but I've been following along with Tech With Tim on youtube trying to write 5 mini python games to just practice. I expect if i put q it will break, but now that i'm typing this i'm realizing that if it were to break i shouldn't get the print statements on line 37,38, and 39. either way, when i input rock , paper, or scissors it comes back as "Type Rock/Paper/Scissors or Q to quit:". I'm having a hard time understanding why my code doesnt work, while Tim has the exact same code, line for line, and his works fine. Any and all help would be appreciated.. even if its directing me to slow my roll
if user_input not in [options] isn't correct. [options] is a list containing one element: all of options. A string can never be all of options, so user_input not in [options] will always be true.
You want
if user_input not in options:

Why do my results show in editor on my Rock, Paper, Scissors game but not when opened in command?

New to python and coded a simple rock, paper scissors game below. Why does the scores show after entering q while running it in visual studio code but this doesn't happen after entering q while opening the file.
import random
user_wins = 0
computer_wins = 0
options = ["rock", "paper", "scissors"]
while True:
user_input = input("Type Rock/Paper/Scissors or Q to quit: ").lower()
if user_input == "q":
break
if user_input not in options:
continue
random_number = random.randint(0, 2)
# Rock: 0 Paper: 1 Scissors: 2
computer_pick = options[random_number]
print("Computer picked", computer_pick + ".")
if user_input == "rock" and computer_pick == "scissors":
print("You Won!")
user_wins += 1
elif user_input == "paper" and computer_pick == "rock":
print("You Won!")
user_wins += 1
elif user_input == "scissors" and computer_pick == "paper":
print("You Won!")
user_wins += 1
elif user_input == computer_pick:
print ("It's a Draw")
else:
print("You lose")
computer_wins += 1
print("You won", user_wins, "rounds!")
print("The Computer won", computer_wins,"rounds!")
print("Thank you for playing")
When opening a program as a file, the window will immediately close when the code ends - this means that as soon as q is entered, the program exits the while loop, shows the scores and closes instantly after, leaving no time for you to read it. Visual studio code doesn't have a window to close, leaving the text able to be read.
To fix this, you can add input() at the end of the code, meaning that the user would have to press enter to end the program.

How to make a helper function work - please see code below

I'm trying to make a rock, paper, and scissors game that receives input from a user that plays against a robot that randomly selects rock, paper, or scissors. Here is my main() code:
"""
Name: Scott Houston
Date: January 19th, 2021
Program Description: Game of classic rock, paps
"""
import random
import gameFunctions2
def main():
while True:
computer_move = random.randint(1, 3)
print("Welcome to rock, paper, scissors! Rock beats scissors, scissors beats paper,"
" and paper beats rock. ")
user_input = input("Press 'A' for rock, 'B' for paper, and 'C' for scissors!\n"
"A. Rock\n"
"B. Paper\n"
"C. Scissors\n")
if gameFunctions2.tie(user_input, computer_move) == False:
if user_input == "A" or user_input == "a":
if computer_move == 2:
print("Your opponent has chosen paper! Paper wraps rock! You lose! ")
else:
print("Your opponent has chosen scissors! Rock breaks scissors! You win! ")
elif user_input == "B" or user_input == "b":
if computer_move == 3:
print("Your opponent has chosen scissors! Paper is cut by scissors! You lose! ")
else:
print("Your opponent has chosen rock! Paper wraps rock! You win! ")
elif user_input == "C" or user_input == "c":
if computer_move == 1:
print("Your opponent has chosen rock! Scissors loses to rock! You lose! ")
else:
print("Your opponent has chosen paper! Scissors beats paper! You win! ")
if gameFunctions2.input_detection(user_input) == True:
print()
else:
print()
user_play_again = input("Would you like to play again? Type 'y' if you'd like to play again. ")
if user_play_again == "y":
print()
else:
print("Have a great day! ")
break
# Calls the Main Function
main()
Here is my helper function (gameFunctions2):
def input_detection(user_input):
if user_input == "A" or user_input == "a" or user_input == "B" or user_input == "b" or user_input == "C" or user_input == "c":
return True
else:
print("Please enter a valid option! ")
return False
def tie(user_input, computer_move):
if user_input == user_input.lower in ["a"] and computer_move == "1":
print("It's a tie!")
return True
if user_input == user_input.lower in ["b"] and computer_move == "2":
print("It's a tie!")
return True
if user_input == user_input.lower in ["c"] and computer_move == "3":
print("It's a tie!")
return True
else:
return False
The problem that I'm facing right now is that there will never be a tie between the user and the computer. I've tried to implement the function tie(user_input, computer_move) into main(), but to no success. I have to use helper functions for this assignment, so I'm trying my best to do so. Also, if there's any place that I can make my code more efficient, it would be fantastic if you could point out where :))
Change your tie function to this:
def tie(user_input, computer_move):
if user_input.lower() == "a" and computer_move == 1:
print("It's a tie!")
return True
elif user_input.lower() == "b" and computer_move == 2:
print("It's a tie!")
return True
elif user_input.lower() == "c" and computer_move == 3:
print("It's a tie!")
return True
else:
return False
You cant compare String and Int like this: computer_move == "1" when computer_move is Int.
Simplify the user_input.lower() == "a" statement.
Here is what you can use to make your code more readable:
Use dictionary to translate users input into integers.
Then you can also easily check all the conditions.
Here is the code (I have only added the part where I have get rid of the tie function):
import random
choose = "Start"
symbols = {"rock":1, "paper":2, "scissors":3}
while True:
choose = input("Hi welcome to my game! Choose between Rock, Paper, Scissors! End the game with 'End':\n")
choose = choose.lower()
computer = random.randint(1,3)
if choose in symbols: #Check if input is in a string and if its in symbols
choose = symbols[choose]
elif choose == "end":
break
else:
print("You have written down something ... weird ... next round.")
continue
if choose == computer:
print("It's a tie!")
else:
#Choose who wins ...
pass
There are a lot of minor issues in your code that can be streamlined and a few major ones, but the one causing your issues is that you are defining computer_move as an integer in the main function (computer_move = random.randint(1, 3)), but in your tie function, you are comparing it to a string (eg, computer_move == "1") The first half of your if statement also is not doing what you want: Rewrite that function as such:
def tie(user_input, computer_move):
if user_input.lower() == "a" and computer_move == 1:
print("It's a tie!")
return True
if user_input.lower() == "b" and computer_move == 2:
print("It's a tie!")
return True
if user_input() == "c" and computer_move == 3:
print("It's a tie!")
return True
else:
return False
If you don't want to have a different if statement for each possible outcome, you can try this:
def outcomes(user_input, computer_move):
end_states = {"tie": [["a", 1], ["b",2], ["c",3]],
"user_win": ["LISTS OF USER WIN STATES"]}
if [user_input.lower(), computer_move] in end_states["tie"]:
print("tie")
if [user_input.lower(), computer_move] in end_states["user_win"]:
print("user wins")
else:
print("computer wins")
A few of the fixes:
user_input = input("Press 'A' for rock, 'B' for paper, and 'C' for scissors!\n"
"A. Rock\n"
"B. Paper\n"
C. Scissors\n")
can be changed to:
user_input = input("Press 'A' for rock, 'B' for paper, and 'C' for scissors!\n"
"A. Rock\n"
"B. Paper\n"
C. Scissors\n").lower()
so that you don't need to check for both upper and lower cases each time (you would also be able to remove .lower() from the tie function.
You should move the input_detection function to right after the user makes the input, and you can rewrite the check as such:
if not gameFunctions2.input_detection(user_input):
continue
Which roughly translates to, if it returns "False", return to the start of your while loop (You can also remove the checks for uppercase and lowercase letters, if you use the previous edit).
For checking if the player wants to play again, add .lower() to the end of the input, and you can change the last lines as such:
if user_play_again != "y":
print("Have a great day! ")
break
You don't need to have a statement that evaluates if user_play_again == "y" just to have the else statement (unless you want there to be a separate action for it). You can evaluate the opposite (if user_play_again != "y") alone.
As I began to do earlier, you can put each ending variation into dictionaries and instead of having a different line for each end state check, you can evaluate the dictionary as a whole to streamline things a bit too.
These might not be the only things, and others might disagree with my changes, but it's a start of how I would rewrite the code.
The other answers have resolved the bugs in your code. This answer is meant to give you some ideas about how you might do things differently - specifically, a more object-oriented approach, and taking advantage of the standard library a bit more.
from enum import Enum
class Move(Enum):
ROCK = 0
PAPER = 1
SCISSOR = 2
def get_user_move():
moves = dict(zip("ABC", Move))
print("Options:")
for option, move in moves.items():
print(f"{option:>5}. {move.name.title()}")
prompt = "Enter your selection: "
while True:
user_input = input(prompt).upper()
if user_input in moves:
break
prompt = "Try again: "
return moves[user_input]
def main():
from random import choice
while True:
user_move = get_user_move()
computer_move = choice(tuple(Move))
print(f"\nYou picked {user_move.name.title()}")
print(f"The computer picked {computer_move.name.title()}")
if user_move is computer_move:
print("It's a tie!\n")
else:
winner = ("The computer", "You")[(computer_move.value + 1) % len(Move) is user_move.value]
print(f"The winner is: {winner}!\n")
return 0
if __name__ == "__main__":
import sys
sys.exit(main())

Rock, paper, Scissors (python 3.3)

Hi i'm making a rock paper scissors game and i have made the following script so far:
def main():
from random import randint
UserChoices = input("'rock', 'paper' or 'scissors'? \n Input: ")
if UserChoices == "rock":
UserChoice = 1
elif UserChoices == "paper":
UserChoice = 2
elif UserChoices == "scissors":
UserChoice = 3
CpuChoice = randint(1,3)
if UserChoice == CpuChoice:
print("DRAW!")
elif UserChoice == "1" and CpuChoice== "3":
print("Rock beats scissors PLAYER WINS!")
main()
elif UserChoice == "3" and CpuChoice== "1":
print("Rock beats scissors CPU WINS")
main()
elif UserChoice == "1" and CpuChoice== "2":
print("Paper beats rock CPU WINS!")
main()
elif UserChoice == "2" and CpuChoice== "1":
print("paper beats rock PLAYER WINS!")
main()
elif UserChoice == "2" and CpuChoice== "3":
print("Scissors beats paper CPU WINS!")
main()
elif UserChoice == "3" and CpuChoice== "2":
print("Scissors beats paper PLAYER WINS!")
main()
elif UserChoice == "1" and CpuChoice== "2":
print("cpu wins")
main()
else:
print("Error: outcome not implemented")
main()
but when I run it I get the error I made "Error: outcome not implemented" Can someone tell me why this is? thank you.
This and all the other comparisons similar to it:
elif UserChoice == "1" and CpuChoice == "3":
... should be:
elif UserChoice == 1 and CpuChoice == 3:
In other words, you should be comparing ints with ints, instead of ints with strings as is happening right now.
User choice is set to an integer, however you compare it to a string. It should be as follows
if userChoice == 1: #Note no quotation marks
Also, you are allowing the CPU to choose from 3 integers, which works. However, it may save lines and be more efficient to choose a random from an array
CPU_Moves = ['Rock','Paper','Scissors']
cpuchoice = random.choice(CPUMoves)
This will set cpuchoice to one of the random from the array, and you can then use it in the comparison of user input to the cpuchoice. This would mean you wouldn't need to set userChoice at all, you could use what the user enters directly.
As the previous answers say, you ended up comparing a string against an integer.
It would be a good idea to avoid using so many conditionals. Here's a "compact version" I've written, in case you're interested:
from random import randrange
def RPS(user_choice = ''):
choices = ('rock', 'paper', 'scissors')
results = ('Draw!', 'You Win!', 'Cpu Wins!')
while user_choice not in choices:
user_choice = input("Choose: rock, paper or scissors? ")
user_num = choices.index(user_choice)
cpu_num = randrange(3)
diff = (user_num - cpu_num) % 3
print("You chose:", user_choice, "-", "Cpu chose:", choices[cpu_num])
print(results[diff])
RPS('rock') # User choice can be passed as an argument.
Notice how you can calculate the winner with a subtraction and a modulo operation. This is even more useful in a Rock, paper, scissors, lizzard, Spock game, where you have 5 choices instead of 3.
remove the quotes from your if else statement. the conditionals are looking for a string to compare while rock paper and scissors are assigned as integers. these are not handled the same way. you need to change your if elif to not have quotes around the numbers. it prints out DRAW because its comparing like items and it give and error because it is not the same variable type.

Most efficient way to reuse code multiple times? And also my while loops infinitly with boolean switch

I'm making a rock, paper scissors game as a little project while I'm starting out and I have to use the same bit of code a lot. What's the best way to do this because at the moment I have it copied and pasted all over the place. It looks untidy plus I'm having an issue with the looping while validating the input and it's a pain to have to change it all.
user_continue = raw_input("Would you like to play again? Y/N: ")
user_continue = user_continue.upper()
#Yes or no continue for the continue while loop to continue working until correct user input.
y_n_continue = False
while y_n_continue == False:
if user_continue == "Y" or user_continue == "YES" or user_continue == "N" or user_continue == "NO":
if user_continue == "Y" or user_continue == "YES":
continue_game = True
y_n_continue = True
elif user_continue == "N" or user_continue == "NO":
continue_game = False
y_n_continue = True
else:
print "Press Y or N"
y_n_continue = False
else:
print ""
It would probably be easier if I added the whole code (With the fix, thanks to Anton.
At the moment I am getting the error - TypeError: 'bool' object is not callable.
I'm basically trying to get it to loop the game for as long as the user wants while also validating the inputs to make everything as bulletproof as possible.
EDIT 2 - Here is the new code and I have some test data under it.
When I launch it you are prompted to enter y/n at the start.
You also have to enter y or n twice after each game.
If you input 'wrong' data into the rock/paper/scissors selection it goes to the y/n selection
import random
def continue_game():
while True:
user_continue = raw_input("Would you like to play again? Y/N: ").upper()
if user_continue in ["Y", "YES", "N", "NO"]:
return user_continue in ["Y", "YES"]
else:
print "Press Y or N"
while continue_game():
#computers choice of rock, paper or scissors
computer_input = ["ROCK", "PAPER", "SCISSORS"]
computer_choice = random.choice(computer_input)
#users choice or rock, paper or scissors
user_input = raw_input("Choose rock, paper or scissors: ")
#Turns user input to upper case.
user_choice = user_input.upper()
if user_choice == "ROCK" or user_choice == "PAPER" or user_choice == "SCISSORS":
#Computer = ROCK
if computer_choice == "ROCK":
#user = ROCK
if user_choice == "ROCK":
print "You have chosen: " + user_choice
print "The computer has chosen: " + computer_choice
print "You draw!"
#replay?
if continue_game():
print "continue"
else:
continue_game = False
#user = PAPER
elif user_choice == "PAPER":
print "You have chosen: " + user_choice
print "The computer has chosen: " + computer_choice
print "You win!"
#replay?
if continue_game():
print "continue"
else:
continue_game = False
#user = SCISSORS
elif user_choice == "SCISSORS":
print "You have chosen: " + user_choice
print "The computer has chosen: " + computer_choice
print "You lose!"
#replay?
if continue_game():
print "continue"
else:
continue_game = False
#Computer = PAPER
elif computer_choice == "PAPER":
#user = ROCK
if user_choice == "ROCK":
print "You have chosen: " + user_choice
print "The computer has chosen: " + computer_choice
print "You lose!"
#replay?
if continue_game():
print "continue"
else:
continue_game = False
#user = PAPER
elif user_choice == "PAPER":
print "You have chosen: " + user_choice
print "The computer has chosen: " + computer_choice
print "You draw!"
if continue_game():
print "continue"
else:
continue_game = False
#user = SCISSORS
elif user_choice == "SCISSORS":
print "You have chosen: " + user_choice
print "The computer has chosen: " + computer_choice
print "You win!"
#replay?
if continue_game():
print "continue"
else:
continue_game = False
#Computer = SCISSORS
elif computer_choice == "SCISSORS":
#user = ROCK
if user_choice == "ROCK":
print "You have chosen: " + user_choice
print "The computer has chosen: " + computer_choice
print "You win!"
#replay?
if continue_game():
print "continue"
else:
continue_game = False
#user = PAPER
elif user_choice == "PAPER":
print "You have chosen: " + user_choice
print "The computer has chosen: " + computer_choice
print "You lose!"
#replay?
if continue_game():
print "continue"
else:
continue_game = False
#user = SCISSORS
elif user_choice == "SCISSORS":
print "You have chosen: " + user_choice
print "The computer has chosen: " + computer_choice
print "You draw!"
#replay?
if continue_game():
print "continue"
else:
continue_game = False
else:
print "Something has gone wrong."
else:
print "Are you sure you entered that correctly?"
Output:
Would you like to play again? Y/N: y
Choose rock, paper or scissors: rock
You have chosen: ROCK
The computer has chosen: PAPER
You lose!
Would you like to play again? Y/N: y
continue
Would you like to play again? Y/N: y
Choose rock, paper or scissors: paper
You have chosen: PAPER
The computer has chosen: ROCK
You win!
Would you like to play again? Y/N: wer
Press Y or N
Would you like to play again? Y/N: dfg
Press Y or N
Would you like to play again? Y/N: y
continue
Would you like to play again? Y/N: y
Choose rock, paper or scissors: test
Are you sure you entered that correctly?
Would you like to play again? Y/N: y
Choose rock, paper or scissors: rock
You have chosen: ROCK
The computer has chosen: SCISSORS
You win!
Would you like to play again? Y/N: n
exit
Would you like to play again? Y/N: n
>>>
I know I'm being a pain but this is all appreciated.
You can just make a function out of the code and return the value of the continue_game variable. Here is a minified version of your code wrapped in a function, along with an example of its usage:
def continue_game():
while True:
user_continue = raw_input("Would you like to play again? Y/N: ").upper()
if user_continue in ["Y", "YES", "N", "NO"]:
return user_continue in ["Y", "YES"]
else:
print "Press Y or N"
if continue_game():
print "continue"
else:
print "exit"
UPDATE: regarding your full code, to fix the error, you need to delete the following line:
continue_game = True
and replace:
while continue_game == True:
with:
while continue_game():
First you should avoid stuff like while var == False use while not var:
same thing for:
"if user_continue == "Y" or user_continue == "YES" or user_continue == "N" or user_continue == "NO":"
do something like:
"if user_continue.upper() in "YESNO"
is a way better right?
instead :)
I think the right way to ask if the player wants to play again is making a "game" function and call it at the end
example here:
http://pastebin.com/0jQtwGdi
Once you figure out this table representing the game rules:
| ROCK2 | PAPR2 | SCIS2 |
------+-------+-------+-------|
ROCK1 | 0 | 2 | 1 |
PAPR1 | 1 | 0 | 2 |
SCIS1 | 2 | 1 | 0 |
1 = column wins, 2 = row wins, 0 = draw
your whole program can be shrinked a lot by using the index of dictionaries and tuples and some exceptions handling:
import random
m = dict(
rock = dict(rock=0, paper=2, scissors=1),
paper = dict(rock=1, paper=0, scissors=2),
scissors = dict(rock=2, paper=1, scissors=0)
)
while True:
try:
continue_game = {'n': False, 'y': True}[
raw_input("Would you like to play again? Y/N: ")[0].lower()
]
except:
print "Press Y or N"
continue # next loop
if not continue_game: break
human = raw_input("Choose rock, paper or scissors: ").lower()
computer = random.choice(m.keys())
print "You have chosen:", human
print "The computer has chosen:", computer
print ("You draw!", "You lose!", "You win!")[ m[computer][human] ]
You could find it a little tricky at the beginning but a such designed code assure you not to repeat yourself and it is even more readable (and maintainable) than a heavily if-then-else structured one like in your situation.

Categories

Resources