From d4056bb034584a76fa5b0fdce230f7ee9bf3e61b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20W=2E=20Urba=C5=84czyk?= Date: Sun, 11 Dec 2011 12:16:12 +0000 Subject: [PATCH] [programming challenge] Improved tactics handling. --- AI/StupidAI/StupidAI.cpp | 31 +++++++++++++++++++++++++--- AI/StupidAI/StupidAI.h | 2 ++ VCMI_BattleAiHost/CheckTime.h | 3 ++- VCMI_BattleAiHost/Client.cpp | 21 +++++++++++++++++++ VCMI_BattleAiHost/Client.h | 2 ++ VCMI_BattleAiHost/NetPacksRunner.cpp | 8 +++++-- 6 files changed, 61 insertions(+), 6 deletions(-) diff --git a/AI/StupidAI/StupidAI.cpp b/AI/StupidAI/StupidAI.cpp index 4b83e9bee..a6f75208c 100644 --- a/AI/StupidAI/StupidAI.cpp +++ b/AI/StupidAI/StupidAI.cpp @@ -113,9 +113,10 @@ BattleAction CStupidAI::activeStack( const CStack * stack ) // const CStack *firstEnemy = cb->battleGetStacks(CBattleCallback::ONLY_ENEMY).front(); // if(cb->battleCanCastThisSpell(VLC->spellh->spells[Spells::FORGETFULNESS]) == SpellCasting::OK) // castSpell(Spells::FORGETFULNESS, firstEnemy->position); - const CStack *firstEnemy = cb->battleGetStacks(CBattleCallback::ONLY_MINE).front(); - if(cb->battleCanCastThisSpell(VLC->spellh->spells[Spells::AIR_SHIELD]) == SpellCasting::OK) - castSpell(Spells::AIR_SHIELD, firstEnemy->position); +// +// const CStack *firstEnemy = cb->battleGetStacks(CBattleCallback::ONLY_MINE).front(); +// if(cb->battleCanCastThisSpell(VLC->spellh->spells[Spells::AIR_SHIELD]) == SpellCasting::OK) +// castSpell(Spells::AIR_SHIELD, firstEnemy->position); BOOST_FOREACH(const CStack *s, cb->battleGetStacks(CBattleCallback::ONLY_ENEMY)) @@ -332,4 +333,28 @@ void CStupidAI::castSpell(int spellID, int destinationTile, bool safe/* = true*/ ba.stackNumber = -(side+1); //-1 dla lewego bohatera, -2 dla prawego ba.additionalInfo = spellID; cb->battleMakeAction(&ba); +} + +void CStupidAI::yourTacticPhase(int distance) +{ + print("yourTacticPhase called"); + + + const CStack *someEnemy = cb->battleGetStacks(CBattleInfoCallback::ONLY_ENEMY).front(); + + BOOST_FOREACH(const CStack *someStack, cb->battleGetStacks(CBattleCallback::ONLY_MINE)) + { + BattleAction move; + if(cb->battleCanShoot(someStack, someEnemy->position)) + move = BattleAction::makeMove(someStack, someStack->position + THex::RIGHT); + else + move = BattleAction::makeMove(someStack, someStack->position + THex::TOP_RIGHT); + + + tlog0 << "Moving " << someStack->nodeName() << " to " << move.destinationTile << std::endl; + cb->battleMakeTacticAction(&move); + } + + BattleAction endTactics = BattleAction::makeEndOFTacticPhase(side); + cb->battleMakeTacticAction(&endTactics); //wazne - trzeba zakonczyc faze taktyczna! } \ No newline at end of file diff --git a/AI/StupidAI/StupidAI.h b/AI/StupidAI/StupidAI.h index 75e9afc15..cae91766b 100644 --- a/AI/StupidAI/StupidAI.h +++ b/AI/StupidAI/StupidAI.h @@ -34,5 +34,7 @@ public: BattleAction goTowards(const CStack * stack, THex hex ); void castSpell(int spellID, int destinationTile, bool safe = true); + + void yourTacticPhase(int distance); //called when interface has opportunity to use Tactics skill -> use cb->battleMakeTacticAction from this function }; diff --git a/VCMI_BattleAiHost/CheckTime.h b/VCMI_BattleAiHost/CheckTime.h index a9c05233a..16b8225a4 100644 --- a/VCMI_BattleAiHost/CheckTime.h +++ b/VCMI_BattleAiHost/CheckTime.h @@ -63,9 +63,10 @@ const int MEASURE_MARGIN = 3; const int HANGUP_TIME = 250; const int CONSTRUCT_TIME = 50; const int STARTUP_TIME = 100; +const int TACTICS_TIME = 1000; void postInfoCall(int timeUsed); -void postDecisionCall(int timeUsed, const std::string &text = "AI was thinking over an action"); +void postDecisionCall(int timeUsed, const std::string &text = "AI was thinking over an action", int timeLimit = MAKE_DECIDION_TIME); struct Bomb { diff --git a/VCMI_BattleAiHost/Client.cpp b/VCMI_BattleAiHost/Client.cpp index d66759db1..e10d814ee 100644 --- a/VCMI_BattleAiHost/Client.cpp +++ b/VCMI_BattleAiHost/Client.cpp @@ -158,4 +158,25 @@ CClient::CClient() applier = new CApplier; registerTypes2(*applier); +} + +void CClient::commenceTacticPhaseForInt(CBattleGameInterface *battleInt) +{ + setThreadName(-1, "CClient::commenceTacticPhaseForInt"); + try + { + boost::shared_lock shl(*gs->mx); + + Bomb *b = new Bomb(TACTICS_TIME + HANGUP_TIME, "yourTacticPhase timer"); + CheckTime timer; + battleInt->yourTacticPhase(gs->curB->tacticDistance); + postDecisionCall(timer.timeSinceStart(), "AI was using tactics ordering", TACTICS_TIME); + b->disarm(); + + if(gs && !!gs->curB && gs->curB->tacticDistance) //while awaiting for end of tactics phase, many things can happen (end of battle... or game) + { + MakeAction ma(BattleAction::makeEndOFTacticPhase(battleInt->playerID)); + serv->sendPack(ma); + } + } HANDLE_EXCEPTION } \ No newline at end of file diff --git a/VCMI_BattleAiHost/Client.h b/VCMI_BattleAiHost/Client.h index 374902f26..9629d4976 100644 --- a/VCMI_BattleAiHost/Client.h +++ b/VCMI_BattleAiHost/Client.h @@ -23,4 +23,6 @@ public: void handlePack( CPack * pack ); //applies the given pack and deletes it void requestMoveFromAI(const CStack *s); void requestMoveFromAIWorker(const CStack *s); + + void commenceTacticPhaseForInt(CBattleGameInterface *battleInt); }; \ No newline at end of file diff --git a/VCMI_BattleAiHost/NetPacksRunner.cpp b/VCMI_BattleAiHost/NetPacksRunner.cpp index 7bb7c8068..f2648187a 100644 --- a/VCMI_BattleAiHost/NetPacksRunner.cpp +++ b/VCMI_BattleAiHost/NetPacksRunner.cpp @@ -22,10 +22,10 @@ void postInfoCall(int timeUsed, int limit) } } -void postDecisionCall(int timeUsed, const std::string &text/* = "AI was thinking over an action"*/) +void postDecisionCall(int timeUsed, const std::string &text/* = "AI was thinking over an action"*/, int timeLimit /*= MAKE_DECIDION_TIME*/) { tlog0 << text << " for " << timeUsed << " ms.\n"; - if(timeUsed > MAKE_DECIDION_TIME + MEASURE_MARGIN) + if(timeUsed > timeLimit + MEASURE_MARGIN) { tlog1 << "That's too long! AI is disqualified!\n"; exit(1); @@ -283,6 +283,10 @@ void GarrisonDialog::applyCl(CClient *cl) void BattleStart::applyCl( CClient *cl ) { BATTLE_INTERFACE_CALL_IF_PRESENT_WITH_TIME_LIMIT(STARTUP_TIME, "battleStart timer", battleStart, info->belligerents[0], info->belligerents[1], info->tile, info->heroes[0], info->heroes[1], cl->color); + if(info->tacticDistance && cl->color == info->tacticsSide) + { + boost::thread(&CClient::commenceTacticPhaseForInt, cl, cl->ai); + } } void BattleNextRound::applyFirstCl(CClient *cl)