Complete Code

The complete code will look like this:

% rpsg
#!/usr/bin/env ruby

=begin
|====================================|
| Req Ruby Ver | Req Ruby Gems Ver   |
|--------------|---------------------|
| >= v2.0.0    | >= v2.6.0           |
|====================================|
=end

# create master class for rpsg
class RockPaperScissorsGame

  # specify the version for the rubygem
  module RPSG
    # create version constant for the rubygem
    VERSION = "0.3.8"
  end

  # create module that holds all contents for this script
  module ProtectedConstants

    # create 2d list of choices
    protected # make protected
    CHOICES = [['r', 'rock'], ['p', 'paper'], ['s', 'scissors']]

    # define entry to symbol (key to value) dictionary
    protected # make protected
    NTRY_TO_SYM = {
      CHOICES[0][0] => :ROCK    , CHOICES[0][1] => :ROCK    ,
      CHOICES[1][0] => :PAPER   , CHOICES[1][1] => :PAPER   ,
      CHOICES[2][0] => :SCISSORS, CHOICES[2][1] => :SCISSORS
    }

    # define valid entries
    protected # make protected
    VALID_ENTRIES = NTRY_TO_SYM.keys

    # define computer choices
    protected # make protected
    COMPUTER_CHOICES = NTRY_TO_SYM.values

    # create winners 2d list array with format: winning choice, losing choice
    protected # make protected
    WINNERS = [
      [:SCISSORS, :PAPER   ],
      [:PAPER   , :ROCK    ],
      [:ROCK    , :SCISSORS]
    ]

    # this will take the original WINNERS array and flip the symbols, thus returning a loss for the user/player
    protected # make protected
    LOSERS = WINNERS.map { |winning_choice,losing_choice| [losing_choice,winning_choice] }

  end

  # protected_methods :ProtectedConstants

  class << self
    # add continue method for asking the user if they want to play rock paper scissors
    def continue(str1,str2,str3)
      puts  str1
      print str2
      gets
      puts  str3
    end
  end

  # print out strings
  continue("\nYou are about to enter a rock-paper-scissors best of 3 match.", "\nPress the return/enter key to continue...", "")

  # initialize variables
  def initialize
    # initialize variables and set all equal to zero
    @player_score = @computer_score = @ties = 0
  end

  # define play method, this will be the main function for playing rock paper scissors
  def play(winning_score)
    # make while loop
    while @player_score < winning_score && @computer_score < winning_score
      puts "\nPlayer score: #{@player_score}, " +
           "Computer score: #{@computer_score}, Ties: #{@ties}.\n"
      player = PrivateMethods.player_choice
      computer = ProtectedConstants::COMPUTER_CHOICES.sample # chooses a random option
      puts "\nPlayer chooses #{player.to_s.downcase}."
      puts "Computer chooses #{computer.to_s.downcase}.\n"
      case PrivateMethods.player_outcome [player, computer]
      when :WIN
        puts "\n#{player.to_s.capitalize} beats #{computer.to_s.downcase}, player wins the round.\n"
        @player_score += 1
      when :LOSE
        puts "\n#{computer.to_s.capitalize} beats #{player.to_s.downcase}, computer wins the round.\n"
        @computer_score += 1
      else
        puts "\nTie, choose again\n"
        @ties += 1
      end
    end
    puts "\nFinal score: player: #{@player_score}, " +
         "computer: #{@computer_score} (ties: #{@ties}).\n"
    case PrivateMethods.final_outcome(@player_score, @computer_score)
    when :WIN
      puts "\nPlayer wins!\n"
    when :LOSE
      puts "\nComputer wins!\n"
    else
      puts "\nIt's a tie!\n"
    end
    print "\n[press the enter/return key to exit game]"
    gets
  end

  private # make private
  # add module for private methods for the rpsg calculations
  module PrivateMethods
    class << self
      # make a definition that asks for the players choice
      def player_choice
        loop do
          print "\nChoose: Rock (r), Paper (p), or Scissors (s): "
          choice = gets.chomp.downcase
          if ProtectedConstants::NTRY_TO_SYM.key?(choice)
            return ProtectedConstants::NTRY_TO_SYM[choice]
          elsif choice != ProtectedConstants::VALID_ENTRIES
            puts "\nThat entry is invalid. Please re-enter.\n"
          else
            return nil
          end
        end
      end
      # define outcomes of players choice against cpu
      def player_outcome(plays)
        return :WIN  if ProtectedConstants::WINNERS.include?(plays)
        return :LOSE if ProtectedConstants::LOSERS.include?(plays)
        return :TIE  if !:WIN | !:LOSE
      end
      # define final outcome that gives the result of who one the whole match
      def final_outcome(pl, co)
        return :WIN  if pl > co
        return :LOSE if pl < co
        # return :TIE  if pl = co
        # there will never be a tie for the final outcome due to the code in the `play()` method
      end
    end
  end
  public # make public again

  # private_methods :PrivateMethods

end

RockPaperScissorsGame.new.play(2) # best out of 3

$end