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 chooseBlockers();
|
||||||
virtual int canFirstStrikeKill(MTGCardInstance * card, MTGCardInstance *ennemy);
|
virtual int canFirstStrikeKill(MTGCardInstance * card, MTGCardInstance *ennemy);
|
||||||
virtual int effectBadOrGood(MTGCardInstance * card, int mode = MODE_PUTINTOPLAY, TargetChooser * tc = NULL);
|
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)
|
// 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);
|
virtual int CanHandleCost(ManaCost * cost, MTGCardInstance * card = NULL);
|
||||||
|
|||||||
@@ -4012,9 +4012,7 @@ int AIPlayerBaka::chooseAttackers()
|
|||||||
MTGCardInstance * card = NULL;
|
MTGCardInstance * card = NULL;
|
||||||
while ((card = cd.nextmatch(game->inPlay, card)))
|
while ((card = cd.nextmatch(game->inPlay, card)))
|
||||||
{
|
{
|
||||||
if ((hints && hints->HintSaysAlwaysAttack(observer, card)) || card->has(Constants::UNBLOCKABLE))
|
if (shouldAIForceAttack(card, attack))
|
||||||
{
|
|
||||||
if (!card->isAttacker())
|
|
||||||
{
|
{
|
||||||
if (card->attackCost)
|
if (card->attackCost)
|
||||||
{
|
{
|
||||||
@@ -4022,7 +4020,6 @@ int AIPlayerBaka::chooseAttackers()
|
|||||||
doAbility(a, card);
|
doAbility(a, card);
|
||||||
observer->cardClick(card, MTGAbility::ATTACK_COST);
|
observer->cardClick(card, MTGAbility::ATTACK_COST);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
observer->cardClick(card, MTGAbility::MTG_ATTACK_RULE);
|
observer->cardClick(card, MTGAbility::MTG_ATTACK_RULE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4052,6 +4049,83 @@ int AIPlayerBaka::chooseAttackers()
|
|||||||
return 1;
|
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 ? */
|
/* Can I first strike my oponent and get away with murder ? */
|
||||||
int AIPlayerBaka::canFirstStrikeKill(MTGCardInstance * card, MTGCardInstance *ennemy)
|
int AIPlayerBaka::canFirstStrikeKill(MTGCardInstance * card, MTGCardInstance *ennemy)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user