Assignment 3: Chatbots

In this assignment your task is to implement and test a number of different chatbots. Each different chatbot is implemented in a class that inherits from the Chatbot base class given below.

Getting Started

For this assignment, all the code you write should be put into a file named a3.cpp that looks like this:

// a3.cpp

/////////////////////////////////////////////////////////////////////////
//
// Student Info
// ------------
//
// Name : <put your full name here!>
// St.# : <put your full SFU student number here>
// Email: <put your SFU email address here>
//
//
// Statement of Originality
// ------------------------
//
// All the code and comments below are my own original work. For any non-
// original work, I have provided citations in the comments with enough
// detail so that someone can see the exact source and extent of the
// borrowed work.
//
// In addition, I have not shared this work with anyone else, and I have
// not seen solutions from other students, tutors, websites, books,
// etc.
//
/////////////////////////////////////////////////////////////////////////

#include "cmpt_error.h"    // These are the only permitted includes!
#include "Chatbot.h"       //
#include <iostream>        // Don't include anything else.
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <chrono>
#include <ctime>
#include <cassert>

using namespace std;

//
// ... write your code here here ...
//

int main() {
  //
  // ... put code for testing your functions here ...
  //
}

Here’s the contents of the file Chatbot.h:

// Chatbot.h

#include <string>

using namespace std;

class Chatbot {
public:
  // Name of this Chatbot
  virtual string name() const = 0;

  // Give a string to this chatbot.
  virtual void tell(const string& s) = 0;

  // Get a string from this chatbot.
  virtual string get_reply() = 0;

  // virtual destructor
  virtual ~Chatbot() { }
}; // class Chatbot

All the chatbot classes you create must inherit from this Chatbot base class and implement all the abstract methods in the intended way. We also want to see you use good programming style and make good use of C++’s object-oriented features.

Every chatbot class must allow for objects to be assigned a unique name (that is returned by the name() method).

Here is a helper method that you can use to have any two chatbots talk to each other:

void converse(Chatbot* a, Chatbot* b, int max_turns = 50) {
  for(int turn = 1; turn <= max_turns; turn++) {
    string a_msg = a->get_reply();
    cout << "(" << turn << ") " << a->name() << ": " << a_msg << "\n";

    turn++;
    if (turn > max_turns) return;

    b->tell(a_msg);
    string b_msg = b->get_reply();

    cout << "(" << turn << ") " << b->name() << ": " << b_msg << "\n";
    a->tell(b_msg);
  } // for
}

You can change this if you like. One way to test a new chatbot is to run it with a User_bot (see below) in this function.

Make sure to test all your chatbots!

Chatbot 1: Mirrored Replies

Implement a chatbot class called Mirror_bot that always replies with the last string that it was told. If it needs to make a reply before being told anything, then its reply is a special “first reply” string that is given to it in its constructor.

For example:

Mirror_bot mbot("repeato", "repeato is ready to go!");

The name of mbot is repeato, and if it is asked to speak first, it will say the second string passed to the constructor.

Chatbot 2: Random Replies

Implement a chatbot class called Random_bot that chooses a random reply from a list of given replies. It should have constructors that allow lists of replies to be read in at least these two ways:

  • From a vector<string> given in a constructor call. If passed-in vector is empty, call cmpt::error in the constructor with a helpful message.
  • From a text file, where each non-empty line of the file contains one reply. The constructor for this is given the name of the file in the constructor call. If the file can’t be opened, or if it is empty, then call cmpt::error in the constructor with a helpful message.

For example, here is one way to construct a random reply bot:

Random_bot cat{"Mittens", {"meow", "prr", "meeeeow"}};

Calling cat.get_reply() returns "meow", "prr", or "meeeeow" at random.

Now suppose the text file dog_sounds.txt contains this:

woof
ruff
yap yap yap
bow wow

Then we can construct another random reply bot like this:

Random_bot dog{"Fido", "dog_sounds.txt"};

Calling dog.get_reply() returns "woof", "ruff", yap yap yap, or "bow wow" at random.

Chatbot 3: The User

Implement a chatbot class called User_bot that asks the user to enter a line of text (on cin) whenever get_reply is called. tell should print the message to the screen. This will allow the user to talk with other bots using a function like converse above.

For example:

User_bot user{"stan"};

Chatbot 4: Current Time and Date

Implement a chatbot class called Datetime_bot that replies with the current date and time just when the last string told to it contains either “date” or “time” (or both) as a substring. If neither “date” nor “time” appears, then the reply is a default message chosen at random from a vector<string> of messages supplied in the constructor.

When checking for “date” or “time”, the case should not matter, e.g. if the last string told to the bot was “what’s the dAtE???”, then that counts as containing “date”.

For example:

Datetime_bot dt_bot{"deetee", {"Ask me about the date or time!",
                               "I know the date and time!"}};

Here, the first input is the bot’s name, and the second is the vector<string> of messages that will chosen from at random when neither “date” nor “time” was in the last string it was told.

Chatbot 5: Turing Bot

The Turing Test is a famous thought experiment that some computer scientists believe can be used to determine if a program has human-level intelligence. The program and the person have a text-only conversation using a chatbot-like interface. If the computer can fool the human into thinking it’s a real person, then, some say, the program must have human-level intelligence.

Implement an original and interesting chatbot class called Turing_bot that tries to pass the Turing test. Make it is as smart and feature-rich as you can. To simplify things a bit, it’s okay if your chatbot is restricted to one particular topic, as long as it is interesting and tries to be intelligent in some way. You can expand upon ideas from the previous bots, or try something new.

Please make something original and interesting, something that you would be proud to show off to others. Do a little bit of research on the web to get ideas for other kinds of chatbots.

Obviously low-effort Turing_bot classes will not get full marks.

Submit Your Work

Please put all your code into a single file named a3.cpp, and submit it on Canvas. Make sure to follow all the naming rules exactly as described, otherwise the marking software will probably give you 0!

The only file you submit is a3.cpp: don’t submit any other files. A copy of cmpt_error.h and Chatbot.h will be in the same folder as a3.cpp when it’s tested.

Basic Requirements

Before we give your program any marks, it must meet the following basic requirements:

  • It must compile on Ubuntu Linux using the standard course makefile:

    $ make a3
    g++  -std=c++14 -Wall -Wextra -Werror -Wfatal-errors -Wno-sign-compare -Wnon-virtual-dtor -g   a3.cpp   -o a3
    

    If your program fails to compile, your mark for this assignment will be 0.

    The standard course file cmpt_error.h will be in the same folder as a3.cpp when it’s compiled, so your program can use cmpt::error if necessary.

  • It must have no memory leaks, according to valgrind, e.g.:

    $ valgrind ./a3
    
    // ... lots of output ...
    

    A program is considered to have no memory leaks if:

    • In the LEAK SUMMARY, definitely lost, indirectly lost, and possibly lost must all be 0.
    • The ERROR SUMMARY must report 0 errors.
    • It is usually okay if still reachable reports a non- zero number of bytes.
  • You must include the large comment section with student info and the statement of originality. If your submitted file does not have this, then we will assume your work is not original and it will not be marked.

If your program meets all these basic requirements, then it will graded using the marking scheme on Canvas.