我在解决“石头,纸,剪刀”的游戏。输入数组并递归地输出优胜者。这是我的代码:
class RockPaperScissors
# Exceptions this class can raise:
class NoSuchStrategyError < StandardError; end
def self.winner(player1, player2)
strategy = player1[1]+player2[1]
raise NoSuchStrategyError.new("Strategy must be one of R,P,S") if strategy !~ /(R|P|S){2}/
strategy =~ /rs|sp|pr|rr|ss|pp/i ? player1 : player2
end
def self.tournament_winner(tournament)
if tournament.length==2 && tournament.first[0].is_a?(String)
winner(tournament[0],tournament[1])
else
#keep slice the array in half
***winner(tournament_winner(tournament[0,tournament.length/2]), tournament_winner(tournament[tournament.length/2]))***
end
end
end谢谢你的帮助!
样本输入:
[
[
[ ["Armando", "P"], ["Dave", "S"] ],
[ ["Richard", "R"], ["Michael", "S"] ],
],
[
[ ["Allen", "S"], ["Omer", "P"] ],
[ ["David E.", "R"], ["Richard X.", "P"] ]
]
]发布于 2014-06-13 19:48:23
您的代码不会将比赛分割成一半-- tournament[tournament.length/2]不返回数组的后半部分--它只返回位于tournament.length/2位置的项,相反,您应该这样做:
winner(tournament_winner(tournament[0...tournament.length/2]), tournament_winner(tournament[tournament.length/2..-1]))此外,您也不考虑长度为1的数组,这会导致无休止的递归。
下面是代码的工作版本:
def tournament_winner(tournament)
if tournament.length == 1
tournament_winner(tournament[0])
elsif tournament.length==2 && tournament.first[0].is_a?(String)
winner(tournament[0],tournament[1])
else
winner(tournament_winner(tournament[0...tournament.length/2]),
tournament_winner(tournament[tournament.length/2..-1]))
end
end发布于 2014-06-13 20:20:51
有很多更好的方法来处理这个问题,而不是杂乱无章的正则表达式、混乱的缩写和字符串。
例如,您可以使用更面向对象的方法:
module RockPaperScissors
class NoSuchStrategyError < StandardError; end
class Move
include Comparable
attr_reader :strategy
def initialize(strategy)
raise NoSuchStrategyError unless strategies.include?(strategy)
@strategy = strategy
end
def <=>(opposing_move)
if strengths[strategy] == opposing_move.strategy
1
elsif strengths[opposing_move.strategy] == strategy
-1
else
0
end
end
protected
def strengths
{
rock: :scissors,
scissors: :paper,
paper: :rock
}
end
def strategies
strengths.keys
end
end
class Player
attr_reader :name, :move
def initialize(name, move)
@name, @move = name, move
end
end
class Tournament
def initialize(*players)
@player_1, @player_2, _ = *players
end
def results
p1move = @player_1.move
p2move = @player_2.move
if p1move > p2move
"#{@player_1.name} wins."
elsif p2move > p1move
"#{@player_2.name} wins."
else
"Tie."
end
end
end
end示例用法:
rock = RockPaperScissors::Move.new(:rock)
paper = RockPaperScissors::Move.new(:paper)
player_1 = RockPaperScissors::Player.new('John Smith', rock)
player_2 = RockPaperScissors::Player.new('Corey', paper)
tournament = RockPaperScissors::Tournament.new(player_1, player_2)
tournament.results #=> "Corey wins."https://stackoverflow.com/questions/24212779
复制相似问题