new plugin for markov-chain chat inanity :)
[rbot] / data / rbot / plugins / markov.rb
1 class MarkovPlugin < Plugin
2   def initialize
3     super
4     @registry.set_default([])
5     @lastline = false
6   end
7
8   def markov(m, params)
9     # limit to max of 50 words
10     return unless @lastline
11     word1, word2 = @lastline.split(/\s+/)
12     output = word1 + " " + word2
13     50.times do
14       wordlist = @registry["#{word1}/#{word2}"]
15       word3 = wordlist[rand(wordlist.length)]
16       break if word3 == :nonword
17       output = output + " " + word3
18       word1, word2 = word2, word3
19     end
20     m.reply output
21   end
22   
23   def help(plugin, topic="")
24     "markov plugin: listens to chat to build a markov chain, with which it can (perhaps) attempt to (inanely) contribute to 'discussion'. Sort of.. Will get a *lot* better after listening to a lot of chat. usage: 'markov' to attempt to say something relevant to the last line of chat, if it can."
25   end
26   
27   def cleanup(s)
28     str = s.dup
29     str.gsub!(/^.+:/, "")
30     str.gsub!(/^.+,/, "")
31     return str.strip
32   end
33
34   def listen(m)
35     return unless m.kind_of?(PrivMessage) && m.public?
36     return if m.address?
37     message = cleanup m.message
38     # in channel message, the kind we are interested in
39     wordlist = message.split(/\s+/)
40     return unless wordlist.length > 2
41     @lastline = message
42     word1, word2 = :nonword, :nonword
43     wordlist.each do |word3|
44       @registry["#{word1}/#{word2}"] = @registry["#{word1}/#{word2}"].push(word3)
45       word1, word2 = word2, word3
46     end
47     @registry["#{word1}/#{word2}"] = [:nonword]
48   end
49 end
50 plugin = MarkovPlugin.new
51 plugin.map 'markov'