While refactoring this code i learned that this was not using the look up table correctly and just randomly selecting words from it. This is not an AI my apologizes.
I will leave the original post as it was bellow this edit.
[/edit]
Ok so AI is a slight over statement this program is designed to learn from you and talk to yo.
the program comes with no no words in its dictionary and cant save so it will lose all words when it resets.
Instructions
talk to he say hello discuss the weather what ever you say to it will make it smarter.
Note: thanks to immibis it have save system now
Version 4 with save system by immibis
*NEW* now saves conversation in convo file.
[EXPERIMENTAL]
this latest it can read information from files and add it to its memory
start it with a parth to a folder that contains the stuff you want it to read
example
AI books
would read all test documents in the folder named "books" on the computers HDDhttp://pastebin.com/BdtQCH4a
[/EXPERIMENTAL]
[STABLE]
http://pastebin.com/Bpqpcv9j
pastebin get Bpqpcv9j AI
Spoiler
--[[
Brain Damage Algorithm BDA for short
Emulates drunk or brain damaged persons speech patterns
Devloped By BigSHinyToys
http://www.computercraft.info/forums2/index.php?/topic/3546-fun-ai-learning-program-that-can-talk/
]]--
local winX,winY = term.getSize()
local length = 8
local tDictionary = {}
local shado = {}
local savefile = "words"
local convofile = "convo"
local function saveTalk(sentence)
local f = fs.open(convofile, "a")
f.write(sentence.."n")
f.close()
end
local function save()
local f = fs.open(savefile, "w")
f.write(textutils.serialize({tDictionary, shado}))
f.close()
end
if fs.exists(savefile) then
local f = fs.open(savefile, "r")
local save = textutils.unserialize(f.readAll())
f.close()
tDictionary = save[1]
shado = save[2]
end
local function dataAI()
local lastTimer = os.startTimer(math.random(1,120))
while true do
local event,arg1,arg2,arg3 = os.pullEvent()
if event == "new_line" or event == "timer" then
if event == "timer" then
if arg1 == lastTimer then
lastTimer = os.startTimer(math.random(1,120))
end
arg1 = ""
end
local sLine = arg1
local tWords = {}
for match in string.gmatch(sLine, "[^ t]+") do
table.insert( tWords, match )
end
for i = 1,#tWords do
if tDictionary[tWords[i]] then
table.insert(tDictionary[tWords[i]]["to"],tWords[i])
else
table.insert(shado,tWords[i])
tDictionary[tWords[i]] = {}
tDictionary[tWords[i]]["name"] = tWords[i]
tDictionary[tWords[i]]["to"] = {}
end
end
local test = ""
local last = nil
for i = 1,math.random(1,length) do
if last then
if #tDictionary[last]["to"] and #tDictionary[last]["to"] > 0 then
sNext = tDictionary[last]["to"][math.random(1,#tDictionary[last]["to"])]
if sNext ~= last then
test = test..sNext.." "
last = sNext
else
last = tDictionary[shado[math.random(1,#shado)]]["name"]
test = test..last.." "
end
else
last = tDictionary[shado[math.random(1,#shado)]]["name"]
test = test..last.." "
end
else
last = tDictionary[shado[math.random(1,#shado)]]["name"]
test = test..last.." "
end
end
term.scroll(1)
term.setCursorPos(1,winY - 1)
term.clearLine()
save()
saveTalk("AI> "..test)
print("AI> "..test)
end
end
end
local function userInput()
while true do
term.setCursorPos(1,winY)
term.clearLine()
local input = read()
saveTalk(input)
os.queueEvent("new_line",input)
end
end
term.clear()
parallel.waitForAny(userInput,dataAI)
NitrogenFingers ver with grammar and immibis save system
*New* with conversation save ver 2
http://pastebin.com/pTKpFVJN
pastebin get pTKpFVJN GrammarAI
Spoiler
--[[
BDA: Brain Damaged Algorithm
A natural language parsing and attempting to creating program
Written by: BigSHinyToys
Modified by: NitrogenFingers 28/8/2012 (12:20am)
--]]
local winX, winY = term.getSize()
--Add your stop word lists here- they can be common subjects, participles, or any other grammatical
--feature you'd like to capture. Denote it with a single, lowercase character- this indicates it is a
--terminating symbol
local stopWords = {
["s"] = {"I", "you", "he", "she", "they", "we"};
["v"] = {"is", "are", "am", "can be", "like", "hate", "often", "will", "must", "should", "might"};
["a"] = {"and", "or", ", also", ", but", ", however", "like"};
}
--This list is of words that aren't stop words- they'll be added as you type them
local vocab = {}
local vcLength = 0
local savefile = "Grammerwords"
local convofile = "Grammerconvo"
local function saveTalk(sentence)
local f = fs.open(convofile, "a")
f.write(sentence.."n")
f.close()
end
local function save()
local f = fs.open(savefile, "w")
f.write(textutils.serialize(vocab))
f.close()
end
if fs.exists(savefile) then
local f = fs.open(savefile, "r")
local save = textutils.unserialize(f.readAll())
f.close()
vocab = save
end
--Here you should have tables with capital letters, your non-terminating characters, that include
--all possible rules for your grammar. These tokens will in turn be selected and randomly replaced
--with one of the contents of the table.
--Note: AVOID INFINITE LOOPS: make sure every possible grammar has a terminating-only character string.
local grammar = {
["S"] = {"svW"},
["W"] = {"waW", "wasW", "w"}
}
function readWords()
while true do
local arg1, arg2 = os.pullEvent("new_line")
if arg1 == "new_line" then
local lastMatch = ""
for match in string.gmatch(arg2, "[^ t]+") do
local stop = false
for _,list in pairs(stopWords) do
for _,stopword in pairs(list) do
--If you want to be supersmart you can try to detect stop words and add them
--to your list here- try looking for "ly" for adverbs, "ing" for present tense verbs
--etc.
if match == stopword then
stop = true
break
end
end
end
if not stop then
--We handle linkages here
if not vocab[match] then
--I must admit I'm unsure how to get just the key in a table (there must be a way)
--Anyway I just include the word itself as the first value in the value table. Cheap and dusty.
vocab[match] = {match, ""}
--And of course because it's a string indexed value now it's not included in the array, or the length!
vcLength = vcLength+1
end
if lastMatch ~= "" then
table.insert(vocab[lastMatch], match)
end
lastMatch = match
else
lastMatch = ""
end
end
end
local newGrammar = "S"
local found = false
--This randomly creates your grammar
repeat
found = false
for k,v in pairs(grammar) do
local f = string.find(newGrammar, k)
if f then
newGrammar = string.gsub(newGrammar, k, v[math.random(1, #v)], 1)
found = true
end
end
until not found
--This then randomly replaces your grammar with actual words
local newSentence = ""
for i=1,#newGrammar do
local token = string.sub(newGrammar, i, i)
if token == "w" then
--This is horribly messy- will fix when less tired!
local chosenWord = math.random(1,vcLength)
local i=1
for k,_ in pairs(vocab) do
if i==chosenWord then
chosenWord = k
break
end
i=i+1
end
local chosenLink = vocab[chosenWord][math.random(2,#vocab[chosenWord])]
if chosenLink ~= "" then chosenLink = chosenLink.." " end
--Again cheap and dusty here, the extra space will make sentences look a bit ugly. Requires a little tweaking, but I'm to tired to fix right now.
newSentence=newSentence..vocab[chosenWord][1].." "..chosenLink
else
local newstop = stopWords[token][math.random(1,#stopWords[token])]
--Cheap and dusty (lots of it in this program!) to get rid of extra space
if string.sub(newstop, 1, 1)=="," then newSentence = string.sub(newSentence, 1, #newSentence-1) end
newSentence=newSentence..newstop.." "
end
end
term.scroll(1)
term.setCursorPos(1,winY - 1)
term.clearLine()
save()
local talk = "AI> "..string.sub(newSentence, 1, #newSentence-1).."."
saveTalk(talk)
print(talk)
end
end
function getInput()
while true do
term.setCursorPos(1,winY)
term.clearLine()
local input = read()
saveTalk(input)
os.queueEvent("new_line",input)
end
end
term.clear()
parallel.waitForAny(getInput, readWords)
and remember it will say what you say swear at it it might swear back lol XD