using YGOSharp.OCGWrapper;
using YGOSharp.OCGWrapper.Enums;
using System.Collections.Generic;
using System.Linq;
using System;
using WindBot;
using WindBot.Game;
using WindBot.Game.AI;
namespace WindBot.Game.AI.Decks
{
    [Deck("Earth_408", "AI_Earth_408")]
    public class Earth_408Executor : DefaultExecutor
    {
        public Earth_408Executor(GameAI ai, Duel duel)
            : base(ai, duel)
        {
            AddExecutor(ExecutorType.Repos, OnSelectMonsterRepos);
            AddExecutor(ExecutorType.SpSummon);

            AddExecutor(ExecutorType.Activate, 19613556, OnSelectActivate);
            AddExecutor(ExecutorType.Activate, 45986603, OnSelectActivate);
            AddExecutor(ExecutorType.Activate, 71044499, OnSelectActivate);
            AddExecutor(ExecutorType.Activate, OnSelectActivate);

            AddExecutor(ExecutorType.Summon, 79575620, OnSelectSummon);
            AddExecutor(ExecutorType.Summon, 60229110, OnSelectSummon);
            AddExecutor(ExecutorType.Summon, 85306040, OnSelectSummon);
            AddExecutor(ExecutorType.Summon, 39168895, OnSelectSummon);
            AddExecutor(ExecutorType.Summon, 74131780, OnSelectSummon);
            AddExecutor(ExecutorType.Summon, 70074904, OnSelectSummon);
            AddExecutor(ExecutorType.Summon, 97017120, OnSelectSummon);
            AddExecutor(ExecutorType.Summon, 37043180, OnSelectSummon);
            AddExecutor(ExecutorType.Summon, 42386471, OnSelectSummon);

            AddExecutor(ExecutorType.SpellSet, OnSelectSpellSet);
            AddExecutor(ExecutorType.MonsterSet, 37043180);
            AddExecutor(ExecutorType.MonsterSet, 70074904);
            AddExecutor(ExecutorType.MonsterSet, 97017120);
            AddExecutor(ExecutorType.MonsterSet, OnSelectMonsterSet);

        }
        private bool chk_release_summon = false;
        private int summonInTurn = 0;
        private int[] changePosInTurn = new int[] { 0, 0, 0, 0, 0, 0 };
        private int[] attacked = new int[] { 0, 0, 0, 0, 0, 0 };

        public override void OnNewTurn()
        {
            summonInTurn = 0;
            changePosInTurn = new int[] { 0, 0, 0, 0, 0, 0 };
            attacked = new int[] { 0, 0, 0, 0, 0, 0 };
        }
        public override BattlePhaseAction OnSelectAttackTarget(ClientCard attacker, IList<ClientCard> defenders)
        {
            if (attacker.CanDirectAttack)
            {
                attacked[GetSequence(attacker)] = attacker.Id;
                return AI.Attack(attacker, null);
            }
            if (attacker.IsCode(new[] { 37043180, 70074904 }))
            {
                if (Bot.GetMonsterCount() >= Enemy.GetMonsterCount())
                {
                    foreach (ClientCard defender in defenders)
                    {
                        attacker.RealPower = attacker.Attack;
                        defender.RealPower = defender.GetDefensePower();
                        if (!OnPreBattleBetween(attacker, defender))
                            continue;

                        if (attacker.RealPower < defender.RealPower && ((Bot.HasInMonstersZone(79575620) && attacked.Any(id => id == 79575620) && Bot.LifePoints > 2000) ? defender.RealPower - attacker.RealPower < Bot.LifePoints - 2000 : defender.RealPower - attacker.RealPower < Bot.LifePoints))
                        {
                            attacked[GetSequence(attacker)] = attacker.Id;
                            return AI.Attack(attacker, defender);
                        }
                    }
                }
            }
            switch (attacker.Id)
            {
                case 79575620:
                    {
                        foreach (ClientCard defender in defenders)
                        {
                            attacker.RealPower = 3400;
                            defender.RealPower = defender.GetDefensePower();
                            if (!OnPreBattleBetween(attacker, defender))
                                continue;

                            if ((attacker.RealPower >= defender.RealPower && defender.IsAttack()) || (attacker.RealPower > defender.RealPower && !GetZoneCards(CardLocation.MonsterZone, Bot).Any(c => c != null && !c.IsCode(79575620) && c.IsAttack() && (c.Attack > defender.RealPower || (c.IsCode(new[] { 37043180, 70074904 }) && defender.RealPower - c.Attack < Bot.LifePoints - 2000)) && attacked[GetSequence(c)] != c.Id) && defender.IsDefense() && defender.IsFaceup()))
                            {
                                attacked[GetSequence(attacker)] = attacker.Id;
                                return AI.Attack(attacker, defender);
                            }
                        }
                        return null;
                    }
            }
            foreach (ClientCard defender in defenders)
            {
                attacker.RealPower = attacker.Attack;
                defender.RealPower = defender.GetDefensePower();
                if (!OnPreBattleBetween(attacker, defender))
                    continue;

                if (attacker.RealPower > defender.RealPower || (attacker.RealPower >= defender.RealPower && attacker.IsLastAttacker && defender.IsAttack()))
                {
                    attacked[GetSequence(attacker)] = attacker.Id;
                    return AI.Attack(attacker, defender);
                }
            }
            return null;
        }
        public override bool OnSelectHand()
        {
            return true;
        }
        public override CardPosition OnSelectPosition(int cardId, IList<CardPosition> positions)
        {
            YGOSharp.OCGWrapper.NamedCard cardData = YGOSharp.OCGWrapper.NamedCard.Get(cardId);
            if (cardData != null)
            {
                switch (cardId)
                {
                    case 39168895:
                        {
                            return CardPosition.Attack;
                        }
                    case 85306040:
                        {
                            return CardPosition.Attack;
                        }
                    case 79575620:
                        {
                            return (Bot.LifePoints > 2000 ? CardPosition.Attack : CardPosition.Defence);
                        }
                }
                if (Duel.Player == 1 && GetZoneCards(CardLocation.MonsterZone, Enemy).Any(c => c != null && c.Attack > cardData.Attack && c.IsAttack()))
                    return CardPosition.Defence;
                if (Duel.Player == 0 && GetZoneCards(CardLocation.MonsterZone, Enemy).Any(c => c != null && c.GetDefensePower() < cardData.Attack))
                    return CardPosition.Attack;
            }
            return base.OnSelectPosition(cardId, positions);
        }
        public override int OnSelectPlace(int cardId, int player, CardLocation location, int available)
        {
            return base.OnSelectPlace(cardId, player, location, available);
        }
        public override IList<ClientCard> OnSelectCard(IList<ClientCard> cards, int min, int max, int hint, bool cancelable)
        {
            if (max > cards.Count()) max = cards.Count();
            // ClientCard currentSolvingChain = Duel.GetCurrentSolvingChainCard();
            ClientCard currentSolvingChain = Card;
            if (currentSolvingChain != null)
            {
                if (currentSolvingChain.IsCode(new[] { 97077563, 70828912 }))
                {
                    List<ClientCard> res = cards.Where(card => card != null && !cards.Any(c => c != null && c.Attack > card.Attack)).ToList();
                    return Util.CheckSelectCount(res, cards, min, max);
                }
                if (currentSolvingChain.IsCode(32807846))
                {
                    if (cards.Any(c => c != null && c.IsCode(new[] { 37043180, 70074904 })) && (Bot.GetMonsterCount() > Enemy.GetMonsterCount() || GetZoneCards(CardLocation.MonsterZone, Enemy).Any(c => c != null && c.IsCode(new[] { 23205979, 31305911 }))))
                        return Util.CheckSelectCount(cards.Where(card => card != null && card.IsCode(new[] { 37043180, 70074904 }) && !cards.Any(c => c != null && !c.IsCode(card.Id) && c.Attack < card.Attack)).ToList(), cards, min, max);
                    if (cards.Any(c => c != null && c.IsCode(74131780) && !GetZoneCards(CardLocation.MonsterZone, Enemy).Any(card => card != null && card.GetDefensePower() < 1000)) && GetZoneCards(CardLocation.MonsterZone, Enemy).Any(card => card != null && !card.IsShouldNotBeTarget()))
                        return Util.CheckSelectCount(cards.Where(c => c != null && c.IsCode(74131780)).ToList(), cards, min, max);
                    return Util.CheckSelectCount(cards.Where(card => card != null && !cards.Any(c => c != null && !c.IsCode(card.Id) && c.Attack < card.Attack)).ToList(), cards, min, max);
                }
                switch (currentSolvingChain.Id)
                {
                    case 60229110:
                        {
                            if (cards.Any(card => card != null && card.Controller == 1 && card.Location == CardLocation.MonsterZone))
                                return Util.CheckSelectCount(cards.Where(card => card != null && card.Controller == 1 && card.Location == CardLocation.MonsterZone).ToList(), cards, min, max);
                            if (cards.Any(card => card != null && card.Controller == 1 && card.Location == CardLocation.SpellZone))
                                return Util.CheckSelectCount(cards.Where(card => card != null && card.Controller == 1 && card.Location == CardLocation.SpellZone).ToList(), cards, min, max);
                            if (cards.Any(card => card != null && card.IsCode(new[] { 70828912, 97077563 })))
                                return Util.CheckSelectCount(cards.Where(card => card != null && card.IsCode(new[] { 70828912, 97077563 })).ToList(), cards, min, max);
                            break;
                        }
                    case 71044499:
                        {
                            return Util.CheckSelectCount(cards.Where(card => card != null && card.Controller == 1).ToList(), cards, min, max);
                        }
                    case 27174286:
                        {
                            return Util.CheckSelectCount(cards, cards, max, max);
                        }
                    case 45986603:
                        {
                            return Util.CheckSelectCount(cards.Where(card => card != null && !cards.Any(c => c != null && c.Attack > card.Attack)).ToList(), cards, min, max);
                        }
                    case 74131780:
                        {
                            return Util.CheckSelectCount(cards.Where(card => card != null && card.Controller == 1 && !cards.Any(c => c != null && card.Controller == 1 && c.Attack > card.Attack)).ToList(), cards, min, max);
                        }
                    case 79571449:
                        {
                            List<ClientCard> res = new List<ClientCard>();
                            List<ClientCard> g = new List<ClientCard>();
                            int step = 0;
                            while (res.Count() < 2)
                            {
                                switch (step)
                                {
                                    case 0:
                                        {
                                            int ct = cards.Count(c => c != null && c.IsCode(32807846)) - CheckCardsInDeck(new[] { 74131780, 37043180, 70074904 }, 4);
                                            if (ct > 0)
                                            {
                                                g = cards.Where(c => c != null && c.IsCode(32807846)).ToList();
                                                for (int i = 0; i < ct; i++)
                                                    res.Add(g[i]);
                                            }
                                            if ((Bot.GetSpellCount() - 1 > Enemy.GetSpellCount() || (Bot.HasInSpellZone(new[] { 70828912, 45986603, 97077563 }) && Enemy.GetSpellCount() < 3)) && cards.Any(c => c != null && c.IsCode(19613556)))
                                                res.AddRange(cards.Where(c => c != null && c.IsCode(19613556)).ToList());
                                            if (cards.Any(c => c != null && c.IsCode(42386471)) && cards.Any(c => c != null && !c.IsCode(42386471) && c.HasType(CardType.Monster) && c.Level < 5))
                                                res.AddRange(cards.Where(c => c != null && c.IsCode(42386471)).ToList());
                                            break;
                                        }
                                    case 1:
                                        {
                                            if (Bot.HasInHand(new[] { 70828912, 97077563 }))
                                            {
                                                g = cards.Where(card => card != null && card.HasType(CardType.Monster)).ToList();
                                                g.Sort(CardContainer.CompareCardAttack);
                                                g.Reverse();
                                                for (int i = 0; i < GetZoneCards(CardLocation.Hand, Bot).Count(c => c != null && c.IsCode(new[] { 70828912, 97077563 })); i++)
                                                {
                                                    if (g.Count() - 1 < i) break;
                                                    res.Add(g[i]);
                                                }
                                            }
                                            break;
                                        }
                                    case 2:
                                        {
                                            if (Bot.HasInHand(new[] { 76305638, 47606319 }))
                                            {
                                                g = cards.Where(card => card != null && card.HasType(CardType.Monster) && !card.IsCode((new[] { 76305638, 47606319 }))).ToList();
                                                if (g.Count() == 0)
                                                {
                                                    g = cards.Where(card => card != null && card.HasType(CardType.Monster) && card.IsCode((new[] { 76305638, 47606319 }))).ToList();
                                                    if (g.Count() <= 1) break;
                                                    for (int i = 0; i < g.Count() / 2; i++)
                                                        res.Add(g[i]);
                                                }
                                                else
                                                {
                                                    g.Sort(CardContainer.CompareCardAttack);
                                                    if (g[0].IsCode(79575620) && Bot.LifePoints > 2000)
                                                        g.Remove(g[0]);
                                                    if (g.Count() > 0) res.AddRange(g);
                                                }
                                            }
                                            break;
                                        }
                                    case 3:
                                        {
                                            g = cards.Where(card => card != null && (card.HasType(CardType.Monster) || card.IsCode(27174286)) && cards.Count(c => c != null && c.IsCode(card.Id)) > 1).ToList();
                                            if (g.Count() == 0) break;
                                            g.Sort(CardContainer.CompareCardCode);
                                            int code = 0;
                                            foreach (ClientCard card in g)
                                            {
                                                if (!card.IsCode(code))
                                                {
                                                    res.Add(card);
                                                    code = card.Id;
                                                }
                                            }
                                            break;
                                        }
                                    case 4:
                                        {
                                            g = cards.Where(card => card != null && card.HasType(CardType.Monster)).ToList();
                                            if (g.Count() == 0) break;
                                            g.Sort(CardContainer.CompareCardAttack);
                                            if (g[0].IsCode(79575620) && Bot.LifePoints > 2000)
                                                g.Remove(g[0]);
                                            if (g.Count() > 0) res.AddRange(g);
                                            break;
                                        }
                                    case 5:
                                        {
                                            foreach (int id in new[] { 71044499, 97169186, 73915051, 45986603, 27174286, 53582587, 14087893, 5318639 })
                                            {
                                                g = cards.Where(card => card != null && card.IsCode(id)).ToList();
                                                if (g.Count() > 0) res.AddRange(g);
                                            }
                                            break;
                                        }
                                }
                                step++;
                                if (step > 5) break;
                            }
                            return Util.CheckSelectCount(res, cards, min, max);
                        }
                }
            }
            if (chk_release_summon)
            {
                chk_release_summon = false;
                List<ClientCard> res = cards.Where(card => card != null && !card.IsCode(new[] { 79575620, 97017120, 74131780 })).ToList();
                if (Bot.LifePoints <= 2000 && cards.Any(card => card != null && !card.IsCode(79575620))) res.AddRange(cards.Where(card => card != null && !card.IsCode(79575620)).ToList());
                res = res.Where(card => card != null && !res.Any(c => c != null && c.Attack < card.Attack)).ToList();
                return Util.CheckSelectCount(res, cards, min, max);
            }
            return base.OnSelectCard(cards, min, max, hint, cancelable);
        }
        public int GetSequence(ClientCard card)
        {
            if (Card.Location != CardLocation.MonsterZone) return 5;
            for (int i = 0; i < 5; ++i)
            {
                if (Bot.MonsterZone[i] == card) return i;
            }
            return 5;
        }
        private List<ClientCard> GetZoneCards(CardLocation loc, ClientField player)
        {
            List<ClientCard> res = new List<ClientCard>();
            List<ClientCard> temp = new List<ClientCard>();
            if ((loc & CardLocation.Hand) > 0) { temp = player.Hand.Where(card => card != null).ToList(); if (temp.Count() > 0) res.AddRange(temp); }
            if ((loc & CardLocation.MonsterZone) > 0) { temp = player.GetMonsters(); if (temp.Count() > 0) res.AddRange(temp); }
            if ((loc & CardLocation.SpellZone) > 0) { temp = player.GetSpells(); if (temp.Count() > 0) res.AddRange(temp); }
            if ((loc & CardLocation.Grave) > 0) { temp = player.Graveyard.Where(card => card != null).ToList(); if (temp.Count() > 0) res.AddRange(temp); }
            if ((loc & CardLocation.Removed) > 0) { temp = player.Banished.Where(card => card != null).ToList(); if (temp.Count() > 0) res.AddRange(temp); }
            if ((loc & CardLocation.Extra) > 0) { temp = player.ExtraDeck.Where(card => card != null).ToList(); if (temp.Count() > 0) res.AddRange(temp); }
            return res;
        }
        private int CheckCardsInDeck(int code, int all_ct)
        {
            int count = 0;
            count += GetZoneCards(CardLocation.SpellZone, Bot).Count(card => card != null && card.IsCode(code));
            count += GetZoneCards(CardLocation.MonsterZone, Bot).Count(card => card != null && card.IsCode(code));
            count += GetZoneCards(CardLocation.Grave, Bot).Count(card => card != null && card.IsCode(code));
            count += GetZoneCards(CardLocation.Hand, Bot).Count(card => card != null && card.IsCode(code));
            count += GetZoneCards(CardLocation.Removed, Bot).Count(card => card != null && card.IsCode(code));
            count += GetZoneCards(CardLocation.Extra, Bot).Count(card => card != null && card.IsCode(code));
            return all_ct - count;
        }
        private int CheckCardsInDeck(int[] code, int all_ct)
        {
            int count = 0;
            count += GetZoneCards(CardLocation.SpellZone, Bot).Count(card => card != null && card.IsCode(code));
            count += GetZoneCards(CardLocation.MonsterZone, Bot).Count(card => card != null && card.IsCode(code));
            count += GetZoneCards(CardLocation.Grave, Bot).Count(card => card != null && card.IsCode(code));
            count += GetZoneCards(CardLocation.Hand, Bot).Count(card => card != null && card.IsCode(code));
            count += GetZoneCards(CardLocation.Removed, Bot).Count(card => card != null && card.IsCode(code));
            count += GetZoneCards(CardLocation.Extra, Bot).Count(card => card != null && card.IsCode(code));
            return all_ct - count;
        }
        private bool OnSelectMonsterRepos()
        {
            if (Card.IsCode(39168895)) return false;
            if (Duel.Phase == DuelPhase.Main1)
            {
                if ((Card.IsFacedown() || Card.IsDefense()) && GetZoneCards(CardLocation.MonsterZone, Enemy).Any(c => c != null && c.GetDefensePower() < Card.Attack))
                    return true;
            }
            else if (Duel.Phase == DuelPhase.Main2)
            {
                if (GetZoneCards(CardLocation.MonsterZone, Enemy).Any(c => c != null && c.Attack > Card.Attack) && Card.IsAttack())
                    return true;
            }
            return false;
        }
        private bool OnSelectActivate()
        {
            if (Card.IsDisabled()) return false;
            IList<int> activate_return_true = new[] { 97017120, 32807846, 79571449, 29401950, 44095762, 70828912, 97077563, 42386471, 45986603 };
            switch (Card.Id)
            {
                case 74131780:
                    {
                        if (Enemy.GetSpellCount() == 0)
                        {
                            if ((Duel.Phase == DuelPhase.Main2 || !Duel.MainPhase.CanBattlePhase) || ((changePosInTurn[GetSequence(Card)] == Card.Id || summonInTurn == Card.Id) && !Card.IsAttack()) || !GetZoneCards(CardLocation.MonsterZone, Enemy).Any(card => card != null && card.GetDefensePower() < Card.Attack))
                                return GetZoneCards(CardLocation.MonsterZone, Enemy).Any(card => card != null && !card.IsShouldNotBeTarget());
                        }
                        else
                        {
                            if (GetZoneCards(CardLocation.MonsterZone, Enemy).Any(card => card != null && !card.IsShouldNotBeTarget())) return true;
                        }
                        return false;
                    }
                case 97169186:
                    {
                        return DefaultSmashingGround();
                    }
                case 71044499:
                    {
                        return GetZoneCards(CardLocation.MonsterZone, Enemy).Any(card => card != null && !card.IsShouldNotBeTarget() && card.IsFacedown());
                    }
                case 73915051:
                    {
                        return (GetZoneCards(CardLocation.MonsterZone, Bot).Count() == 0 && GetZoneCards(CardLocation.MonsterZone, Enemy).Count() > 0 && Duel.Phase > DuelPhase.Main1 && Duel.Phase < DuelPhase.Main2 && Duel.Player == 1);
                    }
                case 19613556:
                    {
                        if (Bot.HasInSpellZone(new[] { 45986603, 70828912 })) return false;
                        if (Bot.HasInHand(5318639)) return Enemy.GetSpellCount() - Bot.GetSpellCount() > 1;
                        return DefaultHeavyStorm();
                    }
                case 53582587:
                    {
                        return DefaultTorrentialTribute();
                    }
                case 5318639:
                    {
                        return DefaultMysticalSpaceTyphoon();
                    }
                case 14087893:
                    {
                        return DefaultBookOfMoon();
                    }
                case 79575620:
                    {
                        return Bot.LifePoints > 2000;
                    }
                case 27174286:
                    {
                        int ct = GetZoneCards(CardLocation.Removed, Bot).Count(c => c != null && c.HasType(CardType.Monster));
                        if (ct == 0) return false;
                        if (ct > 5 - Bot.GetMonsterCount()) ct = 5 - Bot.GetMonsterCount();
                        if (Bot.GetMonsterCount() == 0 && Util.GetBestAttack(Enemy) >= Bot.LifePoints && Duel.Phase > DuelPhase.Main1 && Duel.Phase < DuelPhase.Main2 && Duel.Player == 1)
                            return true;
                        if ((5 - Bot.GetMonsterCount() >= ct || ct > 2) && Duel.Player == 0 && Duel.Phase == DuelPhase.Standby)
                            return true;
                        if (Duel.Phase > DuelPhase.Main1 && Duel.Phase < DuelPhase.Main2 && Duel.Player == 0)
                        {
                            List<ClientCard> g = GetZoneCards(CardLocation.Removed, Bot).Where(c => c != null && c.HasType(CardType.Monster)).ToList();
                            g.Sort(CardContainer.CompareCardAttack);
                            g.Reverse();
                            int atk = 0;
                            for (int i = 0; i < 5 - Bot.GetMonsterCount(); i++)
                            {
                                int a;
                                if (g[i].IsCode(79575620) && Bot.LifePoints > 2000) a = 3400;
                                else a = g[i].Attack;
                                atk += a;
                            }
                            if (Enemy.GetMonsterCount() == 0 && Enemy.LifePoints <= atk)
                                return true;
                        }
                        break;
                    }
            }
            return activate_return_true.IndexOf(Card.Id) >= 0;
        }
        private bool OnSelectSpellSet()
        {
            if (Duel.Phase != DuelPhase.Main2 && !Duel.MainPhase.CanBattlePhase) return false;
            return Card.HasType(CardType.Trap) || Card.HasType(CardType.QuickPlay);
        }
        private bool OnSelectMonsterSet()
        {
            if (Card.IsCode(60229110)) return false;
            if (!GetZoneCards(CardLocation.Hand, Bot).Any(card => card != null && card.Defense > Card.Defense)) return true;
            return false;
        }
        private bool OnSelectSummon()
        {
            if (Enemy.GetMonsterCount() > 0 && !GetZoneCards(CardLocation.MonsterZone, Enemy).Any(card => card != null && (Card.IsCode(79575620) ? card.GetDefensePower() < 3400 : card.GetDefensePower() < Card.Attack)) && !GetZoneCards(CardLocation.MonsterZone, Bot).Any(card => card != null && GetZoneCards(CardLocation.MonsterZone, Enemy).Any(c => c != null && c.GetDefensePower() < c.Attack)))
            {
                if (Card.IsCode(74131780) && GetZoneCards(CardLocation.MonsterZone, Enemy).Any(card => card != null && !card.IsShouldNotBeTarget()))
                {
                    summonInTurn = Card.Id;
                    return true;
                }
                if (Card.IsCode(new[] { 37043180, 70074904 }) && Bot.GetMonsterCount() >= Enemy.GetMonsterCount() - 1)
                {
                    summonInTurn = Card.Id;
                    return true;
                }
            }
            else
            {
                switch (Card.Id)
                {
                    case 60229110:
                        {
                            if ((GetZoneCards(CardLocation.SpellZone, Enemy).Any(card => card != null && !card.IsShouldNotBeTarget() && card.IsFacedown()) || GetZoneCards(CardLocation.MonsterZone, Enemy).Any(card => card != null && !card.IsShouldNotBeTarget() && card.IsFacedown())) && GetZoneCards(CardLocation.MonsterZone, Bot).Any(card => card != null && (!card.IsCode(new[] { 79575620, 97017120, 74131780 }) || (Bot.LifePoints <= 2000 && card.IsCode(79575620)))))
                            {
                                chk_release_summon = true;
                                return true;
                            }
                            List<ClientCard> g = GetZoneCards(CardLocation.MonsterZone, Bot).Where(c => c != null && !c.IsCode(new[] { 73915052, 73915053, 73915054, 73915055 })).ToList();
                            g.Sort(CardContainer.CompareCardAttack);
                            int atk = g[0].Attack;
                            if (Bot.LifePoints > 2000 && g[0].IsCode(79575620)) atk = g[1].Attack;
                            if (Enemy.LifePoints > Util.GetBestAttack(Bot) && Enemy.LifePoints - Util.GetBestAttack(Bot) <= 2400 - atk && Enemy.GetMonsterCount() == 0 && !GetZoneCards(CardLocation.Hand, Bot).Any(c => c != null && c.Level < 5 && c.HasType(CardType.Monster)) && Duel.MainPhase.CanBattlePhase && GetZoneCards(CardLocation.SpellZone, Bot).Any(c => c != null && !c.IsShouldNotBeTarget() && !c.IsFaceup()))
                            {
                                chk_release_summon = true;
                                return true;
                            }
                            return false;
                        }
                    case 79575620:
                        {
                            if (Bot.LifePoints > 2000)
                            {
                                return true;
                            }
                            if (Enemy.LifePoints > Util.GetBestAttack(Bot) && Enemy.LifePoints - Util.GetBestAttack(Bot) <= 400 && Enemy.GetMonsterCount() == 0 && !GetZoneCards(CardLocation.Hand, Bot).Any(c => c != null && c.Level < 5 && c.HasType(CardType.Monster)) && Duel.MainPhase.CanBattlePhase)
                            {
                                return true;
                            }
                            return false;
                        }
                }
                summonInTurn = Card.Id;
                return true;
            }
            return false;
        }
    }
}
