120 lines
3.0 KiB
C++
120 lines
3.0 KiB
C++
#include "bot.h"
|
|
|
|
#include <sstream>
|
|
|
|
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();
|
|
} |