BC0813
BC0813

Reputation: 55

Loop Problems Rock Paper Scissors Game

I am very new to programming. I have to write a Rock Paper Scissors game for my Intro to Programming class. I have a great start but a few issues I don't know how to solve.

I need three different menus. The main menu should ask to 1. Start new game 2. Load game or 3. Quit. Choose 1 or 2 and you input your name then play begins. You are then asked to select 1. Rock 2. Paper 3. Scissors. My game works great but after choosing Rock paper scissors I want a NEW menu to pop up: What would you like to do? 1. Play Again 2. View Statistics 3. Quit. But I have no idea where to put this. I have tried a few different places but it just by passes it and asks for rock paper scissors again.

Then my second issue is, when user selects 1. State new game needs to ask for their name and use their name to save their games to a file. Then when user chooses 2. Load Game, their name will be used to find a file "name.rps" and load their stats to continue to play (stats, round number, name).

Any help is appreciated.

import random
import pickle

tie = 0
pcWon = 0
playerWon = 0
game_round = (tie + playerWon + pcWon) + 1

# Displays program information, starts main play loop
def main():
    print("Welcome to a game of Rock, Paper, Scissors!")
    print("What would you like to do?")
    print ("")
    welcomemenu()
    playGame = True
    while playGame:
        playGame = play()
    displayScoreBoard()
    prompt = input("Press enter to exit")

def welcomemenu():
    print ("[1]: Start New Game")
    print ("[2]: Load Game")
    print ("[3]: Quit")
    print("")
    menuselect = int(input("Enter choice: "))
    print("")
    if menuselect == 1:
        name = input("What is your name? ")
        print("Hello", name, ".")
        print("Let's play!")
    elif menuselect == 2:
        name = input("What is your name? ")
        print("Welcome back", name, ".")
        print("Let's play!")
        player_file = open('name.rps', 'wb')
        pickle.dump(name, player_file)
        player_file.close()
    elif menuselect == 3:
        exit()
    return menuselect


# displays the menu for user, if input ==4, playGame in the calling function (main()) is False, terminating the program.
# Generate a random int 1-3, evaluate the user input with the computer input, update globals accordingly, returning True
# to playGame, resulting in the loop in the calling function (main()) to continue.
def play():
    playerChoice = int(playerMenu())
    if playerChoice == 4:
        return 0
    else:
        pcChoice = pcGenerate()
        outcome = evaluateGame(playerChoice, pcChoice)
        updateScoreBoard(outcome)
        return 1


# prints the menu, the player selects a menu item, the input is validated, if the input is valid, returned the input, if
# the input is not valid, continue to prompt for a valid input
# 1 - rock
# 2 - paper
# 3 - scissors

def playerMenu():
    print("Select a choice: \n [1]: Rock \n [2]: Paper \n [3]: Scissors")
    print("")
    menuSelect = input("What will it be? ")
    while not validateInput(menuSelect):
        invalidChoice(menuSelect)
        menuSelect = input("Enter a correct value: ")

    return menuSelect


# if the user doesn't input a 1-3 then return false, resulting in prompting the user for another value. If the value
# is valid, return True
# takes 1 argument
# menuSelection - value user entered prior
def validateInput(menuSelection):
    if menuSelection == "1" or menuSelection == "2" or menuSelection == "3":
        return True
    else:
        return False


# return a random integer 1-3 to determine pc selection
# 1 - rock
# 2 - paper
# 3 - scissors
def pcGenerate():
    pcChoice = random.randint(1,3)
    return pcChoice


# evaluate if the winner is pc or player or tie, return value accordingly
# 0 - tie
# 1 - player won
# -1 - pc won
def evaluateGame(playerChoice, pcChoice):
    if playerChoice == 1:
        print("You have chosen rock.")
        if pcChoice == 1:
            #tie
            print("Computer has chose rock as well. TIE!")
            return 0
        elif pcChoice == 2:
            #paper covers rock - pc won
            print("The computer has chosen paper. Paper covers rock. You LOSE!")
            return -1
        else:
            #rock breaks scissors - player won
            print("The computer has chosen scissors. Rock breaks scissors. You WIN!")
            return 1
    elif playerChoice == 2:
        print("You have chosen paper.")
        if pcChoice == 1:
            #paper covers rock - player won
            print("The computer has chosen rock. Paper covers rock. You WIN!")
            return 1
        elif pcChoice == 2:
            #tie
            print("The computer has chosen paper as well. TIE!")
            return 0
        else:
            #scissors cut paper - pc won
            print("The computer has chosen scissors. Scissors cut paper. You LOSE!")
            return -1
    else: #plyer choice defaults to 3
        print("You have chosen scissors")
        if pcChoice == 1:
            #rock breaks scissors - pc won
            print("The computer has chosen rock. Rock breaks scissors. You LOSE!")
            return -1
        elif pcChoice == 2:
            #scissors cut paper - player won
            print("The computer has chosen paper. Scissors cut paper. You WIN!")
            return 1
        else: #pc defaults to scissors
            #tie
            print("The computer has chosen scissors as well. TIE!")
            return 0



# Update track of ties, player wins, and computer wins
def updateScoreBoard(gameStatus):
    global tie, playerWon, pcWon
    if gameStatus == 0:
        tie +=1
    elif gameStatus == 1:
        playerWon += 1
    else:
        pcWon += 1


# If user input is invalid, let them know.
def invalidChoice(menuSelect):
    print(menuSelect, "is not a valid option. Please use 1-3")


# Print the scores before terminating the program.
def displayScoreBoard():
    global tie, playerWon, pcWon
    print("Statistics:\nTies:", tie, "\nPlayer Wins:", playerWon, "\nComputer Wins:", pcWon)
    print("Win/Loss Ratio:", playerWon/pcWon)
    print("Rounds:", tie + playerWon + pcWon)

main()

Upvotes: 2

Views: 2125

Answers (4)

shriya
shriya

Reputation: 1

def rps(a, b):
    game = { "rp" : 1, "rr" : 0, "rs" : -1,
             "ps" : 1, "pp" : 0, "pr" : -1,
             "sr" : 1, "ss" : 0, "sp" : -1}
    return (game[a + b])

# For example:     
print (rps("r", "p"))

Upvotes: 0

Cinakyn
Cinakyn

Reputation: 648

I made SPOILER for you! this code work well and helpful for you. but you have to think enough before see this code

BELOW IS SPOILER CODE

import random
import pickle

#I'll use class for easy load, easy dump.
class GameStatus():
    def __init__(self, name):
        self.tie = 0
        self.playerWon = 0
        self.pcWon = 0
        self.name = name

    def get_round(self):
        return self.tie + self.playerWon + self.pcWon + 1

# Displays program information, starts main play loop
def main():
    print "Welcome to a game of Rock, Paper, Scissors!"
    print "What would you like to do?" 
    print  "" 
    game_status  = welcomemenu()
    while True:
        play(game_status)
        endGameSelect(game_status)

#prompt user's choice and return GameStatus instance
def welcomemenu():
    #changed a logic to handle unexpected user input.
    while True:
        print "[1]: Start New Game"
        print "[2]: Load Game"
        print "[3]: Quit"
        print ""
        menuselect = input("Enter choice: ")
        if menuselect in [1, 2, 3]:
            break
        else:
            print "Wrong choice. select again."

    if menuselect == 1:
        name = raw_input("What is your name?: ") # raw_input for string
        print "Hello %s." % name
        print "Let's play!"
        game_status = GameStatus(name) #make a new game status
    elif menuselect == 2:
        while True:
            name = raw_input("What is your name?: ")
            try:
                player_file = open('%s.rsp' % name, 'r')
            except IOError:
                print "There's no saved file with name %s" % name
                continue
            break
        print "Welcome back %s." % name
        print "Let's play!" 
        game_status = pickle.load(player_file) #load game status. not dump.
        displayScoreBoard(game_status)
        player_file.close()
    elif menuselect == 3:
        print "Bye~!"
        exit()
        return

    return game_status


# displays the menu for user, if input == 4, playGame in the calling function (main()) is False, terminating the program.
# Generate a random int 1-3, evaluate the user input with the computer input, update globals accordingly, returning True
# to playGame, resulting in the loop in the calling function (main()) to continue.
def play(game_status):
    playerChoice = int(playerMenu())
    #this if statement is unnecessary. playerMenu() already checked this.
    #if playerChoice == 4:
    #    return 0
    pcChoice = pcGenerate()
    outcome = evaluateGame(playerChoice, pcChoice)
    updateScoreBoard(outcome, game_status)


# prints the menu, the player selects a menu item, the input is validated, if the input is valid, returned the input, if
# the input is not valid, continue to prompt for a valid input
# 1 - rock
# 2 - paper
# 3 - scissors

def playerMenu():
    print "Select a choice: \n [1]: Rock \n [2]: Paper \n [3]: Scissors\n" 
    menuSelect = input("What will it be? ")
    while not validateInput(menuSelect):
        invalidChoice(menuSelect) #I think this function is un necessary. just use print.
        menuSelect = input("Enter a correct value: ")
    return menuSelect


# if the user doesn't input a 1-3 then return false, resulting in prompting the user for another value. If the value
# is valid, return True
# takes 1 argument
# menuSelection - value user entered prior
def validateInput(menuSelection):
    if menuSelection in [1, 2, 3]: # more readable.
        return True
    else:
        return False


# return a random integer 1-3 to determine pc selection
# 1 - rock
# 2 - paper
# 3 - scissors
def pcGenerate():
    pcChoice = random.randint(1,3)
    return pcChoice


# evaluate if the winner is pc or player or tie, return value accordingly
# 0 - tie
# 1 - player won
# 2 - pc won
def evaluateGame(playerChoice, pcChoice):
    #more readable.
    rsp = ['rock', 'paper', 'scissors']
    win_statement  = ['Rock breaks scissors', 'Paper covers rock', 'Scissors cut paper']
    # if player win, win_status = 1 (ex. rock vs scissors -> (1 - 3 == -2) -> (-2 % 3 == 1))
    # if pc win, win_status = 2
    # if tie, win_status = 0
    win_status = (playerChoice - pcChoice) % 3
    print "You have chosen %s" % rsp[playerChoice - 1]
    what_to_say = "Computer has chose %s" % rsp[pcChoice - 1] 
    if win_status == 0:
        what_to_say += " as Well. TIE!"
    elif win_status == 1:
        what_to_say += ". %s. You WIN!" % win_statement[playerChoice - 1]
    else:
        what_to_say += ". %s. You LOSE!" % win_statement[pcChoice - 1]
    print what_to_say
    return win_status



# Update track of ties, player wins, and computer wins
def updateScoreBoard(outcome, game_status):
    if outcome == 0:
        game_status.tie += 1
    elif outcome == 1:
        game_status.playerWon += 1
    else:
        game_status.pcWon += 1

# If user input is invalid, let them know.
def invalidChoice(menuSelect):
    print menuSelect, "is not a valid option. Please use 1-3"


# Print the scores before terminating the program.
def displayScoreBoard(game_status):
    print ""
    print "Statistics:"
    print "Ties: %d" % game_status.tie
    print "Player Wins: %d" % game_status.playerWon
    print "Computer Wins: %d" % game_status.pcWon 
    if game_status.pcWon > 0:
        #if you don't use float, '10 / 4' will be '2', not '2.5'.
        print "Win/Loss Ratio: %f" % (float(game_status.playerWon) / game_status.pcWon) 
    else:
        print "Win/Loss Ratio: Always Win."
    print "Rounds: %d" % game_status.get_round()

def endGameSelect(game_status):
    print ""
    print "[1]: Play again"
    print "[2]: Show Statistics"
    print "[3]: Save Game"
    print "[4]: Quit"
    print ""
    while True:
        menuselect = input("Enter choice: ")
        if menuselect in [1, 2, 3, 4]:
            break
        else:
            print "Wrong input."

    if menuselect == 2:
        displayScoreBoard(game_status)
        endGameSelect(game_status)
    elif menuselect == 3:
        f = open("%s.rsp" % game_status.name, 'w')
        pickle.dump(game_status, f)
        f.close()
        print "Saved."
        endGameSelect(game_status)
    elif menuselect == 4:
        print "Bye~!"
        exit()
main()

Upvotes: 0

Cinakyn
Cinakyn

Reputation: 648

Use '%s.rsp' % name, Not 'name.rsp'. open('name.rsp', 'w') will always open 'name.rsp' evn if name = 'foo'.

Upvotes: 0

progrenhard
progrenhard

Reputation: 2363

def play():
    playerChoice = int(playerMenu())
    if playerChoice == 4:
        return 0
    else:
        pcChoice = pcGenerate()
        outcome = evaluateGame(playerChoice, pcChoice)
        updateScoreBoard(outcome)
        return 1

This is the method we want.

So all you need to do is call the new menu method under updateScoreBoard().

Then under the new menu method.

if(playerChoice == 1)
    play();
if else(playeChoice == 2)
    stats();
else
    quit();

Upvotes: 0

Related Questions