如何修改Ruby猜词游戏代码以通过多单词RSpec测试
Ruby猜词游戏多单词模式代码修改方案
问题描述
我正在学习Ruby,开发的猜词游戏目前仅支持单单词模式,对应的RSpec测试已通过,但多单词模式的测试失败。需要修改代码,让游戏在完成一个单词的猜词(无论胜负)后自动进入下一个单词的猜词流程,使输出匹配测试预期,通过该RSpec测试。
通过的单单词RSpec测试
fit "is lost with a different set of incorrect guesses" do guesses = ["ALPHA", "BETA", "GAMMA"] input = StringIO.new(guesses.join("\n")) game = Game.new(answers: ["RUBY"], input: input, output: output, max_attempts: 3) game.start game_output_lines = output.string.split("\n").map(&:strip) aggregate_failures do expect(game_output_lines.size).to eq 9 expect(game_output_lines[2]).to eq "The answer is not ALPHA." expect(game_output_lines[3]).to eq "Try again. Attempts left: 2" expect(game_output_lines[4]).to eq "The answer is not BETA." expect(game_output_lines[5]).to eq "Try again. Attempts left: 1" expect(game_output_lines[6]).to eq "The answer is not GAMMA." expect(game_output_lines[7]).to eq "You lost." expect(game_output_lines[8]).to eq "Your final score: 0/1." end end
未通过的多单词RSpec测试
it "can be played with multiple words" do guesses = ["ALPHA", "BETA", "GAMMA", "MEGA", "OMEGA"] input = StringIO.new(guesses.join("\n")) game = Game.new(answers: ["DELTA", "OMEGA"], input: input, output: output, max_attempts: 3) game.start game_output_lines = output.string.split("\n").map(&:strip) aggregate_failures do expect(game_output_lines.size).to eq 14 expect(game_output_lines[2]).to eq "The answer is not ALPHA." expect(game_output_lines[3]).to eq "Try again. Attempts left: 2" expect(game_output_lines[4]).to eq "The answer is not BETA." expect(game_output_lines[5]).to eq "Try again. Attempts left: 1" expect(game_output_lines[6]).to eq "The answer is not GAMMA." expect(game_output_lines[7]).to eq "You lost." expect(game_output_lines[8]).to match(/^2\/2. Guess a word from an anagram [OMEGA]{5}$/) expect(game_output_lines[9]).to eq "The answer is not MEGA." expect(game_output_lines[10]).to eq "Try again. Attempts left: 2" expect(game_output_lines[11]).to eq "Correct! The answer is OMEGA." expect(game_output_lines[12]).to eq "So far you have correctly guessed 1 out of 2." expect(game_output_lines[13]).to eq "Your final score: 1/2." end end
当前Game类代码
class Game def initialize(answers:, input: $stdin, output: $stdout, max_attempts: 3) @answers = answers @correct_answers = 0 @input = input @max_attempts = 3 @output = output end def start output.puts "Let's play a game. You will have to guess 1 anagram." output.puts "1/1. Guess a word from an anagram #{answers[-1]}" evaluate_user_guesses end def evaluate_user_guesses guess = nil current_attempt = 1 max_attempts_count = 3 guess_counts = 1 scores = 1 while guess != answers[-1] && current_attempt <= max_attempts guess = input.gets.to_s.strip if guess == answers[-1] output.puts "Correct! The answer is #{answers[-1]}." else output.puts "The answer is not #{guess}." end if guess == answers[-1] && current_attempt <= max_attempts output.puts "So far you have correctly guessed #{guess_counts} out of #{scores}." return output.puts "Your final score: #{guess_counts}/#{scores}." elsif guess != answers[-1] && current_attempt < max_attempts output.puts "Try again. Attempts left: #{max_attempts_count -= 1}" else output.puts "You lost." end current_attempt += 1 end output.puts "Your final score: #{guess_counts -= 1}/#{scores}." end private attr_reader :answers, :correct_answers, :input, :max_attempts, :output end
修改方案
当前代码核心问题是硬编码单单词逻辑,未遍历所有答案,也未跟踪多单词进度。具体修改点:
- 修复
initialize方法的max_attempts赋值,使用传入参数而非硬编码3 - 重构
start方法,动态显示总单词数,遍历所有答案逐个处理猜词流程 - 拆分单个单词猜词逻辑为
play_single_word方法,返回是否猜对以累计分数 - 使用实例变量
@correct_answers跟踪猜对的单词数量,替换硬编码局部变量 - 动态生成提示文本,适配单/多单词场景的进度显示
修改后的完整代码
class Game def initialize(answers:, input: $stdin, output: $stdout, max_attempts: 3) @answers = answers @correct_answers = 0 @input = input @max_attempts = max_attempts # 修复硬编码问题 @output = output end def start total_words = answers.size output.puts "Let's play a game. You will have to guess #{total_words} anagram#{'s' if total_words != 1}." answers.each_with_index do |answer, index| # 输出当前单词的猜词提示 output.puts "#{index+1}/#{total_words}. Guess a word from an anagram #{answer.chars.sort.join}" # 执行单个单词的猜词流程,猜对则累计分数 @correct_answers += 1 if play_single_word(answer) # 非最后一个单词时,输出当前进度 if index != total_words - 1 output.puts "So far you have correctly guessed #{@correct_answers} out of #{total_words}." end end # 所有单词处理完后输出最终得分 output.puts "Your final score: #{@correct_answers}/#{answers.size}." end private def play_single_word(target_answer) current_attempt = 1 attempts_left = max_attempts while current_attempt <= max_attempts guess = input.gets.to_s.strip if guess == target_answer output.puts "Correct! The answer is #{target_answer}." return true # 猜对,返回true else output.puts "The answer is not #{guess}." end if current_attempt < max_attempts attempts_left -= 1 output.puts "Try again. Attempts left: #{attempts_left}" else output.puts "You lost." end current_attempt += 1 end false # 没猜对,返回false end attr_reader :answers, :input, :max_attempts, :output end
修改说明
play_single_word封装单个单词猜词逻辑,返回布尔值标记是否猜对,便于累计分数start方法遍历所有答案,逐个调用猜词方法,并按测试要求输出进度提示- 修复
max_attempts硬编码问题,使用初始化传入的参数 - 动态生成提示文本,适配单/多单词的语法细节(如复数形式)
- 严格匹配RSpec测试的输出顺序与内容,确保断言通过
内容的提问来源于stack exchange,提问作者Adesuyi Fisola
相关产品推荐
相关产品推荐

