2012-02-29 106 views
2

我應該創建在紅寶石的方法,其將在結構化的,多維的陣列,諸如掙扎:紅寶石:遞歸

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

此數組應該代表岩石的比賽,紙&剪刀,玩家的數量將永遠是2^n並且不會重複(玩家)。

我寫的代碼如下:

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

def rps_game_winner(game) 
    raise WrongNumberOfPlayersError unless game.length == 2 
    valid = ["r","p","s"] 
    a1=[(game[0][1]).downcase] 
    a2=[(game[1][1]).downcase] 
    raise NoSuchStrategyError unless (valid & a1) && (valid & a2) 

    return (game[0]) if a1 === a2 
    case (a1[0]) 
    when "r" 
    case (a2[0]) 
    when "p" 
     return (game[1]) 
    else 
     return (game[0]) 
    end 
    when "p" 
    case (a2[0]) 
    when "s" 
     return (game[1]) 
    else 
     return (game[0]) 
    end 
    when "s" 
    case (a2[0]) 
    when "r" 
     return (game[1]) 
    else 
     return (game[0]) 
    end 
    end 
end 

def rps_tournament_winner(tournament) 
    if tournament[0][0].is_a?(Array) 
    rps_tournament_winner(tournament[0]) 
    elsif tournament[1][0].is_a?(Array) 
    rps_tournament_winner(tournament[1]) 
    else 
    rps_game_winner(tournament) 
    end 
end 

所以我的問題是,鑑於使用數組我前面提到被傳遞到rps_tournament_winnerDave的總是贏,而不是Richard,我一直沒能找出我出錯的地方。

泰閱讀的文本/代碼:)

+1

我建議你使用':本文:搖滾,: scissor'而不是字符串,它更容易閱讀代碼,並且對於解釋器來說更快。 – farnoy 2012-02-29 17:44:49

+0

我提供的數組使用類似「R」「p」等字符串,我想我可以在內部使用符號嗎?必須將它轉換回所需結果格式的一個字符串(這就像['Richard','R']? – 2012-02-29 17:51:07

+0

你在哪裏初始化遊戲數組? – 2012-02-29 17:53:45

回答

3

我注意到的一件事是您使用'有效'並不會檢查您的輸入是否真實有效。如果你想檢查a1和a2或者是「R」,「P」或「S」,你應該使用正則表達式:

valid = /[rps]/ # matches either "r" "p" or "s" 
raise NoSuchStrategyError unless (a1 =~ valid) && (a2 =~ valid) 

您的播放器陣列嵌套很深。你會讓你的生活更簡單通過細化出來:

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

您可以更輕鬆地閱讀和破壞你的程序分成幾部分維持。

# This is incomplete as it doesn't deal with ties. I'll let you do that part 
def win(first, second) 
    if (first == "p" && second == "r") || (first == "r" && second == "s") || (first == "s" && second == "p") 
    return true 
    else 
    return false 
    end 
end 

現在,它更容易編寫和理解遊戲本身,採用上述方法:

def rps_game_winner(player1, player2) 
    first = player1[1].downcase 
    second = player2[1].downcase 
    win(first, second) ? player1 : player2 # ternary operator returns the winner 
end 

您現在有一個方法把這一切例如,對於確定一個雙贏創建方法(主要邏輯的種類),我們將在這裏使用遞歸:

def rps_tournament_winner(player_list) 
    round_winners = [] # place to hold the winners for each round 

    if player_list.size == 1 # final condition to stop the recursion 
    puts "The winner is #{player_list[0][0]}." 
    else 
    player_list.each_slice(2) do |l1, l2| # take pairs from your list to play each other 
     round_winners << rps_game_winner(l1, l2) 
    end 

    rps_tournament_winner(round_winners) # use recursion to play the winners against each other 
    end 
end 

# put it into play 
puts test_array(my_arr) 

就是這樣。獲勝者是理查德,而且這將始終是理查德,因爲這場比賽是確定性的。

雖然這會運行,但您應該知道我忽略了一些重要的事情,例如處理關係和奇數的玩家。在這些條件下,該方案無法正常工作。但我會留給你解決這些問題。

編輯:修改原始數組:

new_array = [] 
my_arr.flatten.each_slice(2) do |name, pick| 
    new_array << [name, pick] 
end 
+0

有一個錯誤,我修好了,所以它應該現在工作,如果它之前沒有...除非有另一個我錯過了錯字。 :o – robotcookies 2012-02-29 22:53:15

+0

非常感謝你,我是一個新手,對Ruby和新編碼都很陌生,你的每一點都是寶石,我會把他們全部放在心上。至於球員的數量,它將永遠是平等的(這就是我的方法應該接受比賽陣列)得到「Tie」邏輯將是容易的。再次感謝您解剖這些可怕的代碼和無價的提示。最後一個問題,我如何「瘦」我的陣列?也許陣列#flatten – 2012-03-01 09:14:38

+0

嗨,我會編輯我的帖子,以顯示稀疏你的原始數組的方式。註釋字段並不容易顯示代碼。往上看。 – robotcookies 2012-03-01 17:49:44

0

這是很難調試代碼在牆上。

但我認爲它有根本的缺陷。

當你調用rps_tournament_winner你傳遞

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

它要求tournament[0][0].is_a?(Array)

[['Armando', 'P'], ['Dave', 'S']], [['Richard', 'R'], ['Michael', 'S']] 

是的。

它調用rps_tournament_winner(tournament[0])

tournament = [ [['Armando', 'P'], ['Dave', 'S']], [['Richard', 'R'], ['Michael', 'S']] ] 

它要求tournament[0][0].is_a?(Array)

['Armando', 'P'] 

是的。

它調用rps_tournament_winner(tournament[0])

tournament = [['Armando', 'P'], ['Dave', 'S']] 

它要求tournament[0][0].is_a?(Array)

'Armando' 

沒有它不是。

它調用rps_game_winner(tournament)

並在遊戲戴夫擊敗阿曼多!

我不認爲這是你想要的功能。

我建議你改寫這個,試圖讓事情變得簡單。

+0

TY,我覺得在'阿曼多'獲勝後,'理查'和'邁克爾'在'理查'獲勝並在下面的遞歸中擊敗'阿曼多'。 焦慮問題:你能否提出一些方法讓我的代碼更簡單,更容易閱讀和調試? – 2012-02-29 18:17:01

1

你只遞歸下降錦標賽[0]從來沒有結束比賽前[1]。 你需要參加錦標賽[0]和錦標賽[1],然後相互對抗。

有點像。 (我把它給你寫Ruby代碼)

rps_game_winner([rps_tournament_winner(賽[0],rps_tournament_winner(賽[1])

+0

是的 - 你是對的上面的例子產生了錯誤的結果,因爲最初由Osama Husain描述的「括號內數組」的勝利者會導致Richard X獲勝。需要注意的重要一點是聯賽被括起來。 – 2012-10-07 03:17:24