private bool MulliganLogic(out ICollection <IBotTask> tasks)
        {
            tasks = new List <IBotTask>();

            #region Replace some pairs

            if (Mulligan.Count(typeof(WildHuntRider)) == 2)
            {
                var card = Mulligan.GetCard(typeof(WildHuntRider));
                return(AddMulliganTask(tasks, card, "Replace 2 riders"));
            }

            if (Mulligan.Count(typeof(Foglet)) == 2)
            {
                var card = Mulligan.GetCard(typeof(Foglet));
                return(AddMulliganTask(tasks, card, "Replace 2 foglets"));
            }

            if (Mulligan.Count(typeof(Werewolf)) == 2)
            {
                var card = Mulligan.GetCard(typeof(Werewolf));
                return(AddMulliganTask(tasks, card, "Replace 2 werewolfs"));
            }

            if (Mulligan.Count(typeof(CelaenoHarpy)) == 2)
            {
                var card = Mulligan.GetCard(typeof(CelaenoHarpy));
                return(AddMulliganTask(tasks, card, "Replace 2 celaeno"));
            }

            if (IsRound1())
            {
                if (Mulligan.Count(typeof(Nekker)) == 2)
                {
                    var card = Mulligan.GetCard(typeof(Nekker));
                    return(AddMulliganTask(tasks, card, "Replace 2 nekkers"));
                }
            }

            #endregion

            #region Already tried to thin foglet

            if (GameMemory.InGraveyard(typeof(Foglet)) &&
                Hand.Contain(typeof(Foglet)))
            {
                var card = Mulligan.GetCard(typeof(Foglet));
                return(AddMulliganTask(tasks, card, "Already tried to thin foglet"));
            }

            #endregion

            #region Replace ozzrel and ghouls

            if (IsRound1())
            {
                if (Mulligan.Contain(typeof(Ghoul)))
                {
                    var card = Mulligan.GetCard(typeof(Ghoul));
                    return(AddMulliganTask(tasks, card, "Don't need ghoul R1"));
                }

                if (Mulligan.Contain(typeof(Ozzrel)))
                {
                    var card = Mulligan.GetCard(typeof(Ozzrel));
                    return(AddMulliganTask(tasks, card, "Don't need ozzrel R1"));
                }
            }

            #endregion

            #region Replace weak card in R2+

            if (NotRound1())
            {
                if (Mulligan.Contain(typeof(Foglet)) &&
                    GameMemory.InGraveyard(typeof(Foglet)))
                {
                    var card = Mulligan.GetCard(typeof(Foglet));
                    return(AddMulliganTask(tasks, card, "Don't need Foglet in R2+"));
                }
                if (Mulligan.Contain(typeof(Plumard)))
                {
                    var card = Mulligan.GetCard(typeof(Plumard));
                    return(AddMulliganTask(tasks, card, "Don't need Plumard in R2+"));
                }
                if (Mulligan.Contain(typeof(Nekker)))
                {
                    var card = Mulligan.GetCard(typeof(Nekker));
                    return(AddMulliganTask(tasks, card, "Don't need Nekker in R2+"));
                }
                if (Mulligan.Contain(typeof(Wyvern)))
                {
                    var card = Mulligan.GetCard(typeof(Wyvern));
                    return(AddMulliganTask(tasks, card, "Don't need Wyvern in R2+"));
                }
                if (Mulligan.Contain(typeof(NekkerWarrior)))
                {
                    var card = Mulligan.GetCard(typeof(NekkerWarrior));
                    return(AddMulliganTask(tasks, card, "Don't need NekkerWarrior in R2+"));
                }
                if (Mulligan.Contain(typeof(Brewess)))
                {
                    var card = Mulligan.GetCard(typeof(Brewess));
                    return(AddMulliganTask(tasks, card, "Don't need Brewess in R2+"));
                }
            }

            #endregion

            tasks.Add(new FinishMulliganTask());
            return(false);
        }
        private bool PlayLogic(ref ICollection <IBotTask> tasks)
        {
            var leastBusyRow = Board.RangedSize < Board.MeleeSize ? Card.Rows.Ranged : Card.Rows.Melee;

            #region Thin foglet

            // consume
            if (Board.Count(typeof(Foglet)) == 1)
            {
                var foglet     = Board.GetCard(typeof(Foglet));
                var placePoint = new Point(foglet.Area.Right, foglet.Y + foglet.Height / 2);
                if (Hand.Contain(typeof(Brewess)))
                {
                    return(Hand.Play(typeof(Brewess), out tasks, leastBusyRow, placePoint));
                }
                if (Hand.Contain(typeof(CelaenoHarpy)))
                {
                    return(Hand.Play(typeof(CelaenoHarpy), out tasks, leastBusyRow, placePoint));
                }
                if (Hand.Contain(typeof(Cyclops)))
                {
                    return(Hand.Play(typeof(Cyclops), out tasks, leastBusyRow, placePoint));
                }
            }
            // place foglet
            if (Hand.Contain(typeof(Foglet)) &&
                (Hand.Contain(typeof(Cyclops)) || Hand.Contain(typeof(Brewess)) || Hand.Contain(typeof(CelaenoHarpy))))
            {
                return(Hand.Play(typeof(Foglet), out tasks, Card.Rows.Melee));
            }

            #endregion

            #region Blow brewess/cyclop if we alredy thinned foglet (or its too late)

            if (Extra.CurrentRound == Rounds.Draw ||
                GameMemory.InGraveyard(typeof(Foglet)))
            {
                if (Hand.Contain(typeof(Cyclops)))
                {
                    return(Hand.Play(typeof(Cyclops), out tasks));
                }
                if (Hand.Contain(typeof(Brewess)))
                {
                    return(Hand.Play(typeof(Brewess), out tasks));
                }
            }

            if (Extra.CurrentRound == Rounds.Draw &&
                Hand.Contain(typeof(Golyat)) &&
                !Hand.Contain(typeof(Katakan)) &&
                !Board.Contain(typeof(Katakan)) &&
                !Hand.Contain(typeof(Foglet)) &&
                !Board.Contain(typeof(Foglet)))
            {
                if (Hand.Contain(typeof(Cyclops)))
                {
                    return(Hand.Play(typeof(Cyclops), out tasks));
                }
                if (Hand.Contain(typeof(Brewess)))
                {
                    return(Hand.Play(typeof(Brewess), out tasks));
                }
                if (Hand.Contain(typeof(CelaenoHarpy)))
                {
                    return(Hand.Play(typeof(CelaenoHarpy), out tasks));
                }
            }

            #endregion

            #region Wild hunt raider

            // Manually adding extra wild hunt rider to played list
            if (Board.Count(typeof(WildHuntRider)) == 2 &&
                GameMemory.GetGy().Count(card => card == typeof(WildHuntRider)) == 1)
            {
                GameMemory.RegisterCard(typeof(WildHuntRider));
            }
            // Play wild hunt raider if we can (easy check)
            if (Extra.EnemyScore <= 4 &&
                Hand.Count(typeof(WildHuntRider)) == 1)
            {
                return(Hand.Play(typeof(WildHuntRider), out tasks, Card.Rows.Ranged));
            }

            #endregion

            #region Small thrive

            if (Hand.Contain(typeof(Nekker)))
            {
                return(Hand.Play(typeof(Nekker), out tasks, leastBusyRow));
            }
            if (Hand.Contain(typeof(Wyvern)) && Extra.EnemyScore >= 3)
            {
                return(Hand.Play(typeof(Wyvern), out tasks, Card.Rows.Melee));
            }
            if (Hand.Contain(typeof(NekkerWarrior)))
            {
                return(Hand.Play(typeof(NekkerWarrior), out tasks, leastBusyRow));
            }
            if (Hand.Contain(typeof(AlphaWerewolf)) &&
                HaveOtherImmuneShit())
            {
                return(Hand.Play(typeof(AlphaWerewolf), out tasks, leastBusyRow));
            }

            #endregion

            #region Plumard

            // Play 2 plumard if we can
            if (Hand.Contain(typeof(Plumard)) &&
                Extra.EnemyScore >= 3 &&
                Board.Count(typeof(Plumard)) + Hand.Count(typeof(Plumard)) >= 2)
            {
                return(Hand.Play(typeof(Plumard), out tasks, leastBusyRow));
            }

            #endregion

            #region Play medium sized threats

            if (Hand.Contain(typeof(Katakan)))
            {
                return(Hand.Play(typeof(Katakan), out tasks, leastBusyRow));
            }
            if (Hand.Contain(typeof(WeavessIncantation)))
            {
                if (Hand.Contain(typeof(PrimordialDao)) ||
                    Hand.Contain(typeof(Golyat)) ||
                    Hand.Contain(typeof(OldSpeartipAsleep)) ||
                    Hand.Contain(typeof(OldSpeartip)) ||
                    Hand.Contain(typeof(CountCaldwell)) ||
                    Hand.Contain(typeof(IceGiant)))
                {
                    WeavessIncantationMode = true;
                    return(Hand.Play(typeof(WeavessIncantation), out tasks, Card.Rows.Melee));
                }
            }
            if (Hand.Contain(typeof(IceGiant)))
            {
                return(Hand.Play(typeof(IceGiant), out tasks, leastBusyRow));
            }
            if (Hand.Contain(typeof(PrimordialDao)))
            {
                return(Hand.Play(typeof(PrimordialDao), out tasks, leastBusyRow));
            }
            if (Hand.Contain(typeof(OldSpeartipAsleep)))
            {
                return(Hand.Play(typeof(OldSpeartipAsleep), out tasks, leastBusyRow));
            }
            if (Hand.Contain(typeof(OldSpeartip)))
            {
                return(Hand.Play(typeof(OldSpeartip), out tasks, leastBusyRow));
            }

            #endregion

            #region Crones

            if (Hand.Contain(typeof(Whispess)) && Extra.EnemyScore >= 3)
            {
                return(Hand.Play(typeof(Whispess), out tasks));
            }
            if (Hand.Contain(typeof(Weavess)) && SomethingToBuff())
            {
                return(Hand.Play(typeof(Weavess), out tasks, leastBusyRow));
            }

            #endregion

            #region Swallow + Parasyte
            if (Board.Count() >= 2 &&
                Hand.Contain(typeof(Swallow)) &&
                !Board.Contain(typeof(TacticalAdvantage)))
            {
                return(Hand.Play(typeof(Swallow), out tasks));
            }
            if (Board.Count() >= 2 &&
                Hand.Contain(typeof(Parasite)) &&
                !Board.Contain(typeof(TacticalAdvantage)))
            {
                return(Hand.Play(typeof(Parasite), out tasks));
            }
            #endregion

            #region Consume

            if (Extra.CurrentRound != Rounds.FirstRound &&
                Hand.Contain(typeof(Ghoul)))
            {
                if (GameMemory.InGraveyard(typeof(IceGiant)) ||
                    GameMemory.InGraveyard(typeof(Weavess)) ||
                    GameMemory.InGraveyard(typeof(Whispess)) ||
                    GameMemory.InGraveyard(typeof(Brewess)) ||
                    GameMemory.InGraveyard(typeof(Cyclops)))
                {
                    GhoulMode = true;
                    return(Hand.Play(typeof(Ghoul), out tasks, Card.Rows.Melee));
                }
            }

            if (Extra.CurrentRound != Rounds.FirstRound &&
                Hand.Contain(typeof(Ozzrel)))
            {
                if (GameMemory.InGraveyard(typeof(OldSpeartipAsleep)) ||
                    GameMemory.InGraveyard(typeof(OldSpeartip)) ||
                    GameMemory.InGraveyard(typeof(Golyat)) ||
                    GameMemory.InGraveyard(typeof(CountCaldwell)) ||
                    GameMemory.InGraveyard(typeof(PrimordialDao)))
                {
                    OzzrelMode = true;
                    return(Hand.Play(typeof(Ozzrel), out tasks, Card.Rows.Ranged));
                }
            }

            #endregion

            #region Leader logic

            if (Extra.CurrentRound != Rounds.FirstRound &&
                Hand.Contain(typeof(WoodlandSpirit)))
            {
                LeaderBuffMode = true;
                return(Hand.Play(typeof(WoodlandSpirit), out tasks));
            }
            if (LeaderBuffMode &&
                !Hand.Contain(typeof(WoodlandSpirit)))
            {
                LeaderBuffMode = false;
                foreach (var card in FromHighToLowStr.Reverse())
                {
                    if (Hand.Contain(card))
                    {
                        return(Hand.Play(card, out tasks));
                    }
                }
            }

            #endregion

            #region Katakan->Consume

            if (Board.Contain(typeof(Katakan)))
            {
                var katakan    = Board.GetCard(typeof(Katakan));
                var placePoint = new Point(katakan.Area.Right, katakan.Y + katakan.Height / 2);
                if (Hand.Contain(typeof(Brewess)))
                {
                    tasks.Add(new TooltipTask("Katakan->Consume"));
                    return(Hand.Play(typeof(Brewess), out tasks, default, placePoint));
        /// <summary>
        ///     Returns current potential hand value
        /// </summary>
        private int GetHandValue()
        {
            var value = Hand.GetCards().Sum(card => card.Value);

            if (Hand.Contain(typeof(Ghoul)))
            {
                if (GameMemory.InGraveyard(typeof(IceGiant)))
                {
                    value += 7;
                }
                else if (GameMemory.InGraveyard(typeof(Cyclops)))
                {
                    value += 5;
                }
                else if (GameMemory.InGraveyard(typeof(Werewolf)) ||
                         GameMemory.InGraveyard(typeof(AlphaWerewolf)) ||
                         GameMemory.InGraveyard(typeof(NekkerWarrior)) ||
                         GameMemory.InGraveyard(typeof(WildHuntRider)))
                {
                    value += 4;
                }
            }
            if (Hand.Contain(typeof(Ozzrel)))
            {
                if (GameMemory.InGraveyard(typeof(OldSpeartip)))
                {
                    value += 12;
                }
                else if (GameMemory.InGraveyard(typeof(CountCaldwell)) ||
                         GameMemory.InGraveyard(typeof(Golyat)))
                {
                    value += 10;
                }
                else if (GameMemory.InGraveyard(typeof(OldSpeartipAsleep)) ||
                         GameMemory.InGraveyard(typeof(PrimordialDao)))
                {
                    value += 9;
                }
                else if (GameMemory.InGraveyard(typeof(IceGiant)))
                {
                    value += 7;
                }
            }
            if (Hand.Contain(typeof(WeavessIncantation)))
            {
                if (Hand.Contain(typeof(OldSpeartip)))
                {
                    value += 12;
                }
                else if (Hand.Contain(typeof(CountCaldwell)) ||
                         Hand.Contain(typeof(Golyat)))
                {
                    value += 10;
                }
                else if (Hand.Contain(typeof(OldSpeartipAsleep)) ||
                         Hand.Contain(typeof(PrimordialDao)))
                {
                    value += 9;
                }
                else if (Hand.Contain(typeof(IceGiant)))
                {
                    value += 7;
                }
            }
            return(value);
        }