Initial import.
This commit is contained in:
225
starter/src/chatlogic.cpp
Normal file
225
starter/src/chatlogic.cpp
Normal file
@@ -0,0 +1,225 @@
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
#include <tuple>
|
||||
#include <algorithm>
|
||||
|
||||
#include "graphedge.h"
|
||||
#include "graphnode.h"
|
||||
#include "chatbot.h"
|
||||
#include "chatlogic.h"
|
||||
|
||||
ChatLogic::ChatLogic()
|
||||
{
|
||||
_chatBot = new ChatBot();
|
||||
_chatBot->SetChatLogicHandle(this);
|
||||
}
|
||||
|
||||
ChatLogic::~ChatLogic()
|
||||
{
|
||||
|
||||
delete _chatBot;
|
||||
|
||||
// delete all nodes
|
||||
for (auto it = std::begin(_nodes); it != std::end(_nodes); ++it)
|
||||
{
|
||||
delete *it;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void ChatLogic::AddAllTokensToElement(std::string tokenID, tokenlist &tokens, T &element)
|
||||
{
|
||||
// find all occurences for current node
|
||||
auto token = tokens.begin();
|
||||
while (true)
|
||||
{
|
||||
token = std::find_if(token, tokens.end(), [&tokenID](const std::pair<std::string, std::string> &pair) { return pair.first == tokenID;; });
|
||||
if (token != tokens.end())
|
||||
{
|
||||
element.AddToken(token->second); // add new keyword to edge
|
||||
token++; // increment iterator to next element
|
||||
}
|
||||
else
|
||||
{
|
||||
break; // quit infinite while-loop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ChatLogic::LoadAnswerGraphFromFile(std::string filename)
|
||||
{
|
||||
// load file with answer graph elements
|
||||
std::ifstream file(filename);
|
||||
|
||||
// check for file availability and process it line by line
|
||||
if (file)
|
||||
{
|
||||
// loop over all lines in the file
|
||||
std::string lineStr;
|
||||
while (getline(file, lineStr))
|
||||
{
|
||||
// extract all tokens from current line
|
||||
tokenlist tokens;
|
||||
while (lineStr.size() > 0)
|
||||
{
|
||||
// extract next token
|
||||
int posTokenFront = lineStr.find("<");
|
||||
int posTokenBack = lineStr.find(">");
|
||||
if (posTokenFront < 0 || posTokenBack < 0)
|
||||
break; // quit loop if no complete token has been found
|
||||
std::string tokenStr = lineStr.substr(posTokenFront + 1, posTokenBack - 1);
|
||||
|
||||
// extract token type and info
|
||||
int posTokenInfo = tokenStr.find(":");
|
||||
if (posTokenInfo != std::string::npos)
|
||||
{
|
||||
std::string tokenType = tokenStr.substr(0, posTokenInfo);
|
||||
std::string tokenInfo = tokenStr.substr(posTokenInfo + 1, tokenStr.size() - 1);
|
||||
|
||||
// add token to vector
|
||||
tokens.push_back(std::make_pair(tokenType, tokenInfo));
|
||||
}
|
||||
|
||||
// remove token from current line
|
||||
lineStr = lineStr.substr(posTokenBack + 1, lineStr.size());
|
||||
}
|
||||
|
||||
// process tokens for current line
|
||||
auto type = std::find_if(tokens.begin(), tokens.end(), [](const std::pair<std::string, std::string> &pair) { return pair.first == "TYPE"; });
|
||||
if (type != tokens.end())
|
||||
{
|
||||
// check for id
|
||||
auto idToken = std::find_if(tokens.begin(), tokens.end(), [](const std::pair<std::string, std::string> &pair) { return pair.first == "ID"; });
|
||||
if (idToken != tokens.end())
|
||||
{
|
||||
// extract id from token
|
||||
int id = std::stoi(idToken->second);
|
||||
|
||||
// node-based processing
|
||||
if (type->second == "NODE")
|
||||
{
|
||||
// check if node with this ID exists already
|
||||
auto newNode = std::find_if(_nodes.begin(), _nodes.end(), [&id](GraphNode *node) { return node->GetID() == id; }); // TODO
|
||||
|
||||
// create new element if ID does not yet exist
|
||||
if (newNode == _nodes.end())
|
||||
{
|
||||
_nodes.emplace_back(new GraphNode(id)); // TODO
|
||||
newNode = _nodes.end() - 1; // get iterator to last element
|
||||
|
||||
// add all answers to current node
|
||||
AddAllTokensToElement("ANSWER", tokens, **newNode);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// edge-based processing
|
||||
if (type->second == "EDGE")
|
||||
{
|
||||
//// STUDENT CODE
|
||||
////
|
||||
|
||||
// find tokens for incoming (parent) and outgoing (child) node
|
||||
auto parentToken = std::find_if(tokens.begin(), tokens.end(), [](const std::pair<std::string, std::string> &pair) { return pair.first == "PARENT"; });
|
||||
auto childToken = std::find_if(tokens.begin(), tokens.end(), [](const std::pair<std::string, std::string> &pair) { return pair.first == "CHILD"; });
|
||||
|
||||
if (parentToken != tokens.end() && childToken != tokens.end())
|
||||
{
|
||||
// get iterator on incoming and outgoing node via ID search
|
||||
auto parentNode = std::find_if(_nodes.begin(), _nodes.end(), [&parentToken](GraphNode *node) { return node->GetID() == std::stoi(parentToken->second); }); // TODO
|
||||
auto childNode = std::find_if(_nodes.begin(), _nodes.end(), [&childToken](GraphNode *node) { return node->GetID() == std::stoi(childToken->second); }); // TODO
|
||||
|
||||
// TODO: create new edge
|
||||
GraphEdge *edge = new GraphEdge(id);
|
||||
edge->SetChildNode(*childNode);
|
||||
edge->SetParentNode(*parentNode);
|
||||
//_edges.push_back(edge);
|
||||
// END OF TODO
|
||||
|
||||
// find all keywords for current node
|
||||
AddAllTokensToElement("KEYWORD", tokens, *edge);
|
||||
|
||||
// TODO: store reference in child node and parent node
|
||||
(*childNode)->AddEdgeToParentNode(edge); // TODO: add non-owning reference
|
||||
(*parentNode)->AddEdgeToChildNode(edge); // TODO: transfer ownership to parent node
|
||||
// END OF TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Error: ID missing. Line is ignored!" << std::endl;
|
||||
}
|
||||
}
|
||||
} // eof loop over all lines in the file
|
||||
|
||||
file.close();
|
||||
|
||||
} // eof check for file availability
|
||||
else
|
||||
{
|
||||
std::cout << "File could not be opened!" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
//// STUDENT CODE
|
||||
////
|
||||
|
||||
// identify root node
|
||||
GraphNode *rootNode = nullptr;
|
||||
for (auto it = std::begin(_nodes); it != std::end(_nodes); ++it)
|
||||
{
|
||||
// search for nodes which have no incoming edges
|
||||
if ((*it)->GetNumberOfParents() == 0)
|
||||
{
|
||||
|
||||
if (rootNode == nullptr)
|
||||
{
|
||||
// assign current node to root
|
||||
rootNode = *it; // TODO: assign current node to root
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "ERROR : Multiple root nodes detected" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: add chatbot to graph root node
|
||||
_chatBot->SetRootNode(rootNode);
|
||||
rootNode->moveChatbotHere(_chatBot);
|
||||
// END OF TODO
|
||||
|
||||
}
|
||||
|
||||
#ifdef GUI_APP
|
||||
void ChatLogic::SetPanelDialogHandle(ChatBotPanelDialog *panelDialog)
|
||||
{
|
||||
_panelDialog = panelDialog;
|
||||
}
|
||||
|
||||
void ChatLogic::SendMessageToUser(std::string message)
|
||||
{
|
||||
_panelDialog->PrintChatbotResponse(message);
|
||||
}
|
||||
#else
|
||||
void ChatLogic::SetPanelDialogHandle(ChatBotPanelDialog *panelDialog) {}
|
||||
void ChatLogic::SendMessageToUser(std::string message) {}
|
||||
|
||||
void ChatLogic::SetChatbotHandle(ChatBot *chatbot) {
|
||||
_chatBot = chatbot;
|
||||
}
|
||||
|
||||
void ChatLogic::SendMessageToChatbot(std::string message) {
|
||||
if (_chatBot) {
|
||||
_chatBot->ReceiveMessageFromUser(message);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool ChatLogic::IsGraphLoaded() const {
|
||||
return !_nodes.empty();
|
||||
}
|
||||
Reference in New Issue
Block a user