fixed formatting
This commit is contained in:
@@ -18,20 +18,17 @@ AIMomirPlayer::AIMomirPlayer(MTGDeck * deck, string file, string fileSmall, stri
|
|||||||
int AIMomirPlayer::getEfficiency(AIAction * action)
|
int AIMomirPlayer::getEfficiency(AIAction * action)
|
||||||
{
|
{
|
||||||
MTGAbility * ability = action->ability;
|
MTGAbility * ability = action->ability;
|
||||||
if (ability->cost && !(ability->cost->isExtraPaymentSet()))
|
if (ability->cost && !(ability->cost->isExtraPaymentSet())) return 0; //Does not handle abilities with sacrifice yet
|
||||||
return 0; //Does not handle abilities with sacrifice yet
|
|
||||||
int efficiency = AIPlayerBaka::getEfficiency(action);
|
int efficiency = AIPlayerBaka::getEfficiency(action);
|
||||||
|
|
||||||
GameObserver * g = GameObserver::GetInstance();
|
GameObserver * g = GameObserver::GetInstance();
|
||||||
if (g->getCurrentGamePhase() < Constants::MTG_PHASE_FIRSTMAIN)
|
if (g->getCurrentGamePhase() < Constants::MTG_PHASE_FIRSTMAIN) return 0;
|
||||||
return 0;
|
|
||||||
return efficiency;
|
return efficiency;
|
||||||
}
|
}
|
||||||
|
|
||||||
MTGAbility * AIMomirPlayer::getMomirAbility()
|
MTGAbility * AIMomirPlayer::getMomirAbility()
|
||||||
{
|
{
|
||||||
if (momirAbility)
|
if (momirAbility) return momirAbility;
|
||||||
return momirAbility;
|
|
||||||
|
|
||||||
GameObserver * g = GameObserver::GetInstance();
|
GameObserver * g = GameObserver::GetInstance();
|
||||||
momirAbility = g->mLayers->actionLayer()->getAbility(MTGAbility::MOMIR);
|
momirAbility = g->mLayers->actionLayer()->getAbility(MTGAbility::MOMIR);
|
||||||
@@ -40,8 +37,7 @@ MTGAbility * AIMomirPlayer::getMomirAbility()
|
|||||||
|
|
||||||
int AIMomirPlayer::momir()
|
int AIMomirPlayer::momir()
|
||||||
{
|
{
|
||||||
if (!game->hand->nb_cards)
|
if (!game->hand->nb_cards) return 0; //nothing to discard :/
|
||||||
return 0; //nothing to discard :/
|
|
||||||
int result = 0;
|
int result = 0;
|
||||||
int opponentCreatures = getCreaturesInfo(opponent(), INFO_NBCREATURES);
|
int opponentCreatures = getCreaturesInfo(opponent(), INFO_NBCREATURES);
|
||||||
int myCreatures = getCreaturesInfo(this, INFO_NBCREATURES );
|
int myCreatures = getCreaturesInfo(this, INFO_NBCREATURES );
|
||||||
@@ -50,14 +46,10 @@ int AIMomirPlayer::momir()
|
|||||||
SAFE_DELETE(potentialMana);
|
SAFE_DELETE(potentialMana);
|
||||||
int efficiency = 100;
|
int efficiency = 100;
|
||||||
int chance = 1 + (WRand() % 100);
|
int chance = 1 + (WRand() % 100);
|
||||||
if (converted == 5 && myCreatures > opponentCreatures && game->hand->nb_cards < 4)
|
if (converted == 5 && myCreatures > opponentCreatures && game->hand->nb_cards < 4) efficiency = 5; //Strategy: skip 5 drop
|
||||||
efficiency = 5; //Strategy: skip 5 drop
|
if (converted == 7 && myCreatures > opponentCreatures && game->hand->nb_cards < 2) efficiency = 50; //Strategy: 7 drops have bad upkeep costs and the AI doesn't handle those right now...
|
||||||
if (converted == 7 && myCreatures > opponentCreatures && game->hand->nb_cards < 2)
|
if (converted > 8) converted = 8;
|
||||||
efficiency = 50; //Strategy: 7 drops have bad upkeep costs and the AI doesn't handle those right now...
|
if (converted == 8) efficiency = 100 - (myCreatures - opponentCreatures);
|
||||||
if (converted > 8)
|
|
||||||
converted = 8;
|
|
||||||
if (converted == 8)
|
|
||||||
efficiency = 100 - (myCreatures - opponentCreatures);
|
|
||||||
|
|
||||||
if (efficiency >= chance)
|
if (efficiency >= chance)
|
||||||
{
|
{
|
||||||
@@ -88,18 +80,16 @@ int AIMomirPlayer::computeActions()
|
|||||||
*/
|
*/
|
||||||
GameObserver * g = GameObserver::GetInstance();
|
GameObserver * g = GameObserver::GetInstance();
|
||||||
Player * p = g->currentPlayer;
|
Player * p = g->currentPlayer;
|
||||||
if (!(g->currentlyActing() == this))
|
if (!(g->currentlyActing() == this)) return 0;
|
||||||
return 0;
|
if (chooseTarget()) return 1;
|
||||||
if (chooseTarget())
|
|
||||||
return 1;
|
|
||||||
int currentGamePhase = g->getCurrentGamePhase();
|
int currentGamePhase = g->getCurrentGamePhase();
|
||||||
if (g->isInterrupting == this)
|
if (g->isInterrupting == this)
|
||||||
{ // interrupting
|
{ // interrupting
|
||||||
if(!findingAbility)
|
if (!findingAbility)
|
||||||
{
|
{
|
||||||
AIPlayer::findingAbility = true;
|
AIPlayer::findingAbility = true;
|
||||||
selectAbility();
|
selectAbility();
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if (p == this && g->mLayers->stackLayer()->count(0, NOT_RESOLVED) == 0)
|
else if (p == this && g->mLayers->stackLayer()->count(0, NOT_RESOLVED) == 0)
|
||||||
@@ -133,11 +123,11 @@ int AIMomirPlayer::computeActions()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Constants::MTG_PHASE_SECONDMAIN:
|
case Constants::MTG_PHASE_SECONDMAIN:
|
||||||
if(!findingAbility)
|
if (!findingAbility)
|
||||||
{
|
{
|
||||||
AIPlayer::findingAbility = true;
|
AIPlayer::findingAbility = true;
|
||||||
selectAbility();
|
selectAbility();
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
+193
-252
@@ -23,15 +23,13 @@ int AIAction::Act()
|
|||||||
if (ability)
|
if (ability)
|
||||||
{
|
{
|
||||||
g->mLayers->actionLayer()->reactToClick(ability, click);
|
g->mLayers->actionLayer()->reactToClick(ability, click);
|
||||||
if (target)
|
if (target) g->cardClick(target);
|
||||||
g->cardClick(target);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if (click)
|
else if (click)
|
||||||
{ //Shouldn't be used, really...
|
{ //Shouldn't be used, really...
|
||||||
g->cardClick(click, click);
|
g->cardClick(click, click);
|
||||||
if (target)
|
if (target) g->cardClick(target);
|
||||||
g->cardClick(target);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -78,15 +76,13 @@ MTGCardInstance * AIPlayer::chooseCard(TargetChooser * tc, MTGCardInstance * sou
|
|||||||
int AIPlayer::Act(float dt)
|
int AIPlayer::Act(float dt)
|
||||||
{
|
{
|
||||||
GameObserver * gameObs = GameObserver::GetInstance();
|
GameObserver * gameObs = GameObserver::GetInstance();
|
||||||
if (gameObs->currentPlayer == this)
|
if (gameObs->currentPlayer == this) gameObs->userRequestNextGamePhase();
|
||||||
gameObs->userRequestNextGamePhase();
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AIPlayer::tapLandsForMana(ManaCost * cost, MTGCardInstance * target)
|
void AIPlayer::tapLandsForMana(ManaCost * cost, MTGCardInstance * target)
|
||||||
{
|
{
|
||||||
if (!cost)
|
if (!cost) return;DebugTrace(" AI tapping land for mana");
|
||||||
return; DebugTrace(" AI tapping land for mana");
|
|
||||||
|
|
||||||
ManaCost * pMana = getPotentialMana(target);
|
ManaCost * pMana = getPotentialMana(target);
|
||||||
ManaCost * diff = pMana->Diff(cost);
|
ManaCost * diff = pMana->Diff(cost);
|
||||||
@@ -102,8 +98,7 @@ void AIPlayer::tapLandsForMana(ManaCost * cost, MTGCardInstance * target)
|
|||||||
if (amp && canHandleCost(amp))
|
if (amp && canHandleCost(amp))
|
||||||
{
|
{
|
||||||
MTGCardInstance * card = amp->source;
|
MTGCardInstance * card = amp->source;
|
||||||
if (card == target)
|
if (card == target) used[card] = true; //http://code.google.com/p/wagic/issues/detail?id=76
|
||||||
used[card] = true; //http://code.google.com/p/wagic/issues/detail?id=76
|
|
||||||
if (!used[card] && amp->isReactingToClick(card) && amp->output->getConvertedCost() == 1)
|
if (!used[card] && amp->isReactingToClick(card) && amp->output->getConvertedCost() == 1)
|
||||||
{
|
{
|
||||||
used[card] = true;
|
used[card] = true;
|
||||||
@@ -142,16 +137,15 @@ ManaCost * AIPlayer::getPotentialMana(MTGCardInstance * target)
|
|||||||
if (amp && canHandleCost(amp))
|
if (amp && canHandleCost(amp))
|
||||||
{
|
{
|
||||||
MTGCardInstance * card = amp->source;
|
MTGCardInstance * card = amp->source;
|
||||||
if (card == target)
|
if (card == target) used[card] = true; //http://code.google.com/p/wagic/issues/detail?id=76
|
||||||
used[card] = true; //http://code.google.com/p/wagic/issues/detail?id=76
|
|
||||||
if (!used[card] && amp->isReactingToClick(card) && amp->output->getConvertedCost() == 1)
|
if (!used[card] && amp->isReactingToClick(card) && amp->output->getConvertedCost() == 1)
|
||||||
{
|
{
|
||||||
result->add(amp->output);
|
result->add(amp->output);
|
||||||
used[card] = true;
|
used[card] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result->add(this->getManaPool());
|
result->add(this->getManaPool());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,8 +154,6 @@ int AIPlayer::getEfficiency(AIAction * action)
|
|||||||
return action->getEfficiency();
|
return action->getEfficiency();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Can't yet handle extraCost objects (ex: sacrifice) if they require a target :(
|
//Can't yet handle extraCost objects (ex: sacrifice) if they require a target :(
|
||||||
int AIPlayer::CanHandleCost(ManaCost * cost)
|
int AIPlayer::CanHandleCost(ManaCost * cost)
|
||||||
{
|
{
|
||||||
@@ -173,9 +165,9 @@ int AIPlayer::CanHandleCost(ManaCost * cost)
|
|||||||
for (size_t i = 0; i < ec->costs.size(); ++i)
|
for (size_t i = 0; i < ec->costs.size(); ++i)
|
||||||
{
|
{
|
||||||
if (ec->costs[i]->tc)
|
if (ec->costs[i]->tc)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -190,15 +182,12 @@ int AIPlayer::canHandleCost(MTGAbility * ability)
|
|||||||
int AIAction::getEfficiency()
|
int AIAction::getEfficiency()
|
||||||
{
|
{
|
||||||
//TODO add multiplier according to what the player wants
|
//TODO add multiplier according to what the player wants
|
||||||
if (efficiency != -1)
|
if (efficiency != -1) return efficiency;
|
||||||
return efficiency;
|
if (!ability) return 0;
|
||||||
if (!ability)
|
|
||||||
return 0;
|
|
||||||
GameObserver * g = GameObserver::GetInstance();
|
GameObserver * g = GameObserver::GetInstance();
|
||||||
ActionStack * s = g->mLayers->stackLayer();
|
ActionStack * s = g->mLayers->stackLayer();
|
||||||
Player * p = g->currentlyActing();
|
Player * p = g->currentlyActing();
|
||||||
if (s->has(ability))
|
if (s->has(ability)) return 0;
|
||||||
return 0;
|
|
||||||
|
|
||||||
MTGAbility * a = AbilityFactory::getCoreAbility(ability);
|
MTGAbility * a = AbilityFactory::getCoreAbility(ability);
|
||||||
|
|
||||||
@@ -208,8 +197,7 @@ int AIAction::getEfficiency()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!((AIPlayer *) p)->canHandleCost(ability))
|
if (!((AIPlayer *) p)->canHandleCost(ability)) return 0;
|
||||||
return 0;
|
|
||||||
switch (a->aType)
|
switch (a->aType)
|
||||||
{
|
{
|
||||||
case MTGAbility::DAMAGER:
|
case MTGAbility::DAMAGER:
|
||||||
@@ -246,11 +234,10 @@ int AIAction::getEfficiency()
|
|||||||
{
|
{
|
||||||
MTGCardInstance * _target = (MTGCardInstance *) (a->target);
|
MTGCardInstance * _target = (MTGCardInstance *) (a->target);
|
||||||
efficiency = 0;
|
efficiency = 0;
|
||||||
if (!_target)
|
if (!_target) break;
|
||||||
break;
|
|
||||||
|
|
||||||
if (!_target->regenerateTokens && g->getCurrentGamePhase() == Constants::MTG_PHASE_COMBATBLOCKERS && (_target->defenser
|
if (!_target->regenerateTokens && g->getCurrentGamePhase() == Constants::MTG_PHASE_COMBATBLOCKERS && (_target->defenser
|
||||||
|| _target->blockers.size()))
|
|| _target->blockers.size()))
|
||||||
{
|
{
|
||||||
efficiency = 95;
|
efficiency = 95;
|
||||||
}
|
}
|
||||||
@@ -261,22 +248,20 @@ int AIAction::getEfficiency()
|
|||||||
case MTGAbility::STANDARD_PREVENT:
|
case MTGAbility::STANDARD_PREVENT:
|
||||||
{
|
{
|
||||||
efficiency = 0;//starts out low to avoid spamming it when its not needed.
|
efficiency = 0;//starts out low to avoid spamming it when its not needed.
|
||||||
if (!target)
|
if (!target) break;
|
||||||
break;
|
|
||||||
|
|
||||||
bool NeedPreventing;
|
bool NeedPreventing;
|
||||||
NeedPreventing = false;
|
NeedPreventing = false;
|
||||||
if (g->getCurrentGamePhase() == Constants::MTG_PHASE_COMBATBLOCKERS)
|
if (g->getCurrentGamePhase() == Constants::MTG_PHASE_COMBATBLOCKERS)
|
||||||
{
|
{
|
||||||
if ((target->defenser || target->blockers.size()) && target->preventable < target->getNextOpponent()->power)
|
if ((target->defenser || target->blockers.size()) && target->preventable < target->getNextOpponent()->power) NeedPreventing
|
||||||
NeedPreventing = true;
|
= true;
|
||||||
}
|
}
|
||||||
if (p == target->controller() && NeedPreventing == true && !(target->getNextOpponent()->has(Constants::DEATHTOUCH)
|
if (p == target->controller() && NeedPreventing == true && !(target->getNextOpponent()->has(Constants::DEATHTOUCH)
|
||||||
|| target->getNextOpponent()->has(Constants::WITHER)))
|
|| target->getNextOpponent()->has(Constants::WITHER)))
|
||||||
{
|
{
|
||||||
efficiency = 20 * (target->DangerRanking());//increase this chance to be used in combat if the creature blocking/blocked could kill the creature this chance is taking into consideration how good the creature is, best creature will always be the first "saved"..
|
efficiency = 20 * (target->DangerRanking());//increase this chance to be used in combat if the creature blocking/blocked could kill the creature this chance is taking into consideration how good the creature is, best creature will always be the first "saved"..
|
||||||
if (target->toughness == 1 && target->getNextOpponent()->power == 1)
|
if (target->toughness == 1 && target->getNextOpponent()->power == 1) efficiency += 15;
|
||||||
efficiency += 15;
|
|
||||||
//small bonus added for the poor 1/1s, if we can save them, we will unless something else took precidence.
|
//small bonus added for the poor 1/1s, if we can save them, we will unless something else took precidence.
|
||||||
}
|
}
|
||||||
//note is the target is being blocked or blocking a creature with wither or deathtouch, it is not even considered for preventing as it is a waste.
|
//note is the target is being blocked or blocking a creature with wither or deathtouch, it is not even considered for preventing as it is a waste.
|
||||||
@@ -288,26 +273,23 @@ int AIAction::getEfficiency()
|
|||||||
{
|
{
|
||||||
|
|
||||||
efficiency = 0;
|
efficiency = 0;
|
||||||
if (!target)
|
if (!target) break;
|
||||||
break;
|
|
||||||
|
|
||||||
int equips = p->game->battlefield->countByType("Equipment");
|
int equips = p->game->battlefield->countByType("Equipment");
|
||||||
int myArmy = p->game->battlefield->countByType("Creature");
|
int myArmy = p->game->battlefield->countByType("Creature");
|
||||||
int equilized = abs(equips/myArmy);
|
int equilized = abs(equips / myArmy);
|
||||||
|
|
||||||
if (p == target->controller() && target->equipment <= 1 && !a->source->target)
|
if (p == target->controller() && target->equipment <= 1 && !a->source->target)
|
||||||
{
|
{
|
||||||
efficiency = 20 * (target->DangerRanking());
|
efficiency = 20 * (target->DangerRanking());
|
||||||
if (target->hasColor(5))
|
if (target->hasColor(5)) efficiency += 20;//this is to encourage Ai to equip white creatures in a weenie deck. ultimately it will depend on what had the higher dangerranking.
|
||||||
efficiency += 20;//this is to encourage Ai to equip white creatures in a weenie deck. ultimately it will depend on what had the higher dangerranking.
|
if (target->power == 1 && target->toughness == 1 && target->isToken == 0) efficiency += 10; //small bonus to encourage equipping nontoken 1/1 creatures.
|
||||||
if (target->power == 1 && target->toughness == 1 && target->isToken == 0)
|
|
||||||
efficiency += 10; //small bonus to encourage equipping nontoken 1/1 creatures.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p == target->controller() && !a->source->target && target->equipment < equilized)
|
if (p == target->controller() && !a->source->target && target->equipment < equilized)
|
||||||
{
|
{
|
||||||
efficiency = 15 * (target->DangerRanking());
|
efficiency = 15 * (target->DangerRanking());
|
||||||
efficiency -= 5 * (target->equipment);
|
efficiency -= 5 * (target->equipment);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -335,31 +317,30 @@ int AIAction::getEfficiency()
|
|||||||
efficiency += currentlevel;
|
efficiency += currentlevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(p->game->hand->nb_cards > 0 && p->isAI())
|
if (p->game->hand->nb_cards > 0 && p->isAI())
|
||||||
{
|
{
|
||||||
efficiency -= (10 * p->game->hand->nb_cards);//reduce the eff if by 10 times the amount of cards in Ais hand.
|
efficiency -= (10 * p->game->hand->nb_cards);//reduce the eff if by 10 times the amount of cards in Ais hand.
|
||||||
//it should always try playing more cards before deciding
|
//it should always try playing more cards before deciding
|
||||||
}
|
}
|
||||||
|
|
||||||
if(g->getCurrentGamePhase() == Constants::MTG_PHASE_SECONDMAIN)
|
if (g->getCurrentGamePhase() == Constants::MTG_PHASE_SECONDMAIN)
|
||||||
{
|
{
|
||||||
efficiency = 100;
|
efficiency = 100;
|
||||||
//in 2nd main, go all out and try to max stuff.
|
//in 2nd main, go all out and try to max stuff.
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MTGAbility::STANDARD_PUMP:
|
case MTGAbility::STANDARD_PUMP:
|
||||||
{
|
{
|
||||||
MTGCardInstance * _target = (MTGCardInstance *) (a->target);
|
MTGCardInstance * _target = (MTGCardInstance *) (a->target);
|
||||||
if (!target)
|
if (!target) break;
|
||||||
break;
|
|
||||||
//i do not set a starting eff. on this ability, this allows Ai to sometimes randomly do it as it normally does.
|
//i do not set a starting eff. on this ability, this allows Ai to sometimes randomly do it as it normally does.
|
||||||
if (g->getCurrentGamePhase() == Constants::MTG_PHASE_COMBATBLOCKERS)
|
if (g->getCurrentGamePhase() == Constants::MTG_PHASE_COMBATBLOCKERS)
|
||||||
{
|
{
|
||||||
if (BAKA_EFFECT_GOOD)
|
if (BAKA_EFFECT_GOOD)
|
||||||
{
|
{
|
||||||
if ((_target->defenser || _target->blockers.size()) && ((_target->power < _target->getNextOpponent()->toughness
|
if ((_target->defenser || _target->blockers.size()) && ((_target->power < _target->getNextOpponent()->toughness
|
||||||
|| _target->toughness < _target->getNextOpponent()->power) || (_target->has(Constants::TRAMPLE))))
|
|| _target->toughness < _target->getNextOpponent()->power) || (_target->has(Constants::TRAMPLE))))
|
||||||
{
|
{
|
||||||
//this pump is based on a start eff. of 20 multiplied by how good the creature is.
|
//this pump is based on a start eff. of 20 multiplied by how good the creature is.
|
||||||
efficiency = 20 * _target->DangerRanking();
|
efficiency = 20 * _target->DangerRanking();
|
||||||
@@ -394,124 +375,120 @@ int AIAction::getEfficiency()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MTGAbility::FOREACH:
|
case MTGAbility::FOREACH:
|
||||||
{
|
{
|
||||||
MTGCardInstance * _target = (MTGCardInstance *) (a->target);
|
MTGCardInstance * _target = (MTGCardInstance *) (a->target);
|
||||||
MTGAbility * a = AbilityFactory::getCoreAbility(ability);
|
MTGAbility * a = AbilityFactory::getCoreAbility(ability);
|
||||||
AManaProducer * amp = dynamic_cast<AManaProducer*> (a);
|
AManaProducer * amp = dynamic_cast<AManaProducer*> (a);
|
||||||
efficiency = 0;
|
efficiency = 0;
|
||||||
//trying to encourage Ai to use his foreach manaproducers in first main
|
//trying to encourage Ai to use his foreach manaproducers in first main
|
||||||
if (a->naType == MTGAbility::MANA_PRODUCER && (g->getCurrentGamePhase() == Constants::MTG_PHASE_FIRSTMAIN || g->getCurrentGamePhase() == Constants::MTG_PHASE_SECONDMAIN )
|
if (a->naType == MTGAbility::MANA_PRODUCER && (g->getCurrentGamePhase() == Constants::MTG_PHASE_FIRSTMAIN
|
||||||
&& _target->controller()->game->hand->nb_cards > 0)
|
|| g->getCurrentGamePhase() == Constants::MTG_PHASE_SECONDMAIN) && _target->controller()->game->hand->nb_cards > 0)
|
||||||
{
|
{
|
||||||
for (int i = Constants::MTG_NB_COLORS - 1; i > 0; i--)
|
for (int i = Constants::MTG_NB_COLORS - 1; i > 0; i--)
|
||||||
{
|
{
|
||||||
if((p->game->hand->hasColor(i) || p->game->hand->hasColor(0))
|
if ((p->game->hand->hasColor(i) || p->game->hand->hasColor(0))
|
||||||
&& (dynamic_cast<AManaProducer*>(( dynamic_cast<AForeach*>( a )->ability))->output->hasColor(i)))
|
&& (dynamic_cast<AManaProducer*> ((dynamic_cast<AForeach*> (a)->ability))->output->hasColor(i)))
|
||||||
{
|
{
|
||||||
efficiency = 100;
|
efficiency = 100;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(p->game->hand->hasX())
|
if (p->game->hand->hasX()) efficiency = 100;
|
||||||
efficiency = 100;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AbilityFactory af;
|
AbilityFactory af;
|
||||||
int suggestion = af.abilityEfficiency(a, p, MODE_ABILITY);
|
int suggestion = af.abilityEfficiency(a, p, MODE_ABILITY);
|
||||||
|
|
||||||
if (target && a->naType != MTGAbility::MANA_PRODUCER && ((suggestion == BAKA_EFFECT_BAD && p == target->controller()) || (suggestion == BAKA_EFFECT_GOOD && p
|
if (target && a->naType != MTGAbility::MANA_PRODUCER && ((suggestion == BAKA_EFFECT_BAD && p == target->controller())
|
||||||
!= target->controller())))
|
|| (suggestion == BAKA_EFFECT_GOOD && p != target->controller())))
|
||||||
{
|
{
|
||||||
efficiency = 0;
|
efficiency = 0;
|
||||||
}
|
}
|
||||||
else if (a->naType != MTGAbility::MANA_PRODUCER && (g->getCurrentGamePhase() == Constants::MTG_PHASE_FIRSTMAIN || g->getCurrentGamePhase() == Constants::MTG_PHASE_SECONDMAIN ))
|
else if (a->naType != MTGAbility::MANA_PRODUCER && (g->getCurrentGamePhase() == Constants::MTG_PHASE_FIRSTMAIN
|
||||||
{
|
|| g->getCurrentGamePhase() == Constants::MTG_PHASE_SECONDMAIN))
|
||||||
//if its not a manaproducing foreach, and its not targetted, its eff is 90.
|
{
|
||||||
//added this basically to cover the unknown foreachs, or untrained ones which were not targetted effects.
|
//if its not a manaproducing foreach, and its not targetted, its eff is 90.
|
||||||
efficiency = 90;
|
//added this basically to cover the unknown foreachs, or untrained ones which were not targetted effects.
|
||||||
}
|
efficiency = 90;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MTGAbility::STANDARDABILITYGRANT:
|
case MTGAbility::STANDARDABILITYGRANT:
|
||||||
{
|
{
|
||||||
efficiency = 0;
|
efficiency = 0;
|
||||||
MTGCardInstance * _target = (MTGCardInstance *) (a->target);
|
MTGCardInstance * _target = (MTGCardInstance *) (a->target);
|
||||||
if (!target)
|
if (!target) break;
|
||||||
break;
|
|
||||||
//ensuring that Ai grants abilities to creatures during first main, so it can actually use them in combat.
|
//ensuring that Ai grants abilities to creatures during first main, so it can actually use them in combat.
|
||||||
//quick note: the eff is multiplied by creatures ranking then divided by the number of cards in hand.
|
//quick note: the eff is multiplied by creatures ranking then divided by the number of cards in hand.
|
||||||
//the reason i do this is to encourage more casting and less waste of mana on abilities.
|
//the reason i do this is to encourage more casting and less waste of mana on abilities.
|
||||||
AbilityFactory af;
|
AbilityFactory af;
|
||||||
int suggestion = af.abilityEfficiency(a, p, MODE_ABILITY);
|
int suggestion = af.abilityEfficiency(a, p, MODE_ABILITY);
|
||||||
|
|
||||||
if ((suggestion == BAKA_EFFECT_BAD && p == target->controller()) || (suggestion == BAKA_EFFECT_GOOD && p!= target->controller()))
|
if ((suggestion == BAKA_EFFECT_BAD && p == target->controller()) || (suggestion == BAKA_EFFECT_GOOD && p
|
||||||
|
!= target->controller()))
|
||||||
{
|
{
|
||||||
efficiency = 0;
|
efficiency = 0;
|
||||||
//stop giving trample to the players creatures.
|
//stop giving trample to the players creatures.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (suggestion == BAKA_EFFECT_BAD && p != target->controller() && target->has(a->abilitygranted))
|
if (suggestion == BAKA_EFFECT_BAD && p != target->controller() && target->has(a->abilitygranted))
|
||||||
{
|
{
|
||||||
efficiency += (25 * target->DangerRanking())/p->game->hand->nb_cards;
|
efficiency += (25 * target->DangerRanking()) / p->game->hand->nb_cards;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!target->has(a->abilitygranted) && g->getCurrentGamePhase() == Constants::MTG_PHASE_COMBATBEGIN)
|
if (!target->has(a->abilitygranted) && g->getCurrentGamePhase() == Constants::MTG_PHASE_COMBATBEGIN)
|
||||||
{
|
{
|
||||||
efficiency += (25 * target->DangerRanking())/p->game->hand->nb_cards;
|
efficiency += (25 * target->DangerRanking()) / p->game->hand->nb_cards;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target->has(a->abilitygranted))
|
if (target->has(a->abilitygranted))
|
||||||
{
|
{
|
||||||
//trying to avoid Ai giving ie:flying creatures ie:flying twice.
|
//trying to avoid Ai giving ie:flying creatures ie:flying twice.
|
||||||
efficiency = 0;
|
efficiency = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MTGAbility::UNTAPPER:
|
case MTGAbility::UNTAPPER:
|
||||||
//untap things that Ai owns and are tapped.
|
//untap things that Ai owns and are tapped.
|
||||||
{
|
{
|
||||||
efficiency = 0;
|
efficiency = 0;
|
||||||
if (!target)
|
if (!target) break;
|
||||||
break;
|
|
||||||
|
|
||||||
if (target->isTapped() && target->controller()->isAI())
|
if (target->isTapped() && target->controller()->isAI())
|
||||||
{
|
{
|
||||||
efficiency = (20 * target->DangerRanking());
|
efficiency = (20 * target->DangerRanking());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MTGAbility::TAPPER:
|
case MTGAbility::TAPPER:
|
||||||
//tap things the player owns and that are untapped.
|
//tap things the player owns and that are untapped.
|
||||||
{
|
{
|
||||||
if (!target)
|
if (!target) break;
|
||||||
break;
|
|
||||||
|
|
||||||
if (!target->controller()->isAI())
|
if (!target->controller()->isAI()) efficiency = (20 * target->DangerRanking());
|
||||||
efficiency = (20 * target->DangerRanking());
|
|
||||||
|
|
||||||
if(target->isTapped())
|
if (target->isTapped()) efficiency = 0;
|
||||||
efficiency = 0;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MTGAbility::LIFER:
|
case MTGAbility::LIFER:
|
||||||
{
|
{
|
||||||
//use life abilities whenever possible.
|
//use life abilities whenever possible.
|
||||||
AALifer * alife = (AALifer *) a;
|
AALifer * alife = (AALifer *) a;
|
||||||
Targetable * _t = alife->getTarget();
|
Targetable * _t = alife->getTarget();
|
||||||
|
|
||||||
efficiency = 100;
|
efficiency = 100;
|
||||||
AbilityFactory af;
|
AbilityFactory af;
|
||||||
int suggestion = af.abilityEfficiency(a, p, MODE_ABILITY);
|
int suggestion = af.abilityEfficiency(a, p, MODE_ABILITY);
|
||||||
|
|
||||||
if ((suggestion == BAKA_EFFECT_BAD && _t == p && p->isAI()) || (suggestion == BAKA_EFFECT_GOOD && _t == p && !p->isAI()))
|
if ((suggestion == BAKA_EFFECT_BAD && _t == p && p->isAI()) || (suggestion == BAKA_EFFECT_GOOD && _t == p && !p->isAI()))
|
||||||
@@ -520,8 +497,8 @@ int AIAction::getEfficiency()
|
|||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MTGAbility::MANA_PRODUCER:
|
case MTGAbility::MANA_PRODUCER:
|
||||||
efficiency = 0;
|
efficiency = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -531,7 +508,7 @@ int AIAction::getEfficiency()
|
|||||||
AbilityFactory af;
|
AbilityFactory af;
|
||||||
int suggestion = af.abilityEfficiency(a, p, MODE_ABILITY);
|
int suggestion = af.abilityEfficiency(a, p, MODE_ABILITY);
|
||||||
if ((suggestion == BAKA_EFFECT_BAD && p == target->controller()) || (suggestion == BAKA_EFFECT_GOOD && p
|
if ((suggestion == BAKA_EFFECT_BAD && p == target->controller()) || (suggestion == BAKA_EFFECT_GOOD && p
|
||||||
!= target->controller()))
|
!= target->controller()))
|
||||||
{
|
{
|
||||||
efficiency = 0;
|
efficiency = 0;
|
||||||
}
|
}
|
||||||
@@ -547,13 +524,11 @@ int AIAction::getEfficiency()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->game->hand->nb_cards == 0)
|
if (p->game->hand->nb_cards == 0) efficiency = (int) ((float) efficiency * 1.3); //increase chance of using ability if hand is empty
|
||||||
efficiency = (int) ((float) efficiency * 1.3); //increase chance of using ability if hand is empty
|
|
||||||
if (ability->cost)
|
if (ability->cost)
|
||||||
{
|
{
|
||||||
ExtraCosts * ec = ability->cost->extraCosts;
|
ExtraCosts * ec = ability->cost->extraCosts;
|
||||||
if (ec)
|
if (ec) efficiency = efficiency / 3; //Decrease chance of using ability if there is an extra cost to use the ability
|
||||||
efficiency = efficiency / 3; //Decrease chance of using ability if there is an extra cost to use the ability
|
|
||||||
}
|
}
|
||||||
return efficiency;
|
return efficiency;
|
||||||
}
|
}
|
||||||
@@ -600,8 +575,7 @@ int AIPlayer::selectAbility()
|
|||||||
{ //0 is not a mtgability...hackish
|
{ //0 is not a mtgability...hackish
|
||||||
MTGAbility * a = ((MTGAbility *) g->mLayers->actionLayer()->mObjects[i]);
|
MTGAbility * a = ((MTGAbility *) g->mLayers->actionLayer()->mObjects[i]);
|
||||||
//Skip mana abilities for performance
|
//Skip mana abilities for performance
|
||||||
if (dynamic_cast<AManaProducer*> (a))
|
if (dynamic_cast<AManaProducer*> (a)) continue;
|
||||||
continue;
|
|
||||||
//Make sure we can use the ability
|
//Make sure we can use the ability
|
||||||
for (int j = 0; j < game->inPlay->nb_cards; j++)
|
for (int j = 0; j < game->inPlay->nb_cards; j++)
|
||||||
{
|
{
|
||||||
@@ -609,8 +583,7 @@ int AIPlayer::selectAbility()
|
|||||||
if (a->isReactingToClick(card, totalPotentialMana))
|
if (a->isReactingToClick(card, totalPotentialMana))
|
||||||
{ //This test is to avod the huge call to getPotentialManaCost after that
|
{ //This test is to avod the huge call to getPotentialManaCost after that
|
||||||
ManaCost * pMana = getPotentialMana(card);
|
ManaCost * pMana = getPotentialMana(card);
|
||||||
if (a->isReactingToClick(card, pMana))
|
if (a->isReactingToClick(card, pMana)) createAbilityTargets(a, card, &ranking);
|
||||||
createAbilityTargets(a, card, &ranking);
|
|
||||||
delete (pMana);
|
delete (pMana);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -621,30 +594,28 @@ int AIPlayer::selectAbility()
|
|||||||
{
|
{
|
||||||
AIAction * a = ranking.begin()->first;
|
AIAction * a = ranking.begin()->first;
|
||||||
int chance = 1;
|
int chance = 1;
|
||||||
if (!forceBestAbilityUse)
|
if (!forceBestAbilityUse) chance = 1 + WRand() % 100;
|
||||||
chance = 1 + WRand() % 100;
|
|
||||||
if (getEfficiency(a) < chance)
|
if (getEfficiency(a) < chance)
|
||||||
{
|
{
|
||||||
a = NULL;
|
a = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(!clickstream.size())
|
if (!clickstream.size())
|
||||||
{
|
{
|
||||||
DebugTrace("AIPlayer:Using Activated ability");
|
DebugTrace("AIPlayer:Using Activated ability");
|
||||||
tapLandsForMana(a->ability->cost, a->click);
|
tapLandsForMana(a->ability->cost, a->click);
|
||||||
clickstream.push(a);
|
clickstream.push(a);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
a = NULL;
|
a = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
map<AIAction *, int, CmpAbilities>::iterator it2;
|
map<AIAction *, int, CmpAbilities>::iterator it2;
|
||||||
for (it2 = ranking.begin(); it2 != ranking.end(); it2++)
|
for (it2 = ranking.begin(); it2 != ranking.end(); it2++)
|
||||||
{
|
{
|
||||||
if (a && a != it2->first)
|
if (a && a != it2->first) delete (it2->first);
|
||||||
delete (it2->first);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AIPlayer::findingAbility = false;
|
AIPlayer::findingAbility = false;
|
||||||
@@ -671,8 +642,7 @@ int AIPlayer::effectBadOrGood(MTGCardInstance * card, int mode, TargetChooser *
|
|||||||
int id = card->getMTGId();
|
int id = card->getMTGId();
|
||||||
AbilityFactory af;
|
AbilityFactory af;
|
||||||
int autoGuess = af.magicText(id, NULL, card, mode, tc);
|
int autoGuess = af.magicText(id, NULL, card, mode, tc);
|
||||||
if (autoGuess)
|
if (autoGuess) return autoGuess;
|
||||||
return autoGuess;
|
|
||||||
return BAKA_EFFECT_DONTKNOW;
|
return BAKA_EFFECT_DONTKNOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -691,11 +661,9 @@ int AIPlayer::chooseTarget(TargetChooser * _tc, Player * forceTarget)
|
|||||||
{
|
{
|
||||||
tc = gameObs->getCurrentTargetChooser();
|
tc = gameObs->getCurrentTargetChooser();
|
||||||
}
|
}
|
||||||
if (!tc)
|
if (!tc) return 0;
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!(gameObs->currentlyActing() == this))
|
if (!(gameObs->currentlyActing() == this)) return 0;
|
||||||
return 0;
|
|
||||||
Player * target = forceTarget;
|
Player * target = forceTarget;
|
||||||
|
|
||||||
if (!target)
|
if (!target)
|
||||||
@@ -715,8 +683,7 @@ int AIPlayer::chooseTarget(TargetChooser * _tc, Player * forceTarget)
|
|||||||
potentialTargets.push_back(target);
|
potentialTargets.push_back(target);
|
||||||
nbtargets++;
|
nbtargets++;
|
||||||
}
|
}
|
||||||
if (checkOnly)
|
if (checkOnly) return 1;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
MTGPlayerCards * playerZones = target->game;
|
MTGPlayerCards * playerZones = target->game;
|
||||||
MTGGameZone * zones[] = { playerZones->hand, playerZones->library, playerZones->inPlay, playerZones->graveyard };
|
MTGGameZone * zones[] = { playerZones->hand, playerZones->library, playerZones->inPlay, playerZones->graveyard };
|
||||||
@@ -728,8 +695,7 @@ int AIPlayer::chooseTarget(TargetChooser * _tc, Player * forceTarget)
|
|||||||
MTGCardInstance * card = zone->cards[k];
|
MTGCardInstance * card = zone->cards[k];
|
||||||
if (!tc->alreadyHasTarget(card) && tc->canTarget(card) && nbtargets < 50)
|
if (!tc->alreadyHasTarget(card) && tc->canTarget(card) && nbtargets < 50)
|
||||||
{
|
{
|
||||||
if (checkOnly)
|
if (checkOnly) return 1;
|
||||||
return 1;
|
|
||||||
int multiplier = 1;
|
int multiplier = 1;
|
||||||
if (getStats() && getStats()->isInTop(card, 10))
|
if (getStats() && getStats()->isInTop(card, 10))
|
||||||
{
|
{
|
||||||
@@ -776,11 +742,9 @@ int AIPlayer::chooseTarget(TargetChooser * _tc, Player * forceTarget)
|
|||||||
//Couldn't find any valid target,
|
//Couldn't find any valid target,
|
||||||
//usually that's because we played a card that has bad side effects (ex: when X comes into play, return target land you own to your hand)
|
//usually that's because we played a card that has bad side effects (ex: when X comes into play, return target land you own to your hand)
|
||||||
//so we try again to choose a target in the other player's field...
|
//so we try again to choose a target in the other player's field...
|
||||||
if (checkOnly)
|
if (checkOnly) return 0;
|
||||||
return 0;
|
|
||||||
int cancel = gameObs->cancelCurrentAction();
|
int cancel = gameObs->cancelCurrentAction();
|
||||||
if (!cancel && !forceTarget)
|
if (!cancel && !forceTarget) return chooseTarget(_tc, target->opponent());
|
||||||
return chooseTarget(_tc, target->opponent());
|
|
||||||
|
|
||||||
//ERROR!!!
|
//ERROR!!!
|
||||||
DebugTrace("AIPLAYER: ERROR! AI needs to choose a target but can't decide!!!");
|
DebugTrace("AIPLAYER: ERROR! AI needs to choose a target but can't decide!!!");
|
||||||
@@ -826,7 +790,7 @@ int AIPlayer::chooseAttackers()
|
|||||||
opponentCreatures = getCreaturesInfo(opponent(), INFO_NBCREATURES, -1);
|
opponentCreatures = getCreaturesInfo(opponent(), INFO_NBCREATURES, -1);
|
||||||
opponentForce = getCreaturesInfo(opponent(), INFO_CREATURESPOWER, -1);
|
opponentForce = getCreaturesInfo(opponent(), INFO_CREATURESPOWER, -1);
|
||||||
attack = (myCreatures >= opponentCreatures && myForce > opponentForce) || (myForce > opponentForce) || (myForce
|
attack = (myCreatures >= opponentCreatures && myForce > opponentForce) || (myForce > opponentForce) || (myForce
|
||||||
> opponent()->life);
|
> opponent()->life);
|
||||||
}
|
}
|
||||||
printf("Choose attackers : %i %i %i %i -> %i\n", opponentForce, opponentCreatures, myForce, myCreatures, attack);
|
printf("Choose attackers : %i %i %i %i -> %i\n", opponentForce, opponentCreatures, myForce, myCreatures, attack);
|
||||||
if (attack)
|
if (attack)
|
||||||
@@ -848,14 +812,10 @@ int AIPlayer::chooseAttackers()
|
|||||||
/* Can I first strike my oponent and get away with murder ? */
|
/* Can I first strike my oponent and get away with murder ? */
|
||||||
int AIPlayer::canFirstStrikeKill(MTGCardInstance * card, MTGCardInstance *ennemy)
|
int AIPlayer::canFirstStrikeKill(MTGCardInstance * card, MTGCardInstance *ennemy)
|
||||||
{
|
{
|
||||||
if (ennemy->has(Constants::FIRSTSTRIKE) || ennemy->has(Constants::DOUBLESTRIKE))
|
if (ennemy->has(Constants::FIRSTSTRIKE) || ennemy->has(Constants::DOUBLESTRIKE)) return 0;
|
||||||
return 0;
|
if (!(card->has(Constants::FIRSTSTRIKE) || card->has(Constants::DOUBLESTRIKE))) return 0;
|
||||||
if (!(card->has(Constants::FIRSTSTRIKE) || card->has(Constants::DOUBLESTRIKE)))
|
if (!(card->power >= ennemy->toughness)) return 0;
|
||||||
return 0;
|
if (!(card->power >= ennemy->toughness + 1) && ennemy->has(Constants::FLANKING)) return 0;
|
||||||
if (!(card->power >= ennemy->toughness))
|
|
||||||
return 0;
|
|
||||||
if (!(card->power >= ennemy->toughness + 1) && ennemy->has(Constants::FLANKING))
|
|
||||||
return 0;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -934,7 +894,7 @@ int AIPlayer::chooseBlockers()
|
|||||||
{
|
{
|
||||||
MTGCardInstance * attacker = card->defenser;
|
MTGCardInstance * attacker = card->defenser;
|
||||||
if (opponentsToughness[attacker] <= 0 || (card->toughness <= attacker->power && opponentForce * 2 < life
|
if (opponentsToughness[attacker] <= 0 || (card->toughness <= attacker->power && opponentForce * 2 < life
|
||||||
&& !canFirstStrikeKill(card, attacker)) || attacker->nbOpponents() > 1)
|
&& !canFirstStrikeKill(card, attacker)) || attacker->nbOpponents() > 1)
|
||||||
{
|
{
|
||||||
g->mLayers->actionLayer()->reactToClick(a, card);
|
g->mLayers->actionLayer()->reactToClick(a, card);
|
||||||
}
|
}
|
||||||
@@ -979,11 +939,9 @@ int AIPlayer::combatDamages()
|
|||||||
GameObserver * gameObs = GameObserver::GetInstance();
|
GameObserver * gameObs = GameObserver::GetInstance();
|
||||||
int currentGamePhase = gameObs->getCurrentGamePhase();
|
int currentGamePhase = gameObs->getCurrentGamePhase();
|
||||||
|
|
||||||
if (currentGamePhase == Constants::MTG_PHASE_COMBATBLOCKERS)
|
if (currentGamePhase == Constants::MTG_PHASE_COMBATBLOCKERS) return orderBlockers();
|
||||||
return orderBlockers();
|
|
||||||
|
|
||||||
if (currentGamePhase != Constants::MTG_PHASE_COMBATDAMAGE)
|
if (currentGamePhase != Constants::MTG_PHASE_COMBATDAMAGE) return 0;
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -1033,8 +991,7 @@ AIPlayer * AIPlayerFactory::createAIPlayer(MTGAllCards * collection, Player * op
|
|||||||
nbdecks++;
|
nbdecks++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!nbdecks)
|
if (!nbdecks) return NULL;
|
||||||
return NULL;
|
|
||||||
deckid = 1 + WRand() % (nbdecks);
|
deckid = 1 + WRand() % (nbdecks);
|
||||||
}
|
}
|
||||||
sprintf(deckFile, JGE_GET_RES("ai/baka/deck%i.txt").c_str(), deckid);
|
sprintf(deckFile, JGE_GET_RES("ai/baka/deck%i.txt").c_str(), deckid);
|
||||||
@@ -1062,22 +1019,14 @@ MTGCardInstance * AIPlayerBaka::FindCardToPlay(ManaCost * pMana, const char * ty
|
|||||||
card = NULL;
|
card = NULL;
|
||||||
while ((card = cd.nextmatch(game->hand, card)))
|
while ((card = cd.nextmatch(game->hand, card)))
|
||||||
{
|
{
|
||||||
if (!CanHandleCost(card->getManaCost()))
|
if (!CanHandleCost(card->getManaCost())) continue;
|
||||||
continue;
|
if (card->hasType(Subtypes::TYPE_CREATURE) && this->castrestrictedcreature > 0 && this->castrestrictedspell > 0) continue;
|
||||||
if (card->hasType(Subtypes::TYPE_CREATURE) && this->castrestrictedcreature > 0 && this->castrestrictedspell > 0)
|
if (card->hasType(Subtypes::TYPE_ENCHANTMENT) && this->castrestrictedspell > 0) continue;
|
||||||
continue;
|
if (card->hasType(Subtypes::TYPE_ARTIFACT) && this->castrestrictedspell > 0) continue;
|
||||||
if (card->hasType(Subtypes::TYPE_ENCHANTMENT) && this->castrestrictedspell > 0)
|
if (card->hasType(Subtypes::TYPE_SORCERY) && this->castrestrictedspell > 0) continue;
|
||||||
continue;
|
if (card->hasType(Subtypes::TYPE_INSTANT) && this->castrestrictedspell > 0) continue;
|
||||||
if (card->hasType(Subtypes::TYPE_ARTIFACT) && this->castrestrictedspell > 0)
|
if (card->hasType(Subtypes::TYPE_LAND) && !this->canPutLandsIntoPlay) continue;
|
||||||
continue;
|
if (card->hasType(Subtypes::TYPE_LEGENDARY) && game->inPlay->findByName(card->name)) continue;
|
||||||
if (card->hasType(Subtypes::TYPE_SORCERY) && this->castrestrictedspell > 0)
|
|
||||||
continue;
|
|
||||||
if (card->hasType(Subtypes::TYPE_INSTANT) && this->castrestrictedspell > 0)
|
|
||||||
continue;
|
|
||||||
if (card->hasType(Subtypes::TYPE_LAND) && !this->canPutLandsIntoPlay)
|
|
||||||
continue;
|
|
||||||
if (card->hasType(Subtypes::TYPE_LEGENDARY) && game->inPlay->findByName(card->name))
|
|
||||||
continue;
|
|
||||||
int currentCost = card->getManaCost()->getConvertedCost();
|
int currentCost = card->getManaCost()->getConvertedCost();
|
||||||
int hasX = card->getManaCost()->hasX();
|
int hasX = card->getManaCost()->hasX();
|
||||||
if ((currentCost > maxCost || hasX) && pMana->canAfford(card->getManaCost()))
|
if ((currentCost > maxCost || hasX) && pMana->canAfford(card->getManaCost()))
|
||||||
@@ -1089,8 +1038,7 @@ MTGCardInstance * AIPlayerBaka::FindCardToPlay(ManaCost * pMana, const char * ty
|
|||||||
{
|
{
|
||||||
int hasTarget = (chooseTarget(tc));
|
int hasTarget = (chooseTarget(tc));
|
||||||
delete tc;
|
delete tc;
|
||||||
if (!hasTarget)
|
if (!hasTarget) continue;
|
||||||
continue;
|
|
||||||
shouldPlayPercentage = 90;
|
shouldPlayPercentage = 90;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1109,17 +1057,14 @@ MTGCardInstance * AIPlayerBaka::FindCardToPlay(ManaCost * pMana, const char * ty
|
|||||||
if (hasX)
|
if (hasX)
|
||||||
{
|
{
|
||||||
int xDiff = pMana->getConvertedCost() - currentCost;
|
int xDiff = pMana->getConvertedCost() - currentCost;
|
||||||
if (xDiff < 0)
|
if (xDiff < 0) xDiff = 0;
|
||||||
xDiff = 0;
|
|
||||||
shouldPlayPercentage = shouldPlayPercentage - static_cast<int> ((shouldPlayPercentage * 1.9f) / (1 + xDiff));
|
shouldPlayPercentage = shouldPlayPercentage - static_cast<int> ((shouldPlayPercentage * 1.9f) / (1 + xDiff));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WRand() % 100 > shouldPlayPercentage)
|
if (WRand() % 100 > shouldPlayPercentage) continue;
|
||||||
continue;
|
|
||||||
nextCardToPlay = card;
|
nextCardToPlay = card;
|
||||||
maxCost = currentCost;
|
maxCost = currentCost;
|
||||||
if (hasX)
|
if (hasX) maxCost = pMana->getConvertedCost();
|
||||||
maxCost = pMana->getConvertedCost();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nextCardToPlay;
|
return nextCardToPlay;
|
||||||
@@ -1137,7 +1082,8 @@ AIPlayerBaka::AIPlayerBaka(MTGDeck * deck, string file, string fileSmall, string
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mAvatarTex)
|
if (mAvatarTex)
|
||||||
mAvatar = WResourceManager::Instance()->RetrieveQuad(avatarFile, 0, 0, 35, 50, "bakaAvatar", RETRIEVE_NORMAL, TEXTURE_SUB_AVATAR);
|
mAvatar = WResourceManager::Instance()->RetrieveQuad(avatarFile, 0, 0, 35, 50, "bakaAvatar", RETRIEVE_NORMAL,
|
||||||
|
TEXTURE_SUB_AVATAR);
|
||||||
else
|
else
|
||||||
mAvatar = NULL;
|
mAvatar = NULL;
|
||||||
|
|
||||||
@@ -1153,24 +1099,22 @@ int AIPlayerBaka::computeActions()
|
|||||||
{
|
{
|
||||||
GameObserver * g = GameObserver::GetInstance();
|
GameObserver * g = GameObserver::GetInstance();
|
||||||
Player * p = g->currentPlayer;
|
Player * p = g->currentPlayer;
|
||||||
AIPlayer::findingAbility = false;
|
AIPlayer::findingAbility = false;
|
||||||
if (!(g->currentlyActing() == this))
|
if (!(g->currentlyActing() == this)) return 0;
|
||||||
return 0;
|
|
||||||
if (g->mLayers->actionLayer()->menuObject)
|
if (g->mLayers->actionLayer()->menuObject)
|
||||||
{
|
{
|
||||||
g->mLayers->actionLayer()->doReactTo(0);
|
g->mLayers->actionLayer()->doReactTo(0);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (chooseTarget())
|
if (chooseTarget()) return 1;
|
||||||
return 1;
|
|
||||||
int currentGamePhase = g->getCurrentGamePhase();
|
int currentGamePhase = g->getCurrentGamePhase();
|
||||||
if (g->isInterrupting == this)
|
if (g->isInterrupting == this)
|
||||||
{ // interrupting
|
{ // interrupting
|
||||||
if(!findingAbility)
|
if (!findingAbility)
|
||||||
{
|
{
|
||||||
AIPlayer::findingAbility = true;
|
AIPlayer::findingAbility = true;
|
||||||
selectAbility();
|
selectAbility();
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if (p == this && g->mLayers->stackLayer()->count(0, NOT_RESOLVED) == 0)
|
else if (p == this && g->mLayers->stackLayer()->count(0, NOT_RESOLVED) == 0)
|
||||||
@@ -1191,11 +1135,11 @@ int AIPlayerBaka::computeActions()
|
|||||||
potential = true;
|
potential = true;
|
||||||
}
|
}
|
||||||
nextCardToPlay = FindCardToPlay(currentMana, "land");
|
nextCardToPlay = FindCardToPlay(currentMana, "land");
|
||||||
if(!findingAbility)
|
if (!findingAbility)
|
||||||
{
|
{
|
||||||
AIPlayer::findingAbility = true;
|
AIPlayer::findingAbility = true;
|
||||||
selectAbility();
|
selectAbility();
|
||||||
}
|
}
|
||||||
//look for the most expensive creature we can afford
|
//look for the most expensive creature we can afford
|
||||||
if (castrestrictedspell == 0 && nospellinstant == 0)
|
if (castrestrictedspell == 0 && nospellinstant == 0)
|
||||||
{
|
{
|
||||||
@@ -1206,41 +1150,40 @@ int AIPlayerBaka::computeActions()
|
|||||||
if (castrestrictedcreature == 0 && nocreatureinstant == 0)
|
if (castrestrictedcreature == 0 && nocreatureinstant == 0)
|
||||||
{
|
{
|
||||||
if (!nextCardToPlay)
|
if (!nextCardToPlay)
|
||||||
{
|
{
|
||||||
nextCardToPlay = FindCardToPlay(currentMana, "creature");
|
nextCardToPlay = FindCardToPlay(currentMana, "creature");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Let's Try an enchantment maybe ?
|
//Let's Try an enchantment maybe ?
|
||||||
if (!nextCardToPlay)
|
if (!nextCardToPlay)
|
||||||
{
|
{
|
||||||
nextCardToPlay = FindCardToPlay(currentMana, "enchantment");
|
nextCardToPlay = FindCardToPlay(currentMana, "enchantment");
|
||||||
}
|
}
|
||||||
if (!nextCardToPlay)
|
if (!nextCardToPlay)
|
||||||
{
|
{
|
||||||
nextCardToPlay = FindCardToPlay(currentMana, "artifact");
|
nextCardToPlay = FindCardToPlay(currentMana, "artifact");
|
||||||
}
|
}
|
||||||
if (!nextCardToPlay)
|
if (!nextCardToPlay)
|
||||||
{
|
{
|
||||||
nextCardToPlay = FindCardToPlay(currentMana, "sorcery");
|
nextCardToPlay = FindCardToPlay(currentMana, "sorcery");
|
||||||
}
|
}
|
||||||
if (!nextCardToPlay)
|
if (!nextCardToPlay)
|
||||||
{
|
{
|
||||||
nextCardToPlay = FindCardToPlay(currentMana, "instant");
|
nextCardToPlay = FindCardToPlay(currentMana, "instant");
|
||||||
}
|
}
|
||||||
if (!nextCardToPlay)
|
if (!nextCardToPlay)
|
||||||
{
|
{
|
||||||
if(!findingAbility)
|
if (!findingAbility)
|
||||||
{
|
{
|
||||||
AIPlayer::findingAbility = true;
|
AIPlayer::findingAbility = true;
|
||||||
selectAbility();
|
selectAbility();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (potential)
|
if (potential) delete (currentMana);
|
||||||
delete (currentMana);
|
|
||||||
if (nextCardToPlay)
|
if (nextCardToPlay)
|
||||||
{
|
{
|
||||||
if (potential)
|
if (potential)
|
||||||
@@ -1282,11 +1225,11 @@ int AIPlayerBaka::computeActions()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(!findingAbility)
|
if (!findingAbility)
|
||||||
{
|
{
|
||||||
AIPlayer::findingAbility = true;
|
AIPlayer::findingAbility = true;
|
||||||
selectAbility();
|
selectAbility();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (p->getManaPool()->getConvertedCost() > 0 && Checked == false)//not the best thing ever, but allows the Ai a chance to double check if its mana pool has something before moving on, atleast one time.
|
if (p->getManaPool()->getConvertedCost() > 0 && Checked == false)//not the best thing ever, but allows the Ai a chance to double check if its mana pool has something before moving on, atleast one time.
|
||||||
{
|
{
|
||||||
@@ -1302,11 +1245,11 @@ int AIPlayerBaka::computeActions()
|
|||||||
Checked = false;
|
Checked = false;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if(!findingAbility)
|
if (!findingAbility)
|
||||||
{
|
{
|
||||||
AIPlayer::findingAbility = true;
|
AIPlayer::findingAbility = true;
|
||||||
selectAbility();
|
selectAbility();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1329,8 +1272,7 @@ int AIPlayerBaka::computeActions()
|
|||||||
|
|
||||||
int AIPlayer::receiveEvent(WEvent * event)
|
int AIPlayer::receiveEvent(WEvent * event)
|
||||||
{
|
{
|
||||||
if (getStats())
|
if (getStats()) return getStats()->receiveEvent(event);
|
||||||
return getStats()->receiveEvent(event);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1370,8 +1312,7 @@ int AIPlayerBaka::Act(float dt)
|
|||||||
DebugTrace("Cannot interrupt");
|
DebugTrace("Cannot interrupt");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (clickstream.empty())
|
if (clickstream.empty()) computeActions();
|
||||||
computeActions();
|
|
||||||
if (clickstream.empty())
|
if (clickstream.empty())
|
||||||
{
|
{
|
||||||
if (g->isInterrupting == this)
|
if (g->isInterrupting == this)
|
||||||
|
|||||||
@@ -1013,10 +1013,8 @@ int MTGAttackRule::receiveEvent(WEvent *e)
|
|||||||
for (int i = 0; i < z->nb_cards; i++)
|
for (int i = 0; i < z->nb_cards; i++)
|
||||||
{
|
{
|
||||||
MTGCardInstance * card = z->cards[i];
|
MTGCardInstance * card = z->cards[i];
|
||||||
if (!card->isAttacker() && card->has(Constants::MUSTATTACK))
|
if (!card->isAttacker() && card->has(Constants::MUSTATTACK)) reactToClick(card);
|
||||||
reactToClick(card);
|
if (!card->isAttacker() && card->has(Constants::TREASON) && p->isAI()) reactToClick(card);
|
||||||
if (!card->isAttacker() && card->has(Constants::TREASON) && p->isAI())
|
|
||||||
reactToClick(card);
|
|
||||||
if (card->isAttacker() && card->isTapped())
|
if (card->isAttacker() && card->isTapped())
|
||||||
card->setAttacker(0);
|
card->setAttacker(0);
|
||||||
if (card->isAttacker() && !card->has(Constants::VIGILANCE))
|
if (card->isAttacker() && !card->has(Constants::VIGILANCE))
|
||||||
|
|||||||
Reference in New Issue
Block a user