2012-03-13 22 views
-1
t = [ 
     [ 
     [["Armando", "P"],["Dave", "S"]], 
     [["Richard", "R"],["Michael", "S"]], 
     ], 
     [ 
     [["Allen", "S"],["Omer", "P"]], 
     [["David E.", "R"], ["Richard X.", "P"]] 
     ] 
    ] 

def rps_game_winner(game) 
    raise WrongNumberOfPlayersError unless game.length == 2 
    if (game[0][1] =~ /[r]/i && game[1][1] =~ /[s]/i) || (game[0][1] =~ /[s]/i && game[1][1] =~ /[p]/i) || (game[0][1] =~ /[p]/i && game[1][1] =~ /[r]/i) 
     return game[0] 
    elsif (game[0][1] =~ /[r]/i && game[1][1] =~ /[p]/i) || (game[0][1] =~ /[s]/i && game[1][1] =~ /[r]/i) || (game[0][1] =~ /[p]/i && game[1][1] =~ /[s]/i) 
     return game[1] 
    elsif game[0][1] == game[1][1] 
     return game[0] 
    else 
     raise NoSuchStrategyError.new 
    end 
end 

def rps_tournament_winner(t) 
    t.each do |pair| 
    yield pair 
    end 
end 

rps_tournament_winner(t) { |x| rps_game_winner(x) } 

所以我收到的錯誤是:NoSuchStrategyError: NoSuchStrategyError - 這意味着收率傳遞一個值到所述塊並且被傳遞給我的方法rps_game_winner和它正在評估一些東西並給出這個錯誤 - 按照這個方法。沒有得到適當的迭代與陣列的複雜陣列收率

但它不能正確評估它....因爲它應該看Armando and Dave並返回一個贏家,那麼它應該回去繼續看下一對,並返回贏家等

附:當我做puts pair時,我看到了正確的值 - 並且我已經在單一對上測試rps_game_winner方法,並且它工作正常。它只是迭代多對,給我一個來回控制權的問題。

+1

我想你想提出'WrongNumberOfPlayers.new',而不是'WrongNumberOfPlayers'(類)。 – Linuxios 2012-03-13 21:35:48

+0

可能重複的[獲得工作的數組嵌套數組 - 紅寶石](http://stackoverflow.com/questions/9680612/getting-yield-to-work-on-nested-arrays-of-arrays-ruby) – 2012-03-13 23:46:21

+0

@ Linux_iOS.rb.cpp.c.lisp.m.sh:不,他沒有。雖然兩者都起作用,並且兩者實際上在語義上相同,但您的版本不是慣用的Ruby。 – 2012-03-14 01:20:34

回答

1

您確定你的t正確嗎? 在我看來,像它應該是這樣的:

t = [ 
     [["Armando", "P"],["Dave", "S"]], 
     [["Richard", "R"],["Michael", "S"]], 
     [["Allen", "S"],["Omer", "P"]], 
     [["David E.", "R"], ["Richard X.", "P"]] 
    ] 

我認爲阿曼多起戴夫在第一場比賽。 理查德扮演邁克爾等

在您的代碼[ 「阿曼」, 「P」],[ 「戴夫」, 「S」]]劇[ 「艾倫」, 「S」],[ 「奧馬爾」 ,「P」]]。所以當你的rps_game_winner檢查遊戲[0] [1]時,它實際上會返回[「Dave」,「S」]。不P.

EDIT1:如果你想你會說,你的一套邏輯 需要修改rps_tournament_winner像這樣:

def rps_tournament_winner(t) 
    t.each do |pair| 
    pair.each do |g| 
     puts 'winner:', yield(g) 
    end 
    end 
end 

EDIT2: 做我自己的實現。從中獲取你的意願。但它做你想做的事情。 https://github.com/SpoBo/rock-paper-scissors

你basicaly需要跟蹤的贏家,讓獲獎者對自己玩。我的執行允許任何數量的玩家互相對戰。我實現的唯一問題是一個玩家總是玩同一隻手,並且一旦雙手相同的玩家遇到遊戲就會變得無法預測。所以它需要一些修改來處理這個。

+0

是的,'t'是正確的..這就是原因。有兩輪。所以阿曼多扮演戴夫,戴夫獲勝。然後理查德上場邁克爾和理查德獲勝然後戴夫(第一盤獲勝者)扮演理查德(第二盤獲勝者)。該獲勝者現在是第一輪的勝利者,然後必須繼續參加第二輪的獲勝者才能確定比賽冠軍。所以是的,這有點令人困惑......但't'是正確的。 – marcamillion 2012-03-13 22:23:46

+0

代碼P R和S是什麼意思? – dbenhur 2012-03-14 03:35:05

+0

紙,石頭,剪刀:) – marcamillion 2012-03-14 07:05:09

2

當您進行測試時,您似乎不夠深入索引。

輸入到rps_game_winner看起來像[[["Armando", "P"], ["Dave", "S"]], [["Richard", "R"], ["Michael", "S"]]]game[0][1]看起來像["Dave", "S"]。你的正則表達式匹配看起來像他們試圖測試這些元組的第二項字母。把你所有的game[x][y]改爲game[x][y].last,它可以做你想做的事(我承認我很難理解你想要表達的邏輯)。您可以嘗試製作更自然地表示數據的小對象(可能使用Struct),而不是使用深度嵌套的基本數據結構;通過給這個數據結構中的條目賦予明智的名稱和結構,這將使您的代碼更易於理解。

順便說一句,在你的正則表達式中沒有必要使用[char]類,實際上根本不需要正則表達式。 game[0][1].last.upcase == 'R'而不是game[0][1].last =~ /[r]/i更快更清晰。

+0

使用'.last'不適合我。當我用一個組測試它時,我得到這樣的錯誤:'NoMethodError:undefined method'last'for「R」['Richard','R'],['Michael','S']]' :在一組設備上試用時的字符串 - 應該可以工作。 – marcamillion 2012-03-13 22:42:15