DRYing up Rock Paper Scissors

前端 未结 4 951
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-25 04:18

I\'m a novice ruby programmer and although this code works, I\'m wondering how I can improve it. I have very limited knowledge on lambdas and procs and the like, but any advice

4条回答
  •  傲寒
    傲寒 (楼主)
    2021-01-25 04:53

    Here are a couple of ways:

    #1 Use Array#cycle

    OPS = %w[rock paper scissors]
    
    def rps(roll)
      pick = OPS.sample
      enum = OPS.cycle
      (prev = enum.next) until enum.peek == roll
      return [pick, "lose"] if prev == pick
      enum.next
      return [pick, "win"] if enum.peek == pick
      [pick, "tie"]
    end
    
    rps "scissors" #=> ["scissors", "tie"] 
    rps "scissors" #=> ["scissors", "tie"] 
    rps "scissors" #=> ["rock", "win"] 
    rps "scissors" #=> ["paper", "lose"] 
    

    #2 Take @MurifoX's answer one step farther

    def rps(roll)
      roll_ops = %w|rock paper scissors|
      h = (roll_ops + [roll_ops.first]).each_cons(2).
        with_object(Hash.new("tie")) { |(a,b),h| h[[a,b]]="lose"; h[[b,a]]="win" }
      pick = roll_ops.sample
      [pick, h[[roll,pick]]]
    end
    
    rps "scissors" #=> ["rock", "lose"] 
    rps "scissors" #=> ["scissors", "tie"] 
    rps "scissors" #=> ["paper", "win"] 
    

    Here:

    h #=> {["rock", "paper"]=>"lose", ["paper", "rock"]=>"win",
      #    ["paper", "scissors"]=>"lose", ["scissors", "paper"]=>"win",
      #    ["scissors", "rock"]=>"lose", ["rock", "scissors"]=>"win"} 
    

    and because of the default value "tie":

    h[["rock", "rock"]]         #=> "tie"
    h[["paper", "paper"]]       #=> "tie"
    h[["scissors", "scissors"]] #=> "tie"
    

提交回复
热议问题