Пример #1
0
        static void Main(string[] args)
        {
            var ogre = new MTGLib.MTGObject.BaseCardAttributes()
            {
                name     = "Onakke Ogre",
                manaCost = new ManaCost(
                    2, ManaSymbol.Red
                    ),
                power     = 4,
                toughness = 2,
                cardTypes = new HashSet <MTGLib.MTGObject.CardType> {
                    MTGLib.MTGObject.CardType.Creature
                },
                subTypes = new HashSet <MTGLib.MTGObject.SubType> {
                    MTGLib.MTGObject.SubType.Ogre, MTGLib.MTGObject.SubType.Warrior
                }
            };

            var knight = new MTGObject.BaseCardAttributes()
            {
                name     = "Fireborn Knight",
                manaCost = new ManaCost(
                    ManaSymbol.HybridBoros,
                    ManaSymbol.HybridBoros,
                    ManaSymbol.HybridBoros,
                    ManaSymbol.HybridBoros
                    ),
                power     = 2,
                toughness = 3,
                cardTypes = new HashSet <MTGObject.CardType> {
                    MTGObject.CardType.Creature
                },
                subTypes = new HashSet <MTGObject.SubType> {
                    MTGObject.SubType.Human, MTGObject.SubType.Knight
                },
                // double strike goes here
                activatedAbilities = new List <ActivatedAbility>
                {
                    new ActivatedAbility(
                        new CostEvent.CostGen[]
                    {
                        () => { return(EventContainerPayManaCost.Auto(new ManaCost(
                                                                          ManaSymbol.HybridBoros,
                                                                          ManaSymbol.HybridBoros,
                                                                          ManaSymbol.HybridBoros,
                                                                          ManaSymbol.HybridBoros
                                                                          ))); }
                    },
                        new EffectEvent.Effect[]
                    {
                        (source, targets, callback) =>
                        {
                            MTG mtg_ = MTG.Instance;

                            mtg_.continuousEffects.Add(
                                new ContinuousEffect(
                                    source,
                                    ContinuousEffect.Duration.EndOfTurn,
                                    new ContinuousEffect.DurationData
                            {
                                turn = mtg_.turn.turnCount
                            },
                                    new Modification[]
                            {
                                new PowerMod
                                {
                                    value       = 1,
                                    operation   = Modification.Operation.Add,
                                    specificOID = source
                                },
                                new ToughnessMod
                                {
                                    value       = 1,
                                    operation   = Modification.Operation.Add,
                                    specificOID = source
                                }
                            }
                                    )
                                );
                        }
                    }
                        )
                }
            };

            var landfall = new MTGObject.BaseCardAttributes()
            {
                name      = "Landfall Enchantment",
                manaCost  = new ManaCost(),
                cardTypes = new HashSet <MTGObject.CardType> {
                    MTGObject.CardType.Enchantment
                },
                triggeredAbilities = new List <TriggeredAbility>
                {
                    new TriggeredAbility <MoveZoneEvent>(
                        (source, mtgevent) =>
                    {
                        if (mtgevent.newZone != MTG.Instance.battlefield)
                        {
                            return(false);
                        }
                        var trigobj   = MTG.Instance.objects[mtgevent.oid];
                        var sourceobj = MTG.Instance.objects[source];
                        return(trigobj.attr.controller == sourceobj.attr.controller);
                    },
                        new EffectEvent.Effect[]
                    {
                        (source, targets, callback) =>
                        {
                            var damage = 1;
                            var target = targets[0].SetTargets[0];
                            callback(new DealDamageEvent(source, target, damage));
                        }
                    },
                        new Target[] { Target.AnyTarget }
                        )
                }
            };

            var island = new MTGLib.MTGObject.BaseCardAttributes()
            {
                name      = "Island",
                cardTypes = new HashSet <MTGObject.CardType> {
                    MTGObject.CardType.Land
                },
                superTypes = new HashSet <MTGObject.SuperType> {
                    MTGObject.SuperType.Basic
                },
                subTypes = new HashSet <MTGObject.SubType> {
                    MTGObject.SubType.Island
                },
                activatedAbilities = new List <ActivatedAbility>
                {
                    new ManaAbility(
                        new CostEvent.CostGen[]
                    {
                        () => { return(new TapSelfCostEvent()); }
                    },
                        new EffectEvent.Effect[] {
                        (source, targets, callback) => {
                            int controller = MTG.Instance.objects[source].attr.controller;
                            callback(EventContainerAddMana.Auto(source, controller, ManaSymbol.Blue));
                        }
                    }
                        )
                }
            };
            var mountain = new MTGLib.MTGObject.BaseCardAttributes()
            {
                name      = "Mountain",
                cardTypes = new HashSet <MTGObject.CardType> {
                    MTGObject.CardType.Land
                },
                superTypes = new HashSet <MTGObject.SuperType> {
                    MTGObject.SuperType.Basic
                },
                subTypes = new HashSet <MTGObject.SubType> {
                    MTGObject.SubType.Mountain
                },
                activatedAbilities = new List <ActivatedAbility>
                {
                    new ManaAbility(
                        new CostEvent.CostGen[]
                    {
                        () => { return(new TapSelfCostEvent()); }
                    },
                        new EffectEvent.Effect[] {
                        (source, targets, callback) => {
                            int controller = MTG.Instance.objects[source].attr.controller;
                            callback(EventContainerAddMana.Auto(source, controller, ManaSymbol.Red));
                        }
                    }
                        )
                }
            };

            var crab = new MTGLib.MTGObject.BaseCardAttributes()
            {
                name     = "Wishcoin Crab",
                manaCost = new ManaCost(
                    3, ManaSymbol.Blue
                    ),
                power     = 2,
                toughness = 5,
                cardTypes = new HashSet <MTGObject.CardType> {
                    MTGLib.MTGObject.CardType.Creature
                },
                subTypes = new HashSet <MTGObject.SubType> {
                    MTGLib.MTGObject.SubType.Crab
                }
            };

            var izzetSignet = new MTGObject.BaseCardAttributes()
            {
                name      = "Izzet Signet",
                manaCost  = new ManaCost(2),
                cardTypes = new HashSet <MTGObject.CardType> {
                    MTGObject.CardType.Artifact
                },
                activatedAbilities = new List <ActivatedAbility>
                {
                    new ManaAbility(
                        new CostEvent.CostGen[]
                    {
                        () => { return(new TapSelfCostEvent()); },
                        () => { return(EventContainerPayManaCost.Auto(new ManaCost(1))); }
                    },
                        new EffectEvent.Effect[]
                    {
                        (source, targets, callback) =>
                        {
                            int controller = MTG.Instance.objects[source].attr.controller;
                            callback(EventContainerAddMana.Auto(source, controller, ManaSymbol.Red, ManaSymbol.Blue));
                        }
                    }
                        )
                }
            };

            var bolt = new MTGObject.BaseCardAttributes()
            {
                name      = "Lightning Bolt",
                manaCost  = new ManaCost(ManaSymbol.Red),
                cardTypes = new HashSet <MTGObject.CardType> {
                    MTGObject.CardType.Instant
                },
                spellAbilities = new List <ResolutionAbility>
                {
                    new ResolutionAbility(
                        new EffectEvent.Effect[]
                    {
                        (source, targets, callback) =>
                        {
                            var damage = 3;
                            var target = targets[0].SetTargets[0];
                            callback(new DealDamageEvent(source, target, damage));
                        }
                    },
                        new Target[] { Target.AnyTarget }
                        )
                }
            };

            var lib1 = new List <MTGLib.MTGObject.BaseCardAttributes>();
            var lib2 = new List <MTGLib.MTGObject.BaseCardAttributes>();

            for (int i = 0; i < 26; i++)
            {
                lib1.Add(mountain);
                lib2.Add(island);
            }

            for (int i = 0; i < 17; i++)
            {
                lib1.Add(ogre);
                lib1.Add(landfall);
                lib2.Add(crab);
                lib2.Add(izzetSignet);
            }

            var mtg = new MTG(lib1, lib2);

            mtg.Start();

            BoardViewer boardViewer       = new BoardViewer();
            Thread      boardViewerThread = new Thread(boardViewer.Run);

            boardViewerThread.Name = "Board Viewer Thread";
            boardViewerThread.Start();
            boardViewer.Update(mtg);

            Thread gameLoopThread = new Thread(mtg.GameLoop);

            gameLoopThread.Name = "Game Loop Thread";
            gameLoopThread.Start();

            while (true)
            {
                mtg.ChoiceNewEvent.WaitOne();
                boardViewer.Update(mtg);

                Choice choice = mtg.CurrentUnresolvedChoice;

                if (choice is PriorityChoice cast)
                {
                    if (cast.Options.Count == 1)
                    {
                        Console.WriteLine("Single choice - autoresolving.");
                        cast.Resolve(new List <PriorityOption>(cast.Options));
                    }
                }

                if (!choice.Resolved)
                {
                    choice.ConsoleResolve();
                }

                mtg.ResolveChoice(choice);
            }
        }
Пример #2
0
        public void ReverseCastTest()
        {
            var mountain = new MTGLib.MTGObject.BaseCardAttributes
            {
                name      = "Mountain",
                cardTypes = new HashSet <MTGObject.CardType> {
                    MTGObject.CardType.Land
                },
                superTypes = new HashSet <MTGObject.SuperType> {
                    MTGObject.SuperType.Basic
                },
                subTypes = new HashSet <MTGObject.SubType> {
                    MTGObject.SubType.Mountain
                },
                activatedAbilities = new List <ActivatedAbility>
                {
                    new ManaAbility(
                        new CostEvent.CostGen[]
                    {
                        () => { return(new TapSelfCostEvent()); }
                    },
                        new EffectEvent.Effect[] {
                        (source, targets, callback) => {
                            int controller = MTG.Instance.objects[source].attr.controller;
                            callback(EventContainerAddMana.Auto(source, controller, ManaSymbol.Red));
                        }
                    }
                        )
                }
            };

            var weirdartifact = new MTGLib.MTGObject.BaseCardAttributes
            {
                name      = "Weird",
                cardTypes = new HashSet <MTGObject.CardType> {
                    MTGObject.CardType.Artifact
                },
                activatedAbilities = new List <ActivatedAbility>
                {
                    new ManaAbility(
                        new CostEvent.CostGen[]
                    {
                        () => { return(new TapSelfCostEvent()); },
                        () => { return(EventContainerPayManaCost.Auto(new ManaCost(1))); }
                    },
                        new EffectEvent.Effect[]
                    {
                        (source, targets, callback) =>
                        {
                            int controller = MTG.Instance.objects[source].attr.controller;
                            var mana       = new ManaCost(3);
                            callback(EventContainerAddMana.Auto(source, controller, mana));
                            callback(EventContainerDrawCards.Auto(source, controller, 2));
                        }
                    }
                        )
                }
            };

            var megacreature = new MTGLib.MTGObject.BaseCardAttributes
            {
                name      = "Mega Creature",
                cardTypes = new HashSet <MTGObject.CardType> {
                    MTGObject.CardType.Creature
                },
                power     = 20,
                toughness = 20,
                manaCost  = new ManaCost(10)
            };

            var lib = new List <MTGObject.BaseCardAttributes>();

            for (int x = 0; x < 15; x++)
            {
                lib.Add(mountain);
                lib.Add(weirdartifact);
                lib.Add(megacreature);
            }

            var mtg = new MTG(lib, lib);

            var mountain1OID = mtg.DebugTutor("Mountain", 0, mtg.battlefield);
            var mountain2OID = mtg.DebugTutor("Mountain", 0, mtg.battlefield);
            var weirdOID     = mtg.DebugTutor("Weird", 0, mtg.battlefield);
            var creatureOID  = mtg.DebugTutor("Mega Creature", 0, mtg.players[0].hand);

            mtg.Start();

            Thread gameLoopThread = new Thread(mtg.GameLoop);

            gameLoopThread.Start();

            var pass = new PriorityOption {
                type = PriorityOption.OptionType.PassPriority
            };

            mtg.ChoiceNewEvent.WaitOne();

            Choice choice;

            // Pass until first main
            {
                while (mtg.turn.phase.type != Phase.PhaseType.Main1)
                {
                    choice = mtg.CurrentUnresolvedChoice;
                    if (choice is PriorityChoice cast)
                    {
                        cast.Resolve(pass);
                    }
                    else
                    {
                        Assert.Fail();
                    }
                    mtg.ResolveChoice(choice);
                    mtg.ChoiceNewEvent.WaitOne();
                }
                Assert.AreEqual(mtg.turn.phase.type, Phase.PhaseType.Main1);
            }

            // main1 priority choice - cast spell
            {
                choice = mtg.CurrentUnresolvedChoice;

                if (choice is PriorityChoice cast)
                {
                    foreach (var option in cast.Options)
                    {
                        if (option.type == PriorityOption.OptionType.CastSpell &&
                            option.source == creatureOID)
                        {
                            cast.Resolve(option);
                            break;
                        }
                    }
                }
                else
                {
                    Assert.Fail();
                }
            }

            Assert.IsTrue(choice.Resolved);
            mtg.ResolveChoice(choice);
            mtg.ChoiceNewEvent.WaitOne();

            // Mana payment choice {1} for cast - activate weird
            {
                choice = mtg.CurrentUnresolvedChoice;

                if (choice is ManaChoice cast)
                {
                    foreach (var option in cast.Options)
                    {
                        if (option.type == ManaChoiceOption.OptionType.ActivateManaAbility &&
                            option.manaAbilitySource == weirdOID)
                        {
                            cast.Resolve(option);
                            break;
                        }
                    }
                }
                else
                {
                    Assert.Fail();
                }
            }

            Assert.IsTrue(choice.Resolved);
            mtg.ResolveChoice(choice);
            mtg.ChoiceNewEvent.WaitOne();

            // Mana payment choice {1} for weird artifact - activate mountain 1
            {
                choice = mtg.CurrentUnresolvedChoice;

                if (choice is ManaChoice cast)
                {
                    foreach (var option in cast.Options)
                    {
                        if (option.type == ManaChoiceOption.OptionType.ActivateManaAbility &&
                            option.manaAbilitySource == mountain1OID)
                        {
                            cast.Resolve(option);
                        }
                    }
                }
                else
                {
                    Assert.Fail();
                }
            }

            Assert.IsTrue(choice.Resolved);
            mtg.ResolveChoice(choice);
            mtg.ChoiceNewEvent.WaitOne();

            // Mana payment choice {1} for weird artifact - use {R}
            {
                choice = mtg.CurrentUnresolvedChoice;

                if (choice is ManaChoice cast)
                {
                    foreach (var option in cast.Options)
                    {
                        if (option.type == ManaChoiceOption.OptionType.UseMana &&
                            option.manaSymbol == ManaSymbol.Red)
                        {
                            cast.Resolve(option);
                        }
                    }
                }
                else
                {
                    Assert.Fail();
                }
            }

            int cardcount = mtg.players[0].hand.Count;

            Assert.IsTrue(choice.Resolved);
            mtg.ResolveChoice(choice);
            mtg.ChoiceNewEvent.WaitOne();

            // Weird artifact resolves and draws cards
            Assert.IsTrue(mtg.objects[weirdOID].permanentStatus.tapped);
            Assert.IsTrue(mtg.objects[mountain1OID].permanentStatus.tapped);
            Assert.IsFalse(mtg.objects[mountain2OID].permanentStatus.tapped);

            Assert.AreEqual(mtg.players[0].hand.Count, cardcount + 2);

            // Mana paymanet choice {1} - use mana from weird
            {
                choice = mtg.CurrentUnresolvedChoice;
                if (choice is ManaChoice cast)
                {
                    foreach (var option in cast.Options)
                    {
                        if (option.type == ManaChoiceOption.OptionType.UseMana &&
                            option.manaSymbol == ManaSymbol.Generic)
                        {
                            cast.Resolve(option);
                            break;
                        }
                    }
                }
                else
                {
                    Assert.Fail();
                }
            }

            Assert.IsTrue(choice.Resolved);
            mtg.ResolveChoice(choice);
            mtg.ChoiceNewEvent.WaitOne();

            Assert.IsTrue(mtg.objects[weirdOID].permanentStatus.tapped);
            Assert.IsTrue(mtg.objects[mountain1OID].permanentStatus.tapped);
            Assert.IsFalse(mtg.objects[mountain2OID].permanentStatus.tapped);
            Assert.AreEqual(mtg.players[0].manaPool.Count, 2);

            // *NEW* Mana payment choice {1} - activate mountain 2
            {
                choice = mtg.CurrentUnresolvedChoice;
                if (choice is ManaChoice cast)
                {
                    foreach (var option in cast.Options)
                    {
                        if (option.type == ManaChoiceOption.OptionType.ActivateManaAbility &&
                            option.manaAbilitySource == mountain2OID)
                        {
                            cast.Resolve(option);
                        }
                    }
                }
                else
                {
                    Assert.Fail();
                }
            }

            Assert.IsTrue(choice.Resolved);
            mtg.ResolveChoice(choice);
            mtg.ChoiceNewEvent.WaitOne();

            // Mana payment choice {1} - use {R}
            {
                choice = mtg.CurrentUnresolvedChoice;
                if (choice is ManaChoice cast)
                {
                    foreach (var option in cast.Options)
                    {
                        if (option.type == ManaChoiceOption.OptionType.UseMana &&
                            option.manaSymbol == ManaSymbol.Red)
                        {
                            cast.Resolve(option);
                            break;
                        }
                    }
                }
                else
                {
                    Assert.Fail();
                }
            }

            Assert.IsTrue(choice.Resolved);
            mtg.ResolveChoice(choice);
            mtg.ChoiceNewEvent.WaitOne();

            Assert.IsTrue(mtg.objects[weirdOID].permanentStatus.tapped);
            Assert.IsTrue(mtg.objects[mountain1OID].permanentStatus.tapped);
            Assert.IsTrue(mtg.objects[mountain2OID].permanentStatus.tapped);
            Assert.AreEqual(mtg.players[0].hand.Count, cardcount + 2);

            // Mana payment for {1} - cancel
            {
                choice = mtg.CurrentUnresolvedChoice;

                if (choice is ManaChoice cast)
                {
                    cast.Cancel();
                }
                else
                {
                    Assert.Fail();
                }
            }

            Assert.IsTrue(choice.Resolved);
            mtg.ResolveChoice(choice);
            mtg.ChoiceNewEvent.WaitOne();


            // Mountain 2 gets reverted
            Assert.IsFalse(mtg.objects[mountain2OID].permanentStatus.tapped);

            // Weird oid is not reverted - it drew cards
            Assert.IsTrue(mtg.objects[weirdOID].permanentStatus.tapped);
            Assert.IsTrue(mtg.objects[mountain1OID].permanentStatus.tapped);
            // The card draw isn't reverted, and the spell is returned to hand
            Assert.AreEqual(mtg.players[0].hand.Count, cardcount + 3);

            // We still have 3 mana
            Assert.AreEqual(mtg.players[0].manaPool.Count, 3);
        }