2012-03-20 233 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 

我測試了所有給定的場景,它對我有用。