Ruby:向简单的控制台测验应用程序添加计时器

Ruby: Adding a timer to a simple console quiz app

我正在学习 Ruby 作为练习的一部分,我实现了一个简单的测验应用程序。它的伪代码是这样的

for i in 0..questions.length - 1 do
  puts questions[i]
  $answer = gets.chomp
  if $answer == answers[i]
    correct += 1
  end
end

timer_thread = Thread.new do
  while $answer == nil
    (1..5).each do |number|
      sleep(1)
      number
      if number == 5
        puts "Timer out"
      end
      break if ($answer != nil)
    end
  end
end

我想要的是添加一个计时器,比方说 30 秒,它应该移动到下一个问题,那个问题应该被认为是不正确的。我开始了解 Time.now,但不确定如何将它添加到我的程序中。

有什么指点吗?

我认为这里使用线程是开销

您可以使用Timeout

我看到你使用两个数组来存储问题和答案,你可以用 Array#zip

压缩它

在 Ruby 中我们不喜欢 for 循环。我们使用 Array#each。顺便说一句 for 在幕后使用 each

在代码中使用全局变量可能会导致脚中弹。仅在您绝对确定需要它们时才使用它们

所以我建议像这样重构代码:

require "timeout"

correct_answers_count = 0
TIMEOUT = 30

questions.zip(answers).each do |question, right_answer|
  puts question

  user_answer = nil

  Timeout::timeout(TIMEOUT) { user_answer = gets.strip }

  if user_answer&.downcase == right_answer&.downcase
    correct_answers_count += 1
    puts "Right!"
  else
    puts "Wrong!"
  end
rescue Timeout::Error
  puts "Time is out"
end

puts "Right answers: #{correct_answers_count}"

您可以使用 timeout。通过更改 time_to_answer 设置所需的超时时间(以秒为单位),在本例中它设置为 5。

require 'timeout'

questions = [
  "2 + 2 = ?",
  "Who is Amazons CEO?",
]
answers = [
  "4",
  "Jeff Bezos",
]

def ask_question(question, answer, time_to_answer)
  puts "\n=== NEW QUESTION ==="
  puts question
  Timeout::timeout(time_to_answer) do
    user_action = gets.chomp
    return user_action === answer
  end
rescue Timeout::Error
  puts " time is up! solution: #{answer}"
  return false
end

time_to_answer = 5 # in seconds
score = 0 # initialize score
questions.each_with_index do |question, indx|
  correct = ask_question(question, answers[indx], time_to_answer)
  score += 1 if correct
  puts correct ? "✅ correct" : "❌ wrong! correct solution: #{answers[indx]}"
end

puts "\n Your score is #{score} out of #{questions.size}"