diff --git a/app.js b/app.js index 52af542..b504870 100644 --- a/app.js +++ b/app.js @@ -195,6 +195,7 @@ let kara = new Vue({ } }, getReaction(message) { + let preserveLastMessageData = false; message = this.cleanupMessage(message); let keywords = message.split(' '); @@ -210,7 +211,53 @@ let kara = new Vue({ return false; } - this.lastMessageData = {}; + if (this.lastMessageData.isJeopardy) { + if (this.includesAllOf(keywords, ['give', 'up'])) { + this.lastMessageData = {}; + return 'The right question would have been: "' + this.lastMessageData.question + '"'; + } + + if (this.isSimilar(message, this.lastMessageData.question)) { + this.lastMessageData = {}; + return this.oneOf([ + 'Wow! This is the right question.', + 'Correct!' + ]); + } else { + return this.oneOf([ + "Sorry, that's not correct.", + "That's not what we're searching for.", + "Nope, sorry. You can always give up by typing \"I give up\" if you wan't to.", + ]); + } + } + + if (this.lastMessageData.isTrivia) { + if (this.includesAllOf(keywords, ['give', 'up'])) { + this.lastMessageData = {}; + return this.oneOf([ + 'The right answer would have been: "' + this.lastMessageData.question + '"' + ]); + } + + if (this.isSimilar(message, this.lastMessageData.answer)) { + this.lastMessageData = {}; + return this.oneOf([ + 'Congratulations! This is the correct answer.', + 'Correct!' + ]); + } else { + return this.oneOf([ + "Sorry, that's not correct.", + "That's not what we're searching for.", + "Nope, sorry. You can always give up by typing \"I give up\" if you wan't to.", + ]); + } + } + + if (!preserveLastMessageData) { + this.lastMessageData = {}; + } if (this.includesAllOf(keywords, ['change', 'my', 'name'])) { this.askedForName = true; @@ -324,7 +371,7 @@ let kara = new Vue({ return answer; } - this.getBackupAnswer(message); + this.botMessage("I don't know what to say.."); }, // Forms @@ -339,7 +386,7 @@ let kara = new Vue({ }, // Commands - processCommands(message) { + processCommands: function (message) { if (this.checkForCommands(message, 'note')) { let noteToSave = this.checkForCommands(message, 'note'); this.saveNote(noteToSave); @@ -375,6 +422,14 @@ let kara = new Vue({ this.getRandomBirb(); } + if (this.checkForCommands(message, 'quiz')) { + this.getRandomTriviaQuestion(); + } + + if (this.checkForCommands(message, 'jeopardy')) { + this.startJeopardy(); + } + this.lastMessage = message; }, checkForCommands(message, commands) { @@ -421,20 +476,6 @@ let kara = new Vue({ this.updateStorage(); }, - getBackupAnswer(message) { - let vue = this; - let url = 'https://some-random-api.ml/chatbot?message=' + message; - - axios.get(url) - .then(function (response) { - vue.botMessage(response.data.response); - }) - .catch(function (error) { - vue.botMessage("I don't know what to say.."); - }) - - this.updateStorage(); - }, getRandomMeme(category = 'memes') { let vue = this; let url = 'https://meme-api.herokuapp.com/gimme/'; @@ -573,6 +614,50 @@ let kara = new Vue({ this.updateStorage(); }, + getRandomTriviaQuestion() { + let vue = this; + let url = 'https://jservice.io/api/random'; + + axios.get(url) + .then(function (response) { + let clue = response.data[0]; + + vue.botMessage('Okay! Here is your question from the category "' + clue.category.title + '":'); + vue.botMessage(clue.question); + + vue.lastMessageData = { + isTrivia: true, + answer: clue.answer + }; + }) + .catch(function (error) { + vue.botMessage("It's not a good time for a quiz."); + }); + + this.updateStorage(); + }, + startJeopardy() { + let vue = this; + let url = 'https://jservice.io/api/random'; + + axios.get(url) + .then(function (response) { + let clue = response.data[0]; + + vue.botMessage('Okay! Here we go. The category is "' + clue.category.title + '":'); + vue.botMessage(clue.answer); + + vue.lastMessageData = { + isJeopardy: true, + question: clue.question + }; + }) + .catch(function (error) { + vue.botMessage("It's not a good time for a quiz."); + }); + + this.updateStorage(); + }, // Notes saveNote(message) { @@ -748,6 +833,55 @@ let kara = new Vue({ }).catch((error) => { console.log(error); }); + }, + + // Levenshtein distance + isSimilar(message1, message2) { + let longer = message1; + let shorter = message2; + + if (message1.length < message2.length) { + longer = message2; + shorter = message1; + } + + const longerLength = longer.length; + if (longerLength === 0) { + return 1.0; + } + + let similarity = (longerLength - this.editDistance(longer, shorter)) / parseFloat(longerLength); + + return similarity > 0.65; + }, + + editDistance: function (message1, message2) { + message1 = message1.toLowerCase(); + message2 = message2.toLowerCase(); + + let costs = []; + for (let i = 0; i <= message1.length; i++) { + let lastValue = i; + for (let j = 0; j <= message2.length; j++) { + if (i === 0) + costs[j] = j; + else { + if (j > 0) { + let newValue = costs[j - 1]; + if (message1.charAt(i - 1) !== message2.charAt(j - 1)) + newValue = Math.min(Math.min(newValue, lastValue), + costs[j]) + 1; + costs[j - 1] = lastValue; + lastValue = newValue; + } + } + } + if (i > 0) { + costs[message2.length] = lastValue; + } + } + + return costs[message2.length]; } } }) \ No newline at end of file