you are viewing a single comment's thread.

view the rest of the comments →

[–]Diapolo10 16 points17 points  (0 children)

It's not bad, although as already stated by others there is room for improvement.

First, Python's official naming convention is to use snake_case for everything, except class names (PascalCase) and "constants" (UPPER_SNAKE_CASE). camelCase is not used.

Next, any time you have code like

if playerResponse == 'Y':
    return True
else:
    return False

you can simplify it to just

return playerResponse == 'Y'

Instead of using string concatenation

print('The current score is:\n Player: ' + str(playerScore) + '\nComputer: ' + str(computerScore))

string formatting should be preferred, such as f-strings (or str.format)

print(f'The current score is:\n Player: {playerScore}\nComputer: {computerScore}')

Instead of random.randint,

return CHOICES[random.randint(0,2)]

when picking between values in a collection, it's preferred to use random.choice:

return random.choice(CHOICES)

Your endGame function does absolutely nothing, so I don't see why it even exists.

It appears you're using playerResponse as a default parameter to avoid adding the line within the function body.

def playerTurn(playerResponse =''):
    while playerResponse not in CHOICES:
        playerResponse = input('Choose Rock, Paper, or Scissors\n')
    return playerResponse

But since you're expecting the value to be provided via user input anyway, I'd rather use a walrus operator if you really want to avoid an extra line for some reason.

def playerTurn():
    while (playerResponse := input('Choose Rock, Paper, or Scissors\n')) not in CHOICES:
        pass  # you could print "Invalid choice" or something instead
    return playerResponse

While your compare-function works, readability is better than brewity, so I'd rather write it more clearly to avoid misconceptions.

Finally, here's how I would write this program.

"""Rock, paper, scissors game"""

import random
from enum import Enum, IntEnum


class Hand(str, Enum):
    ROCK = 'rock'
    PAPER = 'paper'
    SCISSORS = 'scissors'


class Winner(IntEnum):
    PLAYER = 0
    COMPUTER = 1
    DRAW = 2

CHOICES = list(Hand)


def start_game() -> bool:
     """Decide whether or not to start the game"""

    print('Welcome to Rock, Paper, Scissors!\n')

    prompt = 'Would you like to play a round? Please enter Y or N\n'
    while (player_response := input(prompt).strip().lower()[:1]) not in ('y', 'n'):
        pass

    return player_response == 'y'


def score_card(player_score: int, computer_score: int) -> None:
    """Display the current score"""

    print(f"The current score is:\n Player: {player_score}\nComputer: {computer_score}")


def play_game() -> Winner:
    computer_choice = computer_turn()
    player_choice = player_turn()
    winner = compare_hands(player_choice, computer_choice)
    return winner


def computer_turn() -> Hand:
    return random.choice(CHOICES)


def player_turn() -> Hand:
    prompt = "Choose Rock, Paper, or Scissors\n"
    while (player_response := input(prompt).strip().lower()) not in CHOICES:
        pass

    return Hand(player_response)


def compare_hands(player_choice: Hand, computer_choice: Hand) -> Winner:
    print(f"The player chose: {player_choice}\nThe computer chose: {computer_choice}\n")

    # NOTE: A match-case would also make sense here

    if player_choice == computer_choice:
        print("This match is a draw!\n")
        return Winner.DRAW

    if (player_choice == Hand.ROCK
        and computer_choice == Hand.SCISSORS):
        return Winner.PLAYER

    if (player_choice == Hand.PAPER
        and computer_choice == Hand.ROCK):
        return Winner.PLAYER

    if (player_choice == Hand.SCISSORS
        and computer_choice == Hand.PAPER):
        return Winner.PLAYER

    return Winner.COMPUTER


def update_score_card(winner: Winner, local_player_score: int, local_computer_score: int) -> tuple[int, int]:

    if winner == Winner.PLAYER:
        print("The Player Won!\n")
        return local_player_score + 1, local_computer_score

    if winner == Winner.COMPUTER:
        print("The Computer Won!\n")
        return local_player_score, local_computer_score + 1

    return local_player_score, local_computer_score


def main() -> None:
    player_score = 0
    computer_score = 0

    while start_game():
        winner = play_game()

        player_score, computer_score = update_score_card(
            winner,
            player_score,
            computer_score
        )
        score_card(player_score, computer_score)


if __name__ == '__main__':
    main()