Beispiel #1
0
void StatsWrapper::updateStats(DeckDataWrapper *myDeck)
{
	if (!this->needUpdate || !myDeck) return;

	this->needUpdate = false;
    this->cardCount = myDeck->getCount(WSrcDeck::UNFILTERED_COPIES);
    this->countLands = myDeck->getCount(Constants::MTG_COLOR_LAND);
    this->totalPrice = myDeck->totalPrice();

    this->countManaProducers = 0;
    // Mana cost
    int currentCount, convertedCost;
    ManaCost * currentCost;
    this->totalManaCost = 0;
    this->totalCreatureCost = 0;
    this->totalSpellCost = 0;
    MTGCard * current = NULL;

    // Clearing arrays
    for (int i = 0; i <= Constants::STATS_MAX_MANA_COST; i++)
    {
        this->countCardsPerCost[i] = 0;
        this->countCreaturesPerCost[i] = 0;
        this->countSpellsPerCost[i] = 0;
    }

    for (int i = 0; i <= Constants::NB_Colors; i++)
    {
        this->totalCostPerColor[i] = 0;
        this->countLandsPerColor[i] = 0;
        this->countBasicLandsPerColor[i] = 0;
        this->countNonLandProducersPerColor[i] = 0;
    }

    for (int i = 0; i <= Constants::STATS_MAX_MANA_COST; i++)
    {
        for (int k = 0; k <= Constants::NB_Colors; k++)
        {
            this->countCardsPerCostAndColor[i][k] = 0;
            this->countCreaturesPerCostAndColor[i][k] = 0;
            this->countSpellsPerCostAndColor[i][k] = 0;
        }
    }

    for (int ic = 0; ic < myDeck->Size(true); ic++)
    {
        current = myDeck->getCard(ic, true);
        currentCost = current->data->getManaCost();
        convertedCost = currentCost->getConvertedCost();
        currentCount = myDeck->count(current);

        // Add to the cards per cost counters
        this->totalManaCost += convertedCost * currentCount;
        if (convertedCost > Constants::STATS_MAX_MANA_COST)
        {
            convertedCost = Constants::STATS_MAX_MANA_COST;
        }
        this->countCardsPerCost[convertedCost] += currentCount;
        if (current->data->isCreature())
        {
            this->countCreaturesPerCost[convertedCost] += currentCount;
            this->totalCreatureCost += convertedCost * currentCount;
        }
        else if (current->data->isSpell())
        {
            this->countSpellsPerCost[convertedCost] += currentCount;
            this->totalSpellCost += convertedCost * currentCount;
        }

        // Lets look for mana producing abilities

        //http://code.google.com/p/wagic/issues/detail?id=650
        //Basic lands are not producing their mana through regular abilities anymore,
        //but through a rule that is outside of the primitives. This block is a hack to address this
        const int colors[] = {Constants::MTG_COLOR_GREEN, Constants::MTG_COLOR_BLUE, Constants::MTG_COLOR_RED, Constants::MTG_COLOR_BLACK, Constants::MTG_COLOR_WHITE};
        const string lands[] = { "forest", "island", "mountain", "swamp", "plains" };
        for (unsigned int i = 0; i < sizeof(colors)/sizeof(colors[0]); ++i)
        {
            int colorId = colors[i];
            string type = lands[i];
            if (current->data->hasType(type.c_str()))
            {
                if (current->data->hasType("Basic"))
                {
                    this->countBasicLandsPerColor[colorId] += currentCount;
                }
                else
                {
                    this->countLandsPerColor[colorId] += currentCount;
                }
            }
        }

        vector<string> abilitiesVector;
        string thisstring = current->data->magicText;
        abilitiesVector = split(thisstring, '\n');

        for (int v = 0; v < (int) abilitiesVector.size(); v++)
        {
            string s = abilitiesVector[v];
            size_t t = s.find("add");
            if (t != string::npos)
            {
                s = s.substr(t + 3);
                ManaCost * mc = ManaCost::parseManaCost(s);
                for (int j = 0; j < Constants::NB_Colors; j++)
                {
                    if (mc->hasColor(j))
                    {
                        if (current->data->isLand())
                        {
                            if (current->data->hasType("Basic"))
                            {
                                this->countBasicLandsPerColor[j] += currentCount;
                            }
                            else
                            {
                                this->countLandsPerColor[j] += currentCount;
                            }
                        }
                        else
                        {
                            this->countNonLandProducersPerColor[j] += currentCount;
                        }
                    }
                }
                SAFE_DELETE(mc);
            }
        }

        // Add to the per color counters
        //  a. regular costs
        for (int j = 0; j < Constants::NB_Colors; j++)
        {
            this->totalCostPerColor[j] += currentCost->getCost(j) * currentCount;
            if (current->data->hasColor(j))
            {
                // Add to the per cost and color counter
                this->countCardsPerCostAndColor[convertedCost][j] += currentCount;
                if (current->data->isCreature())
                {
                    this->countCreaturesPerCostAndColor[convertedCost][j] += currentCount;
                }
                else if (current->data->isSpell())
                {
                    this->countSpellsPerCostAndColor[convertedCost][j] += currentCount;
                }
            }
        }

        //  b. Hybrid costs
        ManaCostHybrid * hybridCost;
        int i;
        i = 0;

        while ((hybridCost = currentCost->getHybridCost(i++)) != NULL)
        {
            this->totalCostPerColor[hybridCost->color1] += hybridCost->value1 * currentCount;
            this->totalCostPerColor[hybridCost->color2] += hybridCost->value2 * currentCount;
        }
    }

    this->totalColoredSymbols = 0;
    for (int j = 1; j < Constants::NB_Colors; j++)
    {
        this->totalColoredSymbols += this->totalCostPerColor[j];
    }

    this->countCardsPerCost[0] -= this->countLands;

    // Counts by type
    this->countCreatures = countCardsByType("Creature", myDeck);
    this->countInstants = countCardsByType("Instant", myDeck);
    this->countEnchantments = countCardsByType("Enchantment", myDeck);
    this->countSorceries = countCardsByType("Sorcery", myDeck);
    this->countSpells = this->countInstants + this->countEnchantments + this->countSorceries;
    //this->countArtifacts = countCardsByType("Artifact", myDeck);

    // Average mana costs
    this->avgManaCost = ((this->cardCount - this->countLands) <= 0) ? 0 : (float) this->totalManaCost / (this->cardCount
            - this->countLands);
    this->avgCreatureCost = (this->countCreatures <= 0) ? 0 : (float) this->totalCreatureCost / this->countCreatures;
    this->avgSpellCost = (this->countSpells <= 0) ? 0 : (float) this->totalSpellCost / this->countSpells;

    // Probabilities
    // TODO: this could be optimized by reusing results
    for (int i = 0; i < Constants::STATS_FOR_TURNS; i++)
    {
        this->noLandsProbInTurn[i] = noLuck(this->cardCount, this->countLands, 7 + i) * 100;
        this->noCreaturesProbInTurn[i] = noLuck(this->cardCount, this->countCreatures, 7 + i) * 100;
    }
}