I have this Python program that plays tic tac toe between two human players. If Player A or Player B ever wins, it is announced and the program terminates. However, if the program ends in a draw, it will keep requesting user input.
I'm not sure how to check for a draw. Does it have to be within the while loop or does it require it's own separate function?
import sys
## Define and create tic tac toe gameboard
board = range(0,9)
def show_board():
print board[0], '|', board[1], '|', board[2]
print '---------'
print board[3], '|', board[4], '|', board[5]
print '---------'
print board[6], '|', board[7], '|', board[8]
# Function used to check for winner
def line(char, box1, box2, box3):
if board[box1] == char and board[box2] == char and board[box3] == char:
return True
# Function used to automate process for checking every possible way to win
def all(char):
# Horizontal check
if line(char, 0, 1, 2):
return True
if line(char, 3, 4, 5):
return True
if line(char, 6, 7, 8):
return True
# Vertical check
if line(char, 0, 3, 6):
return True
if line(char, 1, 4, 7):
return True
if line(char, 2, 5, 8):
return True
# Diagnol check
if line(char, 0, 4, 8):
return True
if line(char, 2, 4, 6):
return True
show_board()
# Initial while loop will ask for player A input and show the board as well
# check conditions to see whether or not player A wins. If player A wins,
# the program will terminate so it does not ask for player B input after.
while True:
player_a = int(raw_input('Player A, please select a spot that is not taken \
(0-8): '))
# Checks for empty spot and places an 'X' if it exists, otherwise
# asks again.
if board[player_a] != 'X' and board[player_a] != 'O':
board[player_a] = 'X'
show_board()
# Check to see if Player A wins.
if all('X') == True:
print "Player A wins."
sys.exit()
break;
# While loop to ask for player B input and display the board as well as check
# the conditions as to whether or not player B wins. If player B wins, the
# program will terminate so it does not ask for player A input after.
while True:
player_b = int(raw_input('Player B, please select a spot that is \
not taken (0-8): '))
# Checks for empty spot and places an 'O' if it exists, otherwise
# asks again.
if board[player_b] != 'O' and board[player_b] != 'X':
board[player_b] = 'O'
# Check to see if Player B wins.
if all('O') == True:
show_board()
print "Player B wins."
sys.exit()
break;
break;
show_board()
Without extensively going through the code, I can tell you that a draw is occurs after 9 turns, and only if both Player A and B do not receive a win on that final turn. For your simple program, what I would do is create a global variable called ELAPSED_TURNS or something of the sort, that increments each time a player enters a character, and then after checking both of the players' win conditions, and if there is no win, check ELAPSED_TURNS. If it is equal to 9, then the game must be a draw.
Here's the function that does what you want.
def is_tie():
for position in board:
if isinstance(position, int):
return False
print "The game is a tie."
sys.exit()
Put a call to is_tie() directly after both while loops like this...
while True:
is_tie()
player_a = int(raw_input(...
while True:
is_tie()
player_b = int(raw_input(...
If this is a learning exercise for you I would recommend refactoring your code to find a way wrap all your logic blocks into functions and getting everything to flow without the use of sys.exit(). Doing so will increase the readability and make it easier to splice in new logic.
EDIT to your comment:
You can create an integer test function using just try / except statements like this...
def is_int(s):
try:
int(s)
return True
except ValueError:
return False
Credit here: Python: Check if a string represents an int, Without using Try/Except?
Your is_tie() function would then look like this:
def is_tie():
for position in board:
if is_int(position):
return False
print "The game is a tie."
sys.exit()
Related
First of all, I am totally new in Python, having just started to learn it. I know a lot of stuff about C++ however and I am just trying to implement some of those in Python.
I have done quite a search on it but I couldn't find any solution that fits my requirement. Please see the following code,
import os
class _Getch:
"""Gets a single character from standard input. Does not echo to the
screen."""
def __init__(self):
try:
self.impl = _GetchWindows()
except:
print("Error!")
def __call__(self): return self.impl()
class _GetchWindows:
def __init__(self):
import msvcrt
def __call__(self):
import msvcrt
return msvcrt.getch()
def mainfun():
check = fh = True
while check:
fh = True
arr = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
print ("Welcome to Tic Tac Toe Game!!!\n\n")
print("Enter 1 to Start Game")
print("Enter 2 to Exit Game")
a = _Getch()
if a == "1":
while fh:
os.system("cls")
drawboard()
playermove()
fh = checkresult()
elif a == "2":
break
As you can see, What I am trying to do here is asking the user to press a number from 1 and 2 and then store that number in "a" and then use it for my requirements.
Now, I first tried using this,
input('').split(" ")[0]
But this didn't work. It required me to always Press Enter after having typed 1 or 2. So, that didn't work.
Then I found this class of Getch and I implemented it. Long story short, it entered me into a never ending loop and my result is something like this now,
Welcome to Tic Tac Toe Game!!!
Enter 1 to Start Game
Enter 2 to Exit Game
Press Enter to Continue....
Welcome to Tic Tac Toe Game!!!
Enter 1 to Start Game
Enter 2 to Exit Game
Press Enter to Continue....
Welcome to Tic Tac Toe Game!!!
Enter 1 to Start Game
Enter 2 to Exit Game
Press Enter to Continue....
And it is a never ending loop... Even if I press any key like "1" or "2", it still doesn't stop and keep on performing this and don't enter any function.
What I want is a function similar to this,
It should work on PYCHARM Console (I am practicing and I don't want to practice on Terminal. I am used to using the console of the IDE I am working on)
It pauses and waits for the user to enter any input (like input does)
It accepts and stores the very first key entered by the user into the variable. Like in this case, if user presses "1" then it should store that character in "a" and simply move on. You don't have to Press "ENTER" to move on.
If the user presses any other button like "a" or "b" or anything like this, it will simply not do anything and keep on asking for the input until the required number "1" or "2" is entered (and I think that can very easily be handled in this while loop)
In other words, I just want an alternative to getch() command of C++ in Python. I have tried a lot to find it, but I couldn't. Please refer to me a question which provides a solution to this exact question or provide a solution here. Thank you.
Edit: Please note this isn't the complete code. I have only provided the code which is relevant. If anyone needs to see the whole code, I am happy to share that as well.
Complete code is as follows,
import os
import keyboard
def getch():
alphabet = list(map(chr, range(97, 123)))
while True:
for letter in alphabet: # detect when a letter is pressed
if keyboard.is_pressed(letter):
return letter
for num in range(10): # detect numbers 0-9
if keyboard.is_pressed(str(num)):
return str(num)
arr = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
playerturn = 1
def drawboard():
global playerturn
print("Player 1 (X) - Player 2 (O)\n")
print("Turn: Player " + str(playerturn))
print("\n")
for i in range(3):
print (" ", end='')
for j in range(3):
print(arr[i][j], end='')
if j == 2:
continue
print(" | ", end='')
if i == 2:
continue
print("")
print("____|____|____")
print(" | | ")
def playermove():
global playerturn
row = col = 0
correctmove = False
print("\n\nMake your Move!\n")
while not correctmove:
row = int(input("Enter Row: "))
col = int(input("Enter Col: "))
if (3 > row > -1) and (-1 < col < 3):
for i in range(3):
for j in range(3):
if arr[row][col] == 0:
correctmove = True
if playerturn == 1:
arr[row][col] = 1
else:
arr[row][col] = 2
playerturn += 1
if playerturn > 2:
playerturn = 1
if not correctmove:
print ("Wrong Inputs, please enter again, ")
def checkwin():
for player in range(1, 3):
for i in range(3):
if arr[i][0] == player and arr[i][1] == player and arr[i][2] == player: return player
if arr[0][i] == player and arr[1][i] == player and arr[2][i] == player: return player
if arr[0][0] == player and arr[1][1] == player and arr[2][2] == player: return player
if arr[0][2] == player and arr[1][1] == player and arr[2][0] == player: return player
return -1
def checkdraw():
for i in range(3):
for j in range(3):
if arr[i][j] == 0:
return False
return True
def checkresult():
check = checkwin()
if check == 1:
os.system('cls')
drawboard()
print("\n\nPlayer 1 has won the game!!\n")
elif check == 2:
os.system('cls')
drawboard()
print("\n\nPlayer 2 has won the game!!\n")
elif check == 3:
os.system('cls')
drawboard()
print("\n\nThe game has been drawn!!\n")
else:
return True
return False
def mainfun():
check = fh = True
while check:
os.system("cls")
fh = True
arr = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
print ("Welcome to Tic Tac Toe Game!!!\n\n")
print("Enter 1 to Start Game")
print("Enter 2 to Exit Game")
a = getch()
if a == "1":
while fh:
os.system("cls")
drawboard()
playermove()
fh = checkresult()
elif a == "2":
break
print ("Press any key to continue...")
getch()
mainfun()
EDIT2: Problem is resolved by using Keyboard module... The next issue here is how do I remove the data stored in input buffer after the getch() function is called? Because the data in buffer is getting displayed on the next input (when I am taking in the row and column) and I don't want that to happen. I fonud a solution for Linux but not for Windows (or for Pycharm)
It looks like this feature isn't in the standard python library but you can recreate it.
First, install the module 'keyboard'
$ pip3 install keyboard
Then you can use keyboard.is_pressed() to see if any one character is pressed.
import keyboard # using module keyboard
import string # use this to get the alphabet
print("Input a character")
def getch():
alphabet = list(string.ascii_lowercase)
while True:
for letter in alphabet: # detect when a letter is pressed
if keyboard.is_pressed(letter):
return letter
for num in range(10): # detect numbers 0-9
if keyboard.is_pressed(str(num)):
return str(num)
answer = getch()
print("you choose " + answer)
Edit: For unix you need to run with the script with sudo. This code should work fine on windows.
For EDIT-2:
Use below code to flush the screen:
sys.stdout.flush()
For some reason the while loop is not breaking when the condition is met. The while loop should be checking for a players input to fill up a tic tac toe board until the variable "win" reads True.
Once the board reflects one of the winning conditions of tic tac toe, it assigns the variable "win" to True, and in turn should break out of the loop.
For some reason the loop isn't breaking, but the variable "win" is still reading True.
Can someone explain why the loop isn't breaking? I have tried rewriting the condition for the while loop to read "while win == False", but that doesn't seem to resolve the issue either.
I have included some of the functions I am using, and explained some of the simpler ones with a comment next to it.
I am using repl.it to do all of this online and not on a program on my local machine, so I think this may be part of the issue as well.
import os
board = ["#"," "," "," "," "," "," "," "," "," "]
def determine_win(marker):
# Winning Patterns:
# (1,2,3), (4,5,6), (7,8,9), (1,4,7), (2,5,8), (3,6,9), (3,5,7), (1,5,9)
if board[1]== board[2]==board[3]==marker:
return True
elif board[4]== board[5]==board[6]==marker:
return True
elif board[7]== board[8]==board[9]==marker:
return True
elif board[1]== board[4]==board[7]==marker:
return True
elif board[2]== board[5]==board[8]==marker:
return True
elif board[3]== board[6]==board[9]==marker:
return True
elif board[3]== board[5]==board[7]==marker:
return True
elif board[1]== board[5]==board[9]==marker:
return True
else:
return False
player1 = xo() # A Function that takes user input either "X" or O"
if player1 == "X":
player2 = "O"
else:
player2 = "X"
win = False
while not win:
display_board(board) # display_baord(board) takes the list "board" and uses it as input to display the tic tac toe board to the screen.
print("\nPlayer 1")
board[player_turn()] = player1
win = determine_win(player1)
print(win) # used to verify if win is changing
input() # used to pause the screen for troubleshooting
display_board(board)
print("\nPlayer 2")
board[player_turn()] = player2
win = determine_win(player2)
print(win) # used to verify if win is changing
input() # used to pause the screen for troubleshooting
print("Win Declared")
As the comment said, the reason is because while only check the condition of win when you finish the whole iteration of the loop. I would prefer the following way to make the code neater:
# win = False <-- you don't need this now
while True:
display_board(board) # display_baord(board) takes the list "board" and uses it as input to display the tic tac toe board to the screen.
print("\nPlayer 1")
board[player_turn()] = player1
if determine_win(player1):
print("Player 1 won")
break # break out of the loop
display_board(board)
print("\nPlayer 2")
board[player_turn()] = player2
if determine_win(player2):
print("Player 2 won")
break # break out of the loop
if not determine_win(player1):
display_board(board)
print("\nPlayer 2")
board[player_turn()] = player2
win = determine_win(player2)
# player 2 wins
else:
# player 1 wins
win = True
use something like this. It is same as #jasonharper and #Idlehands answered
I don't know why my screen won't clear. Instead, I get an arrow pointing to the first letter. I looked on Google and one source said that it certain circumstances it may return a 0. Perhaps that is why it is pointing to the first letter of my first string? There are other problems with my code as well but I've spent a lot of time trying to figure out why this function won't work and I can't figure it out.
import os
import random
'''
In this tic-tac-toe game, the user will be prompted to choose a mark.
The player will play against a computer.
CURRENT PROBLEMS WITH GAME:
board_tiles and tiles_available do not reset after new game
clear_screen function does not work
Error when tie occurs
'''
board_tiles = [0, 1, 2, 3, 4, 5, 6, 7, 8]
tiles_available = [0, 1, 2, 3, 4, 5, 6, 7, 8]
# create a function that clears the screen
def clear_screen():
os.system('cls')
# create a function that draws the tic-tac-toe board
def draw_board():
# clear screen
clear_screen()
print(f'{board_tiles[0]} | {board_tiles[1]} | {board_tiles[2]}')
print('-' * 10)
print(f'{board_tiles[3]} | {board_tiles[4]} | {board_tiles[5]}')
print('-' * 10)
print(f'{board_tiles[6]} | {board_tiles[7]} | {board_tiles[8]}')
# create a function that allows the user to choose a piece
def choose_mark():
player = input("Would you like to be 'X' or 'O'? ").upper()
if player == 'X':
computer = 'O'
else:
computer = 'X'
print(f'Player is {player}. Computer is {computer}.')
return player, computer
# create a function that allows the computer to make a random move on the board
def computer_move(computer):
computers_move = random.choice(tiles_available)
tiles_available.remove(computers_move)
board_tiles.insert(computers_move, computer)
board_tiles.remove(computers_move)
return computers_move
# create a function that checks if the chosen spot is available and draws it to the board
def draw_mark(player, computer):
while tiles_available:
players_move = int(input('Where would you like to move? '))
if players_move in tiles_available:
tiles_available.remove(players_move)
board_tiles.insert(players_move, player)
board_tiles.remove(players_move)
computer_move(computer)
draw_board()
score()
else:
print('{players_move} has already been taken')
return player
# define what is a win/lose/tie
def score():
if board_tiles[0] == board_tiles[1] == board_tiles[2] or \
board_tiles[3] == board_tiles[4] == board_tiles[5] or \
board_tiles[6] == board_tiles[7] == board_tiles[8] or \
board_tiles[0] == board_tiles[3] == board_tiles[6] or \
board_tiles[1] == board_tiles[4] == board_tiles[7] or \
board_tiles[2] == board_tiles[5] == board_tiles[8] or \
board_tiles[0] == board_tiles[4] == board_tiles[8] or \
board_tiles[2] == board_tiles[4] == board_tiles[6]:
print('YOU WIN!!!')
play_again()
if len(tiles_available) == 0:
print('It is a tie!')
play_again()
def play_again():
replay = input("Would you like to play again? \n"
"Type 'y' for yes and 'n' for no: ").lower()
if replay == 'y':
game()
else:
print('Come back!')
quit()
def game():
playing = True
player, computer = choose_mark()
while playing:
draw_board()
draw_mark(player, computer)
game()
I designed a game for tic tac toe.
The game runs well.
However, I can not use the while loop to start the game over again at the very end with the Main. It starts with the board that breaks from the previous game intead of starting from a new and clean board.
Could anyone take a look at it?
Thank you all in advance.
"""
Tic Tac Toe Helper: provides two functions to be used for a game of Tic Tac Toe
1) Check for winner: determines the current state of the board
2) Print ugly board: prints out a tic tac toe board in a basic format
"""
# Given a tic, tac, toe board determine if there is a winner
# Function inputs:
# board_list: an array of 9 strings representing the tic tac toe board
# move_counter: an integer representing the number of moves that have
been made
# Returns a string:
# 'x' if x won
# 'o' if o won
# 'n' if no one wins
# 's' if there is a stalemate
board_list=["0","1","2","3","4","5","6","7","8"]
move_counter=0
def checkForWinner(board_list, move_counter):
j = 0
for i in range(0, 9, 3):
# Check for 3 in a row
if board_list[i] == board_list[i+1] == board_list[i+2]:
return board_list[i]
# Check for 3 in a column
elif board_list[j] == board_list[j+3] == board_list[j+6]:
return board_list[j]
# Check the diagonal from the top left to the bottom right
elif board_list[0] == board_list[4] == board_list[8]:
return board_list[0]
# Check the diagonal from top right to bottom left
elif board_list[2] == board_list[4] == board_list[6]:
return board_list[2]
j += 1
# If winner was not found and board is completely filled up, return stalemate
if move_counter > 8:
return "s"
# Otherwise, 3 in a row anywhere on the board
return "n"
# Print out the tic tac toe board
# Input: list representing the tic tac toe board
# Return value: none
def printUglyBoard(board_list):
print()
counter = 0
for i in range(3):
for j in range(3):
print(board_list[counter], end=" ")
counter += 1
print()
#check if the move is valid
def isValidMove(board_list,spot):
#only the input in the range of [0:8}, not occupied by x or o is valid
if 0<= spot <= 8 and board_list[spot]!='x' and board_list[spot]!='o':
print("True")
return True
else:
print("Invaild. Enter another value.")
return False
#update the board with the input
def updateBoard(board_list,spot,playerLetter):
result=isValidMove(board_list,spot,)
if result==True and playerLetter=='x':
board_list[spot]='x'
playerLetter='o'
elif result==True and playerLetter=='o':
board_list[spot]='o'
playerLetter='x'
print(board_list)
print(playerLetter)
printUglyBoard(board_list)
return playerLetter
def play():
#use the print function to show the board
printUglyBoard(board_list)
playerLetter='x'
move_counter=0
#while loop for keeping the player inputting till a valid one and switch player after a valid input is recorded
while True:
if playerLetter=='x':
spot = int(input('Player x,enter the value:'))
elif playerLetter=='o':
spot = int(input('Player o,enter the value:'))
isValidMove(board_list,spot)
result=isValidMove(board_list,spot,)
#count the move for checking the winner purposes
if result==True:
move_counter+=1
playerLetter=updateBoard(board_list,spot,playerLetter)
print(move_counter)
#check the winner
winner=checkForWinner(board_list, move_counter)
#determine the winner
if winner=='o':
print('o win')
break
if winner=='x':
print('x won')
break
if winner=='s':
print("Tie")
break
def main():
print("Welcome to Tic Tac Toe!")
#while loop for the contining the game
while True:
play()
choice=input("Would you like to play another round? (y/n)")
if choice=='y'.lower():
play()
elif choice=='n'.lower():
print("Goodbye")
break
main()
An easy fix for your problem is putting the variable initialization inside of the function play() like this:
def play():
board_list=["0","1","2","3","4","5","6","7","8"]
#rest of your code...
This way every time you loop and call play you reset the board to its original position.
really board_list should not be declared outside a function (globaly) because it's only used inside play and passed to the rest of the functions that use it.
Declaring the variables a function use only inside a function makes sure they are set correctly every time and improve the codes readability by showing all the pieces in play in that function
I am trying to write a program for an assignment where you input a specific command and you can play Rock-Paper-Scissors-Lizard-Spock against the computer.
It was done and working until I realized that the assignment instructions wanted me to make it so that you keep playing the game until one person gets five wins.
So I thought, no big deals, let's throw in a while loop and some variables to track the wins. But when I run the program, it only runs once still. I don't know what I am doing wrong - as this should work. This is my first time working with Python (version 3.3) and this IDE, so I really need some help. Usually I'd just debug but I can't figure out how to work the one in this IDE.
Here is my code. The trouble while-loop is at the way bottom. I am nearly positive everything inside the class works. I would like to note that I already tried while(computerWins < 5 and userWins < 5), so I don't think the condition is the problem.
import random
computerWins = 0
userWins = 0
print ('SELECTION KEY:\nRock = r\nPaper = p\nScissors = sc\nLizard = l\nSpock = sp')
class rockPaperScissorsLizardSpock:
#Two methods for converting from strings to numbers
#convert name to number using if/elif/else
#also converts abbreviated versions of the name
def convertName(name):
if(name == 'rock' or name == 'r'):
return 0
elif(name == 'Spock' or name == 'sp'):
return 1
elif(name == 'paper' or name == 'p'):
return 2
elif(name == 'lizard' or name == 'l'):
return 3
elif(name == 'scissors' or name == 'sc'):
return 4
else:
print ('Error: Invalid name')
#convert number to a name using if/elif/else
def convertNum(number):
if(number == 0):
return 'rock'
elif(number == 1):
return 'Spock'
elif(number == 2):
return 'paper'
elif(number == 3):
return 'lizard'
elif(number == 4):
return 'scissors'
else:
print ('Error: Invalid number')
#User selects an option, and their selection is saved in the 'choice' variable
#Using a while loop so that the user cannot input something other than one of the legal options
prompt = True
while(prompt):
i = input('\nEnter your selection: ')
if(i=='r' or i=='p' or i=='sc' or i=='l' or i=='sp'):
prompt = False
else:
print('Invalid input.')
prompt = True
#Convert the user's selection first to a number and then to its full string
userNum = convertName(i)
userChoice = convertNum(userNum)
#Generate random guess for the computer's choice using random.randrange()
compNum = random.randrange(0, 4)
#Convert the computer's choice to a string
compChoice = convertNum(compNum)
print ('You chose', userChoice)
print ('The computer has chosen', compChoice)
#Determine the difference between the players' number selections
difference = (compNum - userNum) % 5
#Use 'difference' to determine who the winner of the round is
if(difference == 1 or difference == 2):
print ('The computer wins this round.')
computerWins = computerWins+1
elif (difference == 4 or difference == 3):
print ('You win this round!')
userWins = userWins+1
elif(difference == 0):
print ('This round ended up being a tie.')
#Plays the game until someone has won five times
while(computerWins != 5 and userWins != 5):
rockPaperScissorsLizardSpock()
if(computerWins == 5 and userWins != 5):
print ('The computer wins.')
elif(computerWins != 5 and userWins == 5):
print ('You win!')
The essential problem is that rockpaperscissorslizardspock is a class, where you expect it to be a function. The code inside it runs exactly once, when the whole class definition is parsed, rather than each time you call the class as you seem to expect.
You could put the relevant code into an __init__ method - this is a fairly direct analogue of a Java constructor, and hence is is run each time you call the class. But in this case, you probably don't need it to be in a class at all - calling the class creates a new instance (like doing new MyClass() in Java), which you don't use. You would also in this case (or if you made it into a function) need to make some more modifications to make sure the game state persists properly.
The easiest actual solution is to:
delete the line class rockpaperscissorslizardspock: (and unindent everything below it)
Take all the code that was under the class but not in a function - everything from the player makes a selection to determining the winner of the round - and paste it in place of the call to rockpaperscissorslizardspock() in the bottom loop.
The first thing is that you are using a class where you should probably be using a function.
Your code initially runs because python is loading the class.
However, the line rockPaperScissorsLizardSpock() is creating new anonymous instances of your class which calls a constructor that you haven't defined so it does nothing.
One of the interesting things about python is that it allows nested functions so if you change the class to a def you're almost there.
After that, you'll run into trouble with global variables in a local context. That problem is already explained in another StackOverflow question: Using global variables in a function other than the one that created them.
Here is my suggestion for the skeleton to a more simple solution. Use some ideas from here if you like.
import random
legal_shapes = ['r', 'p', 'sc', 'sp', 'l']
scoreboard = [0, 0]
print('SELECTION KEY:\nRock = r\nPaper = p\nScissors = sc\nLizard = l\n'
'Spock = sp')
while(max(scoreboard) < 5):
print("\nScore is {}-{}".format(*scoreboard))
# pick shapes
p1_shape = input('Enter your selection: ')
if p1_shape not in legal_shapes:
print('Not legal selection!')
continue
p2_shape = random.choice(legal_shapes)
print('\np1 plays {} and p2 plays {}'.format(
p1_shape.upper(), p2_shape.upper()))
# determine int values and result indicator
p1_shape_int = legal_shapes.index(p1_shape)
p2_shape_int = legal_shapes.index(p2_shape)
res = (p1_shape_int - p2_shape_int) % 5
if res != 0:
res = abs((res % 2) - 2)
# Print winner
if res == 0:
print(' -> Draw!!')
else:
print(' -> p{} wins'.format(res))
scoreboard[res-1] += 1
print("\nThe game is over!!")
print("p{} won with score {}-{}".format(res, *scoreboard))
It outputs something like
(env)➜ tmp python3 rsp.py
SELECTION KEY:
Rock = r
Paper = p
Scissors = sc
Lizard = l
Spock = sp
Score is 0-0
Enter your selection: T
Not legal selection!
Score is 0-0
Enter your selection: l
p1 plays L and p2 plays SP
-> p2 wins
Score is 0-1
Enter your selection: l
p1 plays L and p2 plays SC
-> p2 wins
...
The game is over!!
p2 won with score 2-5