magefree / mage

Magic Another Game Engine
http://xmage.today
MIT License
1.84k stars 760 forks source link

"If {A} attacks, {B} attack if able" effects are impossible to implement correctly #8595

Open awjackson opened 2 years ago

awjackson commented 2 years ago

Attack requirement effects are currently only checked once per combat, before the active player has declared any attackers. This is good enough for most requirements, but it doesn't work for effects that depend on which other creatures are attacking.

Affected cards:

[[Ekundu Cyclops]] (not implemented in xmage, see https://github.com/magefree/mage/pull/8594) [[Magnetic Web]] (not implemented in xmage) [[Viashino Bey]] (currently implemented, incorrectly, as a triggered ability) [[War's Toll]] (currently implemented, incorrectly, as a restriction effect)

github-actions[bot] commented 2 years ago

Ekundu Cyclops - (Gatherer) (Scryfall) (EDHREC)

{3}{R} Creature — Cyclops 3/4 If a creature you control attacks, Ekundu Cyclops also attacks if able.

Magnetic Web - (Gatherer) (Scryfall) (EDHREC)

{2} Artifact If a creature with a magnet counter on it attacks, all creatures with magnet counters on them attack if able. Whenever a creature with a magnet counter on it attacks, all creatures with magnet counters on them block that creature this turn if able. {1}, {T}: Put a magnet counter on target creature.

Viashino Bey - (Gatherer) (Scryfall) (EDHREC)

{2}{R}{R} Creature — Viashino 4/3 If Viashino Bey attacks, all creatures you control attack if able.

War's Toll - (Gatherer) (Scryfall) (EDHREC)

{3}{R} Enchantment Whenever an opponent taps a land for mana, tap all lands that player controls. If a creature an opponent controls attacks, all creatures that opponent controls attack if able.

KingSupernova31 commented 3 weeks ago

I present a simple algorithm that can correctly handle those 4 cards here: Step By Step: Declaring Attackers

Unfortunately I believe it's O((2^n)!) in the worst case, but in practice it's not a problem; you can try out the calculator on the page and it's able to return results in <100ms for almost any realistic set of creatures.