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.
This commit is contained in:
omegablast2002@yahoo.com
2011-10-01 21:29:22 +00:00
parent 70ab70651a
commit 76a8f406ec
10 changed files with 66 additions and 54 deletions

View File

@@ -47,7 +47,7 @@ class GameObserver{
DuelLayers * mLayers;
ReplacementEffects *replacementEffects;
Player * gameOver;
Player * players[2]; //created outside
vector<Player *> 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<Player *> _players, int _nbplayers);
Player * currentPlayer;
Player * currentActionPlayer;
Player * isInterrupting;
Player * opponent();
Player * currentlyActing();
GameObserver();
GameObserver(Player * _players[], int _nbplayers);
GameObserver(vector<Player *> _players, int _nbplayers);
~GameObserver();
void gameStateBasedEffects();
void enchantmentStatus();

View File

@@ -28,7 +28,7 @@ private:
Credits * credits;
int mGamePhase;
Player * mCurrentPlayer;
Player * mPlayers[2];
vector<Player *> mPlayers;
GameObserver * game;
DeckMenu * deckmenu;
DeckMenu * opponentMenu;

View File

@@ -29,7 +29,7 @@ public:
TestSuiteState();
~TestSuiteState();
TestSuiteAI* players[2];
vector<TestSuiteAI*> players;
void cleanup(TestSuite*);
};

View File

@@ -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

View File

@@ -35,17 +35,17 @@ void GameObserver::initialize()
connectRule = false;
}
void GameObserver::setPlayers(Player * _players[], int _nbplayers)
void GameObserver::setPlayers(vector<Player *> _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<Player *> _players, int _nb_players)
{
initialize();
setPlayers(_players, _nb_players);
@@ -341,6 +341,7 @@ GameObserver::~GameObserver()
{
SAFE_DELETE(players[i]);
}
players.clear();
LOG("==GameObserver Destroyed==");
}

View File

@@ -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);

View File

@@ -106,6 +106,7 @@ HumanPlayer::HumanPlayer(GameObserver *observer, string file, string fileSmall,
{
loadAvatar("avatar.jpg");
playMode = MODE_HUMAN;
setObserver(observer);
}
ManaPool * Player::getManaPool()

View File

@@ -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)
{

View File

@@ -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<Player *> 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");

View File

@@ -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()