#include "bot.h" #include Bot::Bot(TelegramAPI::Manager* tapi, Conf& conf) : tapi(tapi), conf(conf) {} Bot::~Bot() { for(auto it : games) { delete it.second; } } bool Bot::handleStart(TelegramAPI::Manager* api, const TelegramAPI::Message& msg) { if(msg.chat.id > 0) { api->sendMessage(msg.chat.id, "This bot should be used in group chats"); } // create a game Game* g = new Game(); // g->addPlayer(msg.from.id); // does not work auto sendmsg = api->sendMessage(msg.chat.id, gameToMessage(g), gameToKeyboard(g)); if(sendmsg) { int64_t chatid = sendmsg.chat.id; uint64_t msgid = sendmsg.messageId; g->setMessageID(msgid); games.insert({{chatid, msgid}, g}); return true; } return false; } bool Bot::handleMessage(TelegramAPI::Manager* api, TelegramAPI::Message& msg) { return true; } bool Bot::handleCallback(TelegramAPI::Manager* api, TelegramAPI::CallbackQuery& clbq) { int64_t chatid = clbq.message.chat.id; uint64_t msgid = clbq.message.messageId; const std::string& data = clbq.data; auto it = games.find({chatid, msgid}); if(it == games.end()) { api->answerCallbackQuery(clbq.id, "Invalid game"); return true; } Game* g = it->second; if(data == "join") { if(g->addPlayer(clbq.from.id)) { api->answerCallbackQuery(clbq.id, "You joined the game"); updateGame(chatid, msgid, g); return true; } api->answerCallbackQuery(clbq.id, "You can not join"); return true; } // try to parse "x y" std::istringstream datastream(data); int x = -1, y = -1; datastream >> x >> y; if(x != -1 && y != -1) { Log::info << "turn: " << (int) x << " " << (int) y << " " << clbq.from.id; if(g->turn(x, y, clbq.from.id)) { api->answerCallbackQuery(clbq.id, "ok"); updateGame(chatid, msgid, g); return true; } api->answerCallbackQuery(clbq.id, "Error - this is not your turn"); } api->answerCallbackQuery(clbq.id, "Error - invalid button"); return true; } void Bot::stop() { } void Bot::updateGame(int64_t chatid, uint64_t msgid, const Game* g) { tapi->editMessageText(chatid, msgid, gameToMessage(g), gameToKeyboard(g)); } TelegramAPI::InlineKeyboard Bot::gameToKeyboard(const Game* g) const { static const std::string text[3] = {" ", "X", "O"}; TelegramAPI::InlineKeyboard kb; for(uint_fast8_t row = 0; row < g->getSize(); row++) { for(uint_fast8_t col = 0; col < g->getSize(); col++) { Game::SYM s = g->getPos(col, row); const std::string clb = std::to_string(col) + " " + std::to_string(row); auto btn = TelegramAPI::InlineButton::createCallback(text[(int) s], clb); kb.addButton(btn, row); } } if(!g->ready() && !g->done()) { // missing player kb.addButton(TelegramAPI::InlineButton::createCallback("Join Game", "join"), g->getSize()); } return kb; } std::string Bot::gameToMessage(const Game* g) const { std::ostringstream out; out << "X: " << g->getPlayerA() << std::endl; out << "O: " << g->getPlayerB() << std::endl; if(g->done()) { out << "Winner: " << g->getWinner() << std::endl; } else { out << "nextturn: " << (g->getNextTurn() ? "X" : "O") << std::endl; } return out.str(); }