From 76a8f406ecca3eb1c6f67a6a4a73a297c79dc52c Mon Sep 17 00:00:00 2001 From: "omegablast2002@yahoo.com" Date: Sat, 1 Oct 2011 21:29:22 +0000 Subject: [PATCH] converted the player arrays into vectors, so we can test is a player is actually there at the time we are trying to access its variables. this fixes 2 crashes I found, the first, 2 color random mode would crash on load. 2nd, ai vs ai testing would randomly crash, this should fix that also. I noticed 2 color random mode is now trying to search for it's rules and sometimes flashes for a brief moment "error cant read file" or something like that....I could not find the source of that, it doesn't cause it to crash however it causes it to take a sec longer to load, this is before this commit btw, so the issue is still there. it was trying to load the rules, flashed the error then crashes...i fixed the crash but not the rules error. please review, i might have left in useless stuff... I also did notice something, the way we are creating players is kind of all over the place. imo this is bad, it made this conversation extra hard becuase you create one player over here, another type over there, the human over in this direction, back track and create another somewhere else...this needs to be taken into account for a refactor, all player creation should happen in the same function, and at the same times... the reason these 2 crashes existed was becuase players were being created before "gameobserver" in some modes, and in other modes, no player would exist at the time game was creating to set the player. but we then later call the same function when we actually load the player using the method specific to a mode. this just leads to headaches, I mean no offense, just a general observation i made when converting this players array. unfortunately that kind of refactor is just a little beyond my coding ability. --- projects/mtg/include/GameObserver.h | 6 +-- projects/mtg/include/GameStateDuel.h | 2 +- projects/mtg/include/TestSuiteAI.h | 2 +- projects/mtg/src/AIPlayer.cpp | 2 + projects/mtg/src/GameObserver.cpp | 9 +++-- projects/mtg/src/GameStateDuel.cpp | 32 +++++++--------- projects/mtg/src/Player.cpp | 1 + projects/mtg/src/Rules.cpp | 5 ++- projects/mtg/src/StoryFlow.cpp | 6 +-- projects/mtg/src/TestSuiteAI.cpp | 55 +++++++++++++++++----------- 10 files changed, 66 insertions(+), 54 deletions(-) diff --git a/projects/mtg/include/GameObserver.h b/projects/mtg/include/GameObserver.h index f1909905b..d41a8b169 100644 --- a/projects/mtg/include/GameObserver.h +++ b/projects/mtg/include/GameObserver.h @@ -47,7 +47,7 @@ class GameObserver{ DuelLayers * mLayers; ReplacementEffects *replacementEffects; Player * gameOver; - Player * players[2]; //created outside + vector players; //created outside time_t startedAt; Rules * mRules; @@ -63,14 +63,14 @@ class GameObserver{ void nextGamePhase(); void cleanupPhase(); void nextPlayer(); - void setPlayers(Player * _players[], int _nbplayers); + void setPlayers(vector _players, int _nbplayers); Player * currentPlayer; Player * currentActionPlayer; Player * isInterrupting; Player * opponent(); Player * currentlyActing(); GameObserver(); - GameObserver(Player * _players[], int _nbplayers); + GameObserver(vector _players, int _nbplayers); ~GameObserver(); void gameStateBasedEffects(); void enchantmentStatus(); diff --git a/projects/mtg/include/GameStateDuel.h b/projects/mtg/include/GameStateDuel.h index 924b0823d..78c9cb702 100644 --- a/projects/mtg/include/GameStateDuel.h +++ b/projects/mtg/include/GameStateDuel.h @@ -28,7 +28,7 @@ private: Credits * credits; int mGamePhase; Player * mCurrentPlayer; - Player * mPlayers[2]; + vector mPlayers; GameObserver * game; DeckMenu * deckmenu; DeckMenu * opponentMenu; diff --git a/projects/mtg/include/TestSuiteAI.h b/projects/mtg/include/TestSuiteAI.h index 9f356b03f..1022b5331 100644 --- a/projects/mtg/include/TestSuiteAI.h +++ b/projects/mtg/include/TestSuiteAI.h @@ -29,7 +29,7 @@ public: TestSuiteState(); ~TestSuiteState(); - TestSuiteAI* players[2]; + vector players; void cleanup(TestSuite*); }; diff --git a/projects/mtg/src/AIPlayer.cpp b/projects/mtg/src/AIPlayer.cpp index 385e8a98d..94df22397 100644 --- a/projects/mtg/src/AIPlayer.cpp +++ b/projects/mtg/src/AIPlayer.cpp @@ -269,6 +269,7 @@ AIPlayer * AIPlayerFactory::createAIPlayer(GameObserver *observer, MTGAllCards * // AIPlayerBaka will delete MTGDeck when it's time AIPlayerBaka * baka = NEW AIPlayerBaka(observer, deckFile, deckFileSmall, avatarFilename, NEW MTGDeck(deckFile, collection,0, deckSetting)); baka->deckId = deckid; + baka->setObserver(observer); return baka; } @@ -336,6 +337,7 @@ AIPlayer * AIPlayerFactory::createAIPlayerTest(GameObserver *observer, MTGAllCar NEW AIPlayerBakaB(observer, deckFile, deckFileSmall, avatarFilename, NEW MTGDeck(deckFile, collection,0, deckSetting)) : NEW AIPlayerBaka(observer, deckFile, deckFileSmall, avatarFilename, NEW MTGDeck(deckFile, collection,0, deckSetting)); baka->deckId = deckid; + baka->setObserver(observer); return baka; } #endif diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index f9f31d63e..7cb096ddb 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -35,17 +35,17 @@ void GameObserver::initialize() connectRule = false; } -void GameObserver::setPlayers(Player * _players[], int _nbplayers) +void GameObserver::setPlayers(vector _players, int _nbplayers) { - for (int i = 0; i < _nbplayers; i++) + for (size_t i = 0; i < _players.size(); i++) { - players[i] = _players[i]; + players.push_back(_players[i]); players[i]->setObserver(this); } nbPlayers = _nbplayers; } -GameObserver::GameObserver(Player * _players[], int _nb_players) +GameObserver::GameObserver(vector _players, int _nb_players) { initialize(); setPlayers(_players, _nb_players); @@ -341,6 +341,7 @@ GameObserver::~GameObserver() { SAFE_DELETE(players[i]); } + players.clear(); LOG("==GameObserver Destroyed=="); } diff --git a/projects/mtg/src/GameStateDuel.cpp b/projects/mtg/src/GameStateDuel.cpp index 47797d621..1c0a8ef64 100644 --- a/projects/mtg/src/GameStateDuel.cpp +++ b/projects/mtg/src/GameStateDuel.cpp @@ -68,10 +68,7 @@ int GameStateDuel::selectedAIDeckId = 0; GameStateDuel::GameStateDuel(GameApp* parent) : GameState(parent, "duel") { - for (int i = 0; i < 2; i++) - { - mPlayers[i] = NULL; - } + mPlayers.clear(); premadeDeck = false; game = NULL; deckmenu = NULL; @@ -189,10 +186,7 @@ void GameStateDuel::Start() deckmenu->Add(MENUITEM_CANCEL, "Main Menu", "Return to Main Menu"); } - for (int i = 0; i < 2; ++i) - { - mPlayers[i] = NULL; - } + mPlayers.clear(); } void GameStateDuel::loadPlayer(int playerId, int decknb, bool isAI, bool isNetwork) @@ -210,7 +204,7 @@ void GameStateDuel::loadPlayer(int playerId, int decknb, bool isAI, bool isNetwo sprintf(deckFile, "%s/deck%i.txt", options.profileFile().c_str(), decknb); char deckFileSmall[255]; sprintf(deckFileSmall, "player_deck%i", decknb); - mPlayers[playerId] = NEW HumanPlayer(game, deckFile, deckFileSmall); + mPlayers.push_back(NEW HumanPlayer(game, deckFile, deckFileSmall)); #ifdef NETWORK_SUPPORT if(isNetwork) { @@ -220,7 +214,7 @@ void GameStateDuel::loadPlayer(int playerId, int decknb, bool isAI, bool isNetwo } else { //Remote player - mPlayers[playerId] = NEW RemotePlayer(mParent->mpNetwork); + mPlayers.push_back(NEW RemotePlayer(mParent->mpNetwork)); #endif //NETWORK_SUPPORT } } @@ -229,7 +223,7 @@ void GameStateDuel::loadPlayer(int playerId, int decknb, bool isAI, bool isNetwo AIPlayerFactory playerCreator; Player * opponent = NULL; if (playerId == 1) opponent = mPlayers[0]; - mPlayers[playerId] = playerCreator.createAIPlayer(game, MTGCollection(), opponent, decknb); + mPlayers.push_back(playerCreator.createAIPlayer(game, MTGCollection(), opponent, decknb)); } } else @@ -239,11 +233,11 @@ void GameStateDuel::loadPlayer(int playerId, int decknb, bool isAI, bool isNetwo if (playerId == 1) opponent = mPlayers[0]; #ifdef AI_CHANGE_TESTING if (mParent->players[0] == PLAYER_TYPE_CPU_TEST) - mPlayers[playerId] = playerCreator.createAIPlayerTest(game, MTGCollection(), opponent, playerId == 0 ? "ai/bakaA/" : "ai/bakaB/"); + mPlayers.push_back(playerCreator.createAIPlayerTest(game, MTGCollection(), opponent, playerId == 0 ? "ai/bakaA/" : "ai/bakaB/")); else #endif { - mPlayers[playerId] = playerCreator.createAIPlayer(game, MTGCollection(), opponent); + mPlayers.push_back(playerCreator.createAIPlayer(game, MTGCollection(), opponent)); } if (mParent->players[playerId] == PLAYER_TYPE_CPU_TEST) @@ -265,9 +259,10 @@ void GameStateDuel::loadTestSuitePlayers() initRand(testSuite->seed); SAFE_DELETE(game); game = new GameObserver(); + mPlayers.clear(); for (int i = 0; i < 2; i++) { - mPlayers[i] = new TestSuiteAI(game, testSuite, i); + mPlayers.push_back(new TestSuiteAI(game, testSuite, i)); } game->setPlayers(mPlayers, 2); mParent->gameType = testSuite->gameType; @@ -289,21 +284,22 @@ void GameStateDuel::End() #endif JRenderer::GetInstance()->EnableVSync(false); - if (!premadeDeck && mPlayers[0] && mPlayers[1]) + if (!premadeDeck && mPlayers.size() && mPlayers[0] && mPlayers[1]) { // save the stats for the game mPlayers[0]->End(); } - else if ( !mPlayers[1] && mPlayers[0] ) + else if (mPlayers.size() && !mPlayers[1] && mPlayers[0] ) // clean up player object SAFE_DELETE( mPlayers[0] ); SAFE_DELETE(game); premadeDeck = false; - - for (int i = 0; i < 2; i++) + if(mPlayers.size()) + for (size_t i = 0; i < mPlayers.size(); i++) { mPlayers[i] = NULL; } + mPlayers.clear(); SAFE_DELETE(credits); SAFE_DELETE(menu); diff --git a/projects/mtg/src/Player.cpp b/projects/mtg/src/Player.cpp index 0e99f4db2..018f2fc1e 100644 --- a/projects/mtg/src/Player.cpp +++ b/projects/mtg/src/Player.cpp @@ -106,6 +106,7 @@ HumanPlayer::HumanPlayer(GameObserver *observer, string file, string fileSmall, { loadAvatar("avatar.jpg"); playMode = MODE_HUMAN; + setObserver(observer); } ManaPool * Player::getManaPool() diff --git a/projects/mtg/src/Rules.cpp b/projects/mtg/src/Rules.cpp index e751b201a..0c56b4752 100644 --- a/projects/mtg/src/Rules.cpp +++ b/projects/mtg/src/Rules.cpp @@ -288,7 +288,7 @@ Player * Rules::loadPlayerRandom(GameObserver* observer, int isAI, int mode) Player * Rules::initPlayer(GameObserver *g, int playerId) { - Player * p = g->players[playerId]; + Player * p = g->players.size() > 1?g->players[playerId]:NULL; if (!p) { int isAI = 1; @@ -342,7 +342,8 @@ void Rules::initPlayers(GameObserver *g) for (int i = 0; i < 2; i++) { Player * p = initPlayer(g, i); - g->players[i] = p; + if(p) + g->players.push_back(p); MTGDeck * deck = buildDeck(i); if (deck) { diff --git a/projects/mtg/src/StoryFlow.cpp b/projects/mtg/src/StoryFlow.cpp index 84578704d..ea1c99eb9 100644 --- a/projects/mtg/src/StoryFlow.cpp +++ b/projects/mtg/src/StoryFlow.cpp @@ -303,18 +303,18 @@ StoryChoice::StoryChoice(string pageId, string text, int JGOid, float mX, float //Actually loads a duel void StoryDuel::init() { - Player * players[2]; + vector players; char folder[255], deckFile[255], deckFileSmall[255]; sprintf(folder, CAMPAIGNS_FOLDER"%s/%s", mParent->folder.c_str(), pageId.c_str()); sprintf(deckFile, "%s/deck.txt", folder); sprintf(deckFileSmall, "campaign_%s", mParent->folder.c_str()); - players[0] = NEW HumanPlayer(0, deckFile, deckFileSmall); + players.push_back(NEW HumanPlayer(0, deckFile, deckFileSmall)); sprintf(deckFile, "%s/opponent_deck.txt", folder); sprintf(deckFileSmall, "campaign_ennemy_%s_%s", mParent->folder.c_str(), pageId.c_str()); - players[1] = NEW AIPlayerBaka(0, deckFile, deckFileSmall, "baka.jpg"); + players.push_back(NEW AIPlayerBaka(0, deckFile, deckFileSmall, "baka.jpg")); string rulesFile = folder; rulesFile.append("/rules.txt"); diff --git a/projects/mtg/src/TestSuiteAI.cpp b/projects/mtg/src/TestSuiteAI.cpp index 8a0c8dce1..80ca481b8 100644 --- a/projects/mtg/src/TestSuiteAI.cpp +++ b/projects/mtg/src/TestSuiteAI.cpp @@ -255,16 +255,22 @@ void TestSuiteActions::add(string s) TestSuiteState::TestSuiteState() { - players[0] = 0; - players[1] = 0; + for(size_t p = 0;p < players.size();++p) + { + players[p] = 0; + } + players.clear(); } TestSuiteState::~TestSuiteState() { - if(players[0]) - SAFE_DELETE(players[0]); - if(players[1]) - SAFE_DELETE(players[1]); + if(players.size()) + { + if(players[0]) + SAFE_DELETE(players[0]); + if(players[1]) + SAFE_DELETE(players[1]); + } }; void TestSuiteState::parsePlayerState(int playerId, string s) @@ -288,24 +294,28 @@ MTGPlayerCards * TestSuite::buildDeck(Player* player, int playerId) int list[100]; int nbcards = 0; MTGPlayerCards * deck = NULL; - - if(initState.players[playerId]) + if(initState.players.size()) { - MTGGameZone * loadedPlayerZones[] = { initState.players[playerId]->game->graveyard, - initState.players[playerId]->game->library, - initState.players[playerId]->game->hand, - initState.players[playerId]->game->inPlay }; - - for (int j = 0; j < 4; j++) + if(initState.players.size() > size_t(playerId)) { - for (size_t k = 0; k < loadedPlayerZones[j]->cards.size(); k++) + MTGGameZone * loadedPlayerZones[] = { initState.players[playerId]->game->graveyard, + initState.players[playerId]->game->library, + initState.players[playerId]->game->hand, + initState.players[playerId]->game->inPlay }; + + for (int j = 0; j < 4; j++) { - int cardid = loadedPlayerZones[j]->cards[k]->getId(); - list[nbcards] = cardid; - nbcards++; + for (size_t k = 0; k < loadedPlayerZones[j]->cards.size(); k++) + { + int cardid = loadedPlayerZones[j]->cards[k]->getId(); + list[nbcards] = cardid; + nbcards++; + } } + deck = NEW MTGPlayerCards(player, list, nbcards); } - deck = NEW MTGPlayerCards(player, list, nbcards); + else + deck = NEW MTGPlayerCards(); } else { @@ -591,13 +601,14 @@ void TestSuiteActions::cleanup() void TestSuiteState::cleanup(TestSuite* suite) { - for (int i = 0; i < 2; i++) + for (size_t i = 0; i < players.size(); i++) { SAFE_DELETE(players[i]); } + players.clear(); - players[0] = new TestSuiteAI(0, suite, 0); - players[1] = new TestSuiteAI(0, suite, 1);; + players.push_back(new TestSuiteAI(0, suite, 0)); + players.push_back(new TestSuiteAI(0, suite, 1)); } void TestSuite::cleanup()