# I am beginner at here. If here is not suitable for this kind of talk, please tell me where I go... I am thinking of developing pokemon AI. As a first step, I am trying to develop random-move agent by modifying source code of BattleServer. According to prior research, it will be done by following source code. But this article does not contain main.cpp and I wonder how to write it. # This is Japanese article, but I paste the code below and if you interested in, I will translate this to English. http://shingaryu.hatenablog.com/ent...%e3%82%a4%e3%83%96%e3%83%a9%e3%83%aa%e3%81%a8 # In these codes, I added English comments #ifndef LOCALBATTLETEST_H #define LOCALBATTLETEST_H #include <QObject> #include "battle.h" class LocalBattleTest : public QObject { Q_OBJECT public: explicit LocalBattleTest(QObject *parent = 0); ~LocalBattleTest(); QHash<int, BattleSituation *> battles; ContextSwitcher battleThread; BattleServerPluginManager *pluginManager; void testBattleExecute(); void commandChoice(int battleID, BattleChoice choice); void ShowCurrentHPs(); void databaseInit(); int newBattle(BattlePlayer player1, BattlePlayer player2, ChallengeInfo challengeInfo, TeamBattle team1, TeamBattle team2); void ShowCurrentHPs(int battleID); signals: public slots: void notifyInfo(int battleID, int playerID, const QByteArray &info); void notifyFinished(int battleid, int result, int winner, int loser); }; #endif // LOCALBATTLETEST_H //localbattletest.cpp #include "localbattletest.h" #include "battle.h" #include "pluginmanager.h" #include "moves.h" #include "abilities.h" #include "rbymoves.h" #include <PokemonInfo/movesetchecker.h> #include "../Shared/battlecommands.h" LocalBattleTest::LocalBattleTest(QObject *parent) : QObject(parent) { databaseInit(); battleThread.start(); pluginManager = new BattleServerPluginManager(); } LocalBattleTest::~LocalBattleTest() { } //initialize databese void LocalBattleTest::databaseInit() { //copied from BattleServer::changeDbMod() PokemonInfoConfig::setFillMode(FillMode::Server); PokemonInfoConfig::changeMod(""); /* Really useful for headless servers */ GenInfo::init("db/gens/"); PokemonInfo::init("db/pokes/"); MoveSetChecker::init("db/pokes/"); ItemInfo::init("db/items/"); MoveInfo::init("db/moves/"); TypeInfo::init("db/types/"); NatureInfo::init("db/natures/"); CategoryInfo::init("db/categories/"); AbilityInfo::init("db/abilities/"); HiddenPowerInfo::init("db/types/"); StatInfo::init("db/status/"); GenderInfo::init("db/genders/"); //needed by battlelogs plugin PokemonInfo::loadStadiumTradebacks(); MoveEffect::init(); RBYMoveEffect::init(); ItemEffect::init(); AbilityEffect::init(); } void LocalBattleTest::testBattleExecute() { //set name and ID as you like BattlePlayer player1("Satoshi", 0); BattlePlayer player2("Shigeru", 1); Team team; // you can read files made by Generator team.loadFromFile("(***file path***)"); auto team1 = TeamBattle(team); auto team2 = TeamBattle(); team2.generateRandom(Pokemon::gen(Gen::ORAS)); //random party newBattle(player1, player2, ChallengeInfo(), team1, team2); } // create new instance int LocalBattleTest::newBattle(BattlePlayer player1, BattlePlayer player2, ChallengeInfo challengeInfo, TeamBattle team1, TeamBattle team2) { // definition of Qhash to obey the protocol of server int initialID = 10; //as you like int maxID = 0; foreach (auto item, battles.keys()) { if(item > maxID){ maxID = item; } } auto id = battles.count() == 0 ? initialID : maxID + 1; // 6 on 6 single battle auto newBattle = new BattleSituation(player1, player2, challengeInfo, id, team1, team2, pluginManager); battles.insert(id, newBattle); //connection between BattleSituation and this object connect(newBattle, SIGNAL(battleInfo(int,int,QByteArray)), this, SLOT(notifyInfo(int,int,QByteArray))); connect(newBattle, SIGNAL(battleFinished(int,int,int,int)), this, SLOT(notifyFinished(int,int,int,int))); newBattle->start(battleThread); return id; } //reaction when receiving signal from BattleSituation void LocalBattleTest::notifyInfo(int battleID, int playerID, const QByteArray &info) { //Decoding information via QbyteArray and DataStream DataStream dataStream(info); uchar commandNumber; qint8 who; dataStream >> commandNumber >> who; using namespace BattleCommands; switch((int)commandNumber) //Only react to OfferChoice { case BattleCommand::OfferChoice: //OfferChoice means user must send something { if(who == 0) // showing HP when requirement choice to player1 { ShowCurrentHPs(battleID); } // List all legal moves and select randomly BattleChoices choiceRegulation; dataStream >> choiceRegulation; QList<BattleChoice> validChoices; bool isMegaEvo = choiceRegulation.mega; for(int i = 0; i < 4; i++) { if(choiceRegulation.attackAllowed) { AttackChoice attack; attack.attackTarget = (who == 0) ? 1 : 0; attack.attackSlot = i; BattleChoice battleChoice(who, attack); battleChoice.setMegaEvo(isMegaEvo); validChoices << battleChoice; } } if(choiceRegulation.switchAllowed) { for(int i = 0; i < 6; i++) { if (!battles[battleID]->isOut(who, i) && !battles[battleID]->poke(who, i).ko()) { SwitchChoice switchChoice; switchChoice.pokeSlot = i; validChoices << BattleChoice(who, switchChoice); } } } commandChoice(battleID, validChoices[rand() % validChoices.length()]); break; } } } //end of battle void LocalBattleTest::notifyFinished(int battleid, int result, int winner, int loser) { qDebug() << "finished"; } //execute commands void LocalBattleTest::commandChoice(int battleID, BattleChoice choice) { //for debug switch(choice.type) { case ChoiceType::AttackType: { auto moveNumber = battles[battleID]->poke(choice.slot()).move(choice.attackSlot()).num(); auto moveName = MoveInfo::Name(moveNumber); qDebug() << moveName << "is selected"; break; } case ChoiceType::SwitchType: { auto pokeName = battles[battleID]->poke(choice.slot(), choice.pokeSlot()).nick(); qDebug() << pokeName << "(change) is selected"; break; } } qDebug(); battles[battleID]->battleChoiceReceived(battles[battleID]->id(choice.slot()), choice); } //show HP for debug void LocalBattleTest::ShowCurrentHPs(int battleID) { auto b = battles[battleID]; qDebug() << "Player0 HP:" << b->poke(0, 0).lifePoints() << b->poke(0, 1).lifePoints() << b->poke(0, 2).lifePoints() << b->poke(0, 3).lifePoints() << b->poke(0, 4).lifePoints() << b->poke(0, 5).lifePoints(); qDebug() << "Player1 HP:" << b->poke(1, 0).lifePoints() << b->poke(1, 1).lifePoints() << b->poke(1, 2).lifePoints() << b->poke(1, 3).lifePoints() << b->poke(1, 4).lifePoints() << b->poke(1, 5).lifePoints(); qDebug(); } I modified main.cpp to int main(argc, argv){ QtCoreApplication a(argc,argv); auto lbt = new LocalBattleTest(); return a.exec(); } I succeed compile. But when I start the binary ./BattleServer, it stops during battle. If you know how to fix it please teach me :)