Не получается правильная итерация с yield со сложным массивом массивов - PullRequest
0 голосов
/ 14 марта 2012
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 - это означает, что yield передает значение в блок и передается моему методу rps_game_winner, он что-то оценивает и выдает эту ошибку - заметод.

Но он не оценивает его должным образом .... потому что он должен смотреть на Armando and Dave и возвращать победителя, затем он должен вернуться и продолжить смотреть на следующую пару и вернуть победителя и т. Д.

PS Когда я делаю puts pair, я вижу правильные значения - и я протестировал метод rps_game_winner на одной паре, и он отлично работает.Просто перебор нескольких пар вызывает у меня проблему с передачей контроля вперед и назад.

Ответы [ 2 ]

2 голосов
/ 14 марта 2012

Вы, кажется, недостаточно глубоко индексируете при выполнении тестов.

Входные данные для 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 быстрее и понятнее.

1 голос
/ 14 марта 2012

Вы уверены, что ваш т правильно?Мне кажется, что это должно быть примерно так:

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

Я предполагаю, что Армандо играет Дэйва в первой игре.Ричард играет Майкла и т. Д.

В вашем коде [["Armando", "P"], ["Dave", "S"]] играет [["Allen", "S"], ["Omer"", "П"]].Поэтому, когда ваш 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

Вы должны отслеживать победителей и позволить победителям играть против себя.моя реализация позволяет любому количеству игроков играть друг против друга.Единственная проблема, с которой я столкнулся, заключается в том, что игрок всегда играет одну и ту же руку, и как только 2 игрока с одинаковыми руками встретятся, игра станет непредсказуемой.так что для этого нужны некоторые модификации.

...