/* Defining Costants*/ // Max. length in characters of any automated reply ( Keyword only) # define MAX_RESP_LEN 65 // Max. number of responses for any keyword # define MAX_RESP_NO 20 // Max. number of keywords # define MAX_KEY 13 // Max. number of Transpositions # define TRANSPOSE 12 // Max. Size Of User Input # define MAX_USER_INPUT 100 // Max. Length of Keyword # define MAX_KWD_LEN 20 // Delay involved in typing (in ms) # define DELAY 20
/* Defining Global Variables */
// for getting the user name char user[30]; // for word transpositions char wordin[TRANSPOSE][MAX_RESP_LEN]; char wordout[TRANSPOSE][MAX_RESP_LEN]; int RanNum(int max); void initialize_global();
class progstr
{ public: char userip[MAX_USER_INPUT]; char keyword[30]; int keyfound; int keyno; int nullip; // constructor
progstr()
{
keyno=-1;
nullip=0;
}
}ip;
cout<<" EEEEEEEE L IIIIIII ZZZZZZZ AAA "<<endl;
delay(DELAY);
cout<<" E L I Z A A "<<endl;
delay(DELAY);
cout<<" E L I Z A A "<<endl;
delay(DELAY);
cout<<" EEEEE L I Z A A "<<endl;
delay(DELAY);
cout<<" E L I Z AAAAAAA "<<endl;
delay(DELAY);
cout<<" E L I Z A A "<<endl;
delay(DELAY);
cout<<" EEEEEEEE LLLLLLLL IIIIIII ZZZZZZ A A "<<endl;
} void display_line()
{ int width=80; int i=0; int x=wherex(); int y=wherey()+1;
x=40; for(int k=0;k<40;k++)
{
delay(DELAY);
gotoxy(x+k,y);
cout<<(char)240;
gotoxy(x-k,y);
delay(DELAY);
cout<<(char)240;
}
cout<<"\n";
}
if(ptr!=NULL)
{ // transposition word found in the // user input
flag=1;
// printing text before wordin[m] int times=ptr-s1; for(int i=0;i<times;i++)
{
delay(DELAY);
cout<<ip.userip[strlen(ip.keyword)+i];
} // printing the wordout
cout<<wordout[m]; // printing the left overs char c;
c=*(ptr+strlen(wordin[m])); int t=0; while(c!='\0')
{
cout<<*(ptr+strlen(wordin[m])+t);
t++;
c=*(ptr+strlen(wordin[m])+t);
}
}
} // end of for // if flag is still zero , this means no transpose. if(0==flag)
{ char c;
c=*(s1+strlen(ip.keyword)); int t=0; while(c!='\0')
{
cout<<*(s1+t);
t++;
c=*(s1+t);
}
} // end of if break;
} else
{
cout<<replys[num][i];
delay(RanNum(DELAY));
}
} // end of for
cout<<"\n"<<user<<" > ";
} void resp :: quit_display_resp(int num)
{
cout<<"ELIZA > "; for(int i=0;i<strlen(replys[num]);i++)
{ // for deliberate typing errors if(RanNum(6)==0)
{ char c=RanNum(100); if(c=='\n' || c=='\b' || c==13)
cout<<"w"; else
cout<<c;
delay(RanNum(DELAY));
cout<<"\b";
}
cout<<replys[num][i];
delay(RanNum(DELAY));
} // end of for
}
resp keys[MAX_KEY]; int RanNum(int max)
{
randomize(); return rand() % max;
} void find_keyword()
{ int len=0; int lenkey=0; int key_no=0; char teststr[50]; while((ip.keyfound==0) &&(key_no!=MAX_KEY))
{ // getting the length of the keyword
lenkey=strlen(keys[key_no].getword());
void read_from_file()
{
ifstream fin; int index=-1;
fin.open("eliza.dat"); char line[MAX_RESP_LEN]; while(fin)
{
fin.getline(line,MAX_RESP_LEN); char *ptr=NULL;
ptr=strstr("@KWD@",line); if(strlen(line)<1)
{ break;
} elseif(ptr!=NULL)
{ // the next line is a keyword
fin.getline(line,MAX_RESP_LEN);
keys[++index].addword(line);
} else
{ // it is a response
keys[index].addresp(line);
}
} // end of while
} // end of function
void main()
{
clrscr();
display_line();
display_logo();
display_line(); // for initializing the global variables
initialize_global();
// for no response by the user.
resp null_resp;
null_resp.addresp("HUH ?");
null_resp.addresp("WHAT ?");
null_resp.addresp("COME AGAIN ?");
null_resp.addresp("HOW I AM SUPPOSED TO TALK IF YOU DON'T SAY ANYTHING ?");
// upon logging in
resp signon;
signon.addresp("HI, I'M ELIZA. WHAT DO YOU WANT TO TALK ABOUT ?");
signon.addresp("SO HOW ARE YOU DOING TODAY ?");
signon.addresp("HELLO, WHAT'S UP TODAY ?");
// when no key found
resp no_key;
no_key.addresp("PLEASE GO ON...");
no_key.addresp("WHAT DOES THAT SUGGEST TO YOU ?");
no_key.addresp("I SEE");
no_key.addresp("I'M NOT SURE I KNOW WHAT YOU ARE TALKING ABOUT ");
no_key.addresp("WHAT'S THAT SUPPOSED TO MEAN ?");
no_key.addresp("CAN YOU CLARIFY THAT A BIT ?");
no_key.addresp("THAT'S INTERESTING...");
no_key.addresp("AND ????");
resp bye;
bye.addresp("GOOD BYE, HAVE A NICE DAY...");
bye.addresp("BYE, HOPE TO SEE YOU SOON...");
bye.addresp("BYE AND KEEP IN TOUCH..."); // reading data from dictionary
read_from_file();
// STARTING CONVERSATION WITH THE USER // welcoming the user
cout<<"ELIZA > (PLEASE TYPE IN ALL CAPS) WHAT'S YOUR NAME DEAR ?\n";
cin>>user;
signon.display_resp(RanNum(signon.getcount()));
fflush(stdin);
gets(ip.userip);
strcpy(ip.userip,strupr(ip.userip)); while(strcmp(ip.userip,"BYE")!=0)
{
find_keyword(); if(strlen(ip.userip)<1)
{
null_resp.display_resp(RanNum(null_resp.getcount()));
} elseif(ip.keyfound==1)
{
keys[ip.keyno].display_resp(RanNum(keys[ip.keyno].getcount()));
} else
{
no_key.display_resp(RanNum(no_key.getcount()));
} // again returning to normal values of the data items
strcpy(ip.userip," ");
ip.keyno=-1;
ip.keyfound=0;
fflush(stdin);
gets(ip.userip);
strcpy(ip.userip,strupr(ip.userip));
} // end of while
bye.quit_display_resp(RanNum(null_resp.getcount()));
cout<<endl;
display_line();
cout<<"\t\t\tIMPORTANT\n\nPlease note that the current functionality and \
features of this program are very limited and they are just for \
accompanying the article that I posted on Planet Source Code. If you want \
to make this program more intelligent, make entries in Eliza.Dat file. \
\n You can also increase the string manipulation power of the program, \
like considering multiple lines from the user, etc. I had written this code in 1 1/2 hr. \
just to make it more easier for the readers of my article about what is \
happening.\n\n HOW SMART YOU MAKE YOUR ELIZA DEPENDS ON HOW FAR YOU EXTEND \ THIS PROGRAM. THERE IS PRACTICALLY NO LIMIT ! \n\n\n\ THIS CODE IS THE MINIMAL WORKING SKELETON !!\n\n";
display_line();
getch();
}