From 29132073ded909337c99c88a872c8630871be930 Mon Sep 17 00:00:00 2001 From: Xawotihs Date: Wed, 23 Nov 2011 19:11:48 +0000 Subject: [PATCH] - Modified DeckManager class to not use a global instance anymore when used within the game engine - Modified DuelLayers to not use a global MTGPhaseGame instance anymore - Moved the reset of currentActionCard out of the ActionLayer render function : that fixes the remaing problematic tests in the multithreaded testsuite - Added a method in ActionLayer converting a card ability into a menu index - Used this new method in the game observer to log correctly AI ability actions - Added a DumpAssert method in the game observer, it can be used to dump the game and assert in order to easy crash reproduction - Cleaned up TargetList properties access - Added an optimisation in GuiMana to not compute update code if the rendering is not used (multi-threaded mode) - Added a deadlock detection in the test AI vs AI multithreaded mode - Fixed minor bugs in test AI vs AI multithreaded mode - Added a games/second counter in the test AI vs AI rendering --- projects/mtg/include/ActionLayer.h | 1 + projects/mtg/include/DeckManager.h | 18 ++++----- projects/mtg/include/DuelLayers.h | 3 ++ projects/mtg/include/GameObserver.h | 5 +++ projects/mtg/include/GameStateDuel.h | 1 + projects/mtg/include/MTGGamePhase.h | 2 - projects/mtg/include/TargetsList.h | 5 ++- projects/mtg/src/AIPlayer.cpp | 8 ++-- projects/mtg/src/AIPlayerBaka.cpp | 2 +- projects/mtg/src/ActionLayer.cpp | 30 ++++++++++++++- projects/mtg/src/ActionStack.cpp | 10 +++-- projects/mtg/src/DeckManager.cpp | 15 +++----- projects/mtg/src/DuelLayers.cpp | 2 +- projects/mtg/src/GameObserver.cpp | 55 +++++++++++++++++++++------- projects/mtg/src/GameStateDuel.cpp | 53 +++++++++++++++++++-------- projects/mtg/src/GuiMana.cpp | 1 + projects/mtg/src/MTGAbility.cpp | 8 ++-- projects/mtg/src/MTGGamePhase.cpp | 3 -- projects/mtg/src/Player.cpp | 2 +- projects/mtg/src/Rules.cpp | 2 +- 20 files changed, 153 insertions(+), 73 deletions(-) diff --git a/projects/mtg/include/ActionLayer.h b/projects/mtg/include/ActionLayer.h index c7056b603..c2bf50e5f 100644 --- a/projects/mtg/include/ActionLayer.h +++ b/projects/mtg/include/ActionLayer.h @@ -37,6 +37,7 @@ public: int receiveEventPlus(WEvent * event); int reactToTargetClick(Targetable * card); int isReactingToClick(MTGCardInstance * card); + bool getMenuIdFromCardAbility(MTGCardInstance *card, MTGAbility *ability, int& menuId); int reactToClick(MTGCardInstance * card); int reactToClick(ActionElement * ability, MTGCardInstance * card); int reactToTargetClick(ActionElement * ability, Targetable * card); diff --git a/projects/mtg/include/DeckManager.h b/projects/mtg/include/DeckManager.h index 213066679..1c324c667 100644 --- a/projects/mtg/include/DeckManager.h +++ b/projects/mtg/include/DeckManager.h @@ -8,21 +8,19 @@ using namespace std; class DeckManager { private: - static bool instanceFlag; + vector playerDeckOrderList; + vector aiDeckOrderList; + map playerDeckStatsMap; + map aiDeckStatsMap; + static DeckManager *mInstance; + +public: DeckManager() { //private constructor } -public: - - vector playerDeckOrderList; - vector aiDeckOrderList; - - map playerDeckStatsMap; - map aiDeckStatsMap; - void updateMetaDataList(vector* refList, bool isAI); vector * getPlayerDeckOrderList(); vector * getAIDeckOrderList(); @@ -40,7 +38,7 @@ public: //convenience method to get the difficulty rating between two decks. This should be refined a little more //since the eventual move of all deck meta data should be managed by this class - static int getDifficultyRating(Player *statsPlayer, Player *player); + int getDifficultyRating(Player *statsPlayer, Player *player); ~DeckManager(); diff --git a/projects/mtg/include/DuelLayers.h b/projects/mtg/include/DuelLayers.h index 52986e645..8093a3d5c 100644 --- a/projects/mtg/include/DuelLayers.h +++ b/projects/mtg/include/DuelLayers.h @@ -14,6 +14,7 @@ class GuiCombat; class GuiAvatars; class CardSelectorBase; struct Pos; +class MTGGamePhase; class DuelLayers { @@ -27,6 +28,7 @@ protected: GuiHandSelf *hand; GuiAvatars * avatars; GameObserver* observer; + MTGGamePhase* phaseHandler; public: DuelLayers(); @@ -36,6 +38,7 @@ public: ActionStack * stackLayer(); GuiCombat * combatLayer(); GuiAvatars * GetAvatars(); + MTGGamePhase* getPhaseHandler() {return phaseHandler;}; void init(GameObserver* go); virtual void Update(float dt, Player * player); void CheckUserInput(int isAI); diff --git a/projects/mtg/include/GameObserver.h b/projects/mtg/include/GameObserver.h index 3dfff8efe..7dd22be4f 100644 --- a/projects/mtg/include/GameObserver.h +++ b/projects/mtg/include/GameObserver.h @@ -23,6 +23,7 @@ class TargetChooser; class Rules; class TestSuiteGame; class Trash; +class DeckManager; using namespace std; class GameObserver{ @@ -37,6 +38,8 @@ class GameObserver{ RandomGenerator randomGenerator; WResourceManager* mResourceManager; JGE* mJGE; + DeckManager* mDeckManager; + size_t updateCtr; #ifdef ACTION_LOGGING_TESTING GameObserver* oldGame; @@ -139,6 +142,8 @@ class GameObserver{ CardSelectorBase* getCardSelector() { return mLayers->mCardSelector;}; bool operator==(const GameObserver& aGame); JGE* getInput(){return mJGE;}; + DeckManager* getDeckManager(){ return mDeckManager; }; + void dumpAssert(bool val); }; diff --git a/projects/mtg/include/GameStateDuel.h b/projects/mtg/include/GameStateDuel.h index 2796d7937..5526ac39a 100644 --- a/projects/mtg/include/GameStateDuel.h +++ b/projects/mtg/include/GameStateDuel.h @@ -57,6 +57,7 @@ public: #endif #ifdef AI_CHANGE_TESTING + int startTime; int totalTestGames; int testPlayer2Victories; int totalAIDecks; diff --git a/projects/mtg/include/MTGGamePhase.h b/projects/mtg/include/MTGGamePhase.h index 91ff995d8..96796a931 100644 --- a/projects/mtg/include/MTGGamePhase.h +++ b/projects/mtg/include/MTGGamePhase.h @@ -13,12 +13,10 @@ protected: float animation; int currentState; WFont * mFont; - static MTGGamePhase* instance; GameObserver* observer; public: MTGGamePhase(GameObserver* g, int id); - static MTGGamePhase* GetInstance() { return instance; }; virtual void Update(float dt); bool CheckUserInput(JButton key); virtual MTGGamePhase * clone() const; diff --git a/projects/mtg/include/TargetsList.h b/projects/mtg/include/TargetsList.h index 922979d13..cf4d4c88a 100644 --- a/projects/mtg/include/TargetsList.h +++ b/projects/mtg/include/TargetsList.h @@ -14,15 +14,16 @@ using std::vector; class TargetsList { -private: +protected: size_t iterateTarget(Targetable * previous); + vector targets; public: TargetsList(); TargetsList(Targetable * _targets[], int nbtargets); - vector targets; int alreadyHasTarget(Targetable * target); int removeTarget(Targetable * _card); int toggleTarget(Targetable * _card); + size_t getNbTargets() {return targets.size();}; virtual int addTarget(Targetable * _target); MTGCardInstance * getNextCardTarget(MTGCardInstance * previous = 0); Player * getNextPlayerTarget(Player * previous = 0); diff --git a/projects/mtg/src/AIPlayer.cpp b/projects/mtg/src/AIPlayer.cpp index 1c7ad29ca..5551eaaea 100644 --- a/projects/mtg/src/AIPlayer.cpp +++ b/projects/mtg/src/AIPlayer.cpp @@ -236,7 +236,7 @@ AIPlayer * AIPlayerFactory::createAIPlayer(GameObserver *observer, MTGAllCards * deckid = 1 + WRand() % (nbdecks); } sprintf(deckFile, "ai/baka/deck%i.txt", deckid); - DeckMetaData *aiMeta = DeckManager::GetInstance()->getDeckMetaDataByFilename( deckFile, true); + DeckMetaData *aiMeta = observer->getDeckManager()->getDeckMetaDataByFilename( deckFile, true); avatarFilename = aiMeta->getAvatarFilename(); sprintf(deckFileSmall, "ai_baka_deck%i", deckid); } @@ -245,7 +245,7 @@ AIPlayer * AIPlayerFactory::createAIPlayer(GameObserver *observer, MTGAllCards * if ( opponent ) { bool isOpponentAI = opponent->isAI() == 1; - DeckMetaData *meta = DeckManager::GetInstance()->getDeckMetaDataByFilename( opponent->deckFile, isOpponentAI); + DeckMetaData *meta = observer->getDeckManager()->getDeckMetaDataByFilename( opponent->deckFile, isOpponentAI); if ( meta && meta->getVictoryPercentage() >= 65) deckSetting = HARD; } @@ -320,7 +320,7 @@ AIPlayer * AIPlayerFactory::createAIPlayerTest(GameObserver *observer, MTGAllCar deckid = 1 + WRand() % (nbdecks); sprintf(deckFile, "%sdeck%i.txt", folder.c_str(), deckid); - DeckMetaData *aiMeta = DeckManager::GetInstance()->getDeckMetaDataByFilename( deckFile, true); + DeckMetaData *aiMeta = observer->getDeckManager()->getDeckMetaDataByFilename( deckFile, true); avatarFilename = aiMeta->getAvatarFilename(); sprintf(deckFileSmall, "ai_baka_deck%i", deckid); @@ -329,7 +329,7 @@ AIPlayer * AIPlayerFactory::createAIPlayerTest(GameObserver *observer, MTGAllCar if ( opponent ) { bool isOpponentAI = opponent->isAI() == 1; - DeckMetaData *meta = DeckManager::GetInstance()->getDeckMetaDataByFilename( opponent->deckFile, isOpponentAI); + DeckMetaData *meta = observer->getDeckManager()->getDeckMetaDataByFilename( opponent->deckFile, isOpponentAI); if ( meta->getVictoryPercentage() >= 65) deckSetting = HARD; } diff --git a/projects/mtg/src/AIPlayerBaka.cpp b/projects/mtg/src/AIPlayerBaka.cpp index 9a6d50aaf..6a9982e12 100644 --- a/projects/mtg/src/AIPlayerBaka.cpp +++ b/projects/mtg/src/AIPlayerBaka.cpp @@ -1188,7 +1188,7 @@ int AIPlayerBaka::createAbilityTargets(MTGAbility * a, MTGCardInstance * c, Rank vectorrealTargets; if(a->getActionTc()->maxtargets != 1) { - if(a->getActionTc()->targets.size() && a->getActionTc()->attemptsToFill > 4) + if(a->getActionTc()->getNbTargets() && a->getActionTc()->attemptsToFill > 4) { a->getActionTc()->done = true; return 0; diff --git a/projects/mtg/src/ActionLayer.cpp b/projects/mtg/src/ActionLayer.cpp index e9db9ef8f..354bd8dee 100644 --- a/projects/mtg/src/ActionLayer.cpp +++ b/projects/mtg/src/ActionLayer.cpp @@ -178,7 +178,7 @@ void ActionLayer::Update(float dt) without this, the game locks into a freeze state while you try to select the targets and dont have enough to fill the maxtargets list. */ - if(int(ae->getActionTc()->targets.size()) == countTargets-1) + if(int(ae->getActionTc()->getNbTargets()) == countTargets-1) ae->getActionTc()->done = true; } } @@ -192,7 +192,7 @@ void ActionLayer::Render() abilitiesMenu->Render(); return; } - currentActionCard = NULL; + for (size_t i = 0; i < mObjects.size(); i++) { if (mObjects[i] != NULL) @@ -290,6 +290,29 @@ int ActionLayer::reactToTargetClick(Targetable * card) return result; } +bool ActionLayer::getMenuIdFromCardAbility(MTGCardInstance *card, MTGAbility *ability, int& menuId) +{ + int ctr = 0; + for (size_t i = 0; i < mObjects.size(); i++) + { + ActionElement * currentAction = (ActionElement *) mObjects[i]; + if (currentAction->isReactingToClick(card)) + { + if(currentAction == ability) { + menuId = ctr; + } + ctr++; + } + } + + // ability not working with card or only one ability possible + if(ctr == 0 || ctr == 1) + return false; + else + // several abilities working with card, menuId set + return true; +} + //TODO Simplify with only object !!! int ActionLayer::isReactingToClick(MTGCardInstance * card) { @@ -422,11 +445,13 @@ void ActionLayer::ButtonPressed(int controllerid, int controlid) ActionElement * currentAction = (ActionElement *) mObjects[controlid]; currentAction->reactToTargetClick(menuObject); menuObject = 0; + currentActionCard = NULL; } else if (controlid == kCancelMenuID) { observer->mLayers->stackLayer()->endOfInterruption(false); menuObject = 0; + currentActionCard = NULL; } else { @@ -462,6 +487,7 @@ void ActionLayer::ButtonPressedOnMultipleChoice(int choice) observer->mLayers->stackLayer()->endOfInterruption(false); } menuObject = 0; + currentActionCard = NULL; } ActionLayer::ActionLayer(GameObserver *observer) diff --git a/projects/mtg/src/ActionStack.cpp b/projects/mtg/src/ActionStack.cpp index b898a528d..6e3ec9dc1 100644 --- a/projects/mtg/src/ActionStack.cpp +++ b/projects/mtg/src/ActionStack.cpp @@ -216,8 +216,12 @@ Interruptible(observer, id), tc(tc), cost(_cost), payResult(payResult) _source->backupTargets.clear(); if (tc) { - for(size_t i = 0;i < tc->targets.size();i++) - _source->backupTargets.push_back(tc->targets[i]); + Targetable* t = NULL; + for(size_t i = 0;i < tc->getNbTargets();i++) + { + t = tc->getNextTarget(t); + _source->backupTargets.push_back(t); + } } // fill information on how the card came into this zone. Right now the quickest way is to do it here, based on how the mana was paid... @@ -356,7 +360,7 @@ int Spell::getNbTargets() { if (!tc) return 0; - return (int) (tc->targets.size()); + return (int) (tc->getNbTargets()); } void Spell::Render() diff --git a/projects/mtg/src/DeckManager.cpp b/projects/mtg/src/DeckManager.cpp index 0cf3984ab..ab939ee03 100644 --- a/projects/mtg/src/DeckManager.cpp +++ b/projects/mtg/src/DeckManager.cpp @@ -206,7 +206,6 @@ StatsWrapper * DeckManager::getExtendedDeckStats( DeckMetaData *selectedDeck, MT DeckManager * DeckManager::mInstance = NULL; -bool DeckManager::instanceFlag = false; void DeckManager::EndInstance() { @@ -215,10 +214,9 @@ void DeckManager::EndInstance() DeckManager* DeckManager::GetInstance() { - if (!instanceFlag) + if (!mInstance) { mInstance = NEW DeckManager(); - instanceFlag = true; } return mInstance; @@ -230,7 +228,7 @@ int DeckManager::getDifficultyRating(Player *statsPlayer, Player *player) { if(player->deckFile != "") { - DeckMetaData *meta = DeckManager::GetInstance()->getDeckMetaDataByFilename(player->deckFile, (player->isAI() == 1) ); + DeckMetaData *meta = getDeckMetaDataByFilename(player->deckFile, (player->isAI() == 1) ); return meta->getDifficulty(); } else @@ -239,23 +237,22 @@ int DeckManager::getDifficultyRating(Player *statsPlayer, Player *player) DeckManager::~DeckManager() { - instanceFlag = false; map::iterator it; vector::iterator metaDataIter; - for (it = mInstance->aiDeckStatsMap.begin(); it != mInstance->aiDeckStatsMap.end(); it++){ + for (it = aiDeckStatsMap.begin(); it != aiDeckStatsMap.end(); it++){ SAFE_DELETE(it->second); } - for (it = mInstance->playerDeckStatsMap.begin(); it != mInstance->playerDeckStatsMap.end(); it++){ + for (it = playerDeckStatsMap.begin(); it != playerDeckStatsMap.end(); it++){ SAFE_DELETE(it->second); } - for( metaDataIter = mInstance->aiDeckOrderList.begin(); metaDataIter != mInstance->aiDeckOrderList.end(); ++metaDataIter) + for( metaDataIter = aiDeckOrderList.begin(); metaDataIter != aiDeckOrderList.end(); ++metaDataIter) { SAFE_DELETE( *metaDataIter ); } - for( metaDataIter = mInstance->playerDeckOrderList.begin(); metaDataIter != mInstance->playerDeckOrderList.end(); ++metaDataIter) + for( metaDataIter = playerDeckOrderList.begin(); metaDataIter != playerDeckOrderList.end(); ++metaDataIter) { SAFE_DELETE( *metaDataIter ); } diff --git a/projects/mtg/src/DuelLayers.cpp b/projects/mtg/src/DuelLayers.cpp index 9b8412df5..da3cde38f 100644 --- a/projects/mtg/src/DuelLayers.cpp +++ b/projects/mtg/src/DuelLayers.cpp @@ -19,7 +19,7 @@ void DuelLayers::init(GameObserver* go) mCardSelector = NEW CardSelector(go, this); //1 Action Layer action = NEW ActionLayer(go); - action->Add(NEW MTGGamePhase(go, action->getMaxId())); //Phases handler + action->Add(phaseHandler = NEW MTGGamePhase(go, action->getMaxId())); //Phases handler action->Add(NEW OtherAbilitiesEventReceiver(go, -1)); //autohand, etc... handler //Other display elements action->Add(NEW HUDDisplay(go, -1)); diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 8d5aff325..0120d045d 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -13,6 +13,7 @@ #include "AIPlayerBaka.h" #include "MTGRules.h" #include "Trash.h" +#include "DeckManager.h" #ifdef TESTSUITE #include "TestSuiteAI.h" #endif @@ -69,6 +70,8 @@ GameObserver::~GameObserver() ExtraRules = 0; LOG("==GameObserver Destroyed=="); SAFE_DELETE(mTrash); + SAFE_DELETE(mDeckManager); + } GameObserver::GameObserver(WResourceManager *output, JGE* input) @@ -99,6 +102,7 @@ GameObserver::GameObserver(WResourceManager *output, JGE* input) mLoading = false; mLayers = NULL; mTrash = new Trash(); + mDeckManager = new DeckManager(); } int GameObserver::getCurrentGamePhase() @@ -475,6 +479,16 @@ bool GameObserver::operator==(const GameObserver& aGame) return (error == 0); } +void GameObserver::dumpAssert(bool val) +{ + if(!val) + { + cerr << *this << endl; + assert(0); + } +} + + void GameObserver::Update(float dt) { /*******************/ @@ -489,7 +503,7 @@ void GameObserver::Update(float dt) oldGame = new GameObserver(); oldGame->mRules = mRules; oldGame->load(stream.str()); - assert(*this == *oldGame); + DumpAssert(*this == *oldGame); } #endif // ACTION_LOGGING_TESTING @@ -526,7 +540,7 @@ void GameObserver::Update(float dt) //Handles game state based effects void GameObserver::gameStateBasedEffects() { - if(getCurrentTargetChooser() && int(getCurrentTargetChooser()->targets.size()) == getCurrentTargetChooser()->maxtargets) + if(getCurrentTargetChooser() && int(getCurrentTargetChooser()->getNbTargets()) == getCurrentTargetChooser()->maxtargets) getCurrentTargetChooser()->done = true; if (mLayers->stackLayer()->count(0, NOT_RESOLVED) != 0) return; @@ -993,7 +1007,7 @@ void GameObserver::ButtonPressed(PlayGuiObject * target) } else if (dynamic_cast(target)) { - MTGGamePhase::GetInstance()->NextGamePhase(); + mLayers->getPhaseHandler()->NextGamePhase(); } } @@ -1042,9 +1056,20 @@ bool GameObserver::WaitForExtraPayment(MTGCardInstance * card) int GameObserver::cardClick(MTGCardInstance * card, MTGAbility *ability) { MTGGameZone* zone = card->currentZone; - size_t index = card->currentZone->getIndex(card); + size_t index = 0; + if(zone) + index = zone->getIndex(card); + int choice; + bool logChoice = mLayers->actionLayer()->getMenuIdFromCardAbility(card, ability, choice); int result = ability->reactToClick(card); logAction(card, zone, index, result); + + if(logChoice) { + stringstream stream; + stream << "choice " << choice; + logAction(currentActionPlayer, stream.str()); + } + return result; } @@ -1089,7 +1114,7 @@ int GameObserver::cardClick(MTGCardInstance * card, Targetable * object) if (card == cardWaitingForTargets) { int _result = targetChooser->ForceTargetListReady(); - if(targetChooser->targetMin && int(targetChooser->targets.size()) < targetChooser->maxtargets) + if(targetChooser->targetMin && int(targetChooser->getNbTargets()) < targetChooser->maxtargets) _result = 0; if (_result) { @@ -1548,7 +1573,7 @@ bool GameObserver::processActions(bool undo) size_t begin = s.find("[")+1; size_t size = s.find("]")-begin; size_t index = atoi(s.substr(begin, size).c_str()); - assert(index < zone->cards.size()); + dumpAssert(index < zone->cards.size()); cardClick(zone->cards[index], zone->cards[index]); } else if (s.find("yes") != string::npos) { mLayers->stackLayer()->setIsInterrupting(p); @@ -1571,20 +1596,20 @@ bool GameObserver::processActions(bool undo) // that would allow the AI to use it as well. shuffleLibrary(p); } else { - assert(0); + dumpAssert(0); } size_t nb = actionsList.size(); - for (int i = 0; i<3; i++) + for (int i = 0; i<5; i++) { // let's fake an update Update(counter); counter += 1.000f; } - assert(actionsList.back() == *loadingite); - assert(nb == actionsList.size()); - assert(cmdIndex == (actionsList.size()-1)); + dumpAssert(actionsList.back() == *loadingite); + dumpAssert(nb == actionsList.size()); + dumpAssert(cmdIndex == (actionsList.size()-1)); } mLoading = false; @@ -1618,7 +1643,7 @@ void GameObserver::logAction(const string& s) if(mLoading) { string toCheck = *loadingite; - assert(toCheck == s); + dumpAssert(toCheck == s); } actionsList.push_back(s); }; @@ -1645,8 +1670,10 @@ void GameObserver::createPlayer(const string& playerMode) { case Player::MODE_AI: AIPlayerFactory playerCreator; - // FIXME: gonna break in AI vs AI mode - players.push_back(playerCreator.createAIPlayer(this, MTGCollection(), players[0])); + if(players.size()) + players.push_back(playerCreator.createAIPlayer(this, MTGCollection(), players[0])); + else + players.push_back(playerCreator.createAIPlayer(this, MTGCollection(), 0)); break; case Player::MODE_HUMAN: players.push_back(new HumanPlayer(this, "", "")); diff --git a/projects/mtg/src/GameStateDuel.cpp b/projects/mtg/src/GameStateDuel.cpp index d8e99eaa9..8aef5d085 100644 --- a/projects/mtg/src/GameStateDuel.cpp +++ b/projects/mtg/src/GameStateDuel.cpp @@ -284,12 +284,28 @@ void GameStateDuel::ThreadProc(void* inParam) while(instance->mGamePhase != DUEL_STATE_BACK_TO_MAIN_MENU) { GameObserver observer; + int oldTurn = -1; + int oldPhase = -1; + int stagnationCounter = -1; + observer.loadPlayer(0, PLAYER_TYPE_TESTSUITE); observer.loadPlayer(1, PLAYER_TYPE_TESTSUITE); observer.startGame(instance->mParent->gameType, instance->mParent->rules); - while(!observer.gameOver) + while(!observer.gameOver) { + if(observer.turn == oldTurn && observer.currentGamePhase == oldPhase) { + stagnationCounter++; + } else { + stagnationCounter = 0; + oldTurn = observer.turn; + oldPhase = observer.currentGamePhase; + } + if(stagnationCounter >= 1000) + { + observer.dumpAssert(false); + } observer.Update(counter++); + } instance->handleResults(&observer); } @@ -441,22 +457,25 @@ void GameStateDuel::Update(float dt) else #endif #ifdef AI_CHANGE_TESTING - if (mParent->players[0] == PLAYER_TYPE_CPU_TEST && mParent->players[1] == PLAYER_TYPE_CPU_TEST) { - handleResults(game); - End(); - Start(); - } - if(mWorkerThread.empty()) - { // "I don't like to wait" mode - size_t thread_count = 1; - #ifdef QT_CONFIG - thread_count = QThread::idealThreadCount(); - #endif - for(size_t i = 0; i < (thread_count-1); i++) - mWorkerThread.push_back(boost::thread(ThreadProc, this)); - } + if (mParent->players[0] == PLAYER_TYPE_CPU_TEST && mParent->players[1] == PLAYER_TYPE_CPU_TEST) + { + handleResults(game); + End(); + Start(); + } + if(mWorkerThread.empty()) + { // "I don't like to wait" mode + size_t thread_count = 1; + startTime = JGEGetTime(); + #ifdef QT_CONFIG + thread_count = QThread::idealThreadCount(); + #endif + for(size_t i = 0; i < (thread_count-1); i++) + mWorkerThread.push_back(boost::thread(ThreadProc, this)); + } + } #endif if (mParent->players[0] == PLAYER_TYPE_CPU && mParent->players[1] == PLAYER_TYPE_CPU) { @@ -566,6 +585,7 @@ void GameStateDuel::Render() if (game && totalTestGames) { char buf[4096]; + int currentTime = JGEGetTime(); if (totalTestGames < 2.5 * totalAIDecks) { @@ -580,7 +600,8 @@ void GameStateDuel::Render() mFont->SetColor(ARGB(255,255,0,0)); if (ratio > 0.52) mFont->SetColor(ARGB(255,0,255,0)); - sprintf(buf, "Victories Player 2/total Games: %i/%i", testPlayer2Victories, totalTestGames); + sprintf(buf, "Victories Player 2/total Games: %i/%i - Games/second: %f", + testPlayer2Victories, totalTestGames, (float)(1000*totalTestGames)/(currentTime - startTime)); mFont->DrawString(buf,0,SCREEN_HEIGHT/2); } #endif diff --git a/projects/mtg/src/GuiMana.cpp b/projects/mtg/src/GuiMana.cpp index 89dd55db1..006448f73 100644 --- a/projects/mtg/src/GuiMana.cpp +++ b/projects/mtg/src/GuiMana.cpp @@ -303,6 +303,7 @@ bool remove_dead(ManaIcon* m) void GuiMana::Update(float dt) { + if(observer->getResourceManager()) { float shift = 0; for (vector::iterator it = manas.begin(); it != manas.end(); ++it) diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index bc7b1c4f8..950869da1 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -2834,7 +2834,7 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card, int a->canBeInterrupted = false; } - bool moreThanOneTarget = spell && spell->tc && spell->tc->targets.size() > 1; + bool moreThanOneTarget = spell && spell->tc && spell->tc->getNbTargets() > 1; if(moreThanOneTarget) a->target = spell->getNextTarget(); @@ -2850,7 +2850,7 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card, int } else { - if(!aMay || (aMay && a->target == spell->tc->targets[0])) + if(!aMay || (aMay && a->target == spell->tc->getNextTarget(0))) { MTGAbility * mClone = a->clone(); mClone->addToGame(); @@ -3990,7 +3990,7 @@ int TargetAbility::resolve() t = tc->getNextTarget(t); ability->target = t; } - tc->targets.clear(); + tc->initTargets(); return 1; } else @@ -4002,7 +4002,7 @@ int TargetAbility::resolve() t = tc->getNextTarget(t); ability->target = t; } - tc->targets.clear(); + tc->initTargets(); return 1; } } diff --git a/projects/mtg/src/MTGGamePhase.cpp b/projects/mtg/src/MTGGamePhase.cpp index 950ca9a42..da1cbb0f6 100644 --- a/projects/mtg/src/MTGGamePhase.cpp +++ b/projects/mtg/src/MTGGamePhase.cpp @@ -3,8 +3,6 @@ #include "MTGGamePhase.h" #include "GuiPhaseBar.h" -MTGGamePhase* MTGGamePhase::instance = 0; - MTGGamePhase::MTGGamePhase(GameObserver* g, int id) : ActionElement(id), observer(g) { @@ -12,7 +10,6 @@ MTGGamePhase::MTGGamePhase(GameObserver* g, int id) : currentState = -1; mFont = WResourceManager::Instance()->GetWFont(Fonts::MAIN_FONT); mFont->SetBase(0); // using 2nd font - instance = this; } void MTGGamePhase::Update(float dt) diff --git a/projects/mtg/src/Player.cpp b/projects/mtg/src/Player.cpp index 2236f2915..d8555f495 100644 --- a/projects/mtg/src/Player.cpp +++ b/projects/mtg/src/Player.cpp @@ -268,7 +268,7 @@ bool Player::parseLine(const string& s) if ( opponent() ) { bool isOpponentAI = opponent()->isAI() == 1; - DeckMetaData *meta = DeckManager::GetInstance()->getDeckMetaDataByFilename( opponent()->deckFile, isOpponentAI); + DeckMetaData *meta = observer->getDeckManager()->getDeckMetaDataByFilename( opponent()->deckFile, isOpponentAI); if ( meta && meta->getVictoryPercentage() >= 65) deckSetting = HARD; } diff --git a/projects/mtg/src/Rules.cpp b/projects/mtg/src/Rules.cpp index 0f458a77c..f8ab9fa39 100644 --- a/projects/mtg/src/Rules.cpp +++ b/projects/mtg/src/Rules.cpp @@ -163,7 +163,7 @@ void Rules::addExtraRules(GameObserver* g) #endif //NETWORK_SUPPORT )//keep this out of momir and other game modes. { - difficultyRating = DeckManager::getDifficultyRating(g->players[0], g->players[1]); + difficultyRating = g->getDeckManager()->getDifficultyRating(g->players[0], g->players[1]); } if (a)