Example #1
0
        protected virtual ActionBase PlayCardsToField()
        {
            // Get all available cards...
            List <HRCard> availableCards =
                HRCard.GetCards(HRPlayer.GetLocalPlayer(), HRCardZone.HAND);

            if (availableCards.Count > 0)
            {
                HRCard coin = null;
                foreach (var item in availableCards)
                {
                    #region Skip The Coin
                    string cardID = item.GetEntity().GetCardId();
                    if (cardID == "GAME_005" || cardID == "GAME_005e")
                    {
                        coin = item;
                        continue;
                    }
                    #endregion

                    if (item.GetEntity().GetCost() <= HRPlayer.GetLocalPlayer().GetNumAvailableResources())
                    {
                        if (HRBattle.CanUseCard(item.GetEntity()) && HRCardManager.IsCardAllowedByRule(item))
                        {
                            return(new PlayCardAction(item));
                        }
                    }
                }

                #region The Coin Feature
                // Feature: The Coin
                // https://github.com/juce-mmocrawlerbots/HREngine/issues/13
                if (coin != null)
                {
                    foreach (var card in availableCards)
                    {
                        if (card.GetEntity().GetCardId() != coin.GetEntity().GetCardId())
                        {
                            if (card.GetEntity().IsMinion() || card.GetEntity().IsSpell() || (!HRPlayer.GetLocalPlayer().HasWeapon() && card.GetEntity().IsWeapon()))
                            {
                                if (card.GetEntity().GetCost() <= (HRPlayer.GetLocalPlayer().GetNumAvailableResources() + 1))
                                {
                                    HRLog.Write(
                                        String.Format("Spawn [{0}] and then [{1}]",
                                                      coin.GetEntity().GetName(), card.GetEntity().GetName()));

                                    NextFixedAction = new PlayCardAction(card);
                                    return(new PlayCardAction(coin));
                                }
                            }
                        }
                    }
                }
                #endregion
            }

            return(null);
        }
        protected override API.HRCard GetMinionByPriority(HRCard lastMinion)
        {
            var result = HRBattle.GetNextMinionByPriority(MinionPriority.LowestHealth);

            if (result != null && (lastMinion == null || lastMinion != null && lastMinion.GetEntity().GetCardId() != result.GetCardId()))
            {
                return(result.GetCard());
            }

            return(null);
        }
Example #3
0
        private List <HRCard> GetPlayableCards(List <HRCard> list)
        {
            int           manaLeft = HRPlayer.GetLocalPlayer().GetNumAvailableResources();
            List <HRCard> result   = new List <HRCard>();

            foreach (var item in list)
            {
                if (item.GetEntity().GetCost() <= manaLeft && HRBattle.CanUseCard(item.GetEntity()))
                {
                    result.Add(item);
                }
            }
            return(result);
        }
Example #4
0
        protected virtual HREntity GetNextAttackToAttack()
        {
            HREntity result = null;

            if (HRPlayer.GetLocalPlayer().GetNumEnemyMinionsInPlay() <
                HRPlayer.GetLocalPlayer().GetNumFriendlyMinionsInPlay() ||
                HRPlayer.GetLocalPlayer().GetNumEnemyMinionsInPlay() < 4)
            {
                result = HRBattle.GetNextMinionByPriority(MinionPriority.Hero);
            }
            else
            {
                result = HRBattle.GetNextMinionByPriority(MinionPriority.LowestHealth);
            }

            if (result == null)
            {
                return(HRPlayer.GetEnemyPlayer().GetHero());
            }

            return(result);
        }
Example #5
0
        protected override HRCard GetMinionByPriority(HRCard lastMinion)
        {
            HREntity result = null;

            if (HRPlayer.GetLocalPlayer().GetNumEnemyMinionsInPlay() <
                HRPlayer.GetLocalPlayer().GetNumFriendlyMinionsInPlay() ||
                HRPlayer.GetLocalPlayer().GetNumEnemyMinionsInPlay() < 4)
            {
                result = HRBattle.GetNextMinionByPriority(MinionPriority.Hero);
            }
            else
            {
                result = HRBattle.GetNextMinionByPriority(MinionPriority.LowestHealth);
            }

            if (result != null && (lastMinion == null || lastMinion != null && lastMinion.GetEntity().GetCardId() != result.GetCardId()))
            {
                return(result.GetCard());
            }

            return(null);
        }
Example #6
0
        /// <summary>
        /// [EN]
        /// This handler is executed when the local player turn is active.
        ///
        /// [DE]
        /// Dieses Event wird ausgelöst wenn der Spieler am Zug ist.
        /// </summary>
        private HREngine.API.Actions.ActionBase HandleOnBattleStateUpdate()
        {
            try
            {
                if (HRBattle.IsInTargetMode() && dirtytarget >= 0)
                {
                    HRLog.Write("dirty targeting...");
                    HREntity target = getEntityWithNumber(dirtytarget);
                    dirtytarget = -1;
                    return(new HREngine.API.Actions.TargetAction(target));
                }


                //SafeHandleBattleLocalPlayerTurnHandler();


                sf.updateEverything(this);
                Action moveTodo = Ai.Instance.bestmove;
                if (moveTodo == null)
                {
                    HRLog.Write("end turn");
                    return(null);
                }
                HRLog.Write("play action");
                moveTodo.print();
                if (moveTodo.cardplay)
                {
                    HRCard cardtoplay = getCardWithNumber(moveTodo.cardEntitiy);
                    if (moveTodo.enemytarget >= 0)
                    {
                        HREntity target = getEntityWithNumber(moveTodo.enemyEntitiy);
                        HRLog.Write("play: " + cardtoplay.GetEntity().GetName() + " target: " + target.GetName());
                        Helpfunctions.Instance.logg("play: " + cardtoplay.GetEntity().GetName() + " target: " + target.GetName());
                        if (moveTodo.handcard.card.type == CardDB.cardtype.MOB)
                        {
                            return(new HREngine.API.Actions.PlayCardAction(cardtoplay, target, moveTodo.owntarget + 1));
                        }

                        return(new HREngine.API.Actions.PlayCardAction(cardtoplay, target));
                    }
                    else
                    {
                        HRLog.Write("play: " + cardtoplay.GetEntity().GetName() + " target nothing");
                        if (moveTodo.handcard.card.type == CardDB.cardtype.MOB)
                        {
                            return(new HREngine.API.Actions.PlayCardAction(cardtoplay, null, moveTodo.owntarget + 1));
                        }
                        return(new HREngine.API.Actions.PlayCardAction(cardtoplay));
                    }
                }

                if (moveTodo.minionplay)
                {
                    HREntity attacker = getEntityWithNumber(moveTodo.ownEntitiy);
                    HREntity target   = getEntityWithNumber(moveTodo.enemyEntitiy);
                    HRLog.Write("minion attack: " + attacker.GetName() + " target: " + target.GetName());
                    Helpfunctions.Instance.logg("minion attack: " + attacker.GetName() + " target: " + target.GetName());
                    return(new HREngine.API.Actions.AttackAction(attacker, target));
                }

                if (moveTodo.heroattack)
                {
                    HREntity attacker = getEntityWithNumber(moveTodo.ownEntitiy);
                    HREntity target   = getEntityWithNumber(moveTodo.enemyEntitiy);
                    this.dirtytarget = moveTodo.enemyEntitiy;
                    //HRLog.Write("heroattack: attkr:" + moveTodo.ownEntitiy + " defender: " + moveTodo.enemyEntitiy);
                    HRLog.Write("heroattack: " + attacker.GetName() + " target: " + target.GetName());
                    Helpfunctions.Instance.logg("heroattack: " + attacker.GetName() + " target: " + target.GetName());
                    if (HRPlayer.GetLocalPlayer().HasWeapon())
                    {
                        HRLog.Write("hero attack with weapon");
                        return(new HREngine.API.Actions.AttackAction(HRPlayer.GetLocalPlayer().GetWeaponCard().GetEntity(), target));
                    }
                    HRLog.Write("hero attack without weapon");
                    //HRLog.Write("attacker entity: " + HRPlayer.GetLocalPlayer().GetHero().GetEntityId());
                    return(new HREngine.API.Actions.AttackAction(HRPlayer.GetLocalPlayer().GetHero(), target));
                }

                if (moveTodo.useability)
                {
                    HRCard cardtoplay = HRPlayer.GetLocalPlayer().GetHeroPower().GetCard();

                    if (moveTodo.enemytarget >= 0)
                    {
                        HREntity target = getEntityWithNumber(moveTodo.enemyEntitiy);
                        HRLog.Write("use ablitiy: " + cardtoplay.GetEntity().GetName() + " target " + target.GetName());
                        Helpfunctions.Instance.logg("use ablitiy: " + cardtoplay.GetEntity().GetName() + " target " + target.GetName());
                        return(new HREngine.API.Actions.PlayCardAction(cardtoplay, target));
                    }
                    else
                    {
                        HRLog.Write("use ablitiy: " + cardtoplay.GetEntity().GetName() + " target nothing");
                        Helpfunctions.Instance.logg("use ablitiy: " + cardtoplay.GetEntity().GetName() + " target nothing");
                        return(new HREngine.API.Actions.PlayCardAction(cardtoplay));
                    }
                }
            }
            catch (Exception Exception)
            {
                HRLog.Write(Exception.Message);
                HRLog.Write(Environment.StackTrace);
            }
            return(null);
            //HRBattle.FinishRound();
        }
Example #7
0
        /// <summary>
        /// [EN]
        /// This handler is executed when the local player turn is active.
        ///
        /// [DE]
        /// Dieses Event wird ausgelöst wenn der Spieler am Zug ist.
        /// </summary>
        private HREngine.API.Actions.ActionBase HandleOnBattleStateUpdate()
        {
            try
            {
                if (this.isgoingtoconcede)
                {
                    if (HREngine.API.Utilities.HRSettings.Get.SelectedGameMode == HRGameMode.ARENA)
                    {
                        this.isgoingtoconcede = false;
                    }
                    else
                    {
                        return(new HREngine.API.Actions.ConcedeAction());
                    }
                }

                if (Settings.Instance.passiveWaiting && sf.waitingForSilver)
                {
                    if (!this.sf.readActionFile(true))
                    {
                        return(new HREngine.API.Actions.MakeNothingAction());
                    }
                }

                if (Settings.Instance.learnmode && (HRBattle.IsInTargetMode() || HRChoice.IsChoiceActive()))
                {
                    return(new HREngine.API.Actions.MakeNothingAction());
                }

                if (HRBattle.IsInTargetMode() && dirtytarget >= 0)
                {
                    Helpfunctions.Instance.ErrorLog("dirty targeting...");
                    HREntity target = getEntityWithNumber(dirtytarget);

                    dirtytarget = -1;

                    return(new HREngine.API.Actions.TargetAction(target));
                }
                if (HRChoice.IsChoiceActive())
                {
                    if (this.dirtychoice >= 1)
                    {
                        List <HREntity> choices = HRChoice.GetChoiceCards();
                        int             choice  = this.dirtychoice;
                        this.dirtychoice = -1;
                        string ccId = this.choiceCardId;
                        this.choiceCardId = "";
                        HREntity target = choices[choice - 1];
                        if (ccId == "EX1_160")
                        {
                            foreach (HREntity hre in choices)
                            {
                                if (choice == 1 && hre.GetCardId() == "EX1_160b")
                                {
                                    target = hre;
                                }
                                if (choice == 2 && hre.GetCardId() == "EX1_160a")
                                {
                                    target = hre;
                                }
                            }
                        }
                        if (ccId == "NEW1_008")
                        {
                            foreach (HREntity hre in choices)
                            {
                                if (choice == 1 && hre.GetCardId() == "NEW1_008a")
                                {
                                    target = hre;
                                }
                                if (choice == 2 && hre.GetCardId() == "NEW1_008b")
                                {
                                    target = hre;
                                }
                            }
                        }
                        if (ccId == "EX1_178")
                        {
                            foreach (HREntity hre in choices)
                            {
                                if (choice == 1 && hre.GetCardId() == "EX1_178a")
                                {
                                    target = hre;
                                }
                                if (choice == 2 && hre.GetCardId() == "EX1_178b")
                                {
                                    target = hre;
                                }
                            }
                        }
                        if (ccId == "EX1_573")
                        {
                            foreach (HREntity hre in choices)
                            {
                                if (choice == 1 && hre.GetCardId() == "EX1_573a")
                                {
                                    target = hre;
                                }
                                if (choice == 2 && hre.GetCardId() == "EX1_573b")
                                {
                                    target = hre;
                                }
                            }
                        }
                        if (ccId == "EX1_165")//druid of the claw
                        {
                            foreach (HREntity hre in choices)
                            {
                                if (choice == 1 && hre.GetCardId() == "EX1_165t1")
                                {
                                    target = hre;
                                }
                                if (choice == 2 && hre.GetCardId() == "EX1_165t2")
                                {
                                    target = hre;
                                }
                            }
                        }
                        if (ccId == "EX1_166")//keeper of the grove
                        {
                            foreach (HREntity hre in choices)
                            {
                                if (choice == 1 && hre.GetCardId() == "EX1_166a")
                                {
                                    target = hre;
                                }
                                if (choice == 2 && hre.GetCardId() == "EX1_166b")
                                {
                                    target = hre;
                                }
                            }
                        }
                        if (ccId == "EX1_155")
                        {
                            foreach (HREntity hre in choices)
                            {
                                if (choice == 1 && hre.GetCardId() == "EX1_155a")
                                {
                                    target = hre;
                                }
                                if (choice == 2 && hre.GetCardId() == "EX1_155b")
                                {
                                    target = hre;
                                }
                            }
                        }
                        if (ccId == "EX1_164")
                        {
                            foreach (HREntity hre in choices)
                            {
                                if (choice == 1 && hre.GetCardId() == "EX1_164a")
                                {
                                    target = hre;
                                }
                                if (choice == 2 && hre.GetCardId() == "EX1_164b")
                                {
                                    target = hre;
                                }
                            }
                        }
                        if (ccId == "New1_007")//starfall
                        {
                            foreach (HREntity hre in choices)
                            {
                                if (choice == 1 && hre.GetCardId() == "New1_007b")
                                {
                                    target = hre;
                                }
                                if (choice == 2 && hre.GetCardId() == "New1_007a")
                                {
                                    target = hre;
                                }
                            }
                        }
                        if (ccId == "EX1_154")//warth
                        {
                            foreach (HREntity hre in choices)
                            {
                                if (choice == 1 && hre.GetCardId() == "EX1_154a")
                                {
                                    target = hre;
                                }
                                if (choice == 2 && hre.GetCardId() == "EX1_154b")
                                {
                                    target = hre;
                                }
                            }
                        }
                        Helpfunctions.Instance.logg("chooses the card: " + target.GetCardId());
                        return(new HREngine.API.Actions.ChoiceAction(target));
                    }
                    else
                    {
                        //Todo: ultimate tracking-simulation!
                        List <HREntity> choices = HRChoice.GetChoiceCards();
                        Random          r       = new Random();
                        int             choice  = r.Next(0, choices.Count);
                        Helpfunctions.Instance.logg("chooses a random card");
                        return(new HREngine.API.Actions.ChoiceAction(choices[choice]));
                    }
                }

                bool templearn = sf.updateEverything(behave, Settings.Instance.useExternalProcess, Settings.Instance.passiveWaiting);
                if (templearn == true)
                {
                    Settings.Instance.printlearnmode = true;
                }

                if (Settings.Instance.passiveWaiting && sf.waitingForSilver)
                {
                    return(new HREngine.API.Actions.MakeNothingAction());
                }

                if (Settings.Instance.learnmode)
                {
                    if (Settings.Instance.printlearnmode)
                    {
                        Ai.Instance.simmulateWholeTurnandPrint();
                    }
                    Settings.Instance.printlearnmode = false;
                    return(new HREngine.API.Actions.MakeNothingAction());
                }



                if (Ai.Instance.bestmoveValue <= -900 && Settings.Instance.enemyConcede)
                {
                    return(new HREngine.API.Actions.ConcedeAction());
                }

                Action moveTodo = Ai.Instance.bestmove;

                if (moveTodo == null || moveTodo.actionType == actionEnum.endturn)
                {
                    Helpfunctions.Instance.ErrorLog("end turn");
                    return(null);
                }
                Helpfunctions.Instance.ErrorLog("play action");
                moveTodo.print();
                if (moveTodo.actionType == actionEnum.playcard)
                {
                    HRCard cardtoplay = getCardWithNumber(moveTodo.card.entity);
                    if (moveTodo.target != null)
                    {
                        HREntity target = getEntityWithNumber(moveTodo.target.entitiyID);
                        Helpfunctions.Instance.ErrorLog("play: " + cardtoplay.GetEntity().GetName() + " target: " + target.GetName());
                        Helpfunctions.Instance.logg("play: " + cardtoplay.GetEntity().GetName() + " target: " + target.GetName() + " choice: " + moveTodo.druidchoice);
                        if (moveTodo.druidchoice >= 1)
                        {
                            this.dirtytarget  = moveTodo.target.entitiyID;
                            this.dirtychoice  = moveTodo.druidchoice; //1=leftcard, 2= rightcard
                            this.choiceCardId = moveTodo.card.card.cardIDenum.ToString();
                        }
                        if (moveTodo.card.card.type == CardDB.cardtype.MOB)
                        {
                            return(new HREngine.API.Actions.PlayCardAction(cardtoplay, target, moveTodo.place));
                        }

                        return(new HREngine.API.Actions.PlayCardAction(cardtoplay, target));
                    }
                    else
                    {
                        Helpfunctions.Instance.ErrorLog("play: " + cardtoplay.GetEntity().GetName() + " target nothing");
                        Helpfunctions.Instance.logg("play: " + cardtoplay.GetEntity().GetName() + " choice: " + moveTodo.druidchoice);
                        if (moveTodo.druidchoice >= 1)
                        {
                            this.dirtychoice  = moveTodo.druidchoice; //1=leftcard, 2= rightcard
                            this.choiceCardId = moveTodo.card.card.cardIDenum.ToString();
                        }
                        if (moveTodo.card.card.type == CardDB.cardtype.MOB)
                        {
                            return(new HREngine.API.Actions.PlayCardAction(cardtoplay, null, moveTodo.place));
                        }
                        return(new HREngine.API.Actions.PlayCardAction(cardtoplay));
                    }
                }

                if (moveTodo.actionType == actionEnum.attackWithMinion)
                {
                    HREntity attacker = getEntityWithNumber(moveTodo.own.entitiyID);
                    HREntity target   = getEntityWithNumber(moveTodo.target.entitiyID);
                    Helpfunctions.Instance.ErrorLog("minion attack: " + attacker.GetName() + " target: " + target.GetName());
                    Helpfunctions.Instance.logg("minion attack: " + attacker.GetName() + " target: " + target.GetName());
                    return(new HREngine.API.Actions.AttackAction(attacker, target));
                }

                if (moveTodo.actionType == actionEnum.attackWithHero)
                {
                    HREntity attacker = getEntityWithNumber(moveTodo.own.entitiyID);
                    HREntity target   = getEntityWithNumber(moveTodo.target.entitiyID);
                    this.dirtytarget = moveTodo.target.entitiyID;
                    Helpfunctions.Instance.ErrorLog("heroattack: " + attacker.GetName() + " target: " + target.GetName());
                    Helpfunctions.Instance.logg("heroattack: " + attacker.GetName() + " target: " + target.GetName());
                    if (HRPlayer.GetLocalPlayer().HasWeapon())
                    {
                        Helpfunctions.Instance.ErrorLog("hero attack with weapon");
                        return(new HREngine.API.Actions.AttackAction(HRPlayer.GetLocalPlayer().GetWeaponCard().GetEntity(), target));
                    }
                    Helpfunctions.Instance.ErrorLog("hero attack without weapon");
                    //Helpfunctions.Instance.ErrorLog("attacker entity: " + HRPlayer.GetLocalPlayer().GetHero().GetEntityId());
                    //return new HREngine.API.Actions.AttackAction(HRPlayer.GetLocalPlayer().GetHero(), target);
                    return(new HREngine.API.Actions.PlayCardAction(HRPlayer.GetLocalPlayer().GetHeroCard(), target));
                }

                if (moveTodo.actionType == actionEnum.useHeroPower)
                {
                    HRCard cardtoplay = HRPlayer.GetLocalPlayer().GetHeroPower().GetCard();

                    if (moveTodo.target != null)
                    {
                        HREntity target = getEntityWithNumber(moveTodo.target.entitiyID);
                        Helpfunctions.Instance.ErrorLog("use ablitiy: " + cardtoplay.GetEntity().GetName() + " target " + target.GetName());
                        Helpfunctions.Instance.logg("use ablitiy: " + cardtoplay.GetEntity().GetName() + " target " + target.GetName());
                        return(new HREngine.API.Actions.PlayCardAction(cardtoplay, target));
                    }
                    else
                    {
                        Helpfunctions.Instance.ErrorLog("use ablitiy: " + cardtoplay.GetEntity().GetName() + " target nothing");
                        Helpfunctions.Instance.logg("use ablitiy: " + cardtoplay.GetEntity().GetName() + " target nothing");
                        return(new HREngine.API.Actions.PlayCardAction(cardtoplay));
                    }
                }
            }
            catch (Exception Exception)
            {
                Helpfunctions.Instance.ErrorLog(Exception.Message);
                Helpfunctions.Instance.ErrorLog(Environment.StackTrace);
                if (Settings.Instance.learnmode)
                {
                    return(new HREngine.API.Actions.MakeNothingAction());
                }
            }
            return(null);
            //HRBattle.FinishRound();
        }
Example #8
0
        protected override ActionBase PlayCardsToField()
        {
            var EnemyState = new PlayerState(HRPlayer.GetEnemyPlayer());
            var LocalState = new PlayerState(HRPlayer.GetLocalPlayer());
            var Sorting    = new Sorting();

            // Retreive cards that can be played.
            List <HRCard> playableList =
                GetPlayableCards(HRCard.GetCards(HRPlayer.GetLocalPlayer(), HRCardZone.HAND));

            // Update list with conditions matching this custom class.
            GetConditionalCards(playableList, EnemyState, LocalState);

            // Sort by cost (ascending)
            Sorting.SortByCost(ref playableList);

            // Finally sort by custom priority
            playableList = SortByPriority(playableList);

            // Taunts
            if (LocalState.TauntMinions.Count == 0)
            {
                foreach (var minion in playableList)
                {
                    HREntity Target = null;
                    if (minion.GetEntity().HasTaunt() &&
                        CanHandleCard(minion, EnemyState, LocalState, ref Target))
                    {
                        return(new PlayCardAction(minion, Target));
                    }
                }
            }

            // Charges
            foreach (var minion in playableList)
            {
                HREntity Target = null;
                if (minion.GetEntity().HasCharge() &&
                    CanHandleCard(minion, EnemyState, LocalState, ref Target))
                {
                    return(new PlayCardAction(minion, Target));
                }
            }

            // All other available
            foreach (var minion in playableList)
            {
                HREntity Target = null;
                if (CanHandleCard(minion, EnemyState, LocalState, ref Target))
                {
                    return(new PlayCardAction(minion, Target));
                }
            }

            // Use Hero Power that make sense at last...
            if (LocalState.Player.GetHeroPower().GetCost() <= LocalState.Mana)
            {
                if (LocalState.Player.GetHero().GetClass() == HRClass.HUNTER)
                {
                    if (HRBattle.CanUseCard(LocalState.Player.GetHeroPower()))
                    {
                        return(new PlayCardAction(LocalState.Player.GetHeroPower().GetCard()));
                    }
                }
            }

            if (LocalState.Player.HasWeapon())
            {
                if (HRBattle.CanUseCard(LocalState.Player.GetHeroCard().GetEntity()))
                {
                    return(new AttackAction(LocalState.Player.GetWeaponCard().GetEntity(), GetNextAttackToAttack()));
                }
            }

            return(null);
        }
Example #9
0
        protected virtual HREngine.API.Actions.ActionBase UpdateBattleState()
        {
            HREngine.API.Actions.ActionBase result = NextFixedAction;

            if (result != null)
            {
                NextFixedAction = null;
                return(result);
            }

            // If a previous action was not handled successful the Bot remains
            // in target mode.
            // Target here with 'LastTarget'. If the specified Target is null
            // the bot automatically selects the best target based on a rule
            // or enemy condition.
            if (HRBattle.IsInTargetMode())
            {
                HRLog.Write("Targeting...");
                HREntity TargetEntity = PlayCardAction.LastTarget;
                if (TargetEntity == null)
                {
                    HRCardManager.GetTargetForCard(PlayCardAction.LastPlayedCard);
                    if (TargetEntity == null)
                    {
                        TargetEntity = GetNextAttackToAttack();
                    }
                }
                return(new TargetAction(TargetEntity));
            }

            var localPlayerState = new PlayerState(HRPlayer.GetLocalPlayer());
            var enemyPlayerState = new PlayerState(HRPlayer.GetEnemyPlayer());

            // Fix: Druid: doesn't attack (and even other)
            // https://github.com/Hearthcrawler/HREngine/issues/40
            if (!localPlayerState.Player.HasWeapon() &&
                localPlayerState.Player.GetHero().CanAttack() &&
                localPlayerState.Player.GetHero().GetATK() > 0 &&
                HRBattle.CanUseCard(localPlayerState.Player.GetHero()))
            {
                return(new AttackAction(
                           localPlayerState.Player.GetHero(), GetNextAttackToAttack()));
            }

            if (!enemyPlayerState.Player.HasATauntMinion())
            {
                if (enemyPlayerState.Player.GetHero().CanBeAttacked())
                {
                    var current = PlayerState.GetPossibleAttack(
                        localPlayerState.Player, enemyPlayerState.Health);

                    if (current.Attack >= enemyPlayerState.Health)
                    {
                        if (current.Cards.Count > 0)
                        {
                            return(new AttackAction(current.Cards[0], enemyPlayerState.Player.GetHero()));
                        }
                    }
                }
            }

            if (IsDefaultHealingEnabled())
            {
                if (localPlayerState.Player.GetHero().GetClass() == HRClass.PRIEST)
                {
                    if (localPlayerState.Player.GetHeroPower().GetCost() <= localPlayerState.Mana)
                    {
                        if (localPlayerState.Health <= 17)
                        {
                            if (HRBattle.CanUseCard(localPlayerState.Player.GetHeroPower()))
                            {
                                return(new PlayCardAction(
                                           localPlayerState.Player.GetHeroPower().GetCard(),
                                           HRPlayer.GetLocalPlayer().GetHero()));
                            }
                        }
                        else
                        {
                            // FIX: Heal minions if possible
                            // https://github.com/Hearthcrawler/HREngine/issues/27
                            foreach (var item in localPlayerState.ReadyMinions)
                            {
                                if (item.GetRemainingHP() < item.GetHealth())
                                {
                                    // Heal damaged minions...
                                    if (HRBattle.CanUseCard(localPlayerState.Player.GetHeroPower()))
                                    {
                                        return(new PlayCardAction(
                                                   localPlayerState.Player.GetHeroPower().GetCard(),
                                                   HRPlayer.GetLocalPlayer().GetHero()));
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // Next cards to push...
            if (HRPlayer.GetLocalPlayer().GetNumFriendlyMinionsInPlay() < 7)
            {
                result = PlayCardsToField();
                if (result != null)
                {
                    return(result);
                }
                else
                {
                    // There are no cards to play..
                    if (localPlayerState.Player.GetHero().GetClass() == HRClass.WARLOCK)
                    {
                        // Can we use our hero power?
                        // Warlock should not suicide.
                        // FIX: https://github.com/Hearthcrawler/HREngine/issues/30
                        if (localPlayerState.Health >= 10)
                        {
                            // At least 3 mana left if we draw a card, okay?
                            if (localPlayerState.Player.GetHeroPower().GetCost() + 3 <= localPlayerState.Mana)
                            {
                                if (HRBattle.CanUseCard(localPlayerState.Player.GetHeroPower()))
                                {
                                    return(new PlayCardAction(localPlayerState.Player.GetHeroPower().GetCard()));
                                }
                            }
                        }
                    }
                }
            }

            // Priority: Always attack taunt minions first.
            if (enemyPlayerState.TauntMinions.Count > 0)
            {
                result = AttackTauntMinions(enemyPlayerState);
                if (result != null)
                {
                    return(result);
                }
            }

            // Bot does not attack when there is stealthed taunts
            // Fix: https://github.com/Hearthcrawler/HREngine/issues/60
            // If AttackTauntMinions() cannot attack because of stealthed - the action is null
            // and the bot should continue with default attack routine.
            //
            // Attack other minions or hero...
            result = Attack();
            if (result != null)
            {
                return(result);
            }

            // Use Hero Power that make sense at last...
            if (localPlayerState.Player.GetHeroPower().GetCost() <= localPlayerState.Mana)
            {
                switch (localPlayerState.Player.GetHero().GetClass())
                {
                case HRClass.DRUID:
                case HRClass.WARRIOR:
                case HRClass.MAGE:
                case HRClass.PALADIN:
                case HRClass.HUNTER:
                case HRClass.SHAMAN:
                case HRClass.ROGUE:
                {
                    if (HRBattle.CanUseCard(localPlayerState.Player.GetHeroPower()))
                    {
                        return(new PlayCardAction(localPlayerState.Player.GetHeroPower().GetCard()));
                    }
                }
                break;

                default:
                    break;
                }
            }

            return(null);
        }