2
\$\begingroup\$

Any chance people can read my game code and see if reformatting or rewriting is necessary for a better overall code? I'd really appreciate it.

#I implemened a random module into my program as it is needed to shuffle the 'cpu_choices' list randomly. 
import random
import time #I implemented time module to introduce a timer which will occur when the user selects the amount of rounds they want to play
#            and when the match is over

#---------------VARIABLES---------------#
#I started to plan what variables were necessary to meet the specifications.
#I designated variables to sections to make it easier for myself and future proofing as users can gain an understanding of each variable and their purpose. 

#GAME_RULES are capitalized to represent it is a constant - meaning they never change.
GAME_RULES = ["RULES:", "- Paper wins against Rock", "- Rock wins against Scissors", "- Scissors wins against Paper", "- When asked: 'y' = yes, and 'n' = no"]
cpu_choices = ["Paper", "Scissors", "Rock"] #cpu_choice isn't a constant because the order of the choices will change. (Though the list will not)

player_name = 0 #Stores the player's name after input.
player_score = 0 #player_score remembers the score of the player.
player_history = [] #A placeholder list that holds the player's move history.
player_move = 0 #player_move temporarily holds the move that the player plays.

intro_loop = True #intro_loop is the condition that keeps or stops the introduction running.
game_loop = True #game_loop keeps the "gameplay" section of the code running if the player wants to do another set of rounds.

replay_loop = True #replay_loop keeps asking the user if they want to replay incase they enter an incorrect input.
replay_choice = "y" #replay_choice is the user's input that dicides whether or not the "gameplay" loop repeats.

round_repeat = True #This variable keeps the code asking what move the player wants to play if they enter the wrong thing.
total_rounds = 0 #holds the # of rounds the user wants to play. 
round_num = 0 #round_num stores what number the current round is, as well as dictating how many times it runs.
round_history = [[]] #A placeholder list that will hold the move history of the rounds. This will be used for the match overview at the end of the game.

cpu_move = 0 #cpu_move temporarily holds the move that the computer plays.
cpu_score = 0 #cpu_score remembers the score of the computer.
cpu_history = [] #A placeholder list that holds the cpu's move history.

#----------------------------------------#

#This function serves as the code portion that handles the processes in a round.
#(num) is a parameter which is used to insert the current round number. 

def round_process(num):
    global cpu_history
    global cpu_score
    global player_score        #identifying global variables that will be used within this specific function. 
    global player_history      #changes made to these variables 

    #resets the while loop condition
    round_repeat = True 


    random.shuffle(cpu_choices)
    #creating a random.shuffle for the cpu choices list to allow for a random and unbiased choice of either r, p or s (obviously). 

    #This allows the cpu move to be the first move of 'cpu_choices'.
    #The order of the list is shuffled, so the index should always stay the same. 
    cpu_move = cpu_choices[0]


    #I implemented a while loop to make the input repeat incase the user doesn't input correctly. e.g. inputs a number or misspells a choice. 
    while round_repeat == True: 
        print("\n--------------\nROUND", num, "\n--------------")
        player_move = input("\nWhat's your move? 'Paper', 'Scissors' or 'Rock'?\t") # This input asks and stores what move the user wants to make.
        player_move = player_move.capitalize()
        #Players move is capitalized so if they type 'rock' without a capital R, the program will still recognize it as a valid answer.

        # This 'if' statement validates the user's input. 
        # Otherwise they will be asked again via the else statement. Both non capitalized and capitalized inputs can be accepted, as 
        # .capitalize is utilized in my player_move variable.
        if player_move == "Paper" or player_move == "Rock" or player_move == "Scissors": 
            print("\nLocked in! You chose", player_move, "\nThe CPU chose", cpu_move)



            #----------SCORING----------#

            #The if and elif statements within the SCORING section dictate whether the user wins, draws, or loses with the cpu.
            #Scores are added according to the result. Wins count for two points, draws 1, losses 0. 


            if player_move == "Paper" and cpu_move == "Rock" or player_move == "Rock" and cpu_move == "Scissors" or player_move == "Scissors" and cpu_move == "Paper":
                player_score += 2               #Point is added to the player's score by 2.
                print("\nGood work! You win this round!")
            elif player_move == cpu_move:
                player_score += 1               #this elif gives both the cpu and the player a point each. 
                cpu_score += 1
                print("\nLooks like both of you had the same idea! It's a draw!")
            else:
                cpu_score += 2 #only adds to the cpu_score because the player lost.
                print("\nYikes! You lose this round! He beat you with", cpu_move)


            print("\nYour score is", player_score) #states scores so far for player and cpu
            print("Computer's score is", cpu_score) # <----
            #player_history and cpu_history append, or add, their specific moves from each round into the list.
            #This is required in my specifications and can show a 'Match History' type screen in the end.


            player_history.append(player_move)
            cpu_history.append(cpu_move) #adds the cpu move for each round to the cpu_history list. 
            round_repeat = False #the round loop breaks so player continues to next round OR end of game. 
        else:
            print("\n!!!!!!!!!!!!!!!!!!!!!!!!!\nUh oh! That input is wrong. Please type either 'Paper', 'Scissors' or 'Rock'\n!!!!!!!!!!!!!!!!!!!!!!!!!")

            #---------------------------#


#round_process the function that handles all processes in a single round, and I am using the parameter.

print("-----------------------------------")
print("|                                 |")
print("|       ROCK PAPER SCISSORS       |")
print("|        PYTHON REMASTERED        |")
print("|                                 |")
print("-----------------------------------")
for rule in GAME_RULES:
    print(rule)
# This for loop prints GAME_RULES in a list layout by printing
# each rule within GAME_RULES for every cycle of the loop.
# A for loop is used for iterating over a sequence 

while intro_loop == True:
    #Valid name input is stored inside the player_name variable (was formerly blank)
    player_name = input("\nWelcome to Rock Paper Scissors, PYTHON REMASTERED!\n What is your name?\t")
    if player_name != "": #If statement forces the name to not be blank and to reinput their data input. 
        player_name = player_name.capitalize() #.capitalize capitalises the first letter of the username for a more aesthetically pleasing look. 
        intro_loop = False
        print("\nWelcome", player_name)
    else:
        print("\n-------------------------\nSurely you've got a name! Try again\n-------------------------")
#I started the game loop here because from here on all inputs I request from the user will be only used to play the game.
while game_loop == True:
    try:
        total_rounds = int(input("\nHow many rounds would you like to play? '3', '5', '7' or '9'\t"))
        if total_rounds < 3 or total_rounds > 9 or total_rounds%2 == 0:
            print("\n---------------------------------\nPlease enter '3', '5', '7' or '9'\n---------------------------------")
        else:
            player_history = []
            cpu_history = []
            round_num = 1
            cpu_score = 0
            player_score = 0
            replay_loop = True
            while round_num <= total_rounds:
                round_process(round_num)
                round_num += 1
            round_history = [list(a) for a in zip(player_history, cpu_history)]
            print("\n--------\nHistory\n--------")
            for i in range(0,round_num - 1):
                print("\nRound", str(i + 1) + ": You chose", round_history[i][0] + ". The cpu chose", round_history[i][1])
            print("\n----------\nMatch Results\n----------")
            print("\nYou finished on a total score of", player_score, "\nThe computer finished on a total score of", cpu_score)

            #------------WINNER DETERMINED------------#

            if player_score > cpu_score:
                print("\n You won! Congratulations", player_name, "!")
            elif player_score < cpu_score:
                print("\nUnlucky mate! You lost :(")
            elif player_score == cpu_score:
                print("\nYou drew! :|")

            #-----------------------------------------#

            while replay_loop == True:
                replay_choice = input("\nWould you like to play again? 'y' or 'n'\t")
                replay_choice = replay_choice.lower()
                if replay_choice == "y" or replay_choice == "n":
                    if replay_choice == "n":
                        print("\nHave a good day", player_name,"!")
                        game_loop = False
                    replay_loop = False
                else:
                    print("\n-----------------------\nPlease enter 'y' or 'n'\n-----------------------")
                    #where the input is invalid, the user will be asked again until they input 'y' or 'n'. 
    except:
        print("\n--------------------\nPlease enter a digit\n--------------------")
\$\endgroup\$
1
  • \$\begingroup\$ Welcome to code review, this website is for peer reviewing code, if you just have a question about formatting then this is not an appropriate place for your code. People here provide review for the overall code in terms of style, performance ... \$\endgroup\$
    – watch-this
    Oct 16, 2019 at 10:44

1 Answer 1

1
\$\begingroup\$

Here I will modify the strings you printed such that it doesn't go over the screen.

I don't see why you need to have GAME RULES as a separate variable. No harm and maybe more straightforward doing

print("-----------------------------------")
print("|                                 |")
print("|       ROCK PAPER SCISSORS       |")
print("|        PYTHON REMASTERED        |")
print("|                                 |")
print("-----------------------------------")
print("RULES:                             ")
print("- Paper wins against Rock          ")
print("- Rock wins against Scissors       ")
print("- Scissors wins against Paper      ")
print("- When asked: 'y' = yes, 'n' = no  ")

The intro loop is too long and can be simplified. In Python, an empty string evaluates to false. Furthermore, you can capitalize on the input itself.

# Get player name
while True:
    player_name = input("What is your name? ").capitalize()
    if player_name:
        break
    print("Surely you've got a name! Try again")

print("Welcome", player_name)

The part where it asks for the number of rounds is too complicated. Use an list to indicate the options, or at least use it to check if it is valid. Furthermore, specify the exception you are catching.

while True:
  try:
    validRounds = [3, 5, 7, 9]
    rounds = int(input("How many rounds would you like to play?" + str(validRounds)))
    if rounds in validRounds:
      break
  except ValueError:
    pass
  print("Please enter '3', '5', '7' or '9'")

# Put the large else part here

Now we look at your round_process.

  1. global isn't necessary here. The function shouldn't need to know the score and history of both players. Instead, make the function return the move each of the players made.
  2. Do not shuffle the choices for the cpu, use random.choice instead.
  3. Use list to check existence.
def processRound(num):
  print("Round ", num)
  # Get player move
  while True:
    validMoves = ['Paper', 'Scissors', 'Rock']
    move = input("What's your move? " + str(validMoves))
    if move in moves:
      break
    print("That input is wrong. Please type either 'Paper', 'Scissors' or 'Rock'")

  # cpu move
  cpuMove = random.choice(validMoves)

  print("Locked in! You chose", player_move, "\nThe CPU chose", cpu_move)
  if move == cpuMove:
    # draw
  elif (move, cpuMove) in [('Paper', 'Rock'), ('Scissors', 'Paper'), ('Rock', 'Scissors')]:
    # win
  else:
    # lose

  return (move, score), (cpuMove, cpuScore)

Now that you know the number of rounds, use a for loop instead of a while loop.

for i in range(rounds):
  processRound(i + 1)

One last thing is you may consider using Enum for the moves.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.