Exemple #1
0
 public void RemoveEffect(Effect effect)
 {
     effect.Remove();
     ActiveEffects.Remove(effect);
 }
Exemple #2
0
        /// <summary>
        /// Check for invalid game state, and take necessary actions
        /// </summary>
        private void CheckStateBasedActions()
        {
            // Remove any effects that come from permanents that have left the battlefield
            foreach (ContinuousEffect effect in new List <Effect>(ActiveEffects))
            {
                foreach (var card in Battlefield)
                {
                    effect.UnmodifyObject(this, card);
                }

                if (effect.Source is Card)
                {
                    var card = effect.Source as Card;
                    if (card.IsAPermanent)
                    {
                        if (!Battlefield.Contains(card))
                        {
                            ActiveEffects.Remove(effect);
                        }
                    }
                }
            }

            // Add any effects from permanents that are on the battlefield
            foreach (var permanent in Battlefield)
            {
                foreach (ContinuousEffect effect in permanent.Effects)
                {
                    if (!ActiveEffects.Contains(effect))
                    {
                        ActiveEffects.Add(effect);
                    }
                }
            }

            // Iterate over each active effect once for each active effect. This is likely overkill, but there's not a better way to make sure all interactions are applied.
            for (int i = 0; i < ActiveEffects.Count; i++)
            {
                foreach (var effect in ActiveEffects)
                {
                    foreach (var card in Battlefield)
                    {
                        effect.ModifyObject(this, card);
                    }
                }
            }

            // Kill any creatures that have 0 toughness, or have sustained enough damage to be destroyed and don't have indestructible
            foreach (var player in _players)
            {
                var creatures     = player.Battlefield.Creatures.ToList();
                var deadCreatures = creatures.Where(c => c.IsDead).ToList();
                foreach (var creature in deadCreatures)
                {
                    MoveFromBattlefieldToGraveyard(creature);
                }

                var planeswalkers     = player.Battlefield.Planeswalkers.ToList();
                var deadPlaneswalkers = planeswalkers.Where(c => c.IsDead).ToList();
                foreach (var planeswalker in deadPlaneswalkers)
                {
                    MoveFromBattlefieldToGraveyard(planeswalker);
                }
            }

            // Any players with 0 life total lose the game
            Dictionary <Player, string> _deadPlayers = new Dictionary <Player, string>();

            foreach (var player in _players)
            {
                if (player.LifeTotal <= 0)
                {
                    // Player has Died
                    _deadPlayers.Add(player, "Life Total has Reached Zero");
                }
            }

            // Any players that have attempted to draw from an empty library lose the game
            foreach (var player in _players)
            {
                if (player.PlayerAttemptedToDrawIntoEmptyLibrary)
                {
                    // Player has Died
                    _deadPlayers.Add(player, "Player Attempted to Draw into an Empty Library");
                }
            }

            // Any players with 10 or more poison counters lose the game
            foreach (var player in _players)
            {
                if (player.Counters.Count(c => c == CounterType.Poison) >= 10)
                {
                    _deadPlayers.Add(player, "Player has accumulated 10 poison counters");
                }
            }

            // TODO: If an effect has caused a player to win the game, all other players lose

            // If All Players Lost Simultaneously, then it's a Draw
            if (_players.Except(_deadPlayers.Keys).Count() == 0)
            {
                throw new GameEndedInDrawException();
            }

            // If a player has lost the game, remove them from the _players list.
            foreach (var player in _deadPlayers.Keys)
            {
                PlayerLostTheGame?.Invoke(this, player, _deadPlayers[player]);

                // Active Player gets removed after it gets changed to the next player
                if (player != ActivePlayer)
                {
                    _players.Remove(player);
                    _losingPlayers.Add(player);
                }
            }

            // If only 1 players remains, that player won the game
            if (_players.Except(_deadPlayers.Keys).Count() == 1)
            {
                throw new PlayerWonTheGameException(_players.Except(_deadPlayers.Keys).First(), "Last Man Standing");
            }

            // If the active player died, go to the start of the next player's turn
            if (_deadPlayers.ContainsKey(ActivePlayer))
            {
                throw new ActivePlayerLostTheGameException(_deadPlayers[ActivePlayer]);
            }

            foreach (var player in _players)
            {
                foreach (var card in player.Graveyard)
                {
                    if (card.IsAToken)
                    {
                        player.Graveyard.Remove(card);
                    }
                    else if (card.IsCopying != null)
                    {
                        card.StopCopying(card.IsCopying, card.copyingSource);
                    }
                }
            }

            // Legend Rule (players cannot control more than 1 copy of a legendary permanent with the same name
            foreach (var player in _players)
            {
                // Create a list to hold all the legends that will be removed
                var sacrificedLegends = new List <Card>();

                // While the player has duplicate legends
                while (player.Battlefield.Except(sacrificedLegends).Any(card => card.IsLegendary && player.Battlefield.Except(sacrificedLegends).Count(c => c.Name == card.Name && c.IsLegendary) > 1))
                {
                    var playerControlledLegends = player.Battlefield.Except(sacrificedLegends).Where(card => card.IsLegendary && player.Battlefield.Except(sacrificedLegends).Count(c => c.Name == card.Name && c.IsLegendary) > 1).ToList();
                    var selected = player.MakeChoice("You control duplicate legends. Choose one to sacrifice", 1, playerControlledLegends).First();
                    sacrificedLegends.Add(selected);
                }

                // If the player had to sacrifice permanents, then sacrifice them
                if (sacrificedLegends.Count > 0)
                {
                    // If the player needed to sacrifice more than 1 permanent, then they need to sort them because they enter the graveyard one at a time
                    if (sacrificedLegends.Count > 1)
                    {
                        sacrificedLegends = player.Sort("Choose the order that you wish these permanents to enter the graveyard", sacrificedLegends);
                    }
                    foreach (var permanent in sacrificedLegends)
                    {
                        MoveFromBattlefieldToGraveyard(permanent);
                    }
                }
            }

            // Check State Triggered Abilities
            CheckForTriggeredAbilities();
        }
Exemple #3
0
 public void AddEffect(Effect effect)
 {
     effect.ApplyEffect(this);
     ActiveEffects.Add(effect);
 }