Optimalisatie Chatbot Javascript

Status
Niet open voor verdere reacties.

Max306542

Gebruiker
Lid geworden
18 jul 2012
Berichten
33
Hey allemaal,

Ik heb een chatbot gemaakt die terug praat op alles wat je zegt. Door middel van een new Array kan hij praten. Voorbeeld:

new Array("Als de gebruiker dit zegt", "dan is dit het antwoord"),
Dus de eerste zin tussen de aanhalingstekens is de input die de gebruiker kan versturen. De tweede zin tussen de aanhalingstekens is de reactie van de chatbot op de eerste zin. Dat werkt allemaal.

Nu heb ik honderden zinnen. Maar de chatbot kan steeds maar antwoord geven op één zin. Ik heb bijvoorbeeld ingeprogrammeerd dat als iemand "ja" zegt, de chatbot dan "goed" terug zegt.
Maar nu wil ik dat als iemand "ja" zegt als antwoord op een vraag van de chatbot, dat de chatbot dan daar op door bouwt. Ik heb het al met een if statement geprobeerd, maar dan werkt de code niet meer..

De bedoeling is om dit te krijgen:
Gebruiker: Hoe gaat ie?
Chatbot: Goed, daar ook?
Gebruiker: Ja.
Chatbot: Fijn dat het goed gaat!
Gebruiker: Ja.
Chatbot: Oke

Hier wordt twee keer "ja" gezegd, en de chatbot geeft er verschillende (logische) antwoorden op. Weet iemand hoe dat met alleen new Arrays bereikt kan worden?
Edit: een andere manier mag ook (if statement bijvoorbeeld). Zou super zijn als het lukt!

Alvast super bedankt!
 
Laatst bewerkt:
Ja, natuurlijk.

Code:
<html>
<head>
<title>Chatbot</title>



<style type="text/css">
BODY {
   background-color: buttonface;
   font-family: Helvetica;
   font-size: 10pt;
   margin-top: 10px;
   margin-left: 20px;
   margin-right: 20px;
   margin-bottom: 10px;
   }
.button {
   font-family: Helvetica;
   font-size: 10pt;
   width: 92px;
   }
textarea {
   font-family: arial;
   font-size: 10pt;
   }
select {
   font-family: arial;
   font-size: 10pt;
   width: 350px;
   margin-left: 0px;
   }
td {
   font-family: arial;
   font-size: 10pt;
  }
  
Chatbot:{
   color: red;

}

</style>

<script type="text/javascript">

//----Data Declarations----

var conversatiepatronen = new Array(

new Array (".*Hallo.*", "Hey", "Hoi!", "Hallo", "Goeiendag"),
new Array (".*Alles goed?*", "Jahoor, prima! Gaat het daar ook goed?", "Zeker, dank je! En daar?", "Jup! En daar?", "Ja, alles gaat goed"),
new Array (".*Ja.*", "Oke", "Leuk!", "Goed", "Ok."));

//----En heel veel meer van dit soort regels----

uinput = ""
soutput = ""
dialog = ""
  
  


uinput = ""
soutput = ""
dialog = ""


//-------
 function mainroutine() {
 uinput = document.mainscreen.BasicTextArea4.value;
 dialog = dialog + "Jij: " + uinput +  '\r' + "\n";
  conversationpatterns()
 dialog = dialog  +  '\r' + "\n";
  tekstkleur()
  updatescreen()
  scrollBox()
  
}

//-------
function conversationpatterns() {
   for (i=0; i < conversatiepatronen.length; i++) {
    re = new RegExp (conversatiepatronen[i][0], "i");
    if (re.test(uinput)) {
      len = conversatiepatronen[i].length - 1;
      index = Math.ceil( len * Math.random());
      reply = conversatiepatronen[i][index];
      soutput = uinput.replace(re, reply);
      soutput = initialCap(soutput);
      dialog = dialog + "Chatbot: " + soutput +  '\r' + "\n";
      break;
  }
 }
	
	
 }
 
 

//-------

function initScreen() {
 updatescreen()
}

//-------
function updatescreen() {
 document.mainscreen.BasicTextArea1.value = dialog
 document.mainscreen.BasicTextArea4.value = ""
}

//-------
function initialCap(field) {
   field = field.substr(0, 1).toUpperCase() + field.substr(1);
   return field
}

//Auto Scroll
function scrollBox()
{
var elem = document.getElementById('BasicTextArea1');
elem.scrollTop = elem.scrollHeight;
}

//Color Chatbot
function tekstkleur(){
soutput.fontcolor("green");
}


</script>
</head>

<body onLoad="initScreen()">

<form name="mainscreen" onkeypress = "if(event.keyCode == 13) {mainroutine();return false}">

<table align="center">
<tr>
<td>

Dialoog<br />
<textarea style="color:green;" name="BasicTextArea1" id="BasicTextArea1" rows="15" cols="75" readonly></textarea><br />
<br>

Typ hier je bericht en druk op "Enter"<br />
<textarea name="BasicTextArea4" rows="2" cols="75"></textarea><br />

</td>
</tr>
</table>

<p align = "center">
<input id=runbutton  class="button" type="button" value="Verstuur" name="run_button"  onClick="mainroutine()">
</p>
</form>
</body>
</html>
 
Je zou het eventueel in PHP kunnen maken, dan hoeft die hele array niet worden opgestuurd, maar alleen het antwoord. Eventueel met AJAX zodat je dan je JavaScript een beetje kan behouden.
 
Ik hoop dat je bedoelt dat de chatbot de antwoorden 'cycled', dus zegmaar een voor een door de mogelijke antwoorden loopt en als 'ie aan het eind is weer de eerste pakt?

Zo ja, dan is dat makkelijk op te lossen. Het idee is dit: in plaats van een enkele dimentie in je array te gebruiken maak je er twee, maar dan wel wat logischer:

[js]// vraag, [antwoorden], teller
var antwoorden =
[
['vraag 1', ['antwoord 1', 'antwoord 2', 'antwoord 3'], 0],
['vraag 2', ['antwoord 1'], 0],
['vraag 3', ['antwoord 1', 'antwoord 2'], 0]
];[/js]

dan kan je bij je 'antwoord' script het tellertje veranderen, zodat je wist wat je laatste antwoord was. Bijvoorbeeld:

[js]function antwoord(zinID)
{
// antwoorden is complete array
// antwoorden[zinID] is de 'regel' van een vraag
// antwoorden[zinID] heeft 3 indexen; 0 is de vraag, 1 is de array[] met antwoorden, en 2 is de teller

var antwoord = antwoorden[zinID][1][ antwoorden[zinID][2] ];

antwoorden[zinID][2] = (antwoorden[zinID][2] + 1) % antwoorden[zinID][1].length; // zie uitleg beneden

return antwoord;
}[/js]

wat dit doet is eerst het huidige tellertje ophalen van de correcte regel. Dan sla je even het antwoord-texje op in 'antwoord'. Daarna tel je 1 bij het tellertje op, en kijk je of het niet 'te hoog' wordt (% length) en pas je het automatisch aan (dus: teller loopt van 0 tot aantal antwoorden).




Anyway, bedoelde je dat de chat'bot' echte gesprekken moet gaan voeren, in plaats van simpelweg antwoorden op een voorgedefinieerde vraag (zonder 'loopback'), dan zal zoiets simpels nooit gaan werken. Daarvoor zul je toch echt de kant van de kunstmatige intelligentie op moeten, en dat is *echt* niet makkelijk! En met 'if statements' gaat het al helemaal niet lukken. Het punt is namelijk dat je script moet begrijpen *waar* de conversatie precies over gaat.

Ik raad je echt af om direct in zo'n lastig onderwerp te duiken. Er gaat een heleboel tijd in zitten en je zult er in het begin (eerste paar maanden) weinig nuttigs uit halen.


Iets wat wel mogelijk is zonder de diepte in te gaan is met voorgedefinieerde vragen en antwoorden te werken. Dan krijgt de gebruiker dus een textje, plus een aantal vragen of antwoorden. Bij het selecteren van een antwoord krijgt de gebruiker weer een nieuw textje te zien, plus nieuwe vragen (of antwoorden). Nadeel is dat de gebruiker dan niet zelf dingen kan verzinnen en intypen. Games in de Infinity Engine gebruiken dit, zie bijvoorbeeld http://lparchive.org/Baldurs-Gate-2-and-Throne-of-Bhaal/Update%2018/5-BG2SoAch12019.jpg.
 
Laatst bewerkt:
Dank je voor je antwoord. Het ziet er veel belovend uit, en ik waardeer het enorm! Ik weet alleen niet hoe ik deze codes moet linken aan alle array's die ik er al in heb (zie broncode boven je bericht).
Ik heb nu ongeveer 1300 vraag- en antwoordmogelijkheden. De kunst is nu om in een paar van die mogelijkheden een conversatie mogelijk te maken. Ik weet alleen niet hoe ik dat met het script kan doen wat je gaf.

Overigens gaat het script dat ik nu heb door de antwoorden. Op het moment dat het script de juiste input heeft gevonden, stopt hij met lezen en geeft direct de output. Helaas cycled hij niet.

Nogmaals, ik waardeer het enorm :)
 
Laatst bewerkt:
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan