AIPlayerBaka
Changing how the AI selects attackers, considering creatures with evasion
This commit is contained in:
@@ -76,6 +76,7 @@ class AIPlayerBaka: public AIPlayer{
|
||||
virtual int chooseBlockers();
|
||||
virtual int canFirstStrikeKill(MTGCardInstance * card, MTGCardInstance *ennemy);
|
||||
virtual int effectBadOrGood(MTGCardInstance * card, int mode = MODE_PUTINTOPLAY, TargetChooser * tc = NULL);
|
||||
virtual bool shouldAIForceAttack(MTGCardInstance* card, bool globalAttack);
|
||||
|
||||
// returns 1 if the AI algorithm supports a given cost (ex:simple mana cost), 0 otherwise (ex: cost involves Sacrificing a target)
|
||||
virtual int CanHandleCost(ManaCost * cost, MTGCardInstance * card = NULL);
|
||||
|
||||
@@ -4012,9 +4012,7 @@ int AIPlayerBaka::chooseAttackers()
|
||||
MTGCardInstance * card = NULL;
|
||||
while ((card = cd.nextmatch(game->inPlay, card)))
|
||||
{
|
||||
if ((hints && hints->HintSaysAlwaysAttack(observer, card)) || card->has(Constants::UNBLOCKABLE))
|
||||
{
|
||||
if (!card->isAttacker())
|
||||
if (shouldAIForceAttack(card, attack))
|
||||
{
|
||||
if (card->attackCost)
|
||||
{
|
||||
@@ -4022,7 +4020,6 @@ int AIPlayerBaka::chooseAttackers()
|
||||
doAbility(a, card);
|
||||
observer->cardClick(card, MTGAbility::ATTACK_COST);
|
||||
}
|
||||
}
|
||||
observer->cardClick(card, MTGAbility::MTG_ATTACK_RULE);
|
||||
}
|
||||
}
|
||||
@@ -4052,6 +4049,83 @@ int AIPlayerBaka::chooseAttackers()
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool AIPlayerBaka::shouldAIForceAttack(MTGCardInstance* card, bool globalAttack)
|
||||
{
|
||||
if (globalAttack)
|
||||
return true;
|
||||
|
||||
if (!card || card->isAttacker())
|
||||
return false;
|
||||
|
||||
if (hints)
|
||||
{
|
||||
if (hints->HintSaysDontAttack(observer, card))
|
||||
return false;
|
||||
if (hints->HintSaysAlwaysAttack(observer, card))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (card->has(Constants::UNBLOCKABLE))
|
||||
return true;
|
||||
|
||||
// Flags for opponent defenses
|
||||
bool oppHasShadow = false;
|
||||
bool oppHasAirDefense = false;
|
||||
bool oppHasHorsemanship = false;
|
||||
bool oppHasBlackOrArtifact = false;
|
||||
bool oppHasMatchingColorOrArtifact = false;
|
||||
|
||||
// Flags for landwalk checks
|
||||
bool oppHasSwamp = opponent()->game->inPlay->hasType("Swamp");
|
||||
bool oppHasIsland = opponent()->game->inPlay->hasType("Island");
|
||||
bool oppHasForest = opponent()->game->inPlay->hasType("Forest");
|
||||
bool oppHasMountain = opponent()->game->inPlay->hasType("Mountain");
|
||||
bool oppHasPlains = opponent()->game->inPlay->hasType("Plains");
|
||||
|
||||
MTGCardInstance* oppCard = NULL;
|
||||
CardDescriptor desc;
|
||||
desc.init();
|
||||
desc.setType("creature");
|
||||
|
||||
while ((oppCard = desc.nextmatch(opponent()->game->inPlay, oppCard)))
|
||||
{
|
||||
if (oppCard->isTapped())
|
||||
continue;
|
||||
|
||||
if (oppCard->has(Constants::SHADOW))
|
||||
oppHasShadow = true;
|
||||
if (oppCard->has(Constants::FLYING) || oppCard->has(Constants::REACH))
|
||||
oppHasAirDefense = true;
|
||||
if (oppCard->has(Constants::HORSEMANSHIP))
|
||||
oppHasHorsemanship = true;
|
||||
|
||||
if (oppCard->hasColor(Constants::MTG_COLOR_BLACK) || oppCard->hasType("Artifact"))
|
||||
oppHasBlackOrArtifact = true;
|
||||
|
||||
// Intimidate check: artifact or shares color
|
||||
if (oppCard->hasType("Artifact") || (oppCard->colors & card->colors))
|
||||
oppHasMatchingColorOrArtifact = true;
|
||||
}
|
||||
|
||||
// Decision logic based on evasion
|
||||
if ((card->has(Constants::SHADOW) && !oppHasShadow) ||
|
||||
(card->has(Constants::FLYING) && !oppHasAirDefense) ||
|
||||
(card->has(Constants::HORSEMANSHIP) && !oppHasHorsemanship) ||
|
||||
(card->has(Constants::FEAR) && !oppHasBlackOrArtifact) ||
|
||||
(card->has(Constants::INTIMIDATE) && !oppHasMatchingColorOrArtifact))
|
||||
return true;
|
||||
|
||||
// Landwalk abilities
|
||||
if ((card->has(Constants::SWAMPWALK) && oppHasSwamp) ||
|
||||
(card->has(Constants::ISLANDWALK) && oppHasIsland) ||
|
||||
(card->has(Constants::FORESTWALK) && oppHasForest) ||
|
||||
(card->has(Constants::MOUNTAINWALK) && oppHasMountain) ||
|
||||
(card->has(Constants::PLAINSWALK) && oppHasPlains))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Can I first strike my oponent and get away with murder ? */
|
||||
int AIPlayerBaka::canFirstStrikeKill(MTGCardInstance * card, MTGCardInstance *ennemy)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user