Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
PTriviaBot - QuizEngine.rb

QuizEngine.rb

Caricato da: Piero Tofy
Scarica il programma completo

  1. # Quiz Engine class
  2. # This class takes care of handling quiz questions
  3.  
  4. require './IrcSocket'
  5. require 'csv'
  6. require 'thread'
  7. require 'yaml'
  8. require './Language'
  9. include PLanguageSupport
  10.  
  11. module PTriviaBot
  12. class QuizEngine
  13.   def initialize(questionsFile, scoreFile, delegate, secsbetweenquestions, secstoanswer)
  14.     puts t(:initializing_quiz_engine)
  15.     @questionsFile = questionsFile
  16.     @scoreFile = scoreFile
  17.     @delegate = delegate
  18.     @quizrunning = false
  19.     @questionCount = 0
  20.     @secsbetweenquestions = secsbetweenquestions.to_i
  21.     @secstoanswer = secstoanswer.to_i
  22.     @answers = {}
  23.     @singlequestionrunning = false
  24.  
  25.     loadquestions
  26.     puts t(:loaded_questions, @questions.length.to_s)
  27.  
  28.     loadscores
  29.     puts t(:loaded_scores_database)
  30.   end
  31.  
  32.   def loadscores
  33.     begin
  34.       @scores = YAML::load(File.open(@scoreFile,'r')) || Hash.new
  35.     rescue
  36.       puts t(:exception_no_score_file_exists, @scoreFile)
  37.       @scores = Hash.new
  38.     end
  39.   end
  40.  
  41.   def savescores
  42.     File.open(@scoreFile, 'w') do |out|
  43.        YAML.dump(@scores, out)
  44.     end
  45.   end
  46.  
  47.   def loadquestions
  48.     @questions = []
  49.     CSV.parse(File.open(@questionsFile,'rb')) do |row|
  50.       @questions.push(row)
  51.     end
  52.   end
  53.  
  54.   def startquiz
  55.     if !@quizrunning
  56.       puts t(:starting_a_new_quiz)
  57.       @questionCount = 0
  58.       @delegate.sendmessagetoall('<font color="darkgreen">' + t(:a_new_quiz_is_about_to_begin) + '</font>')
  59.  
  60.       @quizrunning = true
  61.       Thread.new {quizloop()}
  62.     end
  63.   end
  64.  
  65.   def stopquiz
  66.     @quizrunning = false
  67.  
  68.     @delegate.sendmessagetoall('<font color="darkred">' + t(:the_quiz_has_been_stopped) + '</font>')
  69.   end
  70.  
  71.   def quizloop
  72.     while @quizrunning
  73.  
  74.       # Skip wait time if this is a single question
  75.       if !@singlequestionrunning
  76.         @delegate.sendmessagetoall(t(:new_question_in_seconds,@secsbetweenquestions))
  77.         sleep @secsbetweenquestions
  78.       end
  79.      
  80.       @answers.clear #Reset answers
  81.  
  82.       # Double check for stop command
  83.       break unless @quizrunning
  84.  
  85.       # Increase question count
  86.       @questionCount += 1
  87.  
  88.       # Fetch question ID
  89.       @currentQuestionID = getrandomquestionid
  90.  
  91.       # Retrieve actual question
  92.       @question = getquestion(@currentQuestionID)
  93.  
  94.       # Send question text
  95.       @delegate.sendmessagetoall("<b>#{@questionCount}. #{@question[0]}</b>")
  96.  
  97.       # Send answers
  98.       choice = 'A'
  99.       for i in  1..@question.length-2 do
  100.         @delegate.sendmessagetoall("    (#{choice}) #{@question[i]}")
  101.         choice = choice.succ # A-->B-->C-->...
  102.       end
  103.       @delegate.sendmessagetoall(" ")
  104.  
  105.       # Wait for answers
  106.       sleep @secstoanswer/3*2
  107.  
  108.       # Double check for stop command
  109.       break unless @quizrunning
  110.  
  111.       secsremaining = @secstoanswer/3
  112.       @delegate.sendmessagetoall(t(:seconds_left_to_answer,secsremaining))
  113.  
  114.       sleep secsremaining
  115.  
  116.       # Double check for stop command
  117.       break unless @quizrunning
  118.  
  119.       # That's it!
  120.       @delegate.sendmessagetoall(t(:time_is_over))
  121.  
  122.       # Reveal answer
  123.       rightanswer = @question.last
  124.       rightanswerchar = indextoanswer(rightanswer.to_i)
  125.       @delegate.sendmessagetoall('<b>' + t(:correct_answer) + ': <font color="darkgreen">' + rightanswerchar + '</font></b>')
  126.  
  127.       # Evaluate results...
  128.       @answers.each_pair do |nick, answerID|
  129.         @scores[nick] = 1500 unless @scores.has_key?(nick) #First time somebody answered?
  130.  
  131.         previousscore = @scores[nick]
  132.  
  133.         puts t(:comparing_with, answerID, rightanswer)
  134.  
  135.         if answerID.to_s == rightanswer.to_s
  136.           @scores[nick] += 10
  137.           netchange = '+ 10'
  138.         else
  139.           @scores[nick] -= 10
  140.           netchange = '- 10'
  141.         end
  142.         answergiven = indextoanswer(answerID)
  143.  
  144.         @delegate.sendmessagetoall(t(:user_answered,nick,previousscore,netchange,answergiven))
  145.       end
  146.  
  147.       # Save results
  148.       savescores
  149.  
  150.       # If this was a single question, exit
  151.       if @singlequestionrunning
  152.         @quizrunning = false
  153.         @singlequestionrunning = false
  154.       end
  155.     end
  156.   end
  157.  
  158.   def askquestion
  159.     if !@singlequestionrunning and !@quizrunning
  160.       @singlequestionrunning = true
  161.       @quizrunning = true
  162.       Thread.new {quizloop()}
  163.     end
  164.   end
  165.  
  166.   def indextoanswer(index)
  167.     ('A'[0].ord + index).chr
  168.   end
  169.  
  170.   def getrandomquestionid
  171.     rand(@questions.length)
  172.   end
  173.  
  174.   def getquestion(id)
  175.     @questions[id]
  176.   end
  177.  
  178.   def giveanswer(nickname, answer)
  179.     @answers[nickname] = answer.upcase[0].ord - 'A'[0].ord unless @answers.has_key?(nickname)
  180.     puts t(:answers_to_question,nickname,answer)
  181.   end
  182.  
  183.   attr_accessor :quizrunning, :scores
  184. end
  185. end