Skip to content

Instantly share code, notes, and snippets.

@KBeltz
Created June 10, 2015 03:52
Show Gist options
  • Save KBeltz/df3bfbaae8e50b40357b to your computer and use it in GitHub Desktop.
Save KBeltz/df3bfbaae8e50b40357b to your computer and use it in GitHub Desktop.
Rock Paper Scissors Lizard Spock Essay

#Rock Paper Scissors Lizard Spock The assignment was to write a program for a Rock Paper Scissors Lizard Spock game. The game should only accept valid moves, and should provide the option for a computer player.

The Player class exists to store player 1, player 2, and the computer player, as well as to update the player scores at the end of each round. The Game class contains the rules of the game, and also determines the winner of the round and match.

##Player.rb When the Player class is initialized, it accepts one string argument. Four attributes are created: @name is a string, @players_move is a string, @score is an integer with an initial value of zero, and @valid_moves is an array of symbols representing the valid moves in the game.

  def initialize(name)
    @name = name
    @players_move = players_move
    @score = 0
    @valid_moves = [:rock, :paper, :scissors, :lizard, :spock]
  end

The update_score method accepts one string argument, player. It increments the player score, and then returns the new integer value.

  def update_score(player)
    @score += 1
    @score
  end  
end

##Game.rb When the Game class is initialized, it accepts three arguments: player1, player2, and rounds. Player1 and player2 are instances of the Player class, and rounds is an integer. The @valid_moves attribute is an array of symbols representing the valid moves in the game. The @rules attribute is a hash that contains keys that are symbols of the valid player1 moves, and the hash value is a second hash with keys that are symbols of the valid player2 moves and a value that is a symbol of the resulting winner's move. The @player1 and @player2 attributes are strings containing the names of the players, and @player1_move and @player2_move are string attributes containing the moves of the two players. @rounds is an integer attribute for the number of rounds requested by the players.

  def initialize(player1, player2, rounds)
    @valid_moves = [:rock, :paper, :scissors, :lizard, :spock]
    @rules = {rock: {rock: :draw, paper: :paper, scissors: :rock,
        lizard: :rock, spock: :spock},
      paper: {rock: :paper, paper: :draw, scissors: :scissors,
        lizard: :lizard, spock: :paper},
      scissors: {rock: :rock, paper: :scissors, scissors: :draw,
        lizard: :scissors, spock: :spock},
      lizard: {rock: :rock, paper: :lizard, scissors: :scissors,
        lizard: :draw, spock: :lizard},
      spock: {rock: :spock, paper: :paper, scissors: :spock,
        lizard: :lizard, spock: :draw}}
    @player1 = player1
    @player2 = player2
    @player1_move = player1_move
    @player2_move = player2_move
    @rounds = rounds
  end

The round_winner method accepts two string arguments: player1_move and player2_move. The method then compares the two moves to determine the result of the round based on the result of the rules hash. This method returns a string with the result of the round.

def round_winner(player1_move, player2_move)
  if player1_move == player2_move
    "Tie!"
  elsif
    rules[player1_move.to_sym][player2_move.to_sym] == player1_move.to_sym
    "#{player1.players_move.capitalize} beats #{player2_move}!"
    "\n#{player1.name} wins this round!"
    player1.update_score(player1)
  elsif 
    rules[player2_move.to_sym][player1_move.to_sym] == player2_move.to_sym
    "#{player2_move.capitalize} beats #{player1.players_move}!"
    "\n#{player2.name} wins this round!"
    player2.update_score(player2)
  else
    "This shouldn't have happened. How embarrassing!"
  end
end

The game_winner method compares the scores of the players once all of the rounds have been completed to determine which player has the larger score. This method returns a string. Whichever player has the higher score is declared the winner.

 # determine winner of the game by comparing the scores
 #
 # returns string output to declare winner of match
 def game_winner
   if player1.score > player2.score
     "#{player1.name} wins the match!" 
   elsif player2.score > player1.score
     "#{player2.name} wins the match!"
   else
     "Tie game!"
   end
 end
end

##app.rb Here the number of players is determined. The number of players can not be less than 1, and this game does not accept games with more than 2 players. A response other than 1 or 2 will return a string with an error message and request another input.

# determine number of players
puts "Will there be 1 or 2 players?"
response = gets.to_i
# check that the number of players is valid
unless response == 1 || response == 2
  puts "Invalid. Please choose 1 or 2: "
  response = gets.to_i
end 

This instantiates the player2 instance of the Player class, robot or human based on the previous input. This is what allows for the robot player option.

if response == 1
  puts "Your opponent will be a robot."
  player2 = Player.new("Robot")
else
  puts "Please enter the name of player 2:"
  player2 = gets.chomp.capitalize
  player2 = Player.new(player2)
end

This determines how many rounds the user would like to play. The only restriction is that the number of rounds cannot be less than 1.

puts "How many rounds would you like to play?"
rounds = gets.to_i
# checks that the number of rounds entered is valid
unless rounds >= 1
  puts "Invalid input. Please try again: "
  rounds = gets.to_i
end 

This gives the players an option to review the rules of the game. Any response that includes "y" will print the rules of the game to the console.

puts "\nWould you like to review the rules? (y/n)"
response = gets.chomp.downcase

if response.include?("y")
  puts "\nRULES\n#{"-" * 80}\n* Rock crushes scissors\n* Paper covers rock\n* Scissors cuts paper\n* Rock crushes lizard\n* Lizard eats paper\n* Scissors decapitates lizard\n* Spock vaporizes rock\n* Paper disproves Spock\n* Spock smashes scissors\n#{"-" * 80}"
end

play_one_round instantiates a new instance of the Game class.

play_one_round = Game.new(player1, player2, rounds)

This loops through to play the game a specific number of rounds based on the number entered by the user. It checks that the string input is a valid move by converting it to a symbol and comparing it to the valid_moves array. The player2 move can be human input or randomly generated by calling the sample method on the valid_moves object. After both moves are acquired, the round_winner method is called on the play_one_round object to determine which player wins the round and output the result to the console.

rounds.times do
  puts "#{player1.name}, what is your move? "
  player1_move = gets.chomp.downcase
  until valid_moves.include?(player1_move.to_sym)
    puts "Not an acceptable move. Please try again: "
    player1_move = gets.chomp.downcase
  end
  player1.players_move = player1_move
 
  # determines player 2 input: human (manual) or robot (sample) input
  puts "#{player2.name}, what is your move? "
  if player2.name != "Robot"
    player2_move = gets.chomp.downcase
    until valid_moves.include?(player2_move.to_sym)
      puts "Not an acceptable move. Please try again: "
      player2_move = gets.chomp.downcase
    end
    player2.players_move = player2_move
  else
    player2_move = valid_moves.sample
    puts player2_move.to_s
  end
 
  # determine the winner of the round
  puts play_one_round.round_winner(player1_move.to_sym, player2_move.to_sym)

end

This outputs the score of both players.

puts "#{player1.name}: #{player1.score}"
puts "#{player2.name}: #{player2.score}"

This determine the winner of the match by calling the game_winner method on the play_one_round object and printing the output to the console.

puts play_one_round.game_winner
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment