Determining winner in Rock Paper Scissors [python] - python

I'm a beginner in python trying to create a RPS game where human is playing against a computer. The game is created such that it would be played over a number of determined rounds (best of 3 rounds). A draw is considered a point for each side.
My problem is setting the while condition. Initially I did this:
while (player_count + computer_count) != winning_score : where the game ends when all round are played. However there will be instances where not all rounds needs to be played and the winner can already be determined (because of draws, each player will get a point).
How do I change the while condition such that when either players get winning_score/2 + 1, the game ends?

hi you can probably do it like this
winning_count = winning_score/2+1
while(player_count < winning_count) and (computer_count < winning_count):
...
Once either the player win or the computer win is more than the winning count, it goes to False and the loop breaks

Just in case you want to have another perspective on how to implement the game (and how to determine the winner), I exhort you to play with the following version:
import random
options = {1: 'Rock', 2: 'Scissors', 3: 'Paper'}
def play():
score = [0, 0]
while not any(wins == 3 for wins in score):
print(f'SCORE\tUser: {score[0]} - PC: {score[1]}')
user_selection = int(input('Enter your selection:{}> '.format(
''.join([f'\n{n}: {option}\n' for n, option in options.items()]))))
pc_selection = random.randint(1, 3)
print(f'{options[user_selection]} vs. {options[pc_selection]}')
if user_selection in (pc_selection - 1, pc_selection + 2):
print('User wins')
score[0] += 1
elif user_selection == pc_selection:
print('Draw')
else:
print('PC Wins')
score[1] += 1
input('\n_____ ENTER TO PROCEED _____')
winner = 'User' if score[0] == 3 else 'PC'
print(f'\n{winner} won the match!')
play()
Hopefully you will find here something useful and new for your learning process.

Related

How to break a loop depending on answer from input, then move on with the rest of the program [duplicate]

This question already has answers here:
How to make a while true statement in a program that already has a while true statement
(4 answers)
Closed last year.
Hi so I'm very new to coding and I'm making a blackjack game for my high school project, I'm on the part where it asks the user to hit or stand and when they hit it asks them again until they bust or stand, I want it so once they stand the loop for asking them to hit or stand breaks but moves on with the rest of the code which is the logic for the dealer / computer to hit or stand. But when they do stand it just stops the entire program. How do I fix this? The code is not fully completed and I apologize for what probably is a big mess.
# Import the required modules
import random
# Print welcome message
print('Welcome To Blackjack!')
# State the rules for the game
print('This is blackjack. Rules are simple whoever has the biggest sum of the cards at the end wins. Unless someone gets 21 / blackjack or goes over 21 (bust). Bust is when a player goes over 21 and the lose. Once it is your turn you can choose to hit or stand, if you hit you get another card, if you stand it becomes the other persons turn. Your goal is to get the closest number to 21 without going over it. The game uses no suit cards. The values of the face cards are a Jack = 10, Queen = 10, King = 10, Ace = 11 or 1 whatever works the best. ')
# Global Variables
deck = [2, 3, 4, 5, 6, 7, 8, 9, 10, 2, 3, 4, 5, 6, 7, 8, 9, 10, 2, 3, 4, 5, 6, 7, 8, 9, 10, 2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K', 'A']
dealer_cards = []
player_cards = []
print('Dealing...')
# Create the dealcard function to deal a card when needed
def dealcard(turn):
card = random.choice(deck)
turn.append(card)
deck.remove(card) # Removes the card out of the deck so it cant repeat.
# Create the function to calculate the total cards that each player has
def totalvalue(turn):
totalvalue = 0
facecards = ['J', 'Q', 'K']
for card in turn:
if card in range(1, 11):
totalvalue += card # This adds the cards together
elif card in facecards: # Checks if a card is a face card (J, Q, K,)
totalvalue += 10 # This gives value to face cards
else: # This checks if they get an ace and what works the best in case when they get an ace
if totalvalue > 11: # If total is over 11 Ace counts as 1
totalvalue += 1
else: # If total is under 11 Ace counts as 11
totalvalue += 11
return totalvalue
for dealing in range(2):
dealcard(dealer_cards)
dealcard(player_cards)
print(f"The dealer's cards are {dealer_cards} and the total amount is {totalvalue(dealer_cards)}")
print(f"Your cards are {player_cards} and your total amount is {totalvalue(player_cards)}")
while True:
# Take input from user
playerchoice = (input('Would you like to \n1.Hit \nor \n2.Stay\n'))
# Check what choice user chose and execute it
if playerchoice == '1':
dealcard(player_cards)
print(f"You now have a total of {totalvalue(player_cards)} with these cards {player_cards}")
continue
# If they chose to stand move on to dealers / computers turn
if playerchoice == '2':
print(f"Your cards stayed the same {player_cards} with a total of {totalvalue(player_cards)}")
print("What will the dealer do?...")
break
# Create dealer logic
if totalvalue(dealer_cards) >= 18:
print(f"The dealer chose to stand their cards are {dealer_cards} with a total of {totalvalue(dealer_cards)}")
if totalvalue(dealer_cards) < 16:
dealcard(dealer_cards)
print(f"The dealer chose to hit their new cards are {dealer_cards} and their total is {totalvalue(dealer_cards)}")
if totalvalue(dealer_cards) == totalvalue(player_cards):
print(f"Its a tie you both have {totalvalue(player_cards)}")
if totalvalue(dealer_cards) == 21:
print(f"The dealer got blackjack! You lose...")
break
I think what you are requesting is something like this. I wasn't sure if the program was supposed to keep running so you could play multiple games or that it only had to be able to play one game. if it has to be able to play multiple games you run into an issue with updating the global values. to get around this with the code you have you will have to copy the global values every time you played a new game. As you see this doesn't look too pretty but i tried to keep it as close as to what you wrote as possible. There's still some errors in the game I've posted so you'll still have to copy the deck and return the deck in the same way that the player cards have been returned. but that is for you to do :-)
Starting function that copies the variables you already have and return them:
def start():
for dealing in range(2):
copy_dealer_cards = dealer_cards.copy()
copy_player_cards = player_cards.copy()
dealcard(copy_dealer_cards)
dealcard(copy_player_cards)
print(f"The dealer's cards are {copy_dealer_cards} and the total amount is {totalvalue(copy_dealer_cards)}")
print(f"Your cards are {copy_player_cards} and your total amount is {totalvalue(copy_player_cards)}")
return (copy_dealer_cards, copy_player_cards)
Compare the result with. Here you could use the return value to keep score of how many games the player and dealer has each won:
def comp(player_res, dealer_res):
if dealer_res>player_res:
print("Dealer wins\n\n")
return 1
if dealer_res<player_res:
print("Player wins\n\n")
return -1
if dealer_res == player_res:
print(f"Its a tie you both have {player_res}")
return 0
The main function that plays the game with some updated logic and conditions. As well as a slightly modified while loop.
def run() -> None:
d_cards , p_cards = start()
player_stay = False
dealer_stay = False
while not(dealer_stay and player_stay):
# Take input from user
if not player_stay:
playerchoice = (input('Would you like to \n1.Hit \nor \n2.Stay\n'))
# Check what choice user chose and execute it
if playerchoice == '1':
dealcard(p_cards)
print(f"You now have a total of {totalvalue(p_cards)} with these cards {p_cards}")
# If they chose to stand move on to dealers / computers turn
if playerchoice == '2':
print(f"Your cards stayed the same {p_cards} with a total of {totalvalue(p_cards)}")
print("What will the dealer do?...")
player_stay = True
if not dealer_stay:
# Create dealer logic
if totalvalue(d_cards) >= 17:
print(f"The dealer chose to stand their cards are {d_cards} with a total of {totalvalue(d_cards)}")
dealer_stay = True
if totalvalue(d_cards) <= 16:
dealcard(d_cards)
print(f"The dealer chose to hit their new cards are {d_cards} and their total is {totalvalue(d_cards)}")
#If bust
if totalvalue(p_cards) > 21:
print(f"Player bust! You lose...\n\n")
break
if totalvalue(d_cards) > 21:
print(f"Dealer bust! You win...\n\n")
break
#If blakcjack
if totalvalue(p_cards) == 21:
print(f"The player got blackjack! You win...\n\n")
break
if totalvalue(d_cards) == 21:
print(f"The dealer got blackjack! You lose...\n\n")
break
#If hit then evaluate
if dealer_stay and player_stay:
comp(totalvalue(p_cards), totalvalue(d_cards))
print("New round begins...")
break
run()
run()
I want it so once they stand the loop for asking them to hit or stand breaks but moves on with the rest of the code"
Your current while loop while True: just repeats infinitely. Instead, you need a condition to specify when you want to continue. For example, you could do
while playerchoice == '1':
Note that this change will also require more changes to your code. In particular, you won't need the if statement any more because the body of the while loop will only repeat if the user chose "hit me". The logic for "stand" will go after the while loop. I leave the details for you to figure out.

Number of stones is inconsistent, nim game

The issue is that the number of stones the computer takes differs from the number that is displayed on the screen.
I know it's cause the function is being repeated twice. But I can't find a way to store the random number generated and use that number for printing AND subtracting
[Also I know this can be done without using functions but it is required]
Here is the code:
import random
stones = random.randint(15, 30)
turn = 0
while stones > 0:
if turn == 0:
def player_announce():
print('There are', stones, 'stones. How many would you like?', end=' ')
def invalid_entry():
print('Enter a number from 1-3.')
player_announce()
player_stones = int(input(''))
if player_stones > 3 or player_stones < 1:
invalid_entry()
else:
stones = stones - player_stones
turn = 1
else:
def draw_stones():
computer_stones = random.randint(1, 3)
return computer_stones
print('There are', stones, 'stones. The computer takes', draw_stones())
stones -= draw_stones()
turn = 0
if turn == 0:
print('The computer beats the player!')
else:
print('The player beats the computer!')
The simple answer is to call draw_stones once and store the result:
computers_stones = draw_stones()
print('There are', stones, 'stones. The computer takes', computers_stones)
stones -= computers_stones
Once you've got it working, I advise you get someone to read over the whole thing for you there are a lot of things you could do better!

What can I do to fix my simple computer-player game code? Syntax Error

I'm new to Python and I wanted to practice doing loops because I’ve been having the most trouble with them. I decided to make a game where the user will pick a number from 0-100 to see if they can win against the computer.
What I have going right now is only the beginning. The code isn’t finished. But trying out the code I got a Syntax error where the arrow pointed at the colon on the elif function.
How do I fix this? What can I do?
I accept any other additional comments on my code to make it better.
Here’s my code:
import random
min = 0
max = 100
roll_again = "yes"
quit = "no"
players_choice = input()
computer = random.randint
while roll_again == "yes":
print("Pick a number between 1-100: ")
print(players_choice)
if players_choice >= 0:
print("Your number of choice was: ")
print(players_choice)
print("Your number is high.")
if computer >= 0:
print("Computers number is: ")
print(computer)
print("Computers number is high.")
if computer >= players_choice:
print("Computer wins.")
print("You lose.")
print("Would you like to play again? ", +roll_again)
elif:
print(quit)
end
Goal:
Fix computer-player game while learning more about python. Providing additional documentation on where to start would be helpful.
The reason you are getting an error pointing to elif is because elif needs a condition to check. You need to use if elif and else like this:
if a == b:
print('A equals B!')
elif a == c:
print('A equals C!')
else:
print('A equals nothing...')
Also, Python relies on indentation to determine what belongs to what, so make sure you are paying attention to your indents (there is no end).
Your code has more errors after you fix the if statements and indentation, but you should be able to look up help to fix those.
There are a lot of problems with your code. Here is a working version, hope it helps you understand some of the concepts.
If not, feel free to ask
import random
# min and max are names for functions in python. It is better to avoid using
# them for variables
min_value = 0
max_value = 100
# This will loop forever uless something 'breaks' the loop
while True:
# input will print the question, wait for an anwer and put it in the
# 'player' variable (as a string, not a number)
player = input("Pick a number between 1-100: ")
# convert input to a number so we can compare it to the computer's value
player = int(player)
# randint is a function (it needs parentheses to work)
computer = random.randint(min_value, max_value)
# print what player and computer chose
print("Your choice: ", player)
print("Computer's choice: ", computer)
# display the results
if computer >= player:
print("Computer wins. You loose")
else:
print("you win.")
# Determine if user wants to continue playing
choice = raw_input("Would you like to play again? (yes/No) ")
if choice != 'yes':
# if not
break
There are a lot of indentiation issues and the if and elif statements are used incorrectly. Also take a look at how while loops work.
Based on the code you provided here is a working solution, but there are many other ways to implement this.
Here is some helpful tutorials for you on if/else statements as well as other beginner topics:
Python IF...ELIF...ELSE Statements
import random
minval = 0
maxval = 100
roll_again = "yes"
quit_string = "no"
while True:
players_choice = int(input("Pick a number between 1-100:\n"))
computer = random.randint(minval,maxval)
#checks if players choice is between 0 and 100
if players_choice >= 0 and players_choice <= 100:
print("Your number of choice was: ")
print(players_choice)
#otherwise it is out of range
else:
print("Number out of range")
#check if computers random number is in range from 0 to 100
if computer >= 0 and computer <= 100:
print("Computers number is: ")
print(computer)
# if computer's number is greater than players number, computer wins
if computer > players_choice:
print("Computer wins.")
print("You lose.")
#otherwise if players number is higher than computers, you win
elif computer < players_choice:
print("You won.")
#if neither condition is true, it is a tie game
else:
print("Tied game")
#ask user if they want to continue
play_choice = input("Would you like to play again? Type yes or no\n")
#checks text for yes or no use lower method to make sure if they type uppercase it matches string from roll_again or quit_string
if play_choice.lower() == roll_again:
#restarts loop
continue
elif play_choice.lower() == quit_string:
#breaks out of loop-game over
break

Procedure in if loop not working even though condition is met [duplicate]

This question already has answers here:
How can I read inputs as numbers?
(10 answers)
Closed 5 years ago.
I have made this code to emulate a rock paper scissors game. I have a procedure which has the main game, and when I run this by itself without the if loop at the end, it works. However, when I try to validate whether or not the user entry is numerical, it does not print the correct message. Here is the full code:
import random
def game(choice):
number = random.randint(1,3)
if choice == 1 and number == 2:
print("You lose.")
if choice == 1 and number ==3:
print("You win.")
if choice == 1 and number == 1:
print("It is a draw")
if choice == 2 and number == 3:
print("You lose.")
if choice == 2 and number ==1:
print("You win.")
if choice == 2 and number == 2:
print("It is a draw")
if choice == 3 and number == 1:
print("You lose.")
if choice == 3 and number ==2:
print("You win.")
if choice == 3 and number == 3:
print("It is a draw")
x = input("Choose 1 (rock), 2 (paper) or 3 (scissors).")
digit = x.isdigit()
if digit == True:
game(x)
By the way, there is no error message, the procedure just does not work!
First of all, there are a few issues with your code. If you wish to ignore, skip to Error Handling for answer to your question. You will find it in there.
Naming Variables
Your variables do not tell a person reading your code what they are. If you showed someone the word number, they would not know that it is what the computer chooses in rock paper scissors. Same with choice (who's choice?) and even more so x. So why don't we name them computer_choice, user_choice and choice respectively. I know these are a bit longer to type, but it is worth sacrificing a few extra keystrokes for a bit more clarity. Also notice that I used snake_case name formatting as per usual Python standards.
Repetitiveness/ game()
Your game function could do with a bit of re-doing. All you need is a general 'formula' for winning and losing. In this case, losing is when (thanks to #Brett Beatty) if computer_choice == (user_choice + 1) % 3, drawing is when computer_choice == user_choice and winning is everything else. Also, when your code is being played, the user only knows if they have won or lost, and not what the computer chose, so to add a bit more clarity, I added a list and another print() line. This feature is also useful to test code. Additionally, use zero-based variable values, such as in the computer_choice and user_choice variables. This is useful when converting values to list indexes. Below is a revised version of your code that i have made which includes all points above (I have also made it a function, as you will see below - I just think it looks better):
import random
def game(user_choice):
user_choice -= 1
rps = ["Rock", "Paper", "Scissors"]
computer_choice = random.randint(0, 2)
print("You: {} Computer: {}".format(rps[user_choice], rps[computer_choice]))
if user_choice == computer_choice:
return 0
elif computer_choice == (user_choice + 1) % 3:
return -1
else:
return 1
Error Handling
To make sure the user enters an integer, you would have to add int() around the input statement. However, this alone would return ValueError if the value entered by the user is not an integer, and this is a problem. However, there is a way to fix this using try: except: else: blocks, as you will see below. This is what you would need to decide if the value is an integer, it also prints the correct message when it is not. I also think this is what you wanted for if digit == True(FYI you would only need if digit if you were to do it that way).
def main():
while True:
try:
value = int(input("Choose 1 (rock), 2 (paper) or 3 (scissors):"))
except ValueError: # If any part of the code in the try block raises a ValueError
print("Not an integer")
else: # If error is not raised
if not 1 <= value <= 3: # If value is not between 1 and 3
print("Must be between 1 and 3")
else:
result = game(value) # sets result to return value from game()
break
if result == 1:
print("You Win")
elif result == -1:
print("You Lose")
else:
print("It's a Draw")
And Finally, the 'if loop'?
Let me just make this clear. There is no such thing as an if loop!!! An if statement runs code **ONCE** if a certain condition is True. I think what you want is a while loop. This runs code **REPEATEDLY** as long as a certain condition is True. In the code below, I created a while True loop, which runs the code each time the user types in "y", and breaks from the loop if not.
Also, use if __name__ == '__main__'. It exists in Python so that Python files can act as either reusable modules, or as standalone programs. It also looks more complex, if you want to look smart.
if __name__ == '__main__':
while True:
main()
if input("Again? Yes(y) No(Anything else): ").lower() != 'y':
break
Example Output (ignore colours):
Choose 1 (rock), 2 (paper) or 3 (scissors):1
You: Rock Computer: Scissors
You Win
Again? Yes(y) No(Anything else): y
Choose 1 (rock), 2 (paper) or 3 (scissors):3
You: Scissors Computer: Scissors
It's a Draw
Again? Yes(y) No(Anything else): y
Choose 1 (rock), 2 (paper) or 3 (scissors):2
You: Paper Computer: Paper
It's a Draw
Again? Yes(y) No(Anything else): n
Process finished with exit code 0
Also, for the OP, if you haven't already, I would recommend downloading Pycharm. It is completely free, and makes coding a lot easier. It also improves presentation too. It picks up on some of the things mentioned above, as well as keeping your code in line with PEP guidelines.

Python Connect Four game win function

I have most of my Python version of Connect Four coded, except for the win function and the gravity. Below is the code for determining if the game has been won yet.. It doesn't function, currently the only way the game ends is if all the spots are taken up. Any ideas?
winners = [ [1,2,3,4],[2,3,4,5],[3,4,5,6],[4,5,6,7],[8,9,10,11],[9,10,11,12],[10,11,12,13],[11,12,13,14],
[15,16,17,18],[16,17,18,19],[17,18,19,20],[18,19,20,21],[22,23,24,25],[23,24,25,26],[24,25,26,27],
[25,26,27,28],[29,30,31,32],[30,31,32,33],[31,32,33,34],[32,33,34,35],[36,37,38,39],[37,38,39,40],
[38,39,40,41],[39,40,41,42],[1,8,15,22],[8,15,22,29],[15,22,29,36],[2,9,16,23],[9,16,23,30],[16,23,30,37],
[3,10,17,24],[10,17,24,31],[17,23,31,38],[4,11,18,25],[11,18,25,32],[18,24,32,39],[5,12,19,26],[12,19,26,33],
[19,25,33,40],[6,13,20,27],[13,20,27,34],[20,28,34,41],[7,14,21,28],[14,21,28,35],[21,28,35,42],[1,9,17,25],
[9,17,25,33],[17,25,33,41],[8,16,24,32],[16,24,32,40],[15,23,31,39],[2,10,18,26],[10,18,26,34],[18,26,34,42],
[3,11,19,27],[11,19,27,35],[4,12,20,28] ]
def makeMove(self):
self.Player = self.game.Player
if self.game.Player == 'Black':
self.b.config(image=self.Black, command=self.invalidMove)
num = self.num
self.game.moves['Black'].append(num)
self.game.free.remove(num)
w = self.won(self.game.Player)
if self.game.moves['Black'] in winners:
self.game.turninfo.config(text=self.game.Player+' WON!')
elif self.game.free == [ ]:
self.game.turninfo.config(text='Game is a draw!')
else:
self.game.Player = 'Red'
self.game.turninfo.config(text=self.game.Player+"'s Turn")
elif self.game.Player == 'Red':
self.b.config(image=self.Red, command=self.invalidMove)
num = self.num
self.game.moves['Red'].append(num)
self.game.free.remove(num)
w = self.won(self.game.Player)
if contains(self.game.moves['Red'],winners):
self.game.turninfo.config(text=Player+' WON!')
for c in self.game.cells:
c.freeze()
elif self.game.free == [ ]:
self.game.turninfo.config(text='Game is a draw!')
for c in self.game.cells:
c.freeze()
else:
self.game.Player = 'Black'
self.game.turninfo.config(text=self.game.Player+"'s Turn")
I think your issue is that you are checking to see if a players moves match one of the win conditions exactly. This is possible but probably won't happen that often, for example a player might make the moves [2, 3, 1, 4] which should count as a win, but [2, 3, 1, 4] is not in winners so you will not get a match. Also, if it ever took a player more than four moves you would never get a winner for the same reason (since [6, 1, 2, 3, 4] wouldn't be found in winners either).
What you actually want to find out is if for any of the win conditions, all of the moves of the win condition were made by a player. This can be expressed like this:
for winner in winners:
won = True
for move in winner:
if move not in self.game.moves['Black']:
won = False
if won:
# game ending logic
break
This can be shortened considerably to the following (but it might be harder to follow):
if any(all(m in self.game.moves['Black'] for m in w) for w in winners)):
# game ending logic

Categories

Resources