2012-03-20 236 views
3

我正在研究我的第二个ruby程序,并且在字面上坚持站在我和完成的程序之间的最后一件事。我的任务是写一个岩石,纸,剪刀法,返回胜出的球员。要做到这一点,需要[[“Dave”,“S”],[“Dan”,“R”]]形式的游戏参数,其中“S”和“R”是“剪刀”和“摇滚”分别。然后确定赢家并返回包含获胜策略的数组。如果游戏长度错误或策略为==或不在范围内,也会引发错误。Ruby正则表达式与正则表达式匹配

class WrongNumberOfPlayersError < StandardError ; end 
class NoSuchStrategyError < StandardError ; end 


def rps_game_winner(game) 

raise WrongNumberOfPlayersError unless game.length == 2 

    #Hash of whose Keys are the strategies and values are the players 
    playr = {(game[0].slice(1).downcase) => game[0], 
    (game[1].slice(1).downcase) => game[1]} #This fits on the above line in IRB 

    #Collect Strategies in array for comparison 
    stgys = playr.keys 

    #raise NoSuchStrategyError unless players give strategies in range, no duplicates 
    raise NoSuchStrategyError unless (stgys.select { |s| s.match /[prs]/ }.size == 2) 

    #determine Winner 
    case stgys.to_s 
    when /p/ && /r/ 
    playr["p"] 
    when /p/ && /s/ 
    playr["s"] 
    when /s/ && /r/ 
    playr["r"] 
    end 
end 

这可以像我期望的那样工作,检查策略对正则表达式并返回胜者。除最后一种情况外,遇到时总是返回零。如果我把播放器[“R”]下要么成功,其他whens的,它在“/ P/& &/R /”返回正确的球员。如果我改变顺序,它仍然不起作用,所以我知道它不需要处理它的位置。如果我在case语句之外单独进行匹配调用,则正则表达式/ r /会评估它的应用。所以我相信我已经缩小了与/ s /和/ r /相关的问题,否则我就难倒了。还有任何帮助DRYness赞赏,谢谢你的帮助!

+0

似乎是来自saas课程的作业:) – 2012-03-20 20:32:18

+0

你知道吗,迟到开始希望能够赶上,但是在对这个代码打了几个小时的代码之后,我意识到阿曼多可能并不是在开玩笑说它是一个老年人级别课程:) – 2012-03-21 01:32:00

回答

0

其实你并不需要case可言。 我的解决方案版本,该任务:

def rps_game_winner(game) 
    raise WrongNumberOfPlayersError unless game.length == 2 
    raise NoSuchStrategyError if game.any? {|n| !(n[1] =~ /^[spr]$/i)} 
    loose_hash = {'s' => 'r', 'p' => 's', 'r' => 'p'} 
    strategy1 = game[0][1].downcase 
    strategy2 = game[1][1].downcase 
    loose_hash[strategy1] == strategy2 ? game[1] : game[0] 
end 
+0

非常感谢你,对Ruby的新手我不熟悉?:有条件的,你在这里部署得如此之好,并且作为一个新手程序员,我喜欢使用哈希,但真的不知道如何充分利用它。当我看着你的方法时,你的loose_hash很有意义,但我不会想到它。感谢您帮助我成为更好的程序员。 – 2012-03-23 14:24:01

0

问题是您的/X/ && /X/格式。 Ruby不会将其解释为要求两个正则表达式匹配。我不能肯定它,但我相信它会把它一样when /p/, /r/,这将是真实的,如果要么正则表达式匹配。当您测试game = [["Dave","S"], ["Dan","R"]]时,"r"与第一个案例声明相匹配,您尝试引用playr["p"]

试试这个:

case stgys.to_S 
    when "pr", "rp" 
    playr["p"] 
    when "ps", "sp" 
    playr["s"] 
    when "sr", "rs" 
    playr["r"] 
end 
+0

感谢您的回应!不幸的是,当我输入它时,它不起作用,因为.to_s返回自身的表示而不是返回字符串元素的换句话说“[\”p \“,\”r \“]”“。最后,我放弃了自己的野心,并将其添加到hash键的调用中,然后使用三个可能的字符串作为我的'when'参数。 – 2012-03-21 01:50:30

0

你的问题是,之前它的实际用作标签,该标签/p/ && /r/进行评估。由于这两者都不是假或无,因此/p/ && /r/等于/r/,对于其他案例标签也是如此。

除非你重写这个有每个案例一个案例说法,在我看来那只是case不是一个很适合你在做什么

0

随着指令的问题的帮助下,我以不同的方式解决了这个问题。

def rps_game_winner(game) 
    raise WrongNumberOfPlayersError unless game.length == 2 
    raise NoSuchStrategyError unless game[0].length == 2 and game[1].length == 2 
    raise NoSuchStrategyError unless game[0][1] =~ /^[RPS]$/ and game[1][1] =~ /^[RPS]$/ 
    return game[0] unless (game[0][1] == "P" and game[1][1] == "S") or 
         (game[0][1] == "S" and game[1][1] == "R") or 
         (game[0][1] == "R" and game[1][1] == "P") 
    return game[1] 
end 

def rps_tournament_winner(tournament) 
    return rps_game_winner(tournament) unless tournament[0][1] !~ /^[RPS]$/ 
    return rps_tournament_winner([rps_tournament_winner(tournament[0]), rps_tournament_winner(tournament[1])]) 
end 

我测试了所有给定的场景,它对我有用。