All pastes #194355 Raw Edit

Unnamed

public lua v1 · immutable
·published 2006-10-07 20:42 UTC
rendered paste body
learningBot = {}-- Choose what dictionary that should be used at startuplearningBot.startingDictionary = "default.lua"-- Some default settings in case loading the dictionary failslearningBot.options = {}learningBot.options.name = "Failed"learningBot.options.dictionary = "default.lua"learningBot.options.acceptNewWords = truelearningBot.options.maxWords = 1000learningBot.options.replaceWords = truelearningBot.options.maxOccurancesForReplace = 10learningBot.options.acceptInput = truelearningBot.data = {}learningBot.data.numWords = 0learningBot.dictionary = {}-- Handle text and update the dictionaryfunction learningBot:handleInput(sentence)	if learningBot.options.acceptInput == false then return end	-- Lowercase the sentence	sentence = string.lower(sentence)	-- Remove all punctuations	sentence = string.gsub(sentence, "%p", "")	-- Trim the string (remove spaces at the begining and the end)	sentence = string.sub(sentence, string.find(sentence, "[^%s]"), -1)	while string.char(string.byte(sentence, -1)) == " " do		sentence = string.sub(sentence, 1, -2)	end	-- Remove all double, triple etc, spaces	sentence = string.gsub(sentence, "%s%s+", " ")	local words = learningBot:explode(" ", sentence)	for k,v in pairs(words) do		-- If it's a new word, create a base template		if learningBot.dictionary[v] == nil then			if learningBot.options.acceptNewWords == true and learningBot.data.numWords < learningBot.options.maxWords then				-- Create space for the new word				learningBot.dictionary[v] = {}				learningBot.dictionary[v][1] = 0				learningBot.dictionary[v][2] = 0				learningBot.data.numWords = learningBot.data.numWords + 1			elseif learningBot.options.replaceWords == true then				-- Replace the most rarely used word				local tmpLowestOccurances = 9999				local tmpLowestKey = 1				local tmptmpOccurances = 0				for k2,v2 in pairs(learningBot.dictionary) do					tmptmpOccurances = 0					for k3,v3 in pairs(v2) do						tmptmpOccurances = tmptmpOccurances + v3					end					if tmptmpOccurances < tmpLowestOccurances then						tmpLowestOccurances = tmptmpOccurances						tmpLowestKey = k2					end				end				-- Only replace if we have a well established dictionary				if tmpLowestOccurances < learningBot.options.maxOccurancesForReplace then					-- Remove all occurances of tmpLowestKey					learningBot.dictionary[tmpLowestKey] = nil					for k2,v2 in pairs(learningBot.dictionary) do						if v2[tmpLowestKey] ~= nil then v2[tmpLowestKey] = nil end					end					-- Create space for the new word					learningBot.dictionary[v] = {}					learningBot.dictionary[v][1] = 0					learningBot.dictionary[v][2] = 0				end			end		end		if learningBot.dictionary[v] ~= nil then			-- Check if next word exists or not (sentence end)			if k ~= table.getn(words) then				if learningBot.dictionary[v][words[k+1]] == nil then learningBot.dictionary[v][words[k+1]] = 0 end				-- Increase number of occurances of the next word following this one				learningBot.dictionary[v][words[k+1]] = learningBot.dictionary[v][words[k+1]] + 1			else				if learningBot.dictionary[v][2] == nil then learningBot.dictionary[v][2] = 0 end				-- Increase number of occurances of "" following this one				learningBot.dictionary[v][2] = learningBot.dictionary[v][2] + 1			end		end	end	-- Increase number of sentence starter occurances for the first word	if learningBot.dictionary[words[1]] ~= nil then		if learningBot.dictionary[words[1]][1] == nil then learningBot.dictionary[words[1]][1] = 0 end		learningBot.dictionary[words[1]][1] = learningBot.dictionary[words[1]][1] + 1	endend-- Return a sentence constructed from the dictionary. Start with 'word' if it is declaredfunction learningBot:createSentence(word)	if word == nil then		-- max_random is used to pick a word with higher probability to get a more commonly used one (as a sentence starter)		local max_random = 0		for k,v in pairs(learningBot.dictionary) do			max_random = max_random + learningBot.dictionary[k][1]		end		random = math.random(0, max_random)		word = 1		local wordOccurance = 0		-- Get the first word		for k,v in pairs(learningBot.dictionary) do			wordOccurance = wordOccurance + learningBot.dictionary[k][1]			-- We found the word			if wordOccurance >= random then				word = k				break			end		end	end	-- Print the words until nil is returned	local sentence = ""	while word ~= nil do		sentence = sentence..word.." "		word = learningBot:pickNextWord(word)	end	sentence = string.upper(string.sub(sentence, 0, 1))..string.sub(sentence, 2, -2).."."	return sentenceend-- Return a word suited to follow 'word'. Returns nil if end of sentence is suitablefunction learningBot:pickNextWord(word)	if learningBot.dictionary[word] == nil then return end	local max_random = 0	for k,v in pairs(learningBot.dictionary[word]) do		if k ~= 1 then			max_random = max_random + v		end	end	local random = math.random(max_random)		local wordOccurance = 0	for k,v in pairs(learningBot.dictionary[word]) do		if k ~= 1 then			wordOccurance = wordOccurance + v			if wordOccurance >= random then				if k == 2 then return nil end				return k			end		end	endend-- Saves the dictionary in a seperate file and select it for further inputfunction learningBot:saveDictionary(filename)	if filename == nil then filename = learningBot.options.dictionary end	local fileString = "learningBot.options = {}\n\n"	-- Save options	learningBot.options.dictionary = filename	for k,v in pairs(learningBot.options) do		if type(v) ~= "string" then			fileString = fileString.."learningBot.options."..k.." = "..tostring(v).."\n"		else			fileString = fileString.."learningBot.options."..k.." = \""..tostring(v).."\"\n"		end	end	fileString = fileString.."\n\nlearningBot.dictionary = {}\n\n"	-- Save the dictionary, word table declaration	for k,v in pairs(learningBot.dictionary) do		fileString = fileString.."learningBot.dictionary[\""..k.."\"] = {}\n"	end	fileString = fileString.."\n\n"	-- Save dictionary, word table elements	for k,v in pairs(learningBot.dictionary) do		for k2,v2 in pairs(v) do			if type(k2) == "string" then				fileString = fileString.."learningBot.dictionary[\""..k.."\"][\""..k2.."\"] = "..v2.."\n"			else				fileString = fileString.."learningBot.dictionary[\""..k.."\"]["..k2.."] = "..v2.."\n"			end		end		fileString = fileString.."\n"	end	--local file = io.open(filename, "w+")	--file:write(fileString)	--file:close()	_file.Write("lua/lbdict/"..filename, fileString)	_Msg("Learning-Bot Dictionary ("..filename..") has been saved!\n")endfunction learningBot:loadDictionary(filename)	if filename == nil then filename = learningBot.options.dictionary end	--dofile(filename)	_OpenScript("lua/lbdict/"..filename)	-- Calculate the number of words in the dictionary	learningBot.data.numWords = 0	for k,v in pairs(learningBot.dictionary) do		learningBot.data.numWords = learningBot.data.numWords + 1	end	_Msg("Learning-Bot Dictionary ("..filename..") has been loaded!\n")endfunction learningBot:explode(d,p)	local t,ll,l	t={}	ll=0	while true do		l=string.find(p,d,ll+1,true) -- find the next d in the string		if l~=nil then -- if "not not" found then..			table.insert(t, string.sub(p,ll,l-1)) -- Save it in our array.			ll=l+1 -- save just after where we found it for searching next time.		else			table.insert(t, string.sub(p,ll)) -- Save what's left in our array.			break -- Break at end, as it should be, according to the lua manual.		end	end	return tend-- **********GMOD SPECIFIC CODE FOLLOWS HERE, keep above code as Lua universal as possible*************-- Load the default dictionary immediatelylearningBot:loadDictionary(learningBot.startingDictionary)learningBot.startingDictionary = nil-- Talks with chosen output methodfunction learningBot:talk(word)	_PrintMessageAll(HUD_PRINTTALK, learningBot.options.name..": "..learningBot:createSentence(word))endfunction learningBot:talkLocal(propid)	if _EntExists(propid) then		_GModText_Start("Default")		_GModText_SetEntity(propid)		_GModText_SetTime(4, 1, 1)		_GModText_SetText(learningBot.options.name..": "..learningBot:createSentence())		_GModText_SetEntityOffset(vector3(0, 0, 32))		_GModText_Send(0, propid)	endend-- Handles input from console command 'learnbot'function learningBot:handleCommand(userid, arg)_Msg("Check: "..arg.."\n")	if arg == nil then		_PrintMessage(userid, HUD_PRINTCONSOLE, learningBot.options.name..":\nDictionary size: "..learningBot.data.numWords.."\nAccepts input: "..tostring(learningBot.options.acceptInput).."\nAccepts new words: "..tostring(learningBot.options.acceptNewWords).."\nMax number of words allowed in dictionary: "..tostring(learningBot.options.maxWords).."\nReplaces words when dictionary is full: "..tostring(learningBot.options.replaceWords).."\nMax frequency of word to allow it being replaced: "..tostring(learningBot.options.maxOccurancesForReplace).."\n\n--Lua commands. Run with \"lua <command>\"".."\nlearningBot:saveDictionary(\"filename.lua\")".."\nlearningBot:loadDictionary(\"filename.lua\")".."\nlearningBot:talk())".."\nlearningBot:talk(\"word\"))".."\nlearningBot:handleInput(\"sentence here\")\n")	end_Msg("Check: 1\n")	local args = learningBot:explode(" ", arg)_Msg("Check: "..args[1].."\n")	if args[1] == "spawn" then		_TraceLine(_PlayerGetShootPos(userid), _PlayerGetShootAng(userid), 9999, userid)		learningBot.data.entity = _EntCreate("npc_dog")		_EntSetPos(learningBot.data.entity, vecAdd(_TraceEndPos(), vector(0,0,64)))		_EntSetName(learningBot.data.entity, "learnbot")		_EntSpawn(learningBot.data.entity)	end	if args[1] == "save" then		learningBot.saveDictionary(args[2])	elseif args[1] == "load" then		learningBot.loadDictionary(args[2])	endendCONCOMMAND("learnbot", learningBot.handleCommand)-- Speak every 4 minutesAddTimer(240, 0, learningBot.talk)-- Speak locally every 200 secondsAddTimer(200, 0, learningBot.talkLocal)-- Save the dictionary every 2 minutesAddTimer(120, 0, learningBot.saveDictionary)-- Talk when a player someone is killedHookEvent("eventPlayerKilled", function(userid, attacker, weapon) learningBot:talk() end)-- Talk when the bot's name is mentioned. Respond in some cases. Othervise, input the text into the dictionaryHookEvent("eventPlayerSay", function(userid, strText, bTeam)	-- Remove the "PlayerName: " in the string	strText = string.sub(strText, string.len(_PlayerInfo(userid, "name")) + 3)		-- Check if the bot's name is mentioned	if string.find(string.lower(strText), string.lower(learningBot.options.name)) then		words = learningBot:explode(" ", string.lower(strText))				-- Check if there's two words and the last one ends with "?"		if table.getn(words) == 2  and string.char(string.byte(words[2], -1)) == "?" then					-- Remove the "?"			words[2] = string.sub(words[2], 1, -2)			if string.find(words[1], string.lower(learningBot.options.name)) then				learningBot:talk(words[2])			else				learningBot:talk(words[1])			end		else			learningBot:talk()		end	else		learningBot:handleInput(strText)	endend)-- Check if the bot has been "used" and speak "locally" if that is the case.function learningBot:checkUse(userid, propid)    if _EntGetName(propid) == "learnbot" then        learningBot:talkLocal(propid)    endendHookEvent("eventPlayerUseEntity", learningBot.checkUse)