Last active
August 29, 2015 14:25
-
-
Save DataKinds/f9189a29d3f9702448af to your computer and use it in GitHub Desktop.
cinch markov bot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'cinch' | |
require 'cinch/plugins/identify' | |
require 'json' | |
LOOKFORWARD = 2 #how many words forward it generates from a seed word | |
BOTNAME = "MarkovBot" | |
def prepareString(str) | |
#return str.downcase.split(/(\W)+/).map{|word| word.gsub(/\s+/, "")}.reject{|word| word == ""} to remind you what it was | |
return str.split(/\s+/) | |
end | |
def addArrayToChain(strArray, chain) | |
strArray.each_with_index do |currentStr, index| | |
doneWithString = false | |
LOOKFORWARD.times do |t| | |
if strArray[index + t + 1].nil? | |
doneWithString = true | |
end | |
end #break if no more strings can be found up ahead | |
break if doneWithString | |
nextStringsArray = [] #make an array of the next strings | |
LOOKFORWARD.times do |t| nextStringsArray << strArray[index + t + 1] end | |
nextStrings = nextStringsArray.join(" ") | |
if !chain.key?(currentStr) | |
chain[currentStr] = {} | |
end | |
if !chain[currentStr].key?(nextStrings) | |
chain[currentStr][nextStrings] = 0 | |
end | |
chain[currentStr][nextStrings] += 1 | |
end | |
File.open("markovbackup.rson", "w") { |file| file.write(JSON.generate(chain)) } | |
return chain | |
end | |
def generateWords(chain, length, topic) | |
topicWords = topic.split(/\s+/).reject{|word| word.include? BOTNAME}.sort_by(&:length).select{|word| word.length > 2} #select suitable-looking words for the bot to talk about | |
topicWord = chain.keys.sample #fallback to a random topic | |
topicWords.each do |word| #try to make the bot talk about them | |
if !chain[word].nil? | |
topicWord = word | |
break | |
end | |
end | |
outputString = [] | |
outputString << topicWord #put the first seed word in | |
length.times do |currentLength| | |
lastWord = outputString.last.split(" ").last #this is gross, splits the last phrase to get the last word to use as the next seed | |
break if chain[lastWord].nil? #if there aren't words to complete the phrase | |
chanceTable = chain[lastWord] | |
cdf = 0 #calculating the weighted random, warning: gross | |
chanceTable.each do |weight| | |
cdf += weight[1] | |
end | |
randomInt = rand(cdf) | |
runningSum = 0 | |
chanceTable.each_pair do |word, weight| | |
runningSum += weight | |
if runningSum > randomInt | |
outputString << word | |
break | |
end | |
end | |
end | |
return outputString.join(" ") | |
end | |
class MarkovIRC | |
include Cinch::Plugin | |
match /.+/, use_prefix: false #run on anything said | |
def execute(m) | |
@@permChain = addArrayToChain(prepareString(m.message), @@permChain) | |
if m.message.include? BOTNAME | |
if m.channel.name != "#roblox-bots" | |
Target(m.user.nick).send("#{generateWords(@@permChain, rand(5)+20, m.message)}") | |
else | |
m.reply("#{m.user.nick}: #{generateWords(@@permChain, rand(5)+20, m.message)}") | |
#m.reply("NotBoringAces: #{generateWords(@@permChain, rand(5)+20, m.message)}") | |
end | |
end | |
end | |
end | |
bot = Cinch::Bot.new do | |
configure do |c| | |
c.server = "irc.freenode.org" | |
c.nick = BOTNAME | |
c.channels = ["#roblox-bots", "#roblox"] | |
c.delay_joins = :identified | |
c.plugins.plugins = [MarkovIRC, Cinch::Plugins::Identify] | |
c.plugins.options[Cinch::Plugins::Identify] = { | |
:username => "Aearnus", | |
:password => <dfnsdikfnsdk>, | |
:type => :nickserv | |
} | |
end | |
end | |
@@permChain = JSON.parse(File.read("markovbackup.rson")) | |
sampleText = File.read("sampletext") | |
@@permChain = addArrayToChain(prepareString(sampleText), @@permChain) | |
bot.start |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment