Thread: chatter bot of sorts, help?

  1. #1
    Registered User
    Join Date
    Jun 2006
    Posts
    7

    chatter bot of sorts, help?

    I am working on a chatter bot of sorts who is meant to think he is Einstein i have looked into other options such as using aiml and a interpreter but i prefer this way.
    i am a fairly new c++ programmer heres what i quickly came up with
    Code:
    #include <iostream>
    
    using namespace std;
    string mainstring;
    string name = "Albert Einstein";
    string dateofbirth = "March 14, 1879";
    string dateofdeath = "April 18, 1955";
    string job = "theoretical physicist";
    string countryofbirth = "Germany";
    
    string question1 = "what is your name?";
    string userinput;
    
    int main()
    {
        cout<<"Hello ,I am "<< name << ".";
        cin>>userinput;
    
        if (userinput == question1)
        {
            cout << name;
        }
        else
        {
            cout <<"sorry i don't understand your question";
        }
        return 0;
    }
    you can see the obvious problem here i asked a friend who is a programmer and he said "int the output and have a lookup table" i am not really sure what he meant by that or if anyone could offer any other solutions i would be very pleased.
    i don't this belongs in the AI section as much as it does here,if the mods feel diffrent move it at your will.
    Last edited by demiurge; 09-15-2006 at 04:45 AM.

  2. #2
    The Richness... Richie T's Avatar
    Join Date
    Jan 2006
    Location
    Ireland
    Posts
    469
    You have two "problems" with this code:

    1. Need to include <string> to use strings - code will not compile without it
    2. Less of a problem, but probably what your asking about - you should use getline to read in your question - if you type in the correct question and use cin to read it, it will stop reading once it hits whitespace (i.e. the space after "what").

    That should help, but you should have stated the problem instead of leaving it up to us to find it.

    One more thing, no need to make your variables global - they should be inside main.
    No No's:
    fflush (stdin); gets (); void main ();


    Goodies:
    Example of fgets (); The FAQ, C/C++ Reference


    My Gear:
    OS - Windows XP
    IDE - MS Visual C++ 2008 Express Edition


    ASCII stupid question, get a stupid ANSI

  3. #3
    The superhaterodyne twomers's Avatar
    Join Date
    Dec 2005
    Location
    Ireland
    Posts
    2,273
    You may want to look at some toupper/tolower functionality too.

    It's not a good idea to have the if statement so ... sensitive to the inputted question. Instead of checking for "What is your name?", why don't you look for substrings, such as name, and what, and from that say "I'm twomers", or whatever. use a while loop too.

    Code:
    #include <iostream>
    
    using namespace std;
    
    string mainstring;
    string name = "Albert Einstein";
    string dateofbirth = "March 14, 1879";
    string dateofdeath = "April 18, 1955";
    string job = "theoretical physicist";
    string countryofbirth = "Germany";
    
    string question1 = "what is your name?";
    string userinput = "woot";
    
    int main( void )
    {
        while ( userinput != "q" )
        {
            cout<<"Enter your question (q to exit): ";
            getline( cin, userinput );
       
            if ( userinput == question1 )
            {
                cout << name;
            }
            else
            {
                cout <<"sorry i don't understand your question";
            }
        }
    
        return 0;
    }
    It may be easier to parse the question to a vector ... and then check for words that way.

  4. #4
    Its hard... But im here swgh's Avatar
    Join Date
    Apr 2005
    Location
    England
    Posts
    1,688
    You could also program the entire project using OOP. You could divide the project up into many files, each with a class interface, and you could inherit data members and functions from each class. Here are a few classes you could use:

    Userclass // for the user, deals with user name / all personal details

    GenericClass // deals with the cyber bot objerct

    Errorclass // could contain a list of MessageBox functions in a public class to display any errors
    that occur - on second thought, silly me! use a struct! It is silly using a class for all
    public members, what am i thinking!

    Eventclass // deals with all the events of the program, using ideas from the cyber bot class
    and the player class.

    This is just an idea, you are free to ignore me if you want, it would seem very organised
    and look proffesional if it was programed in OOP rather than structured with tons of functions.

    Oh, and one more thing, make sure the user name data member is private and is also a pointer

  5. #5
    Its hard... But im here swgh's Avatar
    Join Date
    Apr 2005
    Location
    England
    Posts
    1,688
    EDIT Sorry, in the original post, why have you declared all the string variables global? They really should be local at best. Global variables are hard to track, and if you have to use a global, it really should be a static one

  6. #6
    Registered User
    Join Date
    Jun 2006
    Posts
    7
    this is about as clear as mud
    oh and well the problem is it can't really anwser questions thats what i was looking for since i can only use one switch for IF and im pretty sure case is only numbers but then again im pretty new to c++ .
    Last edited by demiurge; 09-15-2006 at 09:00 PM.

  7. #7
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    I think your friend meant something like this:
    Code:
    string qa[][2] = {
        {"What is your name?", "John"},
        {"How many megabytes of RAM do you have?", "None of your business"},
        // ...
    };
    
    for(string::size_type x = 0; x < qa.length(); x ++) {
        if(qa[x][0] == question) {
            cout << qa[x][1] << endl;
            break;
        }
    }
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  8. #8
    Registered User
    Join Date
    Jun 2006
    Posts
    7
    hmm i can sort of see what he ment but its still pretty unclear to me on how i should work this since im pretty new to c++.

  9. #9
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Well, I gave you an example. If it's too complicated you might try this . . .
    Code:
    string questions[] = {
        "What is your name?",
        "How many megabytes of RAM do you have?",
        // ...
    };
    
    string answers[] = {
        "John",
        "None of your business",
         // ...
    };
    
    for(string::size_type x = 0; x < questions.length(); x ++) {
        if(thequestion == questions[x]) {
            cout << answers[x] << endl;
        }
    }
    That only uses single dimensional arrays . . . have you used arrays before?
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  10. #10
    Registered User
    Join Date
    Jun 2006
    Posts
    7
    Yes i have used arrays before
    I tryed messing with that code but i got a error
    Code:
    main.cpp:30: error: request for member `length' in `questions', which is of non-class type `std::string[2]'
    Last edited by demiurge; 09-15-2006 at 09:40 PM.

  11. #11
    Registered User
    Join Date
    Mar 2006
    Posts
    725
    Perhaps, maychance, dwks meant the sizeof() operator. (If you don't know what it really does, it's best you don't use it; it can be tricky at times.) But it would do good to stick the strings into a vector instead.
    Code:
    #include <stdio.h>
    
    void J(char*a){int f,i=0,c='1';for(;a[i]!='0';++i)if(i==81){
    puts(a);return;}for(;c<='9';++c){for(f=0;f<9;++f)if(a[i-i%27+i%9
    /3*3+f/3*9+f%3]==c||a[i%9+f*9]==c||a[i-i%9+f]==c)goto e;a[i]=c;J(a);a[i]
    ='0';e:;}}int main(int c,char**v){int t=0;if(c>1){for(;v[1][
    t];++t);if(t==81){J(v[1]);return 0;}}puts("sudoku [0-9]{81}");return 1;}

  12. #12
    The superhaterodyne twomers's Avatar
    Join Date
    Dec 2005
    Location
    Ireland
    Posts
    2,273
    Code:
    #include <vector>
    #include <string>
    
    // ...
    
    int main ( void )
    {
        std::vector<std::string> Questions;
        std::vector<std::string> Answers;
    
        Questions.push_back( "what is your name" );
        Answers.push_back  ( "twomers" );
    
        Questions.push_back( "what age are you" );
        Answers.push_back  ( "42" ); // no really
    
        // etc
        // then get the question, and do..
    
        string user_question;
    
        std::cout<< "What do you want to know: ";
        std::getline( std::cin, user_question );
    
        for ( int i=0; i<Questions.size(); i++ )
        {
            if ( user_question == Questions[i] ) //  or Questions.at( i ) may be better, has bounds checkin'
            {
                std::cout<< Answers[i]; // or Answers.at( i ); again
            }
        }
        // blah blah blah
        return 0;
    }
    using vectors, this is a method of implementing, using dwks' idea. Alternatively, you could have used a multi dim. array as the vector ... erm ... classifier and done the multi dim idea that he suggested

  13. #13
    Registered User
    Join Date
    Jun 2006
    Posts
    7
    ignore this.
    Quote Originally Posted by twomers
    You may want to look at some toupper/tolower functionality too.

    It's not a good idea to have the if statement so ... sensitive to the inputted question. Instead of checking for "What is your name?", why don't you look for substrings, such as name, and what, and from that say "I'm twomers", or whatever. use a while loop too.

    Code:
    #include <iostream>
    
    using namespace std;
    
    string mainstring;
    string name = "Albert Einstein";
    string dateofbirth = "March 14, 1879";
    string dateofdeath = "April 18, 1955";
    string job = "theoretical physicist";
    string countryofbirth = "Germany";
    
    string question1 = "what is your name?";
    string userinput = "woot";
    
    int main( void )
    {
        while ( userinput != "q" )
        {
            cout<<"Enter your question (q to exit): ";
            getline( cin, userinput );
       
            if ( userinput == question1 )
            {
                cout << name;
            }
            else
            {
                cout <<"sorry i don't understand your question";
            }
        }
    
        return 0;
    }
    It may be easier to parse the question to a vector ... and then check for words that way.
    Im found out how to put them into vectors but how do i look for substrings?

  14. #14
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Sorry, yes, I did mean sizeof().
    Code:
    string qa[][2] = {
        {"What is your name?", "John"},
        {"How many megabytes of RAM do you have?", "None of your business"},
        // ...
    };
    
    for(string::size_type x = 0; x < qa.length(); x ++) {
        if(qa[x][0] == question) {
            cout << qa[x][1] << endl;
            break;
        }
    }
    ->
    Code:
    string qa[][2] = {
        {"What is your name?", "John"},
        {"How many megabytes of RAM do you have?", "None of your business"},
        // ...
    };
    
    for(string::size_type x = 0; x < sizeof(qa) / sizeof(*qa); x ++) {
        if(qa[x][0] == question) {
            cout << qa[x][1] << endl;
            break;
        }
    }
    Im found out how to put them into vectors but how do i look for substrings?
    You could compare the value you're looking for with every string in the vector (a sequential search). Or maybe you could use the find algorithm: http://www.cppreference.com/cppalgorithm/find.html
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting a Very Simple Quake 2 Bot to Work
    By bengreenwood in forum C++ Programming
    Replies: 2
    Last Post: 03-19-2009, 05:36 AM
  2. Simple Sorts Confuse ME =/
    By otchster in forum C Programming
    Replies: 5
    Last Post: 12-03-2005, 02:02 PM
  3. active worlds sdk (first test bot)
    By LodeC in forum C++ Programming
    Replies: 2
    Last Post: 07-31-2004, 08:33 AM
  4. Anybody Familiar with A.L.I.C.E. bot?
    By blackwyvern in forum C++ Programming
    Replies: 6
    Last Post: 01-23-2002, 10:53 PM