A Learning Chatterbot in C++

53,208

62

43

The following will provide instructions on how to write a fun and simple chatterbot like application in C++. The user enters a phrase and then the learner responds if the initial phrase exists in memory. If it doesn't exist in memory, then the user can teach the learner what to say. The open source speech synthesiser espeak is used to create audible output. You can get it here:

http://sourceforge.net/projects/espeak/

The code does assume you have this in the same dir as the chatterbot application, but if it is not, you just won't hear any audible message along with the textual output.

If you can't be bothered typing up the code, we have it attached..... but we wouldn't recommend that :P

We are assuming that you have a basic understanding of C++, and compilation of multifile projects.

Teacher Notes

Teachers! Did you use this instructable in your classroom?
Add a Teacher Note to share how you incorporated it into your lesson.

Step 1: Learner.h

Let's first create our learner class. A learner will respond to phrases if it knows how to, and learn how, if it doesn't.
Open up your favourite editor/IDE, create a header file called learner.h and type up the code in the image.
Again, I assume you understand what all this means, but I will explain the algorthmic details in the the next step.

Step 2: Learner.cpp

Create another file called learner.cpp and copy the code in the image.

Let’s take a look at the respond function. The algorithm is fundamentally simple, but the file operations can be confusing.

On line 15 we create a file stream object and then assign the memory file on line 16. Notice the ios::in argument. This means that we want to open the file for input, i.e. to read the file.

At line 19 we begin a while loop which will continue until the end of file is reached.

Line 21, getline, will read a multi word line, where the cursor is currently sat, and then move to the next line for the future operation. The phrase is stored in the identifier variable.

On line 23 we see if the current phrase matches the user’s phrase. If it does we use getline again on line 25 to get the response underneath the matched phrase. The response is then said using the learner’s voice object, and then we leave the function on line 27.

If we reach the end of file and we have found no response, then we go to line 31, where we close the file.

On 32 we again open the file, but this time for output, i.e. program to file. We also add the ios::app argument to ensure that we append to the end of the file.

On 33 we write the initial phrase, and then repeat the phrase on 35 to prompt the user for an ideal response. The user’s response is then written, and the file is closed.

The say function on line 46 simply passes the phrase to the voice objects say function for textual and audible output.

Step 3: Voice.h

Create another file called voice.h, and copy the code in the image. You may be questioning the need for this class, but we did this for portability and reusability. The class is actually quite good for any other projects where you want audible output.

This header file doesn’t require much description. This will come in the next step.

Step 4: Voice.cpp

Create another file called voice.cpp, and copy the code in the image. As expected it’s quite straight forward.

We are basically just executing the espeak application from current one, passing the phrase as an argument, hence the call to the system function…. The simplest way of executing cmd commands.

On 13 we use string summation to add our phrase to the command.

On 14 we convert from string to const char* so that we can pass it to the system function.

On 15 we output the text.

On 16 we call system, and execute espeak with the phrase as the argument to be said.

Make sure you put espeak.exe in the immediate directory of the compiled program.

Step 5: Main.cpp

Create another file named main.cpp, and copy the code in the image.

This is where are main function resides, hence where we start the program.

On line 7 we create a learner object and call it AI.

On 13 we begin the main program loop. It is infinite, therefore the only way to stop execution is if you close the application. The code from 13 to 19 is repeated.

Lines 14 to 16 prompt the user for input.

Lines 18 to 19 represent the learner output. We call AI’s respond function and get a response, or teach him what to say.

Step 6: Compilation and Setting Up for First Run

Now we are all done with the code.

Go ahead and compile.

Make sure you add a memory directory to the directory where the exe is. The memory file will be created in this folder on first run. You can actually edit the memory file directly if you wish to correct or add anything!

Also make sure you have the espeak exe in here too.

Now everything should be set up for the first execution :D

1 Person Made This Project!

Recommendations

  • Made with Math Contest

    Made with Math Contest
  • Multi-Discipline Contest

    Multi-Discipline Contest
  • Robotics Contest

    Robotics Contest

43 Discussions

0
None
SwingingPendulum

Question 5 months ago

I have an error in learner.cpp that says "identifier 'voice' is undefined." I'm having trouble working out the error, and was wondering if anyone could suggest a solution?

0
None
BrokeG

2 years ago

where do i put the memory.txt file and what do i put in it

1 reply
0
None
KellanABrokeG

Reply 6 months ago

typically when working on a project, creating a filestrem object creates a file in the directory (where all the files are stored that are necessary for your program). The directory is also the generic place to find a file to read from.
So if you just say :

fstream memory;
memory.open("memory.txt", ios::in);

it should theoretically create a file in your directory--but I could be wrong, I've only done that with ifstream and ofstream objects.

0
None
anmol1311

2 years ago

Can someone help me with the infinite loop in learner.cpp it's not working at all he to fix

1 reply
0
None
KellanAanmol1311

Reply 6 months ago

anything you put inside a " for(;;) " block will loop infinitely.
If for some reason that doesn't work, you could try " while(1) ".

0
None
elicorrales

1 year ago

Hi, thanks for the article, etc. Had fun with it. I'm at a loss as to how this is AI. (or the beginnings of). Is it just that the program "learns" (by me giving it the correct responses?)

thanks

1 reply
0
None
KellanAelicorrales

Reply 6 months ago

It isn't AI in the classical sense, but a chatbot does technically fall under the umbrella of AI in most code practice. Although the algorithms for a "real" AI would be significantly more complex, the algorithm shown here in the 'learner' class is a really good start for a budding AI developer.

0
None
KellanAartificial_intelligence

Answer 6 months ago

It seems like the above code starts the memory.txt as just an empty file. The algorithm itself relies wholly on the user to teach the bot how to respond (not the best approach in my opinion) rather than preparing the bot with a set of responses and phrases.

If you wanted to you could make a block of code that created the memory.txt file and put some of your own data in it, that way the bot isn't a vegetable when it starts out. something like this :

0
None
GustavoR31

3 years ago

sorry, I have a problem, when I execute the program it runs, but when i tap something and then appears the line of computer, it doesn´t appears any text and also it doesn´t appears the directory of memmory, how can i solve this?

2 replies
0
None
zxl109276GustavoR31

Reply 2 years ago

Instead of creating "memory.txt", just creat a text file and name it "memory"

0
None
ashawe

2 years ago

I get a error while building main.cpp which says that 'getline' : undeclared Identifier,

When I include the header file <string> I get an error:

main.obj : error LNK2001: unresolved external symbol "public: void __thiscall Learner::respond(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?respond@Learner@@QAEXV?$basic_string@DU?$char_traits@D@std@@V?

Please Help me out

Using Visual C++ 6.0

1 reply
0
None
DrewS83

10 months ago

Wow! This runs great in code:blocks. Thanks!

0
None
RigneS

Question 11 months ago on Introduction

i seem to be having an error, saying:
D:\Folder1\AI Project\collect2.exe [Error] Id returned 1 exit status
How do i fix this? please respond, thank you in advance

0
None
0xB4DC0FF3E

1 year ago

Nice programe, pretty easy for beginners

But this is not AI no ?

0
None
DhanushP3

1 year ago

can someone please explain that compilation step briefly please

1 reply
0
None
elicorralesDhanushP3

Reply 1 year ago

i think the easiest way is to use cmake, and place all the source files in their 'correct' location (where cmake expects them to be). I've completed this article both in cygwin and linux with no changes.

a nifty too is 'tree' . it shows your directory / file structure.

In the tree diagram, I placed the header files inside an 'include' dir. The cpp files inside a 'src' directory. I made sure I had 'espeak' already available, and just did a symbolic link 'ln -s <path to espeak> <local espeak name>.

Also, I did a 'touch memory/memory.txt' to create an empty memory file (where the identifiers / responses will be saved).

Finally, here's the contents of the file (CMakeLists.txt) that make cmake such a breeze:

############################################

# start of CMakeLists.txt

############################################

#not all of the lines below are required
cmake_minimum_required(VERSION 3.6)
project(file_reading)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_BUILD_TYPE Debug)
#Bring the headers, such as Student.h into the project
include_directories(include)
#However, the file(GLOB...) allows for wildcard additions:
file(GLOB SOURCES "src/*.cpp")
add_executable(chatterbot ${SOURCES})

############################################

# end of CMakeLists.txt

############################################

then, I ran 'cmake . ' (notice the dot)

After cmake does its thing, I ran 'make' , and that's what compiles and produces the chatterbox executable.

chatterbox-tree-diag.JPGcmake-output.JPGmake-output.JPGchatterbox.JPGchatterbox-output.JPG
0
None
AsadM31

1 year ago

Anyone Knows???How do i change the voice of this app like any other espeak file or computer internal voice of microsoft ???
Please Reply!!!!!!