- reworked the testsuite and the rules (storyflow) to use the same game deserialization code, moved that code to the players and zone classes

- removed every references to the gameobserver singleton. This object can now be instantiated several times as it's needed for minmax. To be able to do that, I mostly added a reference to a gameobserver from any targetable object (cards, players, spells) and abilities.
This commit is contained in:
Xawotihs
2011-10-01 13:30:30 +00:00
parent d6db0c4f63
commit 9adb9d625d
86 changed files with 1902 additions and 1961 deletions
+113 -25
View File
@@ -7,6 +7,9 @@
#include "MTGDeck.h"
#include "Subtypes.h"
#include "Rules.h"
#include "Token.h"
#if defined (WIN32) || defined (LINUX)
#include <time.h>
#endif
@@ -15,14 +18,17 @@
//------------------------------
MTGPlayerCards::MTGPlayerCards()
: owner(0)
{
init();
}
MTGPlayerCards::MTGPlayerCards(int * idList, int idListSize)
MTGPlayerCards::MTGPlayerCards(Player* player, int * idList, int idListSize)
: owner(player)
{
init();
int i;
for (i = 0; i < idListSize; i++)
{
MTGCard * card = MTGCollection()->getCardById(idList[i]);
@@ -35,6 +41,7 @@ MTGPlayerCards::MTGPlayerCards(int * idList, int idListSize)
}
MTGPlayerCards::MTGPlayerCards(MTGDeck * deck)
: owner(0)
{
init();
initDeck(deck);
@@ -116,7 +123,7 @@ void MTGPlayerCards::initGame(int shuffle, int draw)
void MTGPlayerCards::OptimizedHand(Player * who,int amount, int lands, int creatures, int othercards)
{
//give the Ai hand adventage to insure a challanging match.
GameObserver * game = game->GetInstance();
GameObserver * game = who->getObserver();
game->currentPlayerId = game->currentPlayerId;
game->currentPlayer = game->currentPlayer;
@@ -231,7 +238,7 @@ void MTGPlayerCards::drawFromLibrary()
}
if (cantlosers < 1)
{
GameObserver::GetInstance()->gameOver = library->owner;
library->owner->getObserver()->gameOver = library->owner;
}
return;
}
@@ -315,7 +322,7 @@ MTGCardInstance * MTGPlayerCards::putInHand(MTGCardInstance * card)
MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone * from, MTGGameZone * to)
{
MTGCardInstance * copy = NULL;
GameObserver *g = GameObserver::GetInstance();
GameObserver *g = owner->getObserver();
if (!from || !to)
return card; //Error check
@@ -387,7 +394,7 @@ void MTGPlayerCards::discardRandom(MTGGameZone * from, MTGCardInstance * source)
return;
int r = WRand() % (from->nb_cards);
WEvent * e = NEW WEventCardDiscard(from->cards[r]);
GameObserver * game = GameObserver::GetInstance();
GameObserver * game = owner->getObserver();
game->receiveEvent(e);
putInZone(from->cards[r], from, graveyard);
}
@@ -419,7 +426,7 @@ MTGGameZone::MTGGameZone() :
MTGGameZone::~MTGGameZone()
{
for (int i = 0; i < nb_cards; i++)
for (int i = 0; i < cards.size(); i++)
{
SAFE_DELETE( cards[i] );
}
@@ -439,6 +446,7 @@ void MTGGameZone::setOwner(Player * player)
{
cards[i]->owner = player;
cards[i]->lastController = player;
cards[i]->setObserver(player->getObserver());
}
owner = player;
}
@@ -647,7 +655,7 @@ int MTGGameZone::seenThisTurn(TargetChooser * tc, int castMethod)
int MTGGameZone::seenThisTurn(string targetChooserDefinition, int castMethod)
{
TargetChooserFactory tcf;
TargetChooserFactory tcf(owner->getObserver());
TargetChooser *tc = tcf.createTargetChooser(targetChooserDefinition, NULL);
int result = seenThisTurn(tc, castMethod);
delete(tc);
@@ -828,10 +836,10 @@ MTGGameZone * MTGGameZone::intToZone(int zoneId, Player * p, Player * p2)
}
}
MTGGameZone * MTGGameZone::intToZone(int zoneId, MTGCardInstance * source, MTGCardInstance * target)
MTGGameZone * MTGGameZone::intToZone(GameObserver *g, int zoneId, MTGCardInstance * source, MTGCardInstance * target)
{
Player *p, *p2;
GameObserver * g = GameObserver::GetInstance();
if (!source)
p = g->currentlyActing();
else
@@ -956,9 +964,9 @@ int MTGGameZone::zoneStringToId(string zoneName)
return 0;
}
MTGGameZone * MTGGameZone::stringToZone(string zoneName, MTGCardInstance * source, MTGCardInstance * target)
MTGGameZone * MTGGameZone::stringToZone(GameObserver *g, string zoneName, MTGCardInstance * source, MTGCardInstance * target)
{
return intToZone(zoneStringToId(zoneName), source, target);
return intToZone(g, zoneStringToId(zoneName), source, target);
}
ostream& MTGGameZone::toString(ostream& out) const
@@ -993,6 +1001,7 @@ ostream& operator<<(ostream& out, const MTGGameZone& z)
{
return z.toString(out);
}
ostream& operator<<(ostream& out, const MTGPlayerCards& z)
{
out << z.library->nb_cards << " ";
@@ -1002,28 +1011,107 @@ ostream& operator<<(ostream& out, const MTGPlayerCards& z)
return out;
}
istream& operator>>(istream& in, MTGPlayerCards& z)
istream& operator>>(istream& in, MTGGameZone& z)
{
int nb, mtgid;
in >> nb;
for (int i = 0; i < z.library->nb_cards; i++)
for (int i = 0; i < z.nb_cards; i++)
{
SAFE_DELETE( z.library->cards[i] );
SAFE_DELETE( z.cards[i] );
}
z.library->cards.clear();
z.library->cardsMap.clear();
z.cards.clear();
z.cardsMap.clear();
for (int i = 0; i < nb; i++)
string s;
while(std::getline(in, s))
{
in >> mtgid;
MTGCard * card = MTGCollection()->getCardById(mtgid);
if (card)
while(s.size())
{
MTGCardInstance * newCard = NEW MTGCardInstance(card, &z);
z.library->addCard(newCard);
size_t limiter = s.find(",");
MTGCard * card = 0;
string toFind;
if (limiter != string::npos)
{
toFind = trim(s.substr(0, limiter));
s = s.substr(limiter + 1);
}
else
{
toFind = trim(s);
s = "";
}
card = MTGCollection()->getCardByName(toFind);
int id = Rules::getMTGId(toFind);
if (card)
{
/* For the moment we add the card directly in the final zone.
This is not the normal way and this prevents to resolve spells.
We'll need a fusion operation afterward to cast relevant spells */
MTGCardInstance * newCard = NEW MTGCardInstance(card, z.owner->game);
z.addCard(newCard);
}
else
{
if(toFind == "*")
z.nb_cards++;
else if ( id < 0 )
{
// For the moment, we create a dummy Token to please the testsuite
Token* myToken = new Token(id);
z.addCard(myToken);
}
else
{
DebugTrace("Card unfound " << toFind << " " << id);
}
}
}
}
return in;
}
istream& operator>>(istream& in, MTGPlayerCards& z)
{
string s;
streampos pos = in.tellg();
while(std::getline(in, s))
{
size_t limiter = s.find("=");
if (limiter == string::npos) limiter = s.find(":");
string areaS;
if (limiter != string::npos)
{
areaS = s.substr(0, limiter);
if (areaS.compare("graveyard") == 0)
{
istringstream stream(s.substr(limiter+1));
stream >> (*z.graveyard);
}
else if (areaS.compare("library") == 0)
{
istringstream stream(s.substr(limiter+1));
stream >> (*z.library);
}
else if (areaS.compare("hand") == 0)
{
istringstream stream(s.substr(limiter+1));
stream >> (*z.hand);
}
else if (areaS.compare("inplay") == 0 || areaS.compare("battlefield") == 0)
{
istringstream stream(s.substr(limiter+1));
stream >> (*z.battlefield);
}
else
{
in.seekg(pos);
break;
}
}
pos = in.tellg();
}
return in;
}