# Submits input asynchronously to agents, then loops through their responses # until it finds a high scoring response, or until a time limit is reached. # The alternate require paths are relative to the redturnip root directory. begin require 'gagent'; rescue LoadError; require 'mod/bot/gagent'; end #begin require 'aliceagent'; rescue LoadError; require 'mod/bot/aliceagent'; end #begin require 'mathetesagent'; rescue LoadError; require 'mod/bot/mathetesagent'; end #begin require 'wnagent'; rescue LoadError; require 'mod/bot/wnagent'; end #begin require 'linkagent'; rescue LoadError; require 'mod/bot/linkagent'; end #begin require 'megahalagent'; rescue LoadError; require 'mod/bot/megahalagent'; end #begin require 'montyagent'; rescue LoadError; require 'mod/bot/montyagent'; end #begin require 'isragent'; rescue LoadError; require 'mod/bot/isragent'; end #begin require 'lingagent'; rescue LoadError; require 'mod/bot/lingagent'; end begin require 'bcagent'; rescue LoadError; require 'mod/bot/bcagent'; end #begin require 'sumagent'; rescue LoadError; require 'mod/bot/sumagent'; end begin require 'emoagent'; rescue LoadError; require 'mod/bot/emoagent'; end class Controller attr_accessor :MY_NAME, :DEBUG, :DELAY, :SLEEP def initialize @gagent = GAgent.new(self) # port 9011 @bc = BCAgent.new(self) # port 9100 #@opp = OppAgent.new(self) # port 9120 @emo = EmoAgent.new(self) # port 9130 @agent_array = [ @gagent, @bc, @emo ] @response_array = Array.new @response_array = Array.new @THRESHOLD = 1 @SLEEP = 2 # how long the poll loop sleeps each time through @DELAY = 5 # maximum seconds to wait before returning a response @MY_NAME = "(?i)(controller|controlbot|controlagent)" @DEBUG = 0 @last_response = '' @negative_feedback = Array.new @negative_feedback.push("you suck", "that response suck") @positive_feedback = Array.new @positive_feedback.push("lol") end def check_for_preprocessing_commands(input) case input when /add (.*) (?:to|as) negative feedback/i grp1 = process $1 @negative_feedback.push(grp1) return "Okay" when /delete (.*) from negative feedback/i grp1 = process $1 @negative_feedback.delete(grp1) return "Okay" when /show negative feedback/i return @negative_feedback.join('|') when /^#{@negative_feedback.join('|')}/i return getResponse("#{@last_response[2]}: if response =~ /#{@last_response[0]}/ then score -= 1 end") when /add (.*) (?:to|as) positive feedback/i, /positive feedback: (.*)/ grp1 = process $1 @positive_feedback.push(grp1) return "Okay" when /delete (.*) from positive feedback/i grp1 = process $1 @positive_feedback.delete(grp1) return "Okay" when /^#{@positive_feedback.join('|')}$/i return getResponse("#{@last_response[2]}: if response =~ /#{@last_response[0]}/ then score += 1 end") when /show positive feedback/i return @positive_feedback.join('|') when /who said that/i, /wh.*agent.*that/ return @last_response[2].to_s end # case end # Strips delimiters. def process str str.strip! str.sub!(/\?$/, '') str.sub!(/^\[/, '') str.sub!(/\]$/, '') str.sub!(/^(?:"|')/, '') str.sub!(/(?:"|')$/, '') str.sub!(/\.$/, '') str.sub!(/;$/, '') str.sub!(/,$/, '') str.sub!(/!$/, '') str.sub!(/\?$/, '') return str end def getResponse(input = "") r = check_for_preprocessing_commands(input) #puts "r==#{r}" if r != nil then return r end @response_array = [] submitInput(input) total_seconds = 0 some_response = ["Default response from controller."] max_so_far = 0 # Keep a count to ensure that the loop executes at least once before # the top-scoring response is determined: count = 0 # Every few seconds, loop through @response_array looking for # high-scoring responses. loop { count += 1 #puts "#{@SLEEP}, #{@DELAY}" sleep(@SLEEP.to_f) #puts @response_array.inspect @response_array.each { |response| #puts "response==#{response}" score = response[1] rescue score = 1 if input =~ /#{@MY_NAME}[:,!]* (.*)/ then score += 2 end response[1] = score if max_so_far > @THRESHOLD and count > 1 @last_response = some_response #puts "1. @last_response==#{@last_response}" return some_response end if score > max_so_far some_response = response max_so_far = score next end } total_seconds += @SLEEP.to_f if total_seconds > @DELAY.to_f @last_response = some_response #puts "2. @last_response==#{@last_response}" return some_response end } end # Send input asynchronously to agents. def submitInput(input) if input =~ /#{@MY_NAME}[:,!]* (.*)/ then input = $1 end @agent_array.each { |agent| Thread.new(agent) { |myagent| myagent.send(input) } # if input =~ an agent name, send it to that agent only # begin # if input =~ /#{agent.MY_NAME}[:,!]* / then break end # rescue # puts "error!" # end } end # Callback for agents. def addResponse(response) if response.size == 2 then response.push("unknown") end #puts "addResponse called with: #{response}" @response_array.push(response) end end if $0 == __FILE__ c = Controller.new print "\n> "; $stdout.flush quitwords = [":q", "quit", "exit", "bye"] while (line = gets) !~ /^#{quitwords.join('|')}$/ and line !~ /^$/ response = c.getResponse(line.to_s).to_s + "\n\n" print "\n#{response}" print "> "; $stdout.flush end puts "Bye" end