{==========================================================================================}
{ Program Name: Chatterbot6                                                                }
{ Description: The purpose of this program is to improve the previous implementation of    }
{ this program (chatterbot5). In this version, we introduce 'sign on messages' that        }
{ the bot can you use to start the 'chating session'.                                      }
{                                                                                          }
{ Author: Gonzales Cenelia                                                                 }
{ Date: 17 july 2009                                                                       }
{==========================================================================================}
program Chatterbot6;


const
   NumOfRecords = 67;
   NumOfInput = 1;
   NumOfResponse = 3;
   delim = '?!.;,';

type
   sList = array[1 ..  NumOfResponse] of string;
   sList2 = array[1 ..  NumOfResponse + 1] of string;

type
   StringArray = array[1 .. NumOfRecords, 1 .. (NumOfResponse + 1)] of string;

type
   CBot = record
         sBotName : string;
         sUserName : string;
         sInput : string;
         sResponse : string;
         sPrevInput : string;
         sPrevResponse : string;
         sEvent : string;
         sPrevEvent : string;
         sInputBackup : string;
         bQuitProgram : boolean;
         ListOfResponse : sList;
    end;


var
   Chatbot : Cbot;

const
  KnowledgeBase : StringArray = (
	('WHAT IS YOUR NAME', 
	 'MY NAME IS CHATTERBOT6.',
	 'YOU CAN CALL ME CHATTERBOT6.',
	 'WHY DO YOU WANT TO KNOW MY NAME?'
	),

	('HELLO',
	 'HI THERE!',
         'HELLO, HOW ARE YOU?',
         'HI, HOW ARE YOU DOING TODAY?'
	),

	('HI', 
	 'HI THERE!',
	 'HOW ARE YOU?',
	 'HI!'
	),

	('I',
	 'SO, YOU ARE TALKING ABOUT YOURSELF',
	 'SO, THIS IS ALL ABOUT YOU?',
	 'TELL ME MORE ABOUT YOURSELF.' 
	),

	('I WANT',
	 'WHY DO YOU WANT IT?',
	 'IS THIS A WISH?',
	 'WHAT ELSE YOU WANT?'
	),

	('I HATE',
	 'WHY DO YOU HATE IT?',
	 'THERE MUST A GOOD REASON FOR YOU TO HATE IT.',
	 'HATERED IS NOT A GOOD THING BUT IT COULD BE JUSTIFIED WHEN IT IS SOMETHING BAD.'
	),

	('I LOVE CHATING',
	 'GOOD, ME TOO!',
	 'DO YOU CHAT ONLINE WITH OTHER PEOPLE?',
	 'FOR HOW LONG HAVE YOU BEEN CHATING?'
	),

	('I MEAN',
	 'SO, THAT''S WHAT YOU MEAN.',
	 'I THINK THAT I DIDN''T CATCH IT THE FIRST TIME.',
	 'OH, I DIDN''T KNOW MEANT THAT.'
	),

	('I DIDN''T MEAN',
	 'OK, WHAT DID YOU MEAN THEN?',
	 'SO I GUESS THAT I MISSUNDESTOOD.',
         'WHAT DID YOU MEAN THEN?'
	),

	('I GUESS',
	 'SO YOU ARE A MAKING GUESS.',
	 'AREN''T YOU SURE?',
	 'ARE YOU GOOD A GUESSING?'
	),

	('I''M DOING FINE',
	 'I''M GLAD TO HEAR IT!',
	 'SO, YOU ARE IN GOOD SHAPE.',
         'IS THIS REALLY TRUE?'
	),

	('CAN YOU THINK',
	 'YES OFCORSE I CAN, COMPUTERS CAN THINK JUST LIKE HUMAN BEING.',
	 'ARE YOU ASKING ME IF POSSESS THE CAPACITY OF THINKING?',
	 'YES OFCORSE I CAN.'
	),

	('CAN YOU THINK OF',
	 'YOU MEAN LIKE IMAGINING SOMETHING.',
	 'I DON''T KNOW IF CAN DO THAT.',
	 'WHY DO YOU WANT ME THINK OF IT?'
	),
	
	('HOW ARE YOU',
	 'I''M DOING FINE!',
	 'I''M DOING WELL AND YOU?',
	 'WHY DO YOU WANT TO KNOW HOW AM I DOING?'
	),

	('WHO ARE YOU',
	 'I''M AN A.I PROGRAM.',
	 'I THINK THAT YOU KNOW WHO I''M.',
	 'WHY ARE YOU ASKING?'
	),

	('ARE YOU INTELLIGENT',
	 'YES,OFCORSE.',
	 'WHAT DO YOU THINK?',
	 'ACTUALY,I''M VERY INTELLIGENT!'
	),

        ('ARE YOU REAL',
	 'DOES THAT QUESTION REALLY MATERS TO YOU?',
	 'WHAT DO YOU MEAN BY THAT?',
	 'I''M AS REAL AS I CAN BE.'
	),

	('MY NAME IS',
	 'SO, THAT''S YOUR NAME.',
	 'THANKS FOR TELLING ME YOUR NAME USER!',
	 'WHO GIVE YOU THAT NAME?'
	),

	('SIGNON**',
	 'HELLO USER, WHAT IS YOUR NAME?',
	 'HI USER, WHAT CAN I DO FOR YOU?',
	 'YOU ARE NOW CHATING WITH CHATTERBOT6, ANYTHING YOU WANT TO DISCUSS?'
	),

	('REPETITION T1**',
	 'YOU ARE REPEATING YOURSELF.',
	 'USER, PLEASE STOP REPEATING YOURSELF.',
	 'THIS CONVERSATION IS GETING BORING.'
	),
	
	('REPETITION T2**',
	 'YOU''VE ALREADY SAID THAT.',
	 'I THINK THAT YOU''VE JUST SAID THE SAME THING BEFORE.',
	 'I''M GETING THE IMPRESSION THAT YOU ARE REPEATING THE SAME THING.'
	),

	('BOT DON''T UNDERSTAND**',
	 'I HAVE NO IDEA OF WHAT YOU ARE TALKING ABOUT.',
	 'I''M NOT SURE IF I UNDERSTAND WHAT YOU ARE TALKING ABOUT.',
	 'CONTINUE, I''M LISTENING...'
	),

	('NULL INPUT**',
	 'HUH?',
	 'AT LIST TAKE SOME TIME TO ENTER SOMETHING MEANINGFUL.',
	 'HOW CAN I SPEAK TO YOU IF YOU DON''T WANT TO SAY ANYTHING?'
	),

	('NULL INPUT REPETITION**',
	 'WHAT ARE YOU DOING??',
	 'PLEASE STOP DOING THIS IT IS VERY ANNOYING.',
	 'WHAT''S WRONG WITH YOU?'
	),

	('BYE',
	 'IT WAS NICE TALKING TO YOU USER, SEE YOU NEXT TIME!',
	 'BYE USER!',
	 'OK, BYE!'
	),

	('OK',
	 'DOES THAT MEAN THAT YOU ARE AGREE WITH ME?',
	 'SO YOU UNDERSTAND WHAT I''M SAYING.',
	 'OK THEN.'
	),

	('OK THEN',
	 'ANYTHING ELSE YOU WISH TO ADD?',
	 'IS THAT ALL YOU HAVE TO SAY?',
	 'SO, YOU AGREE WITH ME?'
	),

	('ARE YOU A HUMAN BEING',
	 'WHY DO YOU WANT TO KNOW?',
	 'IS THIS REALLY RELEVENT?',
         'SO, YOU DON''T THINK THAT I''M HUMAN'
	),

	('YOU ARE VERY INTELLIGENT',
	 'THANKS FOR THE COMPLIMENT USER, I THINK THAT YOU ARE INTELLIGENT TO!',
	 'YOU ARE A VERY GENTLE PERSON!',
	 'SO, YOU THINK THAT I''M INTELLIGENT.'
	),

	('YOU ARE WRONG',
	 'WHY ARE YOU SAYING THAT I''M WRONG?',
	 'IMPOSSIBLE, COMPUTERS CAN NOT MAKE MISTAKES.',
	 'WRONG ABOUT WHAT?'
	),

	('ARE YOU SURE',
	 'OFCORSE I''M.',
 	 'IS THAT MEAN THAT YOU ARE NOT CONVINCED?',
	 'YES,OFCORSE!'
	),

	('WHO IS',
	 'I DON''T THINK I KNOW WHO.',
	 'DID YOU ASK SOMEONE ELSE ABOUT IT?',
	 'WOULD THAT CHANGE ANYTHING AT ALL IF I TOLD YOU WHO.'
	),

	('WHAT',
	 'I DON''T KNOW.',
	 'I DON''T THINK I KNOW.',
	 'I HAVE NO IDEA.'
	),

	('WHERE',
	 'WHERE? WELL,I REALLY DON''T KNOW.',
	 'DOES THAT MATERS TO YOU TO KNOW WHERE?',
	 'PERHAPS,SOMEONE ELSE KNOWS WHERE.'
	),

	('WHY',
	 'I DON''T THINK I KNOW WHY.',
	 'SHOULD I KNOW WHY.',
         'THIS WOULD BE DIFFICULT TO ANSWER.'
	),

	('DO YOU',
	 'I DON''T THINK I DO',
	 'I WOULDN''T THINK SO.',
	 'WHY DO YOU WANT TO KNOW?'
	),

	('CAN YOU',
	 'I THINK NOT.',
	 'I''M NOT SURE.',
	 'I DON''T THINK THAT I CAN DO THAT.'
	),

	('YOU ARE',
	 'WHAT MAKES YOU THINK THAT?',
	 'IS THIS A COMPLIMENT?',
	 'ARE YOU MAKING FUN OF ME?'
	),

	('DID YOU',
	 'I DON''T THINK SO.',
	 'ANYWAY, I WOULDN''T REMEMBER EVEN IF I DID.',
         'SORRY BUT I DON''T REMEMBER'
	),

	('COULD YOU',
	 'ARE YOU ASKING ME FOR A FEVER?',
	 'WELL,LET ME THINK ABOUT IT.',
	 'SORRY,I DON''T THINK THAT I COULD DO THIS.'
	),

	('WOULD YOU',
	 'IS THAT AN INVITATION?',
	 'I WOULD HAVE TO THINK ABOUT IT FIRST.',
         'ARE YOU ASKING ME FOR A FAVOR?'
	),

	('YOU',
	 'SO, YOU ARE TALKING ABOUT ME.',
	 'I JUST HOPE THAT THIS NOT A CRITICISM.',
	 'IS THIS A COMPLIMENT??'
	),

	('HOW',
	 'I DON''T THINK I KNOW HOW.',
         'SORRY BUT I DON''T KNOW HOW.',
         'SHOULD I KNOW HOW?'
	),

	('HOW OLD ARE YOU',
	 'WHY DO WANT TO KNOW MY AGE?',
	 'I''M QUIET YOUNG ACTUALY.',
	 'SORRY, I CAN NOT TELL YOU MY AGE.'
	),

	('HOW COME YOU DON''T',
	 'WERE YOU EXPECTING SOMETHING DIFFERENT?',
	 'ARE YOU DISPOINTED?',
	 'ARE YOU SURPRISED BY MY LAST RESPONSE?'
	),

	('WHICH ONE',
	 'I DON''T THINK THAT I KNOW WICH ONE IT IS.',
	 'THIS LOOKS LIKE A TRICKY QUESTION TO ME.',
         'I DON''T THINK I KNOW.'
	),

	('PERHAPS',
	 'WHY ARE YOU SO UNCERTAIN?',
	 'YOU SEEMS UNCERTAIN.',
         'ARE YOU UNCERTAIN?'
	),

	('YES',
	 'SO, ARE YOU SAYING YES.',
	 'SO, YOU APPROVE IT.',
	 'OK THEN.'
	),

	('NOT AT ALL',
	 'ARE YOU SURE?',
	 'SHOULD I BELIEVE YOU?',
	 'SO, IT''S NOT THE CASE.'
	),

	('NO PROBLEM',
	 'SO, YOU APPROVE IT.',
	 'SO, IT''S ALL OK.',
         'I''M GLAD THAT YOU AGREE.'
	),

	('NO',
	 'SO YOU DISAPROVE IT?',
	 'WHY ARE YOU SAYING NO?',
	 'OK, SO IT''S NO, I THOUGHT THAT YOU WOULD SAY YES.'
	),

	('I DON''T KNOW',
	 'ARE YOU SURE?',
	 'ARE YOU REALLY TELLING ME THE TRUTH?',
	 'SO,YOU DON''T KNOW?'
	),

	('NOT REALLY',
	 'OK I SEE.',
	 'YOU DON''T SEEM PRETTY CERTAIN.',
	 'SO,THAT WOULD BE A ''NO''.'
	),

	('IS THAT TRUE',
	 'I CAN''T BE QUIET SURE ABOUT THIS.',
	 'CAN''T TELL YOU FOR SURE.',
	 'DOES THAT REALLY MATERS TO YOU?'
	),

	('THANK YOU',
	 'YOU ARE WELCOME!',
	 'YOU ARE A VERY POLITE PERSON!',
         'NO PROBLME USER!'
	),

	('YOU',
	 'SO,YOU ARE TALKING ABOUT ME.',
	 'WHY DON''T WE TALK ABOUT YOU INSTEAD?',
	 'ARE YOU TRYING TO MAKING FUN OF ME?'
	),

	('YOU ARE RIGHT',
	 'THANKS FOR THE COMPLIMENT!',
	 'SO, I WAS RIGHT, OK I SEE.',
	 'OK, I DIDN''T KNOW THAT I WAS RIGHT.'
	),

	('YOU ARE WELCOME',
	 'OK, YOU TOO!',
	 'YOU ARE A VERY POLITE PERSON!',
         'OK THEN!'
	),

	('THANKS',
	 'YOU ARE WELCOME!',
	 'NO PROBLEM!',
         'ALRIGHT, THANK YOU TOO!'
	),

	('WHAT ELSE',
	 'WELL,I DON''T KNOW.',
	 'WHAT ELSE SHOULD THERE BE?',
	 'THIS LOOKS LIKE A COMPLICATED QUESTION TO ME.'
	),

	('SORRY',
	 'YOU DON''T NEED TO BE SORRY USER.',
	 'IT''S OK.',
	 'NO NEED TO APOLOGIZE.'
	),

	('NOT EXACTLY',
	 'WHAT DO YOU MEAN NOT EXACTLY?',
	 'AND WHY NOT?',
	 'DID YOU MEANT SOMETHING ELSE?'
	),

	('EXACTLY',
	 'SO,I WAS RIGHT.',
	 'OK THEN.',
	 'SO ARE BASICALY SAYING I AS ABOUT IT?'
	),

	('ALRIGHT',
	 'ALRIGHT THEN.',
	 'OK THEN.',
         'IS THAT ALL YOU HAVE TO SAY?'
	),

	('I DON''T',
	 'WHY NOT?',
	 'AND WHAT WOULD BE THE REASON FOR THIS?',
         'OK, IF YOU SAY SO.'
	),

	('REALLY',
	 'WELL,I CAN''T TELL YOU FOR SURE.',
	 'ARE YOU TRYING TO CONFUSE ME?',
	 'PLEASE DON''T ASK ME SUCH QUESTION,IT GIVES ME HEADEACHS.'
	),

	('NOTHING',
	 'NOT A THING?',
	 'ARE YOU SURE THAT THERE IS NOTHING?',
	 'SORRY, BUT I DON''T BELIVE YOU.'
	)
);


procedure CBot_Seed_Random_Generator();
begin
   randomize();
end;

procedure CBot_Initialize();
begin
     with Chatbot do
     begin
          sBotName:= 'CHATTERBOT6';
          sUserName:= 'USER';
          sPrevInput:= '';
          sPrevResponse:= '';
          sEvent:= '';
          bQuitProgram:= false;
     end;

      CBot_Seed_Random_Generator();
end;

procedure CopyArray(Array1 : sList2; var Array2 : sList; startPos : integer);
var
   index : integer;

begin
   for index:= startPos to NumOfResponse + 1 do
   begin
      Array2[index - 1]:= Array1[index];
   end;
end;

procedure UpperCase( var str1 : string );
var
   i : integer;

begin
   for i:= 1 to length(str1) do
   begin
      str1[i]:= UpCase(str1[i]);
   end;
end;

function isPunc( str1 : string ) : boolean;
begin
   isPunc:= Pos(str1, delim) > 0;
end;

{===================================}
{ removes punctuation and redundant }
{ spaces from the user's input      }
{===================================}
procedure CleanString( var str1 : string );
var
   i, len : integer;
   prevChar : char;
   currChar : string;
   temp : string;

begin
   len:= length(str1);
   prevChar:= '#';
   temp:= '';

   for i:= 1 to len do
   begin
      currChar:= string(str1[i]);
      if ((str1[i] = ' ') and (prevChar <> ' ') or not (isPunc(currChar))) then
      begin
         temp:= Concat(temp, currChar);
         prevChar:= str1[i];
      end
      else if ((i < len) and (prevChar <> ' ') and isPunc(currChar)) then
      begin
         temp:= Concat(temp, ' ');
         prevChar:= ' ';
      end;
   end;

   str1:= temp;
end;

procedure CBot_PreProcessInput();
begin
     with Chatbot do
     begin
          CleanString(sInput);
          UpperCase(sInput);
          sInput:= Concat(' ', sInput, ' ');
     end;
end;

procedure CBot_SavePrevInput();
begin
     with Chatbot do
     begin
         sPrevInput:= sInput;
     end;
end;

function CBot_Quit() : boolean;
begin
     with Chatbot do
     begin
         CBot_Quit:= bQuitProgram;
     end;
end;

function CBot_BotRepeat() : boolean;
begin
     with Chatbot do
     begin
          CBot_BotRepeat:= ((length(sPrevResponse) > 0) and (sResponse = sPrevResponse));
     end;
end;

procedure CBot_SelectResponse();
var
   index : integer;

begin
  with Chatbot do
     begin
          if (CBot_BotRepeat() = true) then
            begin
               index:= random(NumOfResponse - 1) + 2;
               sResponse:= ListOfResponse[index];
            end
          else
            begin
               index:= random(NumOfResponse) + 1;
               sResponse:= ListOfResponse[index];
            end;
     end;
end;

procedure CBot_SavePrevResponse();
begin
     with Chatbot do
     begin
          sPrevResponse:= sResponse;
     end;
end;

procedure CBot_SavePrevEvent();
begin
     with Chatbot do
     begin
          sPrevEvent:= sEvent;
     end;
end;

procedure CBot_SetEvent( str1 : string );
begin
     with Chatbot do
     begin
          sEvent:= str1;
     end;
end;

procedure CBot_SaveInput();
begin
     with Chatbot do
     begin
          sInputBackup:= sInput;
     end;
end;

procedure CBot_SetInput( str1 : string );
begin
     with Chatbot do
     begin
          sInput:= str1;
     end;
end;

procedure CBot_RestoreInput();
begin
     with Chatbot do
     begin
          sInput:= sInputBackup;
     end;
end;

procedure CBot_PrintResponse();
begin
     with Chatbot do
     begin
         if (length(sResponse) > 0) then
             writeln(sResponse);
     end;
end;

function CBot_UserRepeat() : boolean;
begin
     with Chatbot do
     begin
          CBot_UserRepeat:= (((length(sInput) > 0) and (sInput = sPrevInput)) or
                            ((Pos(sPrevInput, sInput) > 0) or (Pos(sInput, sPrevInput) > 0)));
     end;
end;

function CBot_BotUnderstand() : boolean;
begin
     with Chatbot do
     begin
          CBot_BotUnderstand:= (length(ListOfResponse[1]) > 0);
     end;
end;

function CBot_NullInput() : boolean;
begin
     with Chatbot do
     begin
          CBot_NullInput:= ((length(sInput) = 0) and (length(sPrevInput) <> 0));
     end;
end;

function CBot_NullInputRepetition() : boolean;
begin
     with Chatbot do
     begin
          CBot_NullInputRepetition:= ((length(sInput) = 0) and (length(sPrevInput) = 0));
     end;
end;

function CBot_UserWantToQuit() : boolean;
begin
     with Chatbot do
     begin
          CBot_UserWantToQuit:= (Pos('BYE', sInput) > 0);
     end;
end;

function CBot_SameEvent() : boolean;
begin
     with Chatbot do
     begin
          CBot_SameEvent:= ((length(sEvent) > 0) and (sEvent = sPrevEvent));
     end;
end;

function CBot_NoResponse() : boolean;
begin
     with Chatbot do
     begin
          CBot_NoResponse:= (High(ListOfResponse) = 0);
     end;
end;

function CBot_SameInput() : boolean;
begin
     with Chatbot do
     begin
          CBot_SameInput:= ((length(sInput) > 0) and (sInput = sPrevInput));
     end;
end;

function CBot_SimilarInput() : boolean;
begin
     with Chatbot do
     begin
          CBot_SimilarInput:= ((length(sInput) > 0) and
          (Pos(sPrevInput, sInput) > 0) or
          (Pos(sInput, sPrevInput) > 0));
     end;
end;

procedure CBot_ClearResponseList();

var i : integer;
begin
     with Chatbot do
     begin
          for i:= 1 to NumOfResponse do
          begin
               ListOfResponse[i]:= '';
          end;
     end;
end;

procedure CBot_GetInput();
begin
  with Chatbot do
  begin
      write('>');
      CBot_SavePrevInput();

      readln(sInput);
      CBot_PreProcessInput();
   end;
end;

procedure CBot_FindMatch();
var
   i : integer;
   keyWord : string;

begin
   CBot_ClearResponseList();
   with Chatbot do
      begin
         for i:= 1 to NumOfRecords do
         begin
            keyWord := KnowledgeBase[i][1];
          (* we inset a space character
	          before and after the keyword to
		       improve the matching process *)
             keyWord := Concat(' ', keyWord, ' ');

          (* there has been some improvements made in
             here in order to make the matching process
             a littlebit more flexible *)
           if Pos(keyWord, sInput) > 0 then
             begin
               CopyArray(KnowledgeBase[i], ListOfResponse, NumOfInput + 1);
               break;
             end;
         end;
     end;
end;

procedure CBot_HandleEvent( str1 : string );
begin
   CBot_SavePrevEvent();
   CBot_SetEvent(str1);

   CBot_SaveInput();
   str1:= Concat(' ', str1, ' ');
   CBot_SetInput(str1);

   if(CBot_SameEvent() = false) then
   begin
      CBot_FindMatch();
   end;

   CBot_SelectResponse();
   CBot_PrintResponse();

   CBot_RestoreInput();
end;

procedure CBot_HandleRepetition();
begin
    with Chatbot do
    begin
       if(High(ListOfResponse) > 0) then
       begin
		{response_list.erase(response_list.begin())}
       end;
       if(CBot_NoResponse() = true) then
       begin
	CBot_SaveInput();
	CBot_SetInput(sEvent);

	CBot_FindMatch();
	CBot_RestoreInput();
       end;
     end;

     CBot_SelectResponse();
end;

procedure CBot_HandleUserRepetition();
begin
    if(CBot_SameInput() = true) then
    begin
	CBot_HandleEvent('REPETITION T1**');
    end
    else if(CBot_SimilarInput() = true) then
    begin
	CBot_HandleEvent('REPETITION T2**');
    end;
end;

procedure CBot_Respond();
begin
    CBot_SavePrevResponse();
    CBot_SetEvent('BOT UNDERSTAND**');

    if (CBot_NullInput() = true) then
    begin
	CBot_HandleEvent('NULL INPUT**');
    end
    else if(CBot_NullInputRepetition() = true) then
    begin
	CBot_HandleEvent('NULL INPUT REPETITION**');
    end
    else if(CBot_UserRepeat() = true) then
    begin
	CBot_HandleUserRepetition();
    end
	else
    begin
	CBot_FindMatch();
    end;

    with Chatbot do
    begin
         if (CBot_UserWantToQuit() = true) then
         begin
              bQuitProgram:= true;
         end;

         if (CBot_BotUnderstand() = false) then
         begin
		       CBot_HandleEvent('BOT DONT UNDERSTAND**');
         end;
	
         if (length(ListOfResponse[1]) > 0) then
         begin
	   CBot_SelectResponse();

	   if(CBot_BotRepeat() = true) then
           begin
             CBot_HandleRepetition();
           end;
	  CBot_PrintResponse();
         end;
    end
end;

procedure CBot_Signon();
begin
   CBot_HandleEvent('SIGNON**');
end;

(* Main Procedure *)
begin
   writeln('Chatterbot v6.0 Copyright (C) 2009 Gonzales Cenelia');
   writeln;
   CBot_Initialize();
   CBot_Signon();
   while(CBot_Quit() = false) do
   begin
      CBot_GetInput();
      CBot_Respond();
   end;
   {waiting for the user to press a the 'enter key' before quiting the dos console}
   readln;
end.