Tuesday, March 3, 2009

When to Attack?

MTG Forge does its best to figure out which creatures should attack but overall it does a pretty lousy job. The AI doesn’t even play spells or abilities during the combat phase, which should simplify the combat step. And the AI doesn’t to any planning, like it won’t attack into a bigger creature and then Shock it. With all of that said, determining what creatures should attack is still difficult.

In general the AI will attack with a creature if the creature cannot be blocked, like if the creature has flying or fear, or if the creature is the biggest on the board. The AI will also attack with creatures that can be “traded”, it will attack with a 2/2 if you have a 2/2. I’ve tried to randomize the attacking routine a little bit by not always attacking with all of the creatures, but that seems to just weaken the AI and make the games more of a landslide.

I’m playing around with a very simple attacking routine, such as the AI would attack with all of its creatures if it had the same number or more creatures in play. (If you had 2 creatures in play and the AI had 2, it would attack.)

That way the AI would at least attack more often and would be putting on the pressure even if some of the time it is completely stupid. I read an article awhile ago on magicthegathering.com that suggested that players in limited games should attack 95% of the time and I’m trying to apply that strategy to the AI.

The basic idea of attacking is to attack when it is beneficial, but defining “beneficial” is very hard. When I write the AI attack routine, I am defining “beneficial”.


WilLoW :--) said...

In Wagic, the AI attacks whenever it has more creatures (able to attack) than your total number of creatures, OR if the total power of its creatures able to attack is more than the total power of your creatures, OR if the total power of its creatures able to attack is more than 2 times your remaining life points.
It does a pretty bad job with/against abilities such as first strike, and there are many times where you can just destroy half of its creatures without losing anything on your side.

Unless you use minimax, random is very important here to prevent people from figuring out the complete algorithm (which ruins half of the fun)

Forge said...

Thanks for your attacking algorithm. I've rewritten MTG Forge's attacking code once and twice in order to improve it. I would love to write a simple min-max algorithm but I get too lost in the details. I'm not sure that min-max would help much, but it would help in cases where the computer should not attack with a creature so he can chump block.

In a way I think blocking is more complicated than attacking since you can double block. I'm glad MTG Forge AI's can double block, that way you know it could happen, lol.

Gando the Wandering Fool said...

when to attack:

Alpha striking: You know that you can get damage through no matter what your opponent does (sans a fog). Usually this is seen most often in limited games because one player manages to get more men on the ground than the other, so they will attack despite possibly losing creatures. The attrition to their forces is outweighed by the damage to the player. This is particularly effective if the player is low in life.

No blockers...obviously anything that can get through without being blocked is a candidate for attacking...however you still need to pay attention to things like surprise blockers (opponent removes condition that makes the creature unblockable before blockers are declared) and what on the board might make attacking with said creature a bad idea? Royal Assassin without summoning sickness for example would indicate it is a bad idea unless your guy also has vigilance.

Surprise Tactics. You are holding something or somethings in your hand that combined with what is in play will assure your creatures the victory in combat. Giant Growth, Lightning bolt (with first strike), s way to kill one of two or three chump blockers thus managing card advantage where your attacker survives and theirs does not.

Any time your combat actions are certain to leave you with card advantage is a good time to attack, unless you are leaving yourself without defense when at a critical life total.

You plan to clear the board afterward ala Wrath of God.

You know can stop your opponents counter attack next turn. (Fog in hand? Well this isn't a great idea because of discard but it is a tactic some people favor. Know your opponent before playing something risky like this.)

You can healup your creatures after damage is assigned thus giving yourself a better board position while worsening theirs.

With the advent of Planeswalkers I have found sometimes it is expedient to attack a planeswalker all out just to make sure it gets removed from the table before things become untenable. The ultimate abilities of these cards can completely wreck a game plan if not prevented. This is priority almost as high as your opponent at low life. Of course given a chance to kill your opponent and kill a planeswalker you should think carefully before deciding the latter...Only if the odds are that your opponent can prevent lethal damage to themselves should you choice option B.

fparadis2 said...

Good stuff.. I haven't started any actual AI work, but I definitely want a solid minmax base. I don't want to have to tweak the AI specifically for each card. Although it might be necessary for some special cards that require really long-term planning, I think most (90%) will work out just fine with minmax.

Anonymous said...

Sorry to be anonymous, but I just wanted to add that your AI is also dependent upon number of turns in advance. How many turns can the AI think ahead? Or, instead of turns, how long does the AI have to think?

The higher the difficulty, the more thought processes that the AI should have. This could probably help develop a very intelligent opponent depending on how much processing is available for it.

Forge said...

About attacking planeswalkers, I think the AI will attack then 50% of the time since their ultimates usually win the game.

About min-max, it would still be hard to get the evaluate() function within the correct ballpark because an incorrect evaluate() would always block in order to save life points. So you would have to balance life points versus creatures. And personally I don't mind letting my life points get down to 5 or so (if I'm not playing against red).