- fixed memory leaks introduced in previous revision
- removed incorrect casts of MTGCardInstance into Spell objects. - AI Test system now allows you to put decks in ai/bakaA and ai/bakaB instead of ai/baka. This allows to let AIPlayerBaka and AIPlayerBakaB play with specific decks - Test suite speed improvement. Improved the card name cache. Test suite now runs in 850 seconds instead of 950 on my machine. - minor code cleanup
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
[INIT]
|
[INIT]
|
||||||
UNTAP
|
UNTAP
|
||||||
[PLAYER1]
|
[PLAYER1]
|
||||||
inplay:Thallid
|
#1924 is thallid, we use the id to be sure to match the token in the end
|
||||||
|
inplay:1924
|
||||||
[PLAYER2]
|
[PLAYER2]
|
||||||
[DO]
|
[DO]
|
||||||
eot
|
eot
|
||||||
@@ -13,11 +14,11 @@ eot
|
|||||||
next
|
next
|
||||||
next
|
next
|
||||||
next
|
next
|
||||||
thallid
|
1924
|
||||||
thallid
|
1924
|
||||||
[ASSERT]
|
[ASSERT]
|
||||||
FIRSTMAIN
|
FIRSTMAIN
|
||||||
[PLAYER1]
|
[PLAYER1]
|
||||||
inplay:Thallid,-1924
|
inplay:1924,-1924
|
||||||
[PLAYER2]
|
[PLAYER2]
|
||||||
[END]
|
[END]
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ class AIPlayerFactory{
|
|||||||
public:
|
public:
|
||||||
AIPlayer * createAIPlayer(MTGAllCards * collection, Player * opponent, int deckid = 0);
|
AIPlayer * createAIPlayer(MTGAllCards * collection, Player * opponent, int deckid = 0);
|
||||||
#ifdef AI_CHANGE_TESTING
|
#ifdef AI_CHANGE_TESTING
|
||||||
AIPlayer * createAIPlayerTest(MTGAllCards * collection, Player * opponent, int deckid = 0);
|
AIPlayer * createAIPlayerTest(MTGAllCards * collection, Player * opponent, string folder);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ public:
|
|||||||
Player * lastActionController;
|
Player * lastActionController;
|
||||||
int setIsInterrupting(Player * player);
|
int setIsInterrupting(Player * player);
|
||||||
int count( int type = 0 , int state = 0 , int display = -1);
|
int count( int type = 0 , int state = 0 , int display = -1);
|
||||||
int getActionElementFromCard(MTGCardInstance * card);
|
Interruptible * getActionElementFromCard(MTGCardInstance * card);
|
||||||
Interruptible * getPrevious(Interruptible * next, int type = 0, int state = 0 , int display = -1);
|
Interruptible * getPrevious(Interruptible * next, int type = 0, int state = 0 , int display = -1);
|
||||||
int getPreviousIndex(Interruptible * next, int type = 0, int state = 0 , int display = -1);
|
int getPreviousIndex(Interruptible * next, int type = 0, int state = 0 , int display = -1);
|
||||||
Interruptible * getNext(Interruptible * previous, int type = 0, int state = 0 , int display = -1);
|
Interruptible * getNext(Interruptible * previous, int type = 0, int state = 0 , int display = -1);
|
||||||
|
|||||||
@@ -37,12 +37,9 @@ public:
|
|||||||
if (card) return card->X;
|
if (card) return card->X;
|
||||||
return 1; //this should only hapen when the ai calls the ability. This is to give it an idea of the "direction" of X (positive/negative)
|
return 1; //this should only hapen when the ai calls the ability. This is to give it an idea of the "direction" of X (positive/negative)
|
||||||
}
|
}
|
||||||
WParsedInt(int value = 0)
|
|
||||||
{
|
|
||||||
intValue = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
WParsedInt(string s, Spell * spell, MTGCardInstance * card)
|
private:
|
||||||
|
void init(string s, Spell * spell, MTGCardInstance * card)
|
||||||
{
|
{
|
||||||
if(!card)
|
if(!card)
|
||||||
return;
|
return;
|
||||||
@@ -73,8 +70,7 @@ public:
|
|||||||
}
|
}
|
||||||
if(s == "prex")
|
if(s == "prex")
|
||||||
{
|
{
|
||||||
ManaCost * cX = NEW ManaCost(card->controller()->getManaPool()->Diff(card->getManaCost()));
|
ManaCost * cX = card->controller()->getManaPool()->Diff(card->getManaCost());
|
||||||
int preX =
|
|
||||||
intValue = cX->getCost(Constants::MTG_NB_COLORS);
|
intValue = cX->getCost(Constants::MTG_NB_COLORS);
|
||||||
delete cX;
|
delete cX;
|
||||||
}
|
}
|
||||||
@@ -220,6 +216,22 @@ public:
|
|||||||
}
|
}
|
||||||
intValue *= multiplier;
|
intValue *= multiplier;
|
||||||
}
|
}
|
||||||
|
public:
|
||||||
|
|
||||||
|
WParsedInt(int value = 0)
|
||||||
|
{
|
||||||
|
intValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
WParsedInt(string s, Spell * spell, MTGCardInstance * card)
|
||||||
|
{
|
||||||
|
init(s, spell, card);
|
||||||
|
}
|
||||||
|
|
||||||
|
WParsedInt(string s, MTGCardInstance * card)
|
||||||
|
{
|
||||||
|
init(s, NULL, card);
|
||||||
|
}
|
||||||
|
|
||||||
int getValue()
|
int getValue()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -119,6 +119,11 @@ public:
|
|||||||
map<string, CardPrimitive *> primitives;
|
map<string, CardPrimitive *> primitives;
|
||||||
MTGCard * _(int id);
|
MTGCard * _(int id);
|
||||||
MTGCard * getCardById(int id);
|
MTGCard * getCardById(int id);
|
||||||
|
|
||||||
|
#ifdef TESTSUITE
|
||||||
|
void prefetchCardNameCache();
|
||||||
|
#endif
|
||||||
|
|
||||||
MTGCard * getCardByName(string name);
|
MTGCard * getCardByName(string name);
|
||||||
int load(const char * config_file, const char * setName = NULL, int autoload = 1);
|
int load(const char * config_file, const char * setName = NULL, int autoload = 1);
|
||||||
int countByType(const char * _type);
|
int countByType(const char * _type);
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ private:
|
|||||||
bool forceAbility;
|
bool forceAbility;
|
||||||
int summoningSickness;
|
int summoningSickness;
|
||||||
|
|
||||||
|
|
||||||
int load(const char * filename);
|
int load(const char * filename);
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
@@ -84,6 +85,7 @@ public:
|
|||||||
int assertGame();
|
int assertGame();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
int startTime, endTime;
|
||||||
int gameType;
|
int gameType;
|
||||||
unsigned int seed;
|
unsigned int seed;
|
||||||
int nbFailed, nbTests, nbAIFailed, nbAITests;
|
int nbFailed, nbTests, nbAIFailed, nbAITests;
|
||||||
|
|||||||
@@ -286,46 +286,44 @@ void AIPlayer::Render()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef AI_CHANGE_TESTING
|
#ifdef AI_CHANGE_TESTING
|
||||||
AIPlayer * AIPlayerFactory::createAIPlayerTest(MTGAllCards * collection, Player * opponent, int deckid)
|
AIPlayer * AIPlayerFactory::createAIPlayerTest(MTGAllCards * collection, Player * opponent, string _folder)
|
||||||
{
|
{
|
||||||
char deckFile[512];
|
char deckFile[512];
|
||||||
string avatarFilename; // default imagename
|
string avatarFilename; // default imagename
|
||||||
char deckFileSmall[512];
|
char deckFileSmall[512];
|
||||||
|
|
||||||
if (deckid == GameStateDuel::MENUITEM_EVIL_TWIN)
|
|
||||||
{ //Evil twin
|
string folder = _folder.size() ? _folder : "ai/baka/";
|
||||||
sprintf(deckFile, "%s", opponent->deckFile.c_str());
|
|
||||||
DebugTrace("Evil Twin => " << opponent->deckFile);
|
int deckid = 0;
|
||||||
avatarFilename = "avatar.jpg";
|
|
||||||
sprintf(deckFileSmall, "%s", "ai_baka_eviltwin");
|
//random deck
|
||||||
}
|
int nbdecks = 0;
|
||||||
else
|
int found = 1;
|
||||||
|
while (found && nbdecks < options[Options::AIDECKS_UNLOCKED].number)
|
||||||
{
|
{
|
||||||
if (!deckid)
|
found = 0;
|
||||||
|
char buffer[512];
|
||||||
|
sprintf(buffer, "%sdeck%i.txt", folder.c_str(), nbdecks + 1);
|
||||||
|
if (FileExists(buffer))
|
||||||
{
|
{
|
||||||
//random deck
|
found = 1;
|
||||||
int nbdecks = 0;
|
nbdecks++;
|
||||||
int found = 1;
|
|
||||||
while (found && nbdecks < options[Options::AIDECKS_UNLOCKED].number)
|
|
||||||
{
|
|
||||||
found = 0;
|
|
||||||
char buffer[512];
|
|
||||||
sprintf(buffer, "ai/baka/deck%i.txt", nbdecks + 1);
|
|
||||||
if (FileExists(buffer))
|
|
||||||
{
|
|
||||||
found = 1;
|
|
||||||
nbdecks++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!nbdecks)
|
|
||||||
return NULL;
|
|
||||||
deckid = 1 + WRand() % (nbdecks);
|
|
||||||
}
|
}
|
||||||
sprintf(deckFile, "ai/baka/deck%i.txt", deckid);
|
|
||||||
DeckMetaData *aiMeta = DeckManager::GetInstance()->getDeckMetaDataByFilename( deckFile, true);
|
|
||||||
avatarFilename = aiMeta->getAvatarFilename();
|
|
||||||
sprintf(deckFileSmall, "ai_baka_deck%i", deckid);
|
|
||||||
}
|
}
|
||||||
|
if (!nbdecks)
|
||||||
|
{
|
||||||
|
if (_folder.size())
|
||||||
|
return createAIPlayerTest(collection, opponent, "");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
deckid = 1 + WRand() % (nbdecks);
|
||||||
|
|
||||||
|
sprintf(deckFile, "%sdeck%i.txt", folder.c_str(), deckid);
|
||||||
|
DeckMetaData *aiMeta = DeckManager::GetInstance()->getDeckMetaDataByFilename( deckFile, true);
|
||||||
|
avatarFilename = aiMeta->getAvatarFilename();
|
||||||
|
sprintf(deckFileSmall, "ai_baka_deck%i", deckid);
|
||||||
|
|
||||||
|
|
||||||
int deckSetting = EASY;
|
int deckSetting = EASY;
|
||||||
if ( opponent )
|
if ( opponent )
|
||||||
@@ -337,7 +335,9 @@ AIPlayer * AIPlayerFactory::createAIPlayerTest(MTGAllCards * collection, Player
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AIPlayerBaka will delete MTGDeck when it's time
|
// AIPlayerBaka will delete MTGDeck when it's time
|
||||||
AIPlayerBakaB * baka = NEW AIPlayerBakaB(deckFile, deckFileSmall, avatarFilename, NEW MTGDeck(deckFile, collection,0, deckSetting));
|
AIPlayerBaka * baka = opponent ?
|
||||||
|
NEW AIPlayerBakaB(deckFile, deckFileSmall, avatarFilename, NEW MTGDeck(deckFile, collection,0, deckSetting)) :
|
||||||
|
NEW AIPlayerBaka(deckFile, deckFileSmall, avatarFilename, NEW MTGDeck(deckFile, collection,0, deckSetting));
|
||||||
baka->deckId = deckid;
|
baka->deckId = deckid;
|
||||||
return baka;
|
return baka;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1754,10 +1754,8 @@ int AIPlayerBaka::computeActions()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Interruptible * action = g->mLayers->stackLayer()->getAt(-1);
|
Interruptible * action = g->mLayers->stackLayer()->getAt(-1);
|
||||||
Spell * spell = (Spell *) action;
|
Spell * spell = dynamic_cast<Spell *>(action);
|
||||||
Player * lastStackActionController = NULL;
|
Player * lastStackActionController = spell ? spell->source->controller() : NULL;
|
||||||
if(spell && spell->type == ACTION_SPELL)
|
|
||||||
lastStackActionController = spell->source->controller();
|
|
||||||
if (g->isInterrupting == this
|
if (g->isInterrupting == this
|
||||||
&& this == currentP
|
&& this == currentP
|
||||||
//and i am the currentlyActivePlayer
|
//and i am the currentlyActivePlayer
|
||||||
|
|||||||
@@ -243,7 +243,7 @@ Interruptible(id), tc(tc), cost(_cost), payResult(payResult)
|
|||||||
|
|
||||||
int Spell::computeX(MTGCardInstance * card)
|
int Spell::computeX(MTGCardInstance * card)
|
||||||
{
|
{
|
||||||
ManaCost * c = NEW ManaCost(cost->Diff(card->getManaCost()));
|
ManaCost * c = cost->Diff(card->getManaCost());
|
||||||
int x = c->getCost(Constants::MTG_NB_COLORS);
|
int x = c->getCost(Constants::MTG_NB_COLORS);
|
||||||
delete c;
|
delete c;
|
||||||
return x;
|
return x;
|
||||||
@@ -763,7 +763,7 @@ int ActionStack::count(int type, int state, int display)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ActionStack::getActionElementFromCard(MTGCardInstance * card)
|
Interruptible * ActionStack::getActionElementFromCard(MTGCardInstance * card)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(!card)
|
if(!card)
|
||||||
@@ -773,10 +773,10 @@ int ActionStack::getActionElementFromCard(MTGCardInstance * card)
|
|||||||
Interruptible * current = (Interruptible *) mObjects[i];
|
Interruptible * current = (Interruptible *) mObjects[i];
|
||||||
if (current->source == card)
|
if (current->source == card)
|
||||||
{
|
{
|
||||||
return i;
|
return current;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Interruptible * ActionStack::getNext(Interruptible * previous, int type, int state, int display)
|
Interruptible * ActionStack::getNext(Interruptible * previous, int type, int state, int display)
|
||||||
|
|||||||
@@ -416,7 +416,7 @@ ACounterShroud::~ACounterShroud()
|
|||||||
SAFE_DELETE(counter);
|
SAFE_DELETE(counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
//sheild a card from a certain type of counter.
|
//shield a card from a certain type of counter.
|
||||||
ACounterTracker::ACounterTracker(int id, MTGCardInstance * source, MTGCardInstance * target, string scounter) :
|
ACounterTracker::ACounterTracker(int id, MTGCardInstance * source, MTGCardInstance * target, string scounter) :
|
||||||
MTGAbility(id, source, target),scounter(scounter)
|
MTGAbility(id, source, target),scounter(scounter)
|
||||||
{
|
{
|
||||||
@@ -428,7 +428,7 @@ int ACounterTracker::addToGame()
|
|||||||
MTGCardInstance * _target = (MTGCardInstance*)target;
|
MTGCardInstance * _target = (MTGCardInstance*)target;
|
||||||
Counter * counter = NULL;
|
Counter * counter = NULL;
|
||||||
AbilityFactory af;
|
AbilityFactory af;
|
||||||
counter = af.parseCounter(scounter, _target, (Spell*)source);
|
counter = af.parseCounter(scounter, _target, NULL); //(Spell*)source);
|
||||||
if (!counter)
|
if (!counter)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
@@ -455,7 +455,7 @@ int ACounterTracker::destroy()
|
|||||||
MTGCardInstance * _target = (MTGCardInstance*)target;
|
MTGCardInstance * _target = (MTGCardInstance*)target;
|
||||||
Counter * counter = NULL;
|
Counter * counter = NULL;
|
||||||
AbilityFactory af;
|
AbilityFactory af;
|
||||||
counter = af.parseCounter(scounter, _target, (Spell*)source);
|
counter = af.parseCounter(scounter, _target, NULL); //(Spell*)source);
|
||||||
if (!counter)
|
if (!counter)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
@@ -665,12 +665,12 @@ int AAFizzler::resolve()
|
|||||||
if(!target && source->target)
|
if(!target && source->target)
|
||||||
{
|
{
|
||||||
//ai is casting a spell from it's hand to fizzle.
|
//ai is casting a spell from it's hand to fizzle.
|
||||||
target = stack->getAt(stack->getActionElementFromCard(source->target));
|
target = stack->getActionElementFromCard(source->target);
|
||||||
}
|
}
|
||||||
else if(target->typeAsTarget() == TARGET_CARD)
|
else if(target->typeAsTarget() == TARGET_CARD)
|
||||||
{
|
{
|
||||||
//ai targeted using an ability on a card to fizzle.
|
//ai targeted using an ability on a card to fizzle.
|
||||||
target = stack->getAt(stack->getActionElementFromCard((MTGCardInstance*)target));
|
target = stack->getActionElementFromCard((MTGCardInstance*)target);
|
||||||
}
|
}
|
||||||
Spell * sTarget = (Spell *) target;
|
Spell * sTarget = (Spell *) target;
|
||||||
MTGCardInstance* sCard = (MTGCardInstance*)sTarget->source;
|
MTGCardInstance* sCard = (MTGCardInstance*)sTarget->source;
|
||||||
|
|||||||
@@ -48,8 +48,13 @@ void Credits::compute(Player * _p1, Player * _p2, GameApp * _app)
|
|||||||
GameObserver * g = GameObserver::GetInstance();
|
GameObserver * g = GameObserver::GetInstance();
|
||||||
if (!g->turn)
|
if (!g->turn)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
//no credits when the AI plays :)
|
||||||
|
if (p1->isAI())
|
||||||
|
return;
|
||||||
|
|
||||||
PlayerData * playerdata = NEW PlayerData(MTGCollection());
|
PlayerData * playerdata = NEW PlayerData(MTGCollection());
|
||||||
if (!p1->isAI() && p2->isAI() && p1 != g->gameOver)
|
if (p2->isAI() && p1 != g->gameOver)
|
||||||
{
|
{
|
||||||
gameLength = time(0) - g->startedAt;
|
gameLength = time(0) - g->startedAt;
|
||||||
value = 400;
|
value = 400;
|
||||||
|
|||||||
@@ -238,8 +238,8 @@ void GameStateDuel::loadPlayer(int playerId, int decknb, bool isAI, bool isNetwo
|
|||||||
Player * opponent = NULL;
|
Player * opponent = NULL;
|
||||||
if (playerId == 1) opponent = mPlayers[0];
|
if (playerId == 1) opponent = mPlayers[0];
|
||||||
#ifdef AI_CHANGE_TESTING
|
#ifdef AI_CHANGE_TESTING
|
||||||
if (mParent->players[1] == PLAYER_TYPE_CPU_TEST && playerId == 1)
|
if (mParent->players[0] == PLAYER_TYPE_CPU_TEST)
|
||||||
mPlayers[playerId] = playerCreator.createAIPlayerTest(MTGCollection(), opponent);
|
mPlayers[playerId] = playerCreator.createAIPlayerTest(MTGCollection(), opponent, playerId == 0 ? "ai/bakaA/" : "ai/bakaB/");
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
@@ -646,6 +646,12 @@ void GameStateDuel::Render()
|
|||||||
{
|
{
|
||||||
r->ClearScreen(ARGB(255,0,0,0));
|
r->ClearScreen(ARGB(255,0,0,0));
|
||||||
char buf[4096];
|
char buf[4096];
|
||||||
|
mFont->SetColor(ARGB(255,255,255,255));
|
||||||
|
|
||||||
|
int elapsedTime = (testSuite->endTime - testSuite->startTime);
|
||||||
|
sprintf(buf, "Time to run the tests: %is", elapsedTime/1000);
|
||||||
|
mFont->DrawString(buf,0,SCREEN_HEIGHT/2 - 20);
|
||||||
|
|
||||||
int nbFailed = testSuite->nbFailed;
|
int nbFailed = testSuite->nbFailed;
|
||||||
int nbTests = testSuite->nbTests;
|
int nbTests = testSuite->nbTests;
|
||||||
if (!nbFailed)
|
if (!nbFailed)
|
||||||
@@ -656,7 +662,7 @@ void GameStateDuel::Render()
|
|||||||
{
|
{
|
||||||
sprintf(buf, "%i tests out of %i FAILED!", nbFailed, nbTests);
|
sprintf(buf, "%i tests out of %i FAILED!", nbFailed, nbTests);
|
||||||
}
|
}
|
||||||
mFont->SetColor(ARGB(255,255,255,255));
|
|
||||||
mFont->DrawString(buf,0,SCREEN_HEIGHT/2);
|
mFont->DrawString(buf,0,SCREEN_HEIGHT/2);
|
||||||
nbFailed = testSuite->nbAIFailed;
|
nbFailed = testSuite->nbAIFailed;
|
||||||
nbTests = testSuite->nbAITests;
|
nbTests = testSuite->nbAITests;
|
||||||
|
|||||||
@@ -590,39 +590,75 @@ MTGCard * MTGAllCards::_(int index)
|
|||||||
return getCardById(ids[index]);
|
return getCardById(ids[index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
MTGCard * MTGAllCards::getCardByName(string name)
|
#ifdef TESTSUITE
|
||||||
|
void MTGAllCards::prefetchCardNameCache()
|
||||||
{
|
{
|
||||||
if (!name.size()) return NULL;
|
map<int, MTGCard *>::iterator it;
|
||||||
if (name[0] == '#') return NULL;
|
for (it = collection.begin(); it != collection.end(); it++)
|
||||||
|
{
|
||||||
|
MTGCard * c = it->second;
|
||||||
|
|
||||||
map<string, MTGCard * >::iterator cached = mtgCardByNameCache.end();
|
//Name only
|
||||||
if (mtgCardByNameCache.size() > 0)
|
string cardName = c->data->name;
|
||||||
cached = mtgCardByNameCache.find(name);
|
std::transform(cardName.begin(), cardName.end(), cardName.begin(), ::tolower);
|
||||||
|
mtgCardByNameCache[cardName] = c;
|
||||||
|
|
||||||
|
//Name + set
|
||||||
|
int setId = c->setId;
|
||||||
|
MTGSetInfo* setInfo = setlist.getInfo(setId);
|
||||||
|
if (setInfo)
|
||||||
|
{
|
||||||
|
string setName = setInfo->getName();
|
||||||
|
std::transform(setName.begin(), setName.end(), setName.begin(), ::tolower);
|
||||||
|
cardName = cardName + " (" + setName + ")";
|
||||||
|
mtgCardByNameCache[cardName] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
// id
|
||||||
|
std::stringstream out;
|
||||||
|
out << c->getMTGId();
|
||||||
|
mtgCardByNameCache[out.str()] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
MTGCard * MTGAllCards::getCardByName(string nameDescriptor)
|
||||||
|
{
|
||||||
|
if (!nameDescriptor.size()) return NULL;
|
||||||
|
if (nameDescriptor[0] == '#') return NULL;
|
||||||
|
|
||||||
|
std::transform(nameDescriptor.begin(), nameDescriptor.end(), nameDescriptor.begin(), ::tolower);
|
||||||
|
|
||||||
|
map<string, MTGCard * >::iterator cached = mtgCardByNameCache.find(nameDescriptor);
|
||||||
|
|
||||||
if (cached!= mtgCardByNameCache.end())
|
if (cached!= mtgCardByNameCache.end())
|
||||||
{
|
{
|
||||||
return cached->second;
|
return cached->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cardnb = atoi(name.c_str());
|
int cardnb = atoi(nameDescriptor.c_str());
|
||||||
if (cardnb)
|
if (cardnb)
|
||||||
{
|
{
|
||||||
MTGCard * result = getCardById(cardnb);
|
MTGCard * result = getCardById(cardnb);
|
||||||
mtgCardByNameCache[name] = result;
|
mtgCardByNameCache[nameDescriptor] = result;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::transform(name.begin(), name.end(), name.begin(), ::tolower);
|
|
||||||
int setId = -1;
|
int setId = -1;
|
||||||
size_t found = name.find(" (");
|
size_t found = nameDescriptor.find(" (");
|
||||||
|
string name = nameDescriptor;
|
||||||
if (found != string::npos)
|
if (found != string::npos)
|
||||||
{
|
{
|
||||||
size_t end = name.find(")");
|
size_t end = nameDescriptor.find(")");
|
||||||
string setName = name.substr(found + 2, end - found - 2);
|
string setName = nameDescriptor.substr(found + 2, end - found - 2);
|
||||||
trim(setName);
|
trim(setName);
|
||||||
name = name.substr(0, found);
|
name = nameDescriptor.substr(0, found);
|
||||||
trim(name);
|
trim(name);
|
||||||
setId = setlist[setName];
|
setId = setlist[setName];
|
||||||
|
|
||||||
|
//Reconstruct a clean string "name (set)" for cache consistency
|
||||||
|
nameDescriptor = name + " (" + setName + ")";
|
||||||
|
|
||||||
}
|
}
|
||||||
map<int, MTGCard *>::iterator it;
|
map<int, MTGCard *>::iterator it;
|
||||||
for (it = collection.begin(); it != collection.end(); it++)
|
for (it = collection.begin(); it != collection.end(); it++)
|
||||||
@@ -632,12 +668,12 @@ MTGCard * MTGAllCards::getCardByName(string name)
|
|||||||
string cardName = c->data->name;
|
string cardName = c->data->name;
|
||||||
std::transform(cardName.begin(), cardName.end(), cardName.begin(), ::tolower);
|
std::transform(cardName.begin(), cardName.end(), cardName.begin(), ::tolower);
|
||||||
if (cardName.compare(name) == 0) {
|
if (cardName.compare(name) == 0) {
|
||||||
mtgCardByNameCache[name] = c;
|
mtgCardByNameCache[nameDescriptor] = c;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
mtgCardByNameCache[name] = NULL;
|
mtgCardByNameCache[nameDescriptor] = NULL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -180,11 +180,19 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta
|
|||||||
{
|
{
|
||||||
targetMin = true;//if upto: is not found, then we need to have a minimum of the amount....
|
targetMin = true;//if upto: is not found, then we need to have a minimum of the amount....
|
||||||
}
|
}
|
||||||
WParsedInt * howmuch = NEW WParsedInt(howmany, NULL, card);
|
|
||||||
howmany.find("anyamount") != string::npos?maxtargets = TargetChooser::UNLITMITED_TARGETS:maxtargets = howmuch->getValue();
|
if (howmany.find("anyamount") != string::npos)
|
||||||
if(howmany.find("anyamount") != string::npos)
|
{
|
||||||
|
maxtargets = TargetChooser::UNLITMITED_TARGETS;
|
||||||
targetMin = false;
|
targetMin = false;
|
||||||
delete howmuch;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WParsedInt * howmuch = NEW WParsedInt(howmany, NULL, card);
|
||||||
|
maxtargets = howmuch->getValue();
|
||||||
|
delete howmuch;
|
||||||
|
}
|
||||||
|
|
||||||
s1 = s1.substr(end + 1);
|
s1 = s1.substr(end + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -566,7 +566,8 @@ TestSuite::TestSuite(const char * filename)
|
|||||||
seed = 0;
|
seed = 0;
|
||||||
forceAbility = false;
|
forceAbility = false;
|
||||||
aiMaxCalls = -1;
|
aiMaxCalls = -1;
|
||||||
|
startTime = JGEGetTime();
|
||||||
|
endTime = startTime;
|
||||||
std::string contents;
|
std::string contents;
|
||||||
if (JFileSystem::GetInstance()->readIntoString(filename, contents))
|
if (JFileSystem::GetInstance()->readIntoString(filename, contents))
|
||||||
{
|
{
|
||||||
@@ -585,6 +586,11 @@ TestSuite::TestSuite(const char * filename)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//If more than 1 test, prefecth names to make the suite run faster
|
||||||
|
if (nbfiles > 1)
|
||||||
|
MTGCollection()->prefetchCardNameCache();
|
||||||
|
|
||||||
|
|
||||||
ofstream file2;
|
ofstream file2;
|
||||||
if (JFileSystem::GetInstance()->openForWrite(file2, "/test/results.html"))
|
if (JFileSystem::GetInstance()->openForWrite(file2, "/test/results.html"))
|
||||||
{
|
{
|
||||||
@@ -603,6 +609,7 @@ TestSuite::TestSuite(const char * filename)
|
|||||||
|
|
||||||
int TestSuite::loadNext()
|
int TestSuite::loadNext()
|
||||||
{
|
{
|
||||||
|
endTime = JGEGetTime();
|
||||||
summoningSickness = 0;
|
summoningSickness = 0;
|
||||||
seed = 0;
|
seed = 0;
|
||||||
aiMaxCalls = -1;
|
aiMaxCalls = -1;
|
||||||
@@ -613,8 +620,6 @@ int TestSuite::loadNext()
|
|||||||
return loadNext();
|
return loadNext();
|
||||||
else
|
else
|
||||||
cout << "Starting test : " << files[currentfile - 1] << endl;
|
cout << "Starting test : " << files[currentfile - 1] << endl;
|
||||||
//load(files[currentfile].c_str());
|
|
||||||
//currentfile++;
|
|
||||||
return currentfile;
|
return currentfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user