Rock Paper Scissors, but wait! It's set up differently - python

Alice and Bob are playing rock-paper-scissors game.
Input Specification
The first line contains one integer N (1≤N≤100) that represents the number of games.
The second line is Alice's shape sequence and third line is Bob's shape sequence.
Output Specification
Two integers separated by a space, representing the number of games won by Alice and the number of games won by Bob.
I first made Alice and Bob's shapes in a list using .split() and then I set up a bunch of elif and if statements for each possible scenario. But the problem I'm having is that it is not iterating correctly for example if I input
3
rock rock rock
rock rock paper
instead of output being 0, 1 I get 0,0 and I can't seem to figure out why. Here's my code below.
games = input()
alice = input()
bob = input()
alice = alice.split()
bob = bob.split()
awin = []
bwin = []
a = 0
while a < len(alice):
for i in range(len(alice)):
if alice[i] == "rock" and bob[i] == "rock":
break
elif alice[i] == "scissors" and bob[i] == "scissors":
break
elif alice[i] == "paper" and bob[i] == "paper":
break
elif alice[i] == "rock" and bob[i] == "scissors":
awin.append('rock beat scissors')
break
elif alice[i] == "rock" and bob[i] == "paper":
bwin.append('paper beat rock')
break
elif alice[i] == "paper" and bob[i] == "rock":
awin.append('paper beat rock')
break
elif alice[i] == "paper" and bob[i] == "scissors":
bwin.append('scissors beat paper')
break
elif alice[i] == "scissors" and bob[i] == "paper":
awin.append('scissors beat paper')
break
elif alice[i] == "scissors" and bob[i] == "rock":
bwin.append('rock beat scissors')
break
i += 1
a+=1
print('output:')
print(awin)
print(bwin)
print(str(len(awin)) + " " + str(len(bwin)))

Here's a more simplified version of your code:
games = input()
alice = input()
bob = input()
alice = alice.split()
bob = bob.split()
awin = []
bwin = []
for i in range(len(alice)):
# If both players play the same move
if alice[i] == bob[i]:
continue
elif alice[i] == "rock" and bob[i] == "scissors":
awin.append('rock beat scissors')
elif alice[i] == "rock" and bob[i] == "paper":
bwin.append('paper beat rock')
elif alice[i] == "paper" and bob[i] == "rock":
awin.append('paper beat rock')
elif alice[i] == "paper" and bob[i] == "scissors":
bwin.append('scissors beat paper')
elif alice[i] == "scissors" and bob[i] == "paper":
awin.append('scissors beat paper')
elif alice[i] == "scissors" and bob[i] == "rock":
bwin.append('rock beat scissors')
print('output:')
print(awin)
print(bwin)
print(str(len(awin)) + " " + str(len(bwin)))

Others have given some direction on the original code. I'm just stopping by to offer an alternative approach that is a little more 'pythonic'...and because coding games like this can be a bit of fun!
This implementation doesn't play the same as code in the original question, but has the advantage of following how the game flows in real life.
from collections import defaultdict
# defaultdict returns 0 (int() initial value) if the key does
# not exist. So, encode contests in format AB where 1 means
# A beats B. All other scenarios default to 0 i.e. B wins.
game = defaultdict(int)
game['RS'] = 1
game['SP'] = 1
game['PR'] = 1
num_games = input()
aw,bw = 0,0
while num_games:
alice = raw_input('Shape for Alice:')
bob = raw_input('Shape for Bob:')
aw += game[alice + bob]
bw += game[bob + alice]
num_games -= 1
print(aw,bw)

Related

Tricks and tips for beginners to shorten and simplify code

I am looking for ways to shorten and simplify my python code. Here is one example of one small rock/paper/scissors game I wrote earlier. The code kinda looks too long to me and I want to try to learn how to shorten my code.
import random
user_wins = 0
comp_wins = 0
game_limit = 0
options = ["rock","paper","scissors"]
print("Welcome to Rock Paper Scissors, This is a Best of 5")
while True:
user_input = input("Type in Rock/Paper/Scissors or Q to quit: ").lower()
if user_input == "q":
break
elif user_input not in options:
print("type in a valid word next time")
continue
game_limit += 1
if game_limit == 5 and comp_wins > user_wins:
print("The game is over, YOU LOST!")
elif game_limit == 5 and comp_wins < user_wins:
print("The game is over, YOU WON!")
random_number = random.randint(0,2)
comp_input = options[random_number]
print("Computer picked", comp_input)
if user_input == "rock" and comp_input == "scissors":
print("You win")
user_wins += 1
elif user_input == "rock" and comp_input == "rock":
print("its a draw")
elif user_input == "rock" and comp_input == "paper":
print("You lose!")
comp_wins += 1
if user_input == "scissors" and comp_input == "paper":
print("You win")
user_wins += 1
elif user_input == "scissors" and comp_input == "scissors":
print("its a draw")
elif user_input == "scissors" and comp_input == "rock":
print("You lose!")
comp_wins += 1
if user_input == "paper" and comp_input == "rock":
print("You win")
user_wins += 1
elif user_input == "paper" and comp_input == "paper":
print("its a draw")
elif user_input == "paper" and comp_input == "scissors":
print("You lose!")
comp_wins += 1
Yes. You could simplify your logic by having compound and/or tests for the player and user. Following is a revised version of your code with some simplified logic.
import random
user_wins = 0
comp_wins = 0
game_limit = 0
options = ["rock","paper","scissors"]
print("Welcome to Rock Paper Scissors, This is a Best of 5")
while True:
if game_limit >= 5: # Tweak
if comp_wins > user_wins:
print("The game is over, YOU LOST!")
break
if comp_wins < user_wins:
print("The game is over, YOU WON!")
break
else:
print("We go to sudden death!")
user_input = input("Type in Rock/Paper/Scissors or Q to quit: ").lower()
if user_input == "q":
break
elif user_input not in options:
print("type in a valid word next time")
continue
game_limit += 1
random_number = random.randint(0,2)
comp_input = options[random_number]
print("Computer picked", comp_input)
if user_input == "rock" and comp_input == "scissors" or user_input == "paper" and comp_input == "rock" or user_input == "scissors" and comp_input == "paper":
print("You win")
user_wins += 1
elif user_input == "rock" and comp_input == "paper" or user_input == "paper" and comp_input == "scissors" or user_input == "scissors" and comp_input == "rock":
print("You lose!")
comp_wins += 1
else:
print("It's a draw")
This way all of the scenarios where the user can win are in one logical test and all of the scenarios where the computer can win are in another logical test. If neither test is true, then the default would have to be a draw.
Also, I tweaked game limit test because if the computer and user have the same score when the game limit is reached, the test result would be false and the game would then continue on and not stop. So there is a bit of additional code to handle a tie after five rounds.
Give that a try.

How do I save scores in an external text file from a rock, paper, scissors, game?

I am very new to python so I apologise for that. anyway I have programmed a simple rock, paper, scissors game where you play against a bot that randomly pulls "rock", "paper", or "scissors" from a list. The game (if you can call it that) works fine, However, I want to be able to save the game score to a text file, preferably called "score.txt", when the game ends, I have already tried doing this and it failed miserably, Heres the output from "score.txt"
Test | | # theres meant to be a "Score" and a Win, Loss, and Tie in between
Test | | # the | |, for e.g, Test | Win | 5 - Score
Test | | # Test | Win | 10
Test | | # Test | Loss | 5
and heres the code for the program I made:
import random
rps = ["rock","paper","scissors"]
score = "score"
score1 = 0
name = None
i = None
f = open("score.txt")
while not name:
name = str(input("Enter a name: "))
for i in range(4):
while not (i == "rock" or i == "paper" or i == "scissors"):
i = str(input("Enter rock paper or scissors: "))
choice_rps = random.choice(rps)
print(choice_rps)
if i == "rock" and choice_rps == "paper":
result = "lost"
print("You lost :(")
elif i == "paper" and choice_rps == "rock":
result = "won"
print("You won!!!")
elif i == "paper" and choice_rps == "scissors":
result = "lost"
print("You lost :(")
elif i == "scissors" and choice_rps == "paper":
result = "won"
print("You won!!!!!!!")
elif i == "scissors" and choice_rps == "rock":
result = "lost"
print("You lost :(")
elif i == "rock" and choice_rps == "scissors":
result = "won"
print("You won!!!!!!")
else:
result = "tie"
print("It's a tie")
if result == "won":
print("score + 5")
score1 = score1 + 5
f.write("\n" + name + " | Win | " + str(score1))
elif result == "lost":
print("score - 5")
score1 = score1 - 5
f.write("\n" + name + " | Loss | " + str(score1))
elif result == "tie":
print("score stays same")
score1 = score1
Apologises if this seemms confusing to read. Any advice would be greatly appreciated.
(I'm ten years old so more towards a simple answer would be appreciated :)
There's three issues with your code:
open() takes in a second parameter that describes whether we want to read, write, or append to a file. In this case, we want to write to the file, so we should use open('score.txt', 'w') -- the w is for write.
You need to close your file after you're done writing to it using f.close().
The code to actually write to the file needs to be shifted over one indent. Otherwise, if we win, the score handling code will never be executed (since it's under an else branch that handles ties).
Here's the code with all three fixes:
import random
rps = ["rock","paper","scissors"]
score = "score"
score1 = 0
name = None
i = None
f = open("score.txt", "w")
while not name:
name = str(input("Enter a name: "))
for i in range(4):
while not (i == "rock" or i == "paper" or i == "scissors"):
i = str(input("Enter rock paper or scissors: "))
choice_rps = random.choice(rps)
print(choice_rps)
if i == "rock" and choice_rps == "paper":
result = "lost"
print("You lost :(")
elif i == "paper" and choice_rps == "rock":
result = "won"
print("You won!!!")
elif i == "paper" and choice_rps == "scissors":
result = "lost"
print("You lost :(")
elif i == "scissors" and choice_rps == "paper":
result = "won"
print("You won!!!!!!!")
elif i == "scissors" and choice_rps == "rock":
result = "lost"
print("You lost :(")
elif i == "rock" and choice_rps == "scissors":
result = "won"
print("You won!!!!!!")
else:
result = "tie"
print("It's a tie")
if result == "won":
print("score + 5")
score1 = score1 + 5
f.write("\n" + name + " | Win | " + str(score1))
elif result == "lost":
print("score - 5")
score1 = score1 - 5
f.write("\n" + name + " | Loss | " + str(score1))
elif result == "tie":
print("score stays same")
score1 = score1
f.close()
Edits in the code:
1- with open("score.txt", "a") as f: # not to use close func, "a" is to append new values, use "w" if you want to rewrite the whole file
2- indentation fixed
3- using string format allows you to print a dynamic string
here is a working version of your code:
import random
rps = ["rock", "paper", "scissors"]
score = "score"
score1 = 0
name = None
i = None
with open("score.txt", "a") as f: # not to use close func, "a" is to append new values, use "w" if you want to rewrite the whole file
while not name:
name = str(input("Enter a name: "))
for i in range(4):
while not (i == "rock" or i == "paper" or i == "scissors"):
i = str(input("Enter rock paper or scissors: "))
choice_rps = random.choice(rps)
print(choice_rps)
if i == "rock" and choice_rps == "paper":
result = "lost"
print("You lost :(")
elif i == "paper" and choice_rps == "rock":
result = "won"
print("You won!!!")
elif i == "paper" and choice_rps == "scissors":
result = "lost"
print("You lost :(")
elif i == "scissors" and choice_rps == "paper":
result = "won"
print("You won!!!!!!!")
elif i == "scissors" and choice_rps == "rock":
result = "lost"
print("You lost :(")
elif i == "rock" and choice_rps == "scissors":
result = "won"
print("You won!!!!!!")
else:
result = "tie"
print("It's a tie")
if result == "won": #indentation fixed from here to the end
print("score + 5")
score1 = score1 + 5
f.write(f"{name} | Win | {str(score1)} \n")#using string format allows you to have a dynamic string
elif result == "lost":
print("score - 5")
score1 = score1 - 5
f.write(f"{name} | Lose | {str(score1)} \n")
elif result == "tie":
print("score stays same")
score1 = score1

My input sometimes takes multiple times for it to go in the if statements

I am attempting to make a basic rock, paper, scissors game. When I input either rock, paper, or scissors, I sometimes have to enter the same thing multiple times for it to continue to the if statements. See code below:
# Rock, Paper, Scissors
player_total = 0
computer_total = 0
def get_computer_hand():
choice = randint(1, 3)
if choice == 1:
return "scissors"
elif choice == 2:
return "paper"
else:
return "rock"
def ask_user():
global player_total
global computer_total
player = input("Enter your hand (stop to stop): ")
if player == "stop":
print("Computer had ", computer_total, "points, you had ", player_total, " points.")
exit(0)
computer = get_computer_hand()
if player == "rock":
if computer == "paper":
return "win"
elif computer == "scissors":
return "lose"
else:
return "tie"
elif player == "paper":
if computer == "paper":
return "tie"
elif computer == "scissors":
return "lose"
else:
return "win"
elif player == "scissors":
if computer == "scissors":
return "tie"
elif computer == "paper":
return "win"
else:
return "lose"
def count_winner():
global player_total
global computer_total
player_total = 0
computer_total = 0
while True:
outcome = ask_user()
if outcome == "win":
print("You won that one.")
player_total += 1
elif outcome == "lose":
print("Computer won that one.")
computer_total += 1
count_winner()
I expect it to work the first time and to continue as usual, but I can't seem to figure out why it just asks "Enter your hand (stop to stop): " instead sometimes when I enter either rock, paper, or scissors.
This is happening because there is a tie happening between the computer and the user. This could be fixed by adding the end with the code of
else outcome == "tie":
print("You have tied with the Computer!")
computer_total += 1
player_total += 1
This would add a point to both sides and if you don't want that just delete the last two lines of my code

Inability to execute the call function within my main statement for rock, paper, scissors

Before anyone marks this question as a duplicate of anyone else's relating to this type of program, know that I searched and read the answered questions on this topic and was unable to find anything that suits my needs.
In my program for rock, paper, scissors I am asked to figure out if the computer or the player wins, or if they tie. We are supposed to store computer win as -1, player win as 1, and tie as 0. I thought I wrote this function correctly and called it properly in my main function, however, when I run my code it skips right over my runGame function and instead skips to an infinite loop asking the player to input their choice. I do not know why this is happening. I should note that within my main function, we are supposed to keep a counter to see how many wins the computer has and the player has, and how many times they tie. I also am having difficulty getting this to execute.
import random
# Function: Display Menu
# Input: none
# Output: none
# displays the game rules to the user
def displayMenu():
print("Welcome! Let's play rock, paper, scissors.")
print("The rules of the game are:")
print("\tRock smashes scissors")
print("\tScissors cut paper")
print("\tPaper covers rock")
print("\tIf both the choices are the same, it's a tie")
# Function: Get Computer Choice
# Input: none
# Output: integer that is randomly chosen, a number between 0 to 2
def getComputerChoice():
computerChoice = random.randrange(0,3)
return computerChoice
# Function: Get Player Choice
# Input: none
# Output: integer that represents the choice
# Asks the user for their choice: 0 for rock, 1 for paper, or 2 for scissors
def getPlayerChoice():
playerChoice = int(input("Please choose (0) for rock, (1) for paper or (2) for scissors"))
return playerChoice
# Function: Play Round
# Input: two integers--one representing the computer's choice and the other representing the player's choice
# Output: integer (-1 if computer wins, 1 if player wins, 0 if there is a tie)
# This method contains the game logic so it stimulates the game and determines a winner
def playRound(computerChoice, playerChoice):
if playerChoice == 0 and computerChoice == 2:
return 1
elif computerChoice == 0 and playerChoice == 2:
return -1
elif playerChoice == 2 and computerChoice == 1:
return 1
elif computerChoice == 2 and playerChoice == 1:
return -1
elif playerChoice == 1 and computerChoice == 0:
return 1
elif computerChoice == 1 and playerChoice == 0:
return 1
else:
return 0
# Function: Continue Game
# Input: none
# Output: boolean
# Ask the user is they want to continue (Y/N), and then return True or False accordingly
def continueGame():
playAgain = input("Do you want to continue playing? Enter (y) for yes or (n) for no.")
if playAgain.lower() == "y":
return True
elif playAgain.lower() == "n":
return False
# Function: main
# Input: none
# Output: none
def main():
playerCounter = 0
computerCounter = 0
tieCounter = 0
displayMenu()
p_choice = getPlayerChoice()
if p_choice == 0:
choicePlayer = "rock"
elif p_choice == 1:
choicePlayer = "paper"
elif p_choice == 2:
choicePlayer = "scissors"
getComputerChoice()
c_choice = getComputerChoice()
if c_choice == 0:
choiceComputer = "rock"
elif c_choice == 1:
choiceComputer = "paper"
elif c_choice == 2:
choiceComputer = "scissors"
print("You chose", choicePlayer + ".")
print("The computer chose", choiceComputer + ".")
playRound(getComputerChoice(), getPlayerChoice())
while playRound(c_choice, p_choice) == -1:
computerCounter += 1
while playRound(getPlayerChoice(), getPlayerChoice()) == 1:
playerCounter += 1
while playRound(getPlayerChoice(), getPlayerChoice()) == 0:
tieCounter += 1
continueGame()
while continueGame() == True:
displayMenu()
getPlayerChoice()
getComputerChoice()
playRound(getComputerChoice(), getPlayerChoice())
continueGame()
while continueGame() == False:
print()
print("You won", playerCounter, "game(s).")
print("The computer won", computerCounter, "game(s).")
print("You tied with the computer", tieCounter, "time(s).")
print()
print("Thanks for playing!")
# Call Main
main()
You don't have a "runGame" method, I believe you are referring to playRound.
In that case, once again, in this line:
playRound(getComputerChoice(), getPlayerChoice())
You are calling the getComputerChoice() and getPlayerChoice() methods again, and this is not what you want. Because of that it is asking you for the input again. You should do:
playRound(c_choice, p_choice)
There are some issues with your code. Firstly, you unnecessary call getComputerChoice(), getPlayerChoice() and continueGame() functions multiple times when it is not needed. Secondly, you have multiple weird while loops that don't do what you actually think they do.
Here is how you can modify your function in order to have a working program.
def main():
playerCounter = 0
computerCounter = 0
tieCounter = 0
displayMenu()
next_game = True
while next_game:
p_choice = getPlayerChoice()
if p_choice == 0:
choicePlayer = "rock"
elif p_choice == 1:
choicePlayer = "paper"
elif p_choice == 2:
choicePlayer = "scissors"
c_choice = getComputerChoice()
if c_choice == 0:
choiceComputer = "rock"
elif c_choice == 1:
choiceComputer = "paper"
elif c_choice == 2:
choiceComputer = "scissors"
print("You chose", choicePlayer + ".")
print("The computer chose", choiceComputer + ".")
result = playRound(p_choice, c_choice)
if result == -1:
computerCounter += 1
elif result == 0:
tieCounter += 1
else:
playerCounter += 1
next_game = continueGame()
print("You won", playerCounter, "game(s).")
print("The computer won", computerCounter, "game(s).")
print("You tied with the computer", tieCounter, "time(s).")
print()
print("Thanks for playing!")

How to add up wins/ties/losses using returns (in a game rock/paper/scissors)

So I'm trying to create a game of rock, paper, scissors that has multiple rounds and counts the number of wins/losses/ties within it and I think I have most if it down but I'm having trouble with counting up the number of losses/wins/ties within the loop.
I think what I'm supposed to do is include a "return" statement here but I'm not sure how to approach it and I've tried looking at other examples and I'm still not sure how it works so the returns I have in my code right now just shows where I think it should be.
I feel like I should have a +1 in those areas as well but again, I'm unsure how to approach this.
I cut out my_choice == scissors and my_choice == paper because I think the whole wins/ties/losses business works the same way as it does for my_choice == rock
import random
rounds = eval(input("Enter the number of rounds: "))
comp_pack = ["rock", "paper", "scissors"]
my_pack = ["rock", "paper", "scissors"]
for i in range (rounds):
count_win = ""
count_losses = ""
count_ties = ""
my_choice = input("Enter rock, paper, or sissors: ")
comp_choice = comp_pack[random.randint(0, len(comp_pack)-1)]
if my_choice == comp_choice:
print("tie")
return count_ties
elif my_choice == "rock":
if comp_choice == "paper":
print("paper covers rock loser")
return count_losses
elif comp_choice == "scissors":
print("rock smashes scissors winner")
return count_wins
print(count_losses)
print(count_wins)
print(count_ties)
Pull your counter variables out of the for loop and increment appropriately using += 1depending on win/loss/tie:
import random
rounds = eval(input("Enter the number of rounds: "))
comp_pack = ["rock", "paper", "scissors"]
my_pack = ["rock", "paper", "scissors"]
count_wins = 0
count_losses = 0
count_ties = 0
for i in range (rounds):
my_choice = input("Enter rock, paper, or sissors: ")
comp_choice = comp_pack[random.randint(0, len(comp_pack)-1)]
if my_choice == comp_choice:
print("tie")
count_ties += 1
elif my_choice == "rock":
if comp_choice == "paper":
print("paper covers rock loser")
count_losses += 1
elif comp_choice == "scissors":
print("rock smashes scissors winner")
count_wins +=1
print(count_losses)
print(count_wins)
print(count_ties)
return statement is only for function.
So, if you want to use 'return' statement, you have to make function.
I hope my code could help you.
import random
def game(round):
count_wins = 0
count_losses = 0
count_ties = 0
for i in range(round):
# I just defined r, c, p in number.
pack = {"scissors": 1, "rock": 2, "paper": 3}
my_choice = pack[input("Enter rock, paper, or scissors: ")]
comp_choice = random.randint(1, len(pack))
if my_choice == comp_choice:
print("tie")
count_ties += 1
elif comp_choice - my_choice == 1 or comp_choice - my_choice == -1:
if comp_choice < my_choice:
# I defined r, c, p in number because of this compare algorithm. I will explain about this at bottom. And I omitted some messages like "paper covers rock", if you want, you can define message dictionary and print here.
print("win")
count_wins += 1
else:
print("lose")
count_losses += 1
else:
if comp_choice < my_choice:
print("lose")
count_losses += 1
else:
print("win")
count_wins += 1
return count_wins, count_losses, count_ties
if __name__ == "__main__":
# You can use function game like this.
game_result = game(3)
print("Win: %d" % game_result[0])
print("Lose: %d" % game_result[1])
print("Tie: %d" % game_result[2])
This is detailed explain about algorithm which i used in my code.
Scissor: 1, Rock: 2, Paper: 3
If number is same => TIE
If |comp - my| is 1:
Big number wins => Rock(2) wins Scissors(1), Paper(3) wins Rock(2)
If |comp - my| is 2:
Big number loses => Scissors(1) wins Paper(3)
The spacing might be weird from copy/pasting but this is essentially the final result:
import random
def winner(comp_pack):
my_choice = input("Enter rock, paper, or scissors: ")
comp_choice = comp_pack[random.randint(0, len(comp_pack)-1)]
if my_choice == comp_choice:
print("tie")
return "tie"
elif my_choice == "rock":
if comp_choice == "paper":
print("paper covers rock, computer wins!")
return "comp"
elif comp_choice == "scissors":
print("rock smashes, scissors winner")
return "user"
elif my_choice == "paper":
if comp_choice == "scissors":
print("scissors cut paper, computer wins!")
return "comp"
elif comp_choice == "rock":
print("paper covers rock, you win!")
return "user"
elif my_choice == "scissors":
if comp_choice == "paper":
print("scissors cut paper, you win!")
return "user"
elif comp_choice == "rock":
print("rock smashes paper, computer wins!")
return "comp"
def main():
rounds = eval(input("Enter the number of rounds: "))
comp_pack = ["rock", "paper", "scissors"]
i_win = 0
comp_win = 0
tie = 0
for i in range (rounds):
result = winner(comp_pack)
if result == "user":
i_win += 1
elif result == "comp":
comp_win += 1
elif result == "tie":
tie += 1
print ("current score: user ", i_win , ", computer ", comp_win)
if i_win > comp_win:
print("You win!")
elif i_win < comp_win:
print("You lose!")
else:
print("Tie!")
main()

Categories