You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 01:18:14