class ChatBot {
/*
let chatbot:ChatBot = ChatBot(logParamLim: 5)
chatbot.addParam("name", "jinpachi")
chatbot.addParam("name", "sakura")
chatbot.addParam("verb", "eat")
chatbot.addParam("verb", "code")
chatbot.addSentence("i can verb #")
chatbot.learnParam("ryu is a name")
chatbot.learnParam("ken is a name")
chatbot.learnParam("drink is a verb")
chatbot.learnParam("rest is a verb")
chatbot.learnV2("hello ryu i like to code")
chatbot.learnV2("greetings ken")
for _ in 0...10{
print(chatbot.talk())
}
*/
var sentences = RefreshQ()
var wordToList = [String: RefreshQ]()
private var regexUtil = RegexUtil()
var allParamRef = [String: String]()
var paramLim = 5
var loggedParams = RefreshQ()
private var conjuration = "is a"
init(logParamLim: Int) {
loggedParams.setLimit(lim: logParamLim)
}
func setConjuration(_ conjuration: String) {
self.conjuration = conjuration
}
func setSentencesLim(_ lim: Int) {
sentences.setLimit(lim: lim)
}
func setParamLim(_ paramLim: Int) {
self.paramLim = paramLim
}
func getWordToList() -> [String: RefreshQ] {
return wordToList
}
func talk() -> String {
let result = sentences.getRndItem()
return clearRecursion(result)
}
private func clearRecursion(_ result: String) -> String {
var tempResult:String = result
var params = [String]()
params = regexUtil.extractAllRegexResults(regex: "(\\w+)(?= #)", text: result)
for strI in params {
guard let temp = wordToList[strI] else { continue }
let s1 = temp.getRndItem()
tempResult = tempResult.replacingOccurrences(of: strI + " #", with: s1)
}
if !tempResult.contains("#") {
return tempResult
} else {
return clearRecursion(tempResult)
}
}
func addParam(_ category: String, _ value: String) {
if !(wordToList.keys.contains(category)) {
let temp = RefreshQ()
temp.setLimit(lim: paramLim)
wordToList[category] = temp
}
wordToList[category]?.input(in1: value)
allParamRef[value] = category
}
// same as the addParam but only the latest parameter is saved
// used for topics, names, cases where 1 latest parameter is needed
func addSubject(_ category: String, _ value: String) {
if !(wordToList.keys.contains(category)) {
let temp = RefreshQ()
temp.setLimit(lim: 1)
wordToList[category] = temp
}
wordToList[category]?.input(in1: value)
allParamRef[value] = category
}
func addParam(_ kv: AXKeyValuePair) {
if !(wordToList.keys.contains(kv.getKey())) {
let temp = RefreshQ()
temp.setLimit(lim: paramLim)
wordToList[kv.getKey()] = temp
}
wordToList[kv.getKey()]?.input(in1: kv.getValue())
allParamRef[kv.getValue()] = kv.getKey()
}
func addSentence(_ sentence: String) {
sentences.input(in1: sentence)
}
func learn(_ s1: String) {
var s1 = " " + s1
for key in wordToList.keys {
s1 = s1.replacingOccurrences(of: " " + key, with: " \(key) #")
}
sentences.input(in1: s1.trimmingCharacters(in: .whitespaces))
}
@discardableResult
func learnV2(_ s1: String) -> Bool {
let OGStr = s1
var s1 = " " + s1
for key in allParamRef.keys {
s1 = s1.replacingOccurrences(of: " " + key, with: " \(allParamRef[key]!) #")
}
s1 = s1.trimmingCharacters(in: .whitespaces)
if OGStr != s1 {
sentences.input(in1: s1)
return true
}
return false
}
func learnParam(_ s1: String) {
guard s1.contains(conjuration) else { return }
let category = regexUtil.afterWord(word: conjuration, str2Check: s1)
guard wordToList.keys.contains(category) else { return }
let param = s1.replacingOccurrences(of: conjuration + " " + category, with: "").trimmingCharacters(in: .whitespaces)
wordToList[category]?.input(in1: param)
allParamRef[param] = category
loggedParams.input(in1: s1)
}
// add key value pair collected by an AXPrompt object
func addParamFromAXPrompt(_ kv: AXKeyValuePair) {
if !(wordToList.keys.contains(kv.getKey())) {
return
}
wordToList[kv.getKey()]?.input(in1: kv.getValue())
allParamRef[kv.getValue()] = kv.getKey()
}
// load entire RefreshQ of parameters
// example : list of nicknames per name
// this special use case requires a specialized Object to retain
// a set topic(name) and {category, param1#param2#...}(converted into a que)
func addRefreshQ(_ category: String, _ q1: RefreshQ) {
if !(wordToList.keys.contains(category)) {
return
}
wordToList[category]! = q1
}
func getALoggedParam() -> String {
return loggedParams.getRndItem()
}
}