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"
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"
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
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.