我正在尝试创建一个石头剪刀程序,到目前为止这个代码有效但参数没有被抛出,我该如何解决这个问题?
class RockPaperScissors
# Exceptions this class can raise:
class NoSuchStrategyError < StandardError ; end
def self.winner(player1, player2)
p1c = player1.last.downcase
p2c = player2.last.downcase
p1wins = false
case p1c
when "p"
if (p2c == "p" or p2c == "r")
p1wins = true
end
when "s"
if (p2c == "p" or p2c == "s")
p1wins = true
end
when "r"
if (p2c == "r" or p2c == "s")
p1wins = true
end
else
raise NoSuchStrategyError, "Strategy must be one of R,P,S"
end
end
为什么不抛出错误? 编辑*
这用于使用rspec测试代码,因为你可以看到一个带有Name的数组,后跟他们在capse中选择的内容
before(:each) do
@rock = ['Armando','R'] ; @paper = ['Dave','P'] ; @scissors = ['Sam','S']
end
describe 'game' do
it 'rock breaks scissors' do
RockPaperScissors.winner(@rock, @scissors).should == @rock
end
it 'scissors cut paper' do
RockPaperScissors.winner(@paper, @scissors).should == @scissors
end
it 'paper covers rock' do
RockPaperScissors.winner(@rock, @paper).should == @paper
end
it 'first player wins if both use same strategy' do
RockPaperScissors.winner(@scissors, ['Dave','S']).should == @scissors
end
end
it "should raise NoSuchStrategyError if strategy isn't R, P, or S" do
lambda { RockPaperScissors.winner(@rock, ['Dave', 'w']) }.
should raise_error(RockPaperScissors::NoSuchStrategyError,
"Strategy must be one of R,P,S")
end
答案 0 :(得分:1)
编辑:根据您新提供的测试代码,问题是您只测试代码中第一个播放器的策略。但是,在测试代码中,第一个玩家(@rock
)有一个有效的策略;这是第二个拥有无效策略的玩家。请参阅我的代码,了解一种测试方法。
当我将缺少的end
添加到您的代码中时,它适用于我:
Player = Struct.new(:last)
RockPaperScissors.winner(
Player.new("cats"),
Player.new("dogs")
)
#=> /Users/phrogz/Desktop/tmp.rb:24:in `winner': Strategy must be one of R,P,S (RockPaperScissors::NoSuchStrategyError)
请注意,我会像这样重写您的方法:
class RockPaperScissors
class NoSuchStrategyError < StandardError ; end
LEGAL_MOVES = %w[r p s]
def self.winner(player1, player2)
p1c = player1.last.downcase
p2c = player2.last.downcase
unless LEGAL_MOVES.include?(p1c) && LEGAL_MOVES.include?(p2c)
raise NoSuchStrategyError, "Strategy must be one of R,P,S"
end
if p1c!=p2c then
case p1c
when "r" then p2c=="s" ? player1 : player2
when "p" then p2c=="r" ? player1 : player2
when "s" then p2c=="p" ? player1 : player2
end
end
end
end
这会在无效移动时引发错误,如果两个玩家并列,则返回nil
,否则返回其中一个玩家。你可以通过重写内部部分来使它更简洁,但可以说不太明确:
if p1c!=p2c then
case p1c
when "r" then p2c=="s"
when "p" then p2c=="r"
when "s" then p2c=="p"
end ? player1 : player2
end