/ AI.js
AI.js
1 (function(g,Ai) { 2 if (typeof module!="undefined") { 3 module.exports=Ai; 4 }else{ 5 g.Ai=Ai; 6 } 7 })(this,(function() { 8 function randomString(len, an){//comes from http://stackoverflow.com/a/27872144 9 an = an&&an.toLowerCase(); 10 var str="", i=0, min=an=="a"?10:0, max=an=="n"?10:62; 11 for(;i++<Math.ceil(len);){//the "Math.ceil(len)" part used to be just "len" 12 var r = Math.random()*(max-min)+min <<0, 13 n = String.fromCharCode(r+=r>9?r<36?55:61:48); 14 if (Math.random()*100<=18) { 15 n=" "; 16 } 17 str+=n; 18 } 19 return str; 20 } 21 function lint(str){ 22 var bestBefore="",bestBeforeVal=0,len=0,index=0,index2=0,part="",newPart="",newPartVal=0,qWord; 23 for(len=str.length;len>=3;len--){//each possable length of part>=3 24 //find bad parts 25 bestBefore=newPart=randomString(len,"an");//alfa-numeric string with length of len 26 for(index=0; index<(str.length-len); index++) { 27 part=str.substr(index,len); 28 if(typeof this.words[len]==="undefined"){ 29 this.words[len]={}; 30 } 31 if(typeof this.context[len]==="undefined"){ 32 this.context[len]={}; 33 } 34 if(typeof this.words[len][part]==="undefined"){ 35 this.words[len][part]=0; 36 } 37 if(typeof this.context[len][part]==="undefined"){ 38 this.context[len][part]={ 39 before:[str.substr(0,index)], 40 after:[str.slice(index+len)], 41 }; 42 } 43 if(this.words[len][part]<0){//if part is bad 44 //replace bad parts with alternative if any. Otherwise replace them with a random string 45 for(index2 in this.context[len][part].before){//all before parts 46 qWord=this.context[len][part].before[index2]; 47 if(qWord.length<1){ 48 qWord=randomString(3,"an"); 49 } 50 if(typeof this.words[qWord.length]==="undefined"){ 51 this.words[qWord.length]={}; 52 } 53 if(typeof this.words[qWord.length][part]==="undefined"){ 54 this.words[qWord.length][qWord]=0; 55 } 56 if(this.words[qWord.length][qWord]>=bestBeforeVal){//if this "question word" is the best 57 bestBeforeVal=this.words[qWord.length][qWord]; 58 bestBefore=qWord; 59 } 60 } 61 //by now the best "before part" has been determined 62 for(index2 in this.context[bestBefore.length][bestBefore].after){//all before parts 63 qWord=this.context[bestBefore.length][bestBefore].after[index2]; 64 if(qWord.length<1){ 65 qWord=randomString(3,"an"); 66 } 67 if(typeof this.words[qWord.length]==="undefined"){ 68 this.words[qWord.length]={}; 69 } 70 if(typeof this.words[qWord.length][part]==="undefined"){ 71 this.words[qWord.length][qWord]=0; 72 } 73 if(this.words[qWord.length][qWord]>=newPartVal){//if this "question word" is the best 74 newPartVal=this.words[qWord.length][qWord]; 75 newPart=qWord; 76 } 77 } 78 //by now the new part has been found 79 str=[str.substr(0,index),newPart,str.slice(index+len)].join(""); 80 } 81 } 82 } 83 //return the clean string 84 return str; 85 } 86 var Ai=function(name,obj) { 87 /* 88 There are 2 ways two run this function 89 90 var myAi= new Ai("My AI's name");//1st 91 var mySecondAi= new Ai("My 2nd AI's name",{ 92 //values here 93 });//2nd 94 */ 95 if (arguments.length===0||arguments.length>2) throw "The Ai constructor requires 1-2 values passed"; 96 obj=obj||{};//prevent bugs 97 this.name=name; 98 this.defaultResponces={ 99 "How are you?":"If you got this message, I am at least 25% operational.", 100 }; 101 this.lastResponce=""; 102 this.words=[]; 103 this.context=[]; 104 this.inputTypes={ 105 string:function(str) {return str;}, 106 }; 107 if(typeof obj!="undefined") { 108 for (var i in this) { 109 if (typeof this[i]!="undefined") { 110 for (var ii in obj[i]) { 111 this[i][ii]=obj[i][ii]; 112 } 113 }else this[i]=obj[i];//overwrite with obj 114 } 115 } 116 /*if (typeof this.name!=="string") { 117 throw "The name for your Ai bot must be a string"; 118 }*/ 119 this.reactTo=function(input,type) { 120 /* 121 How to use this function: 122 123 var myAi= new Ai("My AI's name"); 124 var aisOutput=myAi.reactTo("input","usersname","type of input(optional but will use the typeof operator to determine this value if not specified)"); 125 */ 126 var output=randomString(Math.random()*this.lastResponce.length),len,index,word;//set varubles 127 type=type||typeof input; 128 129 //check varubles 130 if (typeof this.inputTypes[type]==="undefined") { 131 throw "Invalid type"; 132 }else{ 133 input=this.inputTypes[type](input); 134 } 135 136 //apply default responce 137 if (this.defaultResponces.hasOwnProperty(input)) output=this.defaultResponces[input]; 138 //lint 139 output=lint.call(this,output); 140 //add to memory 141 this.defaultResponces[input]=output; 142 this.lastResponce=output;//For the punish and reward functions 143 for (len=1; len<output.length; len++) { 144 if (!this.words[len]) { 145 this.words[len]={}; 146 this.context[len]={}; 147 } 148 for (index=0; index<(output.length-len); index++) { 149 word=output.substr(index,len); 150 if(!this.words[len][word]) { 151 this.words[len][word]=0;//value indicates how "good" a word is 152 this.context[len][word]={ 153 before:[output.substr(index-len,len)], 154 after:[output.substr(index+len,len)], 155 }; 156 }else{ 157 this.context[len][word].before.push(output.substr(index-len,len)); 158 this.context[len][word].after.push(output.substr(index+len,len)); 159 } 160 } 161 } 162 //act & remember 163 this.lastResponce=output; 164 return output; 165 }; 166 this.punish=function(str){ 167 if (typeof str==="undefined") { 168 str=this.lastResponce; 169 } 170 for (var len=1; len<str.length; len++) { 171 if (typeof this.words[len]==="undefined") this.words[len]={}; 172 for (var index=0; index<(str.length-len); index++) { 173 var word=str.substr(index,len); 174 if(!this.words[len][word]) { 175 this.words[len][word]=0;//value indicates how "good" a word is 176 }else{ 177 this.words[len][word]--; 178 } 179 } 180 } 181 }; 182 this.reward=function(str){ 183 if (typeof str==="undefined") { 184 str=this.lastResponce; 185 } 186 for (var len=1; len<str.length; len++) { 187 if (typeof this.words[len]==="undefined") this.words[len]={}; 188 for (var index=0; index<(str.length-len); index++) { 189 var word=str.substr(index,len); 190 if(!this.words[len][word]) { 191 this.words[len][word]=0;//value indicates how "good" a word is 192 }else{ 193 this.words[len][word]++; 194 } 195 } 196 } 197 }; 198 }; 199 return Ai; 200 })());