ika_bot/lib/drill.rb

136 lines
3.3 KiB
Ruby
Raw Normal View History

2025-08-28 21:02:26 -04:00
require "rufus-scheduler"
2025-08-19 21:07:51 -04:00
class Drill
2025-08-28 21:02:26 -04:00
attr_reader :responder, :current_question, :scheduler
attr_accessor :length, :participants, :timer_job_id
def initialize(responder: nil, scheduler: Rufus::Scheduler.new)
@responder = responder
@participants = []
@length = "10m"
@running = false
@scheduler = scheduler
@time_is_up = false
end
def respond(response)
responder.call response
end
def can_handle_message?(message)
true
end
2025-08-23 14:38:42 -04:00
2025-08-28 21:02:26 -04:00
ACTIONS = %w[join leave start stop]
CUSTOMIZATIONS = %w[length]
2025-08-19 21:07:51 -04:00
2025-08-28 21:02:26 -04:00
def handle_message(message)
if ACTIONS.include? message.content
return send("handle_#{message.content.downcase}", message)
elsif customization = CUSTOMIZATIONS.find { |c| message.content.start_with?("#{c} ") }
return send("handle_customize_#{customization}", message)
end
return unless running?
return unless message.author == current_question_target
handle_question_response(message)
2025-08-19 21:07:51 -04:00
end
2025-08-28 21:02:26 -04:00
def handle_join(message)
return respond "The drill's already started!" if running?
2025-08-28 21:02:26 -04:00
if participants.include? message.author
respond "You've already joined"
else
self.participants << message.author
respond "#{message.author.display_name} has joined"
end
2025-08-23 14:38:42 -04:00
end
2025-08-28 21:02:26 -04:00
def handle_leave(message)
return respond "The drill's already started!" if running?
2025-08-28 21:02:26 -04:00
if participants.include? message.author
self.participants -= [message.author]
respond "#{message.author.display_name} has left"
else
respond "You aren't a participant"
end
2025-08-19 21:07:51 -04:00
end
2025-08-28 21:02:26 -04:00
def handle_start(message)
return respond "The drill's already started!" if running?
return respond "Nobody has joined the drill! Type `join` to join it!" if participants.empty?
2025-08-28 21:02:26 -04:00
@running = true
@time_is_up = false
self.timer_job_id = scheduler.in(length){ @time_is_up = true }
respond "Drill started!"
participants.shuffle!
next_question!
2025-08-19 21:07:51 -04:00
end
2025-08-28 21:02:26 -04:00
def handle_stop(message)
return respond "The drill's not running yet" unless running?
scheduler.unschedule(timer_job_id) if timer_job_id
end_drill!
2025-08-28 21:02:26 -04:00
end
def handle_customize_length(message)
return respond "The drill's already started!" if running?
cmd, desired_length = message.content.split
return respond "Please specify a length" unless desired_length
self.length = desired_length
respond "Drill length set to #{desired_length}"
2025-08-19 21:07:51 -04:00
end
2025-08-28 21:02:26 -04:00
def handle_question_response(message)
if current_question.correct_answer == message.content
respond "Correct!"
2025-08-23 14:38:42 -04:00
else
2025-08-28 21:02:26 -04:00
respond "Incorrect: #{current_question.correct_answer}"
2025-08-19 21:07:51 -04:00
end
2025-08-28 21:02:26 -04:00
next_question!
end
def next_question!
return end_drill! if time_is_up?
self.participants = participants.rotate
generate_question
respond "#{current_question_target.display_name}: #{current_question.question_text}"
end
def end_drill!
respond "Time's up! Everyone did great!"
@running = false
@participants = []
2025-08-28 21:02:26 -04:00
end
def generate_question
value = (1..100).to_a.sample
@current_question = OpenStruct.new(
question_text: "Type the number #{value}",
correct_answer: value.to_s
)
end
def current_question_target
participants.first
2025-08-23 14:38:42 -04:00
end
2025-08-19 21:07:51 -04:00
2025-08-28 21:02:26 -04:00
def running?
@running
2025-08-23 14:38:42 -04:00
end
2025-08-19 21:07:51 -04:00
2025-08-28 21:02:26 -04:00
def time_is_up?
@time_is_up
2025-08-19 21:07:51 -04:00
end
end