2
def winner(p1, p2)
  wins = {rock: :scissors, scissors: :paper, paper: :rock}
  {true => p1, false => p2}[wins[p1] == p2]
end

From this question: HW impossibility?: "Create a rock paper scissors program in ruby WITHOUT using conditionals"

Community
  • 1
  • 1
ismail
  • 3,882
  • 5
  • 36
  • 47
  • I removed the additional question, so that the post now conforms to "one question per question" policy. It has been answered many times, anyway. – Sergio Tulentsev Oct 09 '12 at 09:36

2 Answers2

6

I admit, this is not the most readable code for a novice programmer. I rewrote it, extracted some variables and added comments. Hope you can understand it better now.

def winner(p1, p2)
  # rules of dominance, who wins over who
  wins = {
    rock: :scissors, 
    scissors: :paper, 
    paper: :rock
  }

  # this hash is here to bypass restriction on using conditional operators
  # without it, the code would probably look like 
  #   if condition
  #     p1
  #   else
  #     p2
  #   end
  answers = {
    true => p1, 
    false => p2
  }

  # given the choice of first player, which element can he beat?
  element_dominated_by_first_player = wins[p1]

  # did the second player select the element that first player can beat?
  did_player_one_win = element_dominated_by_first_player == p2

  # pick a winner from our answers hash
  answers[did_player_one_win]
end

winner(:rock, :scissors) # => :rock
winner(:rock, :paper) # => :paper
winner(:scissors, :paper) # => :scissors
Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
1

This is a rock-scissor-paper game as you can see. The def keyword starts a method definition. And end means the end of the method.

The first line of the method's body wins = {rock: :scissors, scissors: :paper, paper: :rock} defines a hash called wins. This is a syntax sugar in ruby. You can also write this line into wins = { :rock => :scissors, :scissors => :paper, :paper => :rock}.

Names starting with a : is called Symbol in ruby. Symbol objects represent constant names and some strings inside the Ruby interpreter.

The first part of the 2nd line {true => p1, false => p2} is also a hash. And the value of wins[p1] == p2 can be calculated according to the first line. For example, if you call this method with winner(:paper, :rock), wins[p1] is :rock now and wins[p1] == p2 should be true. So {true => p1, false => p2}[true] is p1.

The return value of a method in ruby is the value of the last expression.

halfelf
  • 9,737
  • 13
  • 54
  • 63