Ruby实现类Mastermind游戏时线索提示逻辑异常求助
Ruby版Mastermind猜数字游戏线索提示Bug修复
问题现象
开发类Mastermind猜数字游戏时,基础输入接收、合法性校验、游戏流程控制均可正常运行,但线索提示模块存在两类异常:
- 「数字正确且位置正确」的提示完全无法按规则生效
- 「数字正确但位置错误」的提示计数不稳定,某轮猜测匹配到对应数字后,后续轮次即使输入包含相同数字,该类提示的计数也会异常消失
原始问题代码
class Mastermind def initialize @answer = create_code @guess_number = 12 @winner = false end def ask_what_you_guess while @guess_number > 0 do break if @winner p "#{@guess_number.to_s.rjust(2)} attempts left: " input = gets.chomp.split("") if guess_is_vaild?(input) win = guess(input) else puts "Invalid input! Please try again!" end end game_over end def guess(number) if number == @answer @winner = true else x = get_x(number) y = get_y(number) puts "Please try again, #{x} Correct/#{y} Wrong Spot." @guess_number -= 1 end end def game_over input = nil until ["y", "n"].include?(input) if @winner print "You won! Would you like to try again? [Y/N]" else print "You lose, this time! Would you like to give it another try? [Y/N]" end input = gets.chomp.downcase end restart_game?(input) end def restart_game?(input) case input when "y" true when "n" false end end def create_code code = [] until code.size == 4 do number = (rand(6) + 1).to_s code << number unless code.include?(number) end code end def guess_is_vaild?(input) if input.size == 4 && input.all? { |e| "123456".include? (e) } return true else return false end end def get_y(number) y = 0 number.each_with_index do |e, i| y += 1 if e == @answer[i] end return y end def get_x(number) x = 0 number.each_with_index do |e, i| x += 1 if e != number[i] && number.include?(e) end return x end end puts "***********************************************\n" \ "*CodeBreaker: can you guess the right number? *\n" \ "* Guess a 4 digit number composed of 1-6. *\n" \ "* Y means how many numbers are correct. *\n" \ "* X correct but in the wrong position. *\n" \ "***********************************************" restart = true while restart do mastermind = Mastermind.new restart = mastermind.ask_what_you_guess end puts "Thanks for playing CodeBreaker, Code Master!"
根因定位
代码存在3处核心逻辑错误,直接导致线索提示异常:
- 变量映射颠倒:
get_y方法实际实现的是「数字+位置均正确」的计数逻辑,但输出提示时将x标记为Correct、y标记为Wrong Spot,对应关系完全错位。 - 比对对象错误:
get_x方法判断位置是否匹配时,错误地将当前遍历元素和猜测数组自身的同位置元素比较(e != number[i]是恒假判断),根本没有和标准答案数组@answer做比对,计数逻辑从根本上失效。 - 无去重计数逻辑:原逻辑没有排除已经判定为「位置正确」的数字,也没有处理数字重复出现的计数边界,导致出现重复计数、跨轮次计数异常的不稳定问题。
修复方案
按照Mastermind标准规则重写线索计数逻辑,遵循「先统计精确匹配,再统计部分匹配,重复数字不重复计数」的原则:
- 逐位比对猜测值和答案,先统计「数字和位置都正确」的精确匹配数量,标记这些已匹配的位置,后续统计时排除这部分数字
- 对剩余未匹配的猜测数字、答案数字分别统计出现频率
- 对两边共有的数字,取两边剩余出现次数的最小值累加,得到「数字正确但位置错误」的部分匹配数量,避免重复计数
替换原有get_x、get_y方法,同时修正guess方法中的输出对应关系,修复后的核心代码如下:
def guess(number) if number == @answer @winner = true else exact, partial = get_exact_and_partial(number) puts "Please try again, #{exact} Correct (right number and position)/#{partial} Wrong Spot (right number, wrong position)." @guess_number -= 1 end end def get_exact_and_partial(number) exact = 0 matched_guess = Array.new(4, false) matched_answer = Array.new(4, false) # 先统计精确匹配 4.times do |i| if number[i] == @answer[i] exact += 1 matched_guess[i] = true matched_answer[i] = true end end # 统计剩余未匹配数字的频率 guess_remaining = Hash.new(0) answer_remaining = Hash.new(0) 4.times do |i| guess_remaining[number[i]] += 1 unless matched_guess[i] answer_remaining[@answer[i]] += 1 unless matched_answer[i] end # 统计部分匹配 partial = 0 guess_remaining.each do |num, count| partial += [count, answer_remaining[num]].min end [exact, partial] end
替换后删除原有失效的get_x、get_y方法即可,线索计数将完全符合游戏规则,不会再出现计数异常问题。
内容的提问来源于stack exchange,提问作者C-Lund2021
相关产品推荐
相关产品推荐

