summaryrefslogtreecommitdiff
path: root/data/rbot/plugins/markov.rb
blob: fc6658d27e33103574e5610a303bdf649faeb70b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
class MarkovPlugin < Plugin
  def initialize
    super
    @registry.set_default([])
    @lastline = false
    @enabled = false
  end

  def get_line
    # limit to max of 50 words
    return unless @lastline
    word1, word2 = @lastline.split(/\s+/)
    output = word1 + " " + word2
    50.times do
      wordlist = @registry["#{word1}/#{word2}"]
      word3 = wordlist[rand(wordlist.length)]
      break if word3 == :nonword
      output = output + " " + word3
      word1, word2 = word2, word3
    end
    return output
  end

  def markov(m, params)
    m.reply get_line
  end
  
  def help(plugin, topic="")
    "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."
  end
  
  def clean_str(s)
    str = s.dup
    str.gsub!(/^.+:/, "")
    str.gsub!(/^.+,/, "")
    return str.strip
  end

  def enable(m, params)
    @enabled = true
    m.okay
  end

  def disable(m, params)
    @enabled = false
    m.okay
  end

  def should_talk
    return false unless @enabled
    # 50:50
    return false if rand(2) == 1
    return true
  end

  def random_markov(m)
    return unless should_talk
    line = get_line
    puts "got line #{line}"
    m.reply line unless line == @lastline
  end

  def listen(m)
    return unless m.kind_of?(PrivMessage) && m.public?
    return if m.address?
    message = clean_str m.message
    # in channel message, the kind we are interested in
    wordlist = message.split(/\s+/)
    return unless wordlist.length > 2
    @lastline = message
    word1, word2 = :nonword, :nonword
    wordlist.each do |word3|
      @registry["#{word1}/#{word2}"] = @registry["#{word1}/#{word2}"].push(word3)
      word1, word2 = word2, word3
    end
    @registry["#{word1}/#{word2}"] = [:nonword]
    random_markov(m)
  end
end
plugin = MarkovPlugin.new
plugin.map 'markov enable', :action => "enable"
plugin.map 'markov disable', :action => "disable"
plugin.map 'markov'