Reducing the memory footprint: reworked the concept of 'colors' in CardPrimitives. What used to be an array of ints (ie 28 bytes) is now contained in a single byte, we use bit masking to support setting multiple colors on this variable. This also eliminates a lot of silly loops for setting colors in the code - now it's a straight byte copy.

Also thrown in are a couple of string to const string& conversions.
This commit is contained in:
wrenczes@gmail.com
2011-04-25 11:20:07 +00:00
parent b8310838f4
commit 1cbf3db582
8 changed files with 162 additions and 120 deletions
+6 -3
View File
@@ -11,6 +11,7 @@
#define CD_OR 1 #define CD_OR 1
#define CD_AND 2 #define CD_AND 2
#define CD_NOT 3
enum ENUM_COMPARISON_MODES enum ENUM_COMPARISON_MODES
{ {
@@ -23,10 +24,12 @@ enum ENUM_COMPARISON_MODES
COMPARISON_UNEQUAL COMPARISON_UNEQUAL
}; };
class CardDescriptor: public MTGCardInstance{ class CardDescriptor: public MTGCardInstance
{
protected: protected:
MTGCardInstance * match_or(MTGCardInstance * card); MTGCardInstance * match_or(MTGCardInstance * card);
MTGCardInstance * match_and(MTGCardInstance * card); MTGCardInstance * match_and(MTGCardInstance * card);
MTGCardInstance * match_not(MTGCardInstance * card);
bool valueInRange(int comparisonMode, int value, int criterion); bool valueInRange(int comparisonMode, int value, int criterion);
public: public:
int mode; int mode;
+14 -5
View File
@@ -11,6 +11,15 @@
using namespace std; using namespace std;
const uint8_t kColorBitMask_Artifact = 0x01;
const uint8_t kColorBitMask_Green = 0x02;
const uint8_t kColorBitMask_Blue = 0x04;
const uint8_t kColorBitMask_Red = 0x08;
const uint8_t kColorBitMask_Black = 0x10;
const uint8_t kColorBitMask_White = 0x20;
const uint8_t kColorBitMask_Land = 0x40;
class CardPrimitive class CardPrimitive
#ifdef TRACK_OBJECT_USAGE #ifdef TRACK_OBJECT_USAGE
: public InstanceCounter<CardPrimitive> : public InstanceCounter<CardPrimitive>
@@ -25,7 +34,7 @@ public:
string name; string name;
int init(); int init();
int colors[Constants::MTG_NB_COLORS]; uint8_t colors;
map<int,int> basicAbilities; map<int,int> basicAbilities;
map<string,string> magicTexts; map<string,string> magicTexts;
string magicText; string magicText;
@@ -44,10 +53,10 @@ public:
virtual ~CardPrimitive(); virtual ~CardPrimitive();
void setColor(int _color, int removeAllOthers = 0); void setColor(int _color, int removeAllOthers = 0);
void setColor(string _color, int removeAllOthers = 0); void setColor(const string& _color, int removeAllOthers = 0);
void removeColor(int color); void removeColor(int color);
int getColor(); int getColor();
int hasColor(int _color); bool hasColor(int inColor);
int countColors(); int countColors();
int has(int ability); int has(int ability);
@@ -70,11 +79,11 @@ public:
int removeType(int value, int removeAll = 0); int removeType(int value, int removeAll = 0);
bool hasSubtype(int _subtype); bool hasSubtype(int _subtype);
bool hasSubtype(const char * _subtype); bool hasSubtype(const char * _subtype);
bool hasSubtype(string _subtype); bool hasSubtype(const string& _subtype);
bool hasType(int _type); bool hasType(int _type);
bool hasType(const char * type); bool hasType(const char * type);
void setManaCost(string value); void setManaCost(const string& value);
ManaCost * getManaCost(); ManaCost * getManaCost();
bool isCreature(); bool isCreature();
bool isLand(); bool isLand();
+18 -42
View File
@@ -101,6 +101,13 @@ bool CardDescriptor::valueInRange(int comparisonMode, int value, int criterion)
return false; return false;
} }
MTGCardInstance* CardDescriptor::match_not(MTGCardInstance * card)
{
// if we have a color match, return null
bool colorFound = (colors & card->colors) > 0;
return colorFound ? NULL : card;
}
MTGCardInstance * CardDescriptor::match_or(MTGCardInstance * card) MTGCardInstance * CardDescriptor::match_or(MTGCardInstance * card)
{ {
int found = 1; int found = 1;
@@ -128,27 +135,11 @@ MTGCardInstance * CardDescriptor::match_or(MTGCardInstance * card)
if (!found) if (!found)
return NULL; return NULL;
for (int i = 0; i < Constants::MTG_NB_COLORS; i++) if (colors)
{ {
if (colors[i] == 1) found = (colors & card->colors);
{
found = 0;
if (card->hasColor(i))
{
found = 1;
break;
}
}
else if (colors[i] == -1)
{
found = 0;
if (!card->hasColor(i))
{
found = 1;
break;
}
}
} }
if (!found) if (!found)
return NULL; return NULL;
@@ -184,13 +175,8 @@ MTGCardInstance * CardDescriptor::match_and(MTGCardInstance * card)
} }
} }
} }
for (int i = 0; i < Constants::MTG_NB_COLORS; i++) if ((colors & card->colors) != colors)
{ match = NULL;
if ((colors[i] == 1 && !card->hasColor(i)) || (colors[i] == -1 && card->hasColor(i)))
{
match = NULL;
}
}
if (powerComparisonMode && !valueInRange(powerComparisonMode, card->getPower(), power)) if (powerComparisonMode && !valueInRange(powerComparisonMode, card->getPower(), power))
match = NULL; match = NULL;
@@ -200,21 +186,7 @@ MTGCardInstance * CardDescriptor::match_and(MTGCardInstance * card)
match = NULL; match = NULL;
if(nameComparisonMode && compareName != card->name) if(nameComparisonMode && compareName != card->name)
match = NULL; match = NULL;
if(colorComparisonMode)
{
bool hasMatch = false;
for (int i=0;i< Constants::MTG_NB_COLORS;i++)
{
if (card->hasColor(i) && colors[i] > 0)
{
hasMatch = true;
}
}
if( !hasMatch )
{
match = NULL;
}
}
return match; return match;
} }
@@ -226,10 +198,14 @@ MTGCardInstance * CardDescriptor::match(MTGCardInstance * card)
{ {
match = match_and(card); match = match_and(card);
} }
else else if (mode == CD_OR)
{ {
match = match_or(card); match = match_or(card);
} }
else
{
match = match_not(card);
}
//Abilities //Abilities
for (map<int, int>::const_iterator it = basicAbilities.begin(); it != basicAbilities.end(); ++it) for (map<int, int>::const_iterator it = basicAbilities.begin(); it != basicAbilities.end(); ++it)
+87 -28
View File
@@ -1,5 +1,6 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "MTGDefinitions.h"
#include "CardPrimitive.h" #include "CardPrimitive.h"
#include "MTGDeck.h" #include "MTGDeck.h"
@@ -8,9 +9,68 @@
using std::string; using std::string;
namespace
{
uint8_t ConvertColorToBitMask(int inColor)
{
uint8_t value = 0;
switch (inColor)
{
case Constants::MTG_COLOR_ARTIFACT:
value = kColorBitMask_Artifact;
break;
case Constants::MTG_COLOR_GREEN:
value = kColorBitMask_Green;
break;
case Constants::MTG_COLOR_BLUE:
value = kColorBitMask_Blue;
break;
case Constants::MTG_COLOR_RED:
value = kColorBitMask_Red;
break;
case Constants::MTG_COLOR_BLACK:
value = kColorBitMask_Black;
break;
case Constants::MTG_COLOR_WHITE:
value = kColorBitMask_White;
break;
case Constants::MTG_COLOR_LAND:
value = kColorBitMask_Land;
break;
default:
break;
}
return value;
}
/**
** Count the number of set bits in a given integer
*/
int CountSetBits(int n)
{
int count = 0;
while (n)
{
n &= (n-1);
count++;
}
return count;
}
}
SUPPORT_OBJECT_ANALYTICS(CardPrimitive) SUPPORT_OBJECT_ANALYTICS(CardPrimitive)
CardPrimitive::CardPrimitive() CardPrimitive::CardPrimitive()
: colors(0)
{ {
init(); init();
} }
@@ -22,8 +82,7 @@ CardPrimitive::CardPrimitive(CardPrimitive * source)
for (size_t i = 0; i < source->types.size(); ++i) for (size_t i = 0; i < source->types.size(); ++i)
types.push_back(source->types[i]); types.push_back(source->types[i]);
for (int i = 0; i < Constants::MTG_NB_COLORS; ++i) colors = source->colors;
colors[i] = source->colors[i];
manaCost.copy(source->getManaCost()); manaCost.copy(source->getManaCost());
//reducedCost.copy(source->getReducedManaCost()); //reducedCost.copy(source->getReducedManaCost());
//increasedCost.copy(source->getIncreasedManaCost()); //increasedCost.copy(source->getIncreasedManaCost());
@@ -56,9 +115,6 @@ int CardPrimitive::init()
types.clear(); types.clear();
for (int i = 0; i < Constants::MTG_NB_COLORS; ++i)
colors[i] = 0;
magicText = ""; magicText = "";
magicTexts.clear(); magicTexts.clear();
spellTargetType = ""; spellTargetType = "";
@@ -102,17 +158,17 @@ void CardPrimitive::getOtherRestrictions()
otherrestriction; otherrestriction;
} }
void CardPrimitive::setColor(string _color, int removeAllOthers) void CardPrimitive::setColor(const string& _color, int removeAllOthers)
{ {
if (_color.compare("blue") == 0) if (_color.compare(Constants::kManaBlue) == 0)
return setColor(Constants::MTG_COLOR_BLUE, removeAllOthers); return setColor(Constants::MTG_COLOR_BLUE, removeAllOthers);
if (_color.compare("red") == 0) if (_color.compare(Constants::kManaRed) == 0)
return setColor(Constants::MTG_COLOR_RED, removeAllOthers); return setColor(Constants::MTG_COLOR_RED, removeAllOthers);
if (_color.compare("green") == 0) if (_color.compare(Constants::kManaGreen) == 0)
return setColor(Constants::MTG_COLOR_GREEN, removeAllOthers); return setColor(Constants::MTG_COLOR_GREEN, removeAllOthers);
if (_color.compare("black") == 0) if (_color.compare(Constants::kManaBlack) == 0)
return setColor(Constants::MTG_COLOR_BLACK, removeAllOthers); return setColor(Constants::MTG_COLOR_BLACK, removeAllOthers);
if (_color.compare("white") == 0) if (_color.compare(Constants::kManaWhite) == 0)
return setColor(Constants::MTG_COLOR_WHITE, removeAllOthers); return setColor(Constants::MTG_COLOR_WHITE, removeAllOthers);
if (_color.compare("artifact") == 0) if (_color.compare("artifact") == 0)
return setColor(Constants::MTG_COLOR_ARTIFACT, removeAllOthers); return setColor(Constants::MTG_COLOR_ARTIFACT, removeAllOthers);
@@ -121,39 +177,43 @@ void CardPrimitive::setColor(string _color, int removeAllOthers)
void CardPrimitive::setColor(int _color, int removeAllOthers) void CardPrimitive::setColor(int _color, int removeAllOthers)
{ {
if (removeAllOthers) if (removeAllOthers)
for (int i = 0; i < Constants::MTG_NB_COLORS; i++) colors = 0;
colors[i] = 0;
colors[_color] = 1; colors |= ConvertColorToBitMask(_color);
} }
void CardPrimitive::removeColor(int _color) void CardPrimitive::removeColor(int _color)
{ {
colors[_color] = 0; uint8_t mask = ~ConvertColorToBitMask(_color);
colors &= mask;
} }
int CardPrimitive::getColor() int CardPrimitive::getColor()
{ {
for (int i = 1; i < Constants::MTG_NB_COLORS; i++) if (colors)
if (colors[i]) {
return i; for (int i = 1; i < Constants::MTG_NB_COLORS; i++)
if (hasColor(i))
return i;
}
return 0; return 0;
} }
int CardPrimitive::hasColor(int color) bool CardPrimitive::hasColor(int inColor)
{ {
return (colors[color]); return (colors & ConvertColorToBitMask(inColor)) > 0;
} }
int CardPrimitive::countColors() int CardPrimitive::countColors()
{ {
int result = 0; uint8_t mask = kColorBitMask_Green | kColorBitMask_Blue | kColorBitMask_Red | kColorBitMask_Black | kColorBitMask_White;
for (int i = Constants::MTG_COLOR_GREEN; i <= Constants::MTG_COLOR_WHITE; ++i) mask &= colors;
if (hasColor(i))
++result; return CountSetBits(mask);
return result;
} }
void CardPrimitive::setManaCost(string s) void CardPrimitive::setManaCost(const string& s)
{ {
ManaCost::parseManaCost(s, &manaCost); ManaCost::parseManaCost(s, &manaCost);
for (int i = Constants::MTG_COLOR_GREEN; i <= Constants::MTG_COLOR_WHITE; i++) for (int i = Constants::MTG_COLOR_GREEN; i <= Constants::MTG_COLOR_WHITE; i++)
@@ -163,7 +223,6 @@ void CardPrimitive::setManaCost(string s)
setColor(i); setColor(i);
} }
} }
} }
void CardPrimitive::setType(const string& _type_text) void CardPrimitive::setType(const string& _type_text)
@@ -290,7 +349,7 @@ bool CardPrimitive::hasSubtype(const char * _subtype)
return hasType(id); return hasType(id);
} }
bool CardPrimitive::hasSubtype(string _subtype) bool CardPrimitive::hasSubtype(const string& _subtype)
{ {
int id = Subtypes::subtypesList->find(_subtype); int id = Subtypes::subtypesList->find(_subtype);
return hasType(id); return hasType(id);
+1 -2
View File
@@ -3113,8 +3113,7 @@ int AbilityFactory::getAbilities(vector<MTGAbility *> * v, Spell * spell, MTGCar
card->setColor(0,1); card->setColor(0,1);
card->name = card->model->data->name; card->name = card->model->data->name;
card->types = card->model->data->types; card->types = card->model->data->types;
for (int i = 0; i < Constants::MTG_NB_COLORS; ++i) card->colors = card->model->data->colors;
card->colors[i] = card->model->data->colors[i];
for (map<int, int>::const_iterator it = card->model->data->basicAbilities.begin(); it != card->model->data->basicAbilities.end(); ++it) for (map<int, int>::const_iterator it = card->model->data->basicAbilities.begin(); it != card->model->data->basicAbilities.end(); ++it)
{ {
int i = it->first; int i = it->first;
+22 -22
View File
@@ -62,10 +62,9 @@ void MTGCardInstance::copy(MTGCardInstance * card)
{ {
types.push_back(data->types[i]); types.push_back(data->types[i]);
} }
for (int i = 0; i < Constants::MTG_NB_COLORS; i++)
{ colors = data->colors;
colors[i] = data->colors[i];
}
manaCost.copy(data->getManaCost()); manaCost.copy(data->getManaCost());
text = data->text; text = data->text;
@@ -197,32 +196,33 @@ void MTGCardInstance::initMTGCI()
} }
} }
int colored = 0; int colored = 0;
for (int i = Constants::MTG_COLOR_GREEN; i <= Constants::MTG_COLOR_WHITE; ++i) for (int i = Constants::MTG_COLOR_GREEN; i <= Constants::MTG_COLOR_WHITE; ++i)
{ {
if (this->hasColor(i)) if (this->hasColor(i))
++colored; ++colored;
} }
if(colored > 1) if (colored > 1)
{ {
isMultiColored = 1; isMultiColored = 1;
if(this->hasColor(Constants::MTG_COLOR_WHITE) && this->hasColor(Constants::MTG_COLOR_BLACK))
isBlackAndWhite = 1;
if(this->hasColor(Constants::MTG_COLOR_RED) && this->hasColor(Constants::MTG_COLOR_BLUE))
isRedAndBlue = 1;
if(this->hasColor(Constants::MTG_COLOR_GREEN) && this->hasColor(Constants::MTG_COLOR_BLACK))
isBlackAndGreen = 1;
if(this->hasColor(Constants::MTG_COLOR_BLUE) && this->hasColor(Constants::MTG_COLOR_GREEN))
isBlueAndGreen = 1;
if(this->hasColor(Constants::MTG_COLOR_RED) && this->hasColor(Constants::MTG_COLOR_WHITE))
isRedAndWhite = 1;
}
if(previous && previous->morphed && !turningOver)
{
morphed = true;
isMorphed = true;
} }
if(this->hasColor(Constants::MTG_COLOR_WHITE) && this->hasColor(Constants::MTG_COLOR_BLACK))
isBlackAndWhite = 1;
if(this->hasColor(Constants::MTG_COLOR_RED) && this->hasColor(Constants::MTG_COLOR_BLUE))
isRedAndBlue = 1;
if(this->hasColor(Constants::MTG_COLOR_GREEN) && this->hasColor(Constants::MTG_COLOR_BLACK))
isBlackAndGreen = 1;
if(this->hasColor(Constants::MTG_COLOR_BLUE) && this->hasColor(Constants::MTG_COLOR_GREEN))
isBlueAndGreen = 1;
if(this->hasColor(Constants::MTG_COLOR_RED) && this->hasColor(Constants::MTG_COLOR_WHITE))
isRedAndWhite = 1;
if(previous && previous->morphed && !turningOver)
{
morphed = true;
isMorphed = true;
}
} }
const string MTGCardInstance::getDisplayName() const const string MTGCardInstance::getDisplayName() const
+11 -15
View File
@@ -507,13 +507,11 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta
} }
else if( CDtype.find("color") != string::npos ) else if( CDtype.find("color") != string::npos )
{ {
for(int i = 0; i < Constants::MTG_NB_COLORS; i++) if(card->target)
{ cd->colors = card->target->colors;
if(card->target) else
cd->colors[i] = card->target->colors[i]; cd->colors = card->colors;
else
cd->colors[i] = card->colors[i];
}
cd->mode = CD_OR; cd->mode = CD_OR;
} }
else if( CDtype.find("types") != string::npos ) else if( CDtype.find("types") != string::npos )
@@ -571,20 +569,17 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta
else else
{ {
int attributefound = 0; int attributefound = 0;
//Colors //Colors - remove Artifact and Land from the loop
for (int cid = 1; cid < Constants::MTG_NB_COLORS - 1; cid++) for (int cid = 1; cid < Constants::MTG_NB_COLORS - 1; cid++)
{ //remove Artifact and Land from the loop {
if (attribute.find(Constants::MTGColorStrings[cid]) != string::npos) if (attribute.find(Constants::MTGColorStrings[cid]) != string::npos)
{ {
attributefound = 1; attributefound = 1;
if (minus) if (minus)
{ {
cd->colors[cid] = -1; cd->mode = CD_NOT;
}
else
{
cd->colors[cid] = 1;
} }
cd->setColor(cid);
} }
} }
if (!attributefound) if (!attributefound)
@@ -621,7 +616,8 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta
} }
} }
} }
if (nbminuses) cd->mode = CD_AND; if (nbminuses && cd->mode != CD_NOT)
cd->mode = CD_AND;
typeName = typeName.substr(0, found); typeName = typeName.substr(0, found);
} }
//X targets allowed ? //X targets allowed ?
+3 -3
View File
@@ -211,7 +211,7 @@ string WCFilterSet::getCode()
bool WCFilterColor::isMatch(MTGCard * c) bool WCFilterColor::isMatch(MTGCard * c)
{ {
if (!c || !c->data) return false; if (!c || !c->data) return false;
return (c->data->hasColor(color) > 0); return (c->data->hasColor(color));
} }
string WCFilterColor::getCode() string WCFilterColor::getCode()
{ {
@@ -242,9 +242,9 @@ bool WCFilterOnlyColor::isMatch(MTGCard * c)
for (int i = 0; i < Constants::MTG_NB_COLORS; i++) for (int i = 0; i < Constants::MTG_NB_COLORS; i++)
{ {
if (i == color) continue; if (i == color) continue;
if (c->data->hasColor(i) > 0) return false; if (c->data->hasColor(i)) return false;
} }
return (c->data->hasColor(color) > 0); return (c->data->hasColor(color));
} }
string WCFilterOnlyColor::getCode() string WCFilterOnlyColor::getCode()
{ {