Ruby版Hangman游戏问题:胜利提示延迟、存档加载弹窗重复
Hangman游戏问题修复方案
以下是针对你遇到的两个问题的完整修复代码及详细说明:
修复后的完整代码
require 'yaml' class Hangman def initialize(file, skip_load_prompt = false) saved_file_exist if File.exist?('save_game.yaml') && !skip_load_prompt @data = File.readlines(file) # 仅当未从存档加载时初始化默认游戏状态 unless instance_variable_defined?(:@word) @word = select_word @array = Array.new(@word.size - 1) { '_' } @attempts_left = 100 @incorrect_guesses = [] end end def saved_file_exist puts 'Do you want to load the saved game? (yes/no). Press enter if you have already done that' choice = gets.chomp.downcase return unless choice == 'yes' Hangman.load_game exit # 加载存档后终止当前实例的初始化流程 end def select_word guessed_word = @data.select { |word| word.strip.size >= 5 && word.strip.size <= 12 } guessed_word.sample end def guessing_selection puts 'Try guessing a letter from the secret word' guess = gets.chomp.downcase until guess.match?(/^[a-zA-Z]$/) puts 'Your input should be one letter and not a number' guess = gets.chomp.downcase end guess end def give_a_clue(array, word, guess) word.chars.each_with_index do |letter, index| array[index] = letter if letter == guess end array.join(', ') end def save_game File.open('save_game.yaml', 'w') do |file| file.puts self.to_yaml end puts 'Game saved successfully!' end def self.load_game saved_game_data = YAML.load(File.read('save_game.yaml')) # 创建实例时跳过加载提示,避免重复触发 saved_game = Hangman.new('words.txt', true) saved_game.yaml_initialize(saved_game_data) puts 'Game loaded successfully!' saved_game.play end def to_yaml YAML.dump( { 'word' => @word, 'array' => @array, 'attempts_left' => @attempts_left, 'incorrect_guesses' => @incorrect_guesses } ) end def yaml_initialize(map) @word = map['word'] @array = map['array'].nil? ? Array.new(@word.size - 1) { '_' } : map['array'] @attempts_left = map['attempts_left'] @incorrect_guesses = map['incorrect_guesses'] end def play_again puts "Current state: #{@array}" puts "Attempts left: #{@attempts_left}" puts "Incorrect guesses so far: #{@incorrect_guesses.join(', ')}" play end def keep_playing @guess = guessing_selection if @word.include?(@guess) give_a_clue(@array, @word, @guess) else @incorrect_guesses << @guess unless @incorrect_guesses.include?(@guess) @attempts_left -= 1 # 仅猜错时减少剩余次数,修正原逻辑错误 end play_again end def delete_saved_game File.delete('save_game.yaml') if File.exist?('save_game.yaml') end def game_state if !@array.include?('_') puts "Congratulations, You won! The word is: #{@word}" delete_saved_game exit elsif @attempts_left.positive? keep_playing else puts "Game over! The word was: #{@word}" delete_saved_game exit end end def play # 先检测游戏状态,已结束则直接触发收尾逻辑,不显示操作提示 return game_state unless @array.include?('_') && @attempts_left.positive? puts "Type 'save' to save the game and exit, or continue with a letter guess." input = gets.chomp.downcase if input == 'save' save_game exit end game_state end end hangman = Hangman.new('words.txt') hangman.play
问题修复说明
1. 获胜后仍弹出操作提示的修复
原代码中play方法会先输出操作提示,再检测游戏状态,导致玩家猜对最后一个字母后,play_again调用play时会先弹出提示再进入获胜逻辑。修复点:
- 在
play方法开头优先检测游戏状态,若已获胜或失败,直接执行收尾逻辑,跳过操作提示 - 修正
attempts_left的减少逻辑:原代码每次调用play_again都会减1,改为仅当猜错字母时才减少次数,避免正确猜测消耗次数
2. 加载存档时提示重复出现的修复
原代码加载存档时,load_game会新创建Hangman实例,新实例的initialize又会触发加载提示,同时原实例的初始化流程未终止,导致两次提示。修复点:
- 给
initialize方法添加skip_load_prompt参数,加载存档时创建实例跳过提示 - 在
saved_file_exist中调用load_game后立即exit,终止原实例的初始化流程 - 调整
initialize中的变量初始化逻辑,仅当未从存档加载时才设置默认值
内容的提问来源于stack exchange,提问作者Shahid Haris
相关产品推荐
相关产品推荐

