Esempio n. 1
0
        /// <summary>
        /// Generate a play action for current scene.
        /// </summary>
        /// <param name="scene">The scene.</param>
        /// <returns>The cards to be played.</returns>
        public RockAction GetPlayAction(RockScene scene)
        {
            this.tracer.Verbose(RockJsonSerializer.Serialize(scene));

            try
            {
                if (string.IsNullOrEmpty(this.configuration.BotEndpoint))
                {
                    var robot  = new Bot.RockBot();
                    var action = robot.GetPlayAction(scene);
                    this.tracer.Verbose(RockJsonSerializer.Serialize(action));
                    return(action);
                }
                else
                {
                    var apiClient = new RockApiClient();
                    var action    = apiClient.Post <RockAction>($"{this.configuration.BotEndpoint}{RockConstants.DefaultBotPlayRelativePath}", scene);
                    this.tracer.Verbose(RockJsonSerializer.Serialize(action));
                    return(action);
                }
            }
            catch (Exception e)
            {
                this.tracer.Error($"Unexpected Exception from Bot: {e}");
                return(RockAction.Create());
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Generate a play action for current scene.
        /// </summary>
        /// <param name="scene">The scene.</param>
        /// <returns>The cards to be played.</returns>
        public RockAction GetPlayAction(RockScene scene)
        {
            // You can just return an null or empty list, which means ends turn.
            //// return null;

            //// Put your codes in here.

            RockSceneContext context = new RockSceneContext(scene);

            double     bestScore  = 0d;
            List <int> bestAction = null;
            Random     r          = new Random();

            foreach (List <int> action in scene.PlayOptions)
            {
                double score = PlayActionScore.ComputeScore(context, action);

                score += r.NextDouble();
                if (score >= bestScore)
                {
                    bestScore  = score;
                    bestAction = action;
                }
            }

            if (bestAction != null)
            {
                return(RockAction.Create(bestAction));
            }

            return(this.DefaultGetPlayAction(scene));
        }
Esempio n. 3
0
 /// <summary>
 /// The default implementation of GetPlayAction
 /// </summary>
 /// <param name="scene">the scene</param>
 /// <returns>the cards to be played</returns>
 private RockAction DefaultGetPlayAction(RockScene scene)
 {
     if (scene.PlayOptions.Count == 0)
     {
         return(RockAction.Create());
     }
     else
     {
         // this smart bot will randomly choose an play action.
         return(RockAction.Create(scene.PlayOptions[new Random().Next(0, scene.PlayOptions.Count)]));
     }
 }
Esempio n. 4
0
        public void TestRockActionFactoryMethods()
        {
            var action = RockAction.Create(new List <int>());

            Assert.AreEqual(action.Version, 1);
            Assert.AreEqual(action.Objects.Count, 0);
            Assert.AreEqual(action.Slot, -1);

            action = RockAction.Create(new List <int>(), 2);
            Assert.AreEqual(action.Version, 1);
            Assert.AreEqual(action.Objects.Count, 0);
            Assert.AreEqual(action.Slot, 2);
        }
Esempio n. 5
0
        /// <summary>
        /// The default implementation of GetMulliganAction
        /// </summary>
        /// <param name="scene">the scene</param>
        /// <returns>the cards to be mulligan-ed</returns>
        private RockAction DefaultGetMulliganAction(RockScene scene)
        {
            List <int> cards = new List <int>();

            foreach (RockCard card in scene.Self.Cards)
            {
                if (card.Cost >= 4)
                {
                    cards.Add(card.RockId);
                }
            }

            return(RockAction.Create(cards));
        }
Esempio n. 6
0
 /// <summary>
 /// Sets the action that this rock causes to the player, based on its size
 /// </summary>
 private void SetRockAction_()
 {
     // if big enough, the rock will knock player over
     if (_sizeFactor > 0.5f)
     {
         _action = RockAction.KnockDown;
     }
     // if medium sized, player is knocked back, but not disabled
     else if (_sizeFactor > 0.35f)
     {
         _action = RockAction.KnockBack;
     }
     // if small, power up is lost
     else if (_sizeFactor >= 0.3f)
     {
         _action = RockAction.LosePowerUp;
     }
 }
Esempio n. 7
0
        public static RockAction RockIt()
        {
            RockAction action = new RockAction();

            Player player = GameState.Get().GetFriendlySidePlayer();
            Player player_enemy = GameState.Get().GetFirstOpponentPlayer(GameState.Get().GetFriendlySidePlayer());
            Card hero = player.GetHeroCard();
            Card hero_enemy = player_enemy.GetHeroCard();
            int resource = player.GetNumAvailableResources();

            List<Card> crads = player.GetHandZone().GetCards();
            List<Card> minions = player.GetBattlefieldZone().GetCards();
            List<Card> minions_enemy = player_enemy.GetBattlefieldZone().GetCards();
            Card heropower = player.GetHeroPowerCard();

            // find best match taunt attacker
            List<Card> minion_taunts_enemy = new List<Card>();
            List<Card> minion_dangerous_enemy = new List<Card>();
            List<Card> minion_notaunts = new List<Card>();
            List<Card> minion_taunts = new List<Card>();
            List<Card> minion_attacker = new List<Card>();

            int attack_count_enemy = 0;
            foreach (Card minion_enemy in minions_enemy)
            {
                attack_count_enemy += minion_enemy.GetEntity().GetATK();
                if (minion_enemy.GetEntity().HasWindfury())
                {
                    attack_count_enemy += minion_enemy.GetEntity().GetATK();
                }
            }
            attack_count_enemy += hero_enemy.GetEntity().GetATK();

            foreach (Card card_oppo in minions_enemy)
            {
                if (card_oppo.GetEntity().CanBeAttacked() && !card_oppo.GetEntity().IsStealthed())
                {
                    if (card_oppo.GetEntity().HasTaunt())
                    {
                        minion_taunts_enemy.Add(card_oppo);
                    }
                    else if (IsEnimyDangerous(card_oppo.GetEntity()))
                    {
                        minion_dangerous_enemy.Add(card_oppo);
                    }
                }
            }

            foreach (Card card in minions)
            {
                if (card.GetEntity().CanAttack() && !card.GetEntity().IsExhausted() && !card.GetEntity().IsFrozen() && !card.GetEntity().IsAsleep() && card.GetEntity().GetATK() > 0)
                {
                    if (card.GetEntity().HasTaunt())
                    {
                        minion_taunts.Add(card);
                    }
                    else
                    {
                        minion_notaunts.Add(card);
                    }
                    minion_attacker.Add(card);
                }
            }

            minions_enemy.Sort(new CardPowerComparer());
            minion_taunts_enemy.Sort(new CardPowerComparer());
            minion_notaunts.Sort(new CardPowerComparer());
            minion_notaunts.Reverse();
            minion_taunts.Sort(new CardPowerComparer());
            minion_taunts.Reverse();
            minion_attacker.Sort(new CardPowerComparer());
            minion_attacker.Reverse();

            // PlayEmergencyCard
            RockAction action_temp = PlayEmergencyCard(resource, crads, hero, hero_enemy, attack_count_enemy);
            if (action_temp != null)
            {
                action = action_temp;
                return action;
            }

            // if coin necessory
            Card coin_card = null;
            bool need_coin_card = false;
            foreach (Card card in crads)
            {
                if (card.GetEntity().GetCardId() == "GAME_005")
                {
                    coin_card = card;
                    continue;
                }
                if (resource == card.GetEntity().GetCost() - 1)
                {
                    need_coin_card = true;
                }
            }

            // use coin
            if (coin_card != null && need_coin_card)
            {
                action.type = HEARTHROCK_ACTIONTYPE.PLAY;
                action.card1 = coin_card;
                return action;
            }

            // PlayEmergencyCard  again
            action_temp = PlayEmergencyCard(resource, crads, hero, hero_enemy, attack_count_enemy);
            if (action_temp != null)
            {
                action = action_temp;
                return action;
            }

            // use as much spell as possible
            foreach (Card card in crads)
            {
                // but not the coin
                if (card.GetEntity().GetCardId() == "GAME_005")
                {
                    continue;
                }
                if (resource < card.GetEntity().GetCost())
                {
                    continue;
                }
                if (card.GetEntity().IsSpell() || card.GetEntity().IsWeapon())
                {
                    action.type = HEARTHROCK_ACTIONTYPE.PLAY;
                    action.card1 = card;
                    return action;
                }
            }

            // find a minion which can use all resource
            foreach (Card card in crads)
            {
                if (resource < card.GetEntity().GetCost())
                {
                    continue;
                }
                if (card.GetEntity().IsMinion() && GameState.Get().GetFriendlySidePlayer().GetBattlefieldZone().GetCards().Count < 6 && (card.GetEntity().GetCost() == resource || ((card.GetEntity().GetCost() == resource - 2) && HeroSpellReady)))
                {
                    action.type = HEARTHROCK_ACTIONTYPE.PLAY;
                    action.card1 = card;
                    return action;
                }
            }

            // find a minion which can use all resource
            foreach (Card card in crads)
            {
                if (resource < card.GetEntity().GetCost())
                {
                    continue;
                }

                if (card.GetEntity().IsMinion() && GameState.Get().GetFriendlySidePlayer().GetBattlefieldZone().GetCards().Count < 6)
                {
                    action.type = HEARTHROCK_ACTIONTYPE.PLAY;
                    action.card1 = card;
                    return action;
                }
                if (card.GetEntity().IsMinion() && GameState.Get().GetFriendlySidePlayer().GetBattlefieldZone().GetCards().Count == 6)
                {
                    if (card.GetEntity().HasCharge() || card.GetEntity().HasTaunt())
                    {
                        action.type = HEARTHROCK_ACTIONTYPE.PLAY;
                        action.card1 = card;
                        return action;
                    }
                }
            }

            // begin attack
            { // deal with his taunts
                // PlayKill  notaunts > taunts
                action_temp = PlayKill(minion_taunts_enemy, minion_notaunts);
                if (action_temp != null)
                {
                    action = action_temp;
                    return action;
                }

                // PlayKill  taunts > taunts
                action_temp = PlayKill(minion_taunts_enemy, minion_taunts);
                if (action_temp != null)
                {
                    action = action_temp;
                    return action;
                }

                //deal damage with no taunt
                foreach (Card card_oppo in minion_taunts_enemy)
                {
                    foreach (Card card in minion_notaunts)
                    {
                        action.type = HEARTHROCK_ACTIONTYPE.ATTACK;
                        action.card1 = card;
                        action.card2 = card_oppo;
                        return action;
                    }
                }

                //deal damage with taunt
                foreach (Card card_oppo in minion_taunts_enemy)
                {
                    foreach (Card card in minion_taunts)
                    {
                        action.type = HEARTHROCK_ACTIONTYPE.ATTACK;
                        action.card1 = card;
                        action.card2 = card_oppo;
                        return action;
                    }
                }

            }

            { // deal with his dangerous
                // TODO: should check maybe i can kill him
                // PlayKill  notaunts > dangerous
                action_temp = PlayKill(minion_dangerous_enemy, minion_notaunts);
                if (action_temp != null)
                {
                    action = action_temp;
                    return action;
                }

                //deal damage with no taunt
                foreach (Card card_oppo in minion_dangerous_enemy)
                {
                    foreach (Card card in minion_notaunts)
                    {
                        action.type = HEARTHROCK_ACTIONTYPE.ATTACK;
                        action.card1 = card;
                        action.card2 = card_oppo;
                        return action;
                    }
                }
            }

            { // deal with enemy depends on my health
                // TODO: should check maybe i can kill him
                // no taunt, but in danger
                if (minion_taunts_enemy.Count == 0 && (hero.GetEntity().GetHealth() - attack_count_enemy) < 10)
                {
                    foreach (Card card_oppo in minions_enemy)
                    {
                        // find dangerous card
                        if (card_oppo.GetEntity().GetATK() - card_oppo.GetEntity().GetHealth() > 3)
                        {
                            foreach (Card card in minion_attacker)
                            {
                                // if can kill, kill
                                if (card.GetEntity().GetATK() >= card_oppo.GetEntity().GetHealth())
                                {
                                    action.type = HEARTHROCK_ACTIONTYPE.ATTACK;
                                    action.card1 = card;
                                    action.card2 = card_oppo;
                                    return action;
                                }
                            }
                        }
                    }
                }

                // no taunt, but in great danger
                if (minion_taunts_enemy.Count == 0 && (hero.GetEntity().GetHealth() - attack_count_enemy) < 0)
                {
                    foreach (Card card_oppo in minions_enemy)
                    {
                        // find dangerous card
                        if (card_oppo.GetEntity().GetATK() - card_oppo.GetEntity().GetHealth() > 1)
                        {
                            foreach (Card card in minion_attacker)
                            {
                                if (card.GetEntity().GetATK() > card_oppo.GetEntity().GetATK())
                                {
                                    continue;
                                }
                                // if can kill, kill
                                if (card.GetEntity().GetATK() >= card_oppo.GetEntity().GetHealth())
                                {
                                    action.type = HEARTHROCK_ACTIONTYPE.ATTACK;
                                    action.card1 = card;
                                    action.card2 = card_oppo;
                                    return action;
                                }
                            }
                        }
                    }
                }
            } // END deal with enemy depends on my health

            // attack his face!
            foreach (Card card in minions)
            {
                if (card.GetEntity().CanAttack() && !card.GetEntity().IsExhausted() && !card.GetEntity().IsFrozen() && !card.GetEntity().IsAsleep() && card.GetEntity().GetATK() > 0)
                {
                    foreach (Card card_oppo in minions_enemy)
                    {
                        // for bug, should noy run
                        if (card_oppo.GetEntity().HasTaunt())
                        {
                            action.type = HEARTHROCK_ACTIONTYPE.ATTACK;
                            action.card1 = card;
                            action.card2 = card_oppo;
                            return action;
                        }
                    }
                    action.type = HEARTHROCK_ACTIONTYPE.ATTACK;
                    action.card1 = card;
                    action.card2 = player_enemy.GetHeroCard();
                    return action;
                }

            }

            // deal with hero weapon and atk
            HearthrockEngine.Log("HasWeapon " + player.HasWeapon());
            if (player.HasWeapon())
            {
                HearthrockEngine.Log("HasWeapon CanAttack " + player.GetWeaponCard().GetEntity().CanAttack());
            }
            if (minion_taunts_enemy.Count == 0 && player.HasWeapon() && player.GetWeaponCard().GetEntity().CanAttack())
            {
                action.type = HEARTHROCK_ACTIONTYPE.ATTACK;
                action.card1 = player.GetWeaponCard();
                action.card2 = player_enemy.GetHeroCard();
                return action;
            }

            Entity me = player.GetHeroCard().GetEntity();
            if (minion_taunts_enemy.Count == 0 && me.CanAttack() && me.GetATK() > 0)
            {
                action.type = HEARTHROCK_ACTIONTYPE.ATTACK;
                action.card1 = player.GetHeroCard();
                action.card2 = player_enemy.GetHeroCard();
                return action;
            }

            if (resource >= 2 && HeroSpellReady)
            {
                HeroSpellReady = false;
                TAG_CLASS hero_class = player.GetHeroCard().GetEntity().GetClass();
                switch (hero_class)
                {
                    case TAG_CLASS.WARLOCK:
                        if (crads.Count > 8)
                        {
                            return action;
                        }
                        if (hero.GetEntity().GetRemainingHP() < 5)
                        {
                            return action;
                        }
                        else if (hero.GetEntity().GetRemainingHP() < 12)
                        {

                            if (attack_count_enemy + 2 > hero.GetEntity().GetRemainingHP())
                            {
                                return action;
                            }
                            else
                            {
                                action.type = HEARTHROCK_ACTIONTYPE.PLAY;
                                action.card1 = heropower;
                                return action;
                            }
                        }
                        else
                        {
                            action.type = HEARTHROCK_ACTIONTYPE.PLAY;
                            action.card1 = heropower;
                            return action;
                        }
                    case TAG_CLASS.HUNTER:
                    case TAG_CLASS.DRUID:
                    case TAG_CLASS.PALADIN:
                    case TAG_CLASS.ROGUE:
                    case TAG_CLASS.SHAMAN:
                    case TAG_CLASS.WARRIOR:
                        action.type = HEARTHROCK_ACTIONTYPE.PLAY;
                        action.card1 = heropower;
                        return action;
                    case TAG_CLASS.PRIEST:
                        action.type = HEARTHROCK_ACTIONTYPE.ATTACK;
                        action.card1 = heropower;
                        action.card2 = player.GetHeroCard();
                        return action;
                    case TAG_CLASS.MAGE:
                        action.type = HEARTHROCK_ACTIONTYPE.ATTACK;
                        action.card1 = heropower;
                        action.card2 = player_enemy.GetHeroCard();
                        return action;
                    default:
                        break;
                }
            }
            return action;
        }
Esempio n. 8
0
        private static RockAction PlayKill(List<Card> minion_target, List<Card> minion_attacker)
        {
            RockAction action = new RockAction();
            Card target_best = null;
            Card attacker_best = null;

            //find taunt kill attacker
            foreach (Card card_oppo in minion_target)
            {
                foreach (Card card in minion_attacker)
                {
                    if (card_oppo.GetEntity().GetRemainingHP() <= card.GetEntity().GetATK())
                    {
                        if (target_best == null)
                        {
                            target_best = card_oppo;
                            attacker_best = card;
                        }
                        else
                        {
                            if (attacker_best.GetEntity().GetATK() > card.GetEntity().GetATK())
                            {
                                attacker_best = card;
                            }
                        }
                    }
                }

                if (target_best != null)
                {
                    action.type = HEARTHROCK_ACTIONTYPE.ATTACK;
                    action.card1 = attacker_best;
                    action.card2 = target_best;
                    return action;
                }
            }
            return null;
        }
Esempio n. 9
0
        private static RockAction PlayEmergencyCard(int resource, List<Card> crads, Card hero, Card hero_enemy, int attack_count_enemy)
        {
            RockAction action = new RockAction();

            // best fit taunt
            foreach (Card card in crads)
            {
                if (resource < card.GetEntity().GetCost())
                {
                    continue;
                }
                if (card.GetEntity().IsMinion() && card.GetEntity().HasTaunt() && GameState.Get().GetFriendlySidePlayer().GetBattlefieldZone().GetCards().Count < 7 && (card.GetEntity().GetCost() == resource || ((card.GetEntity().GetCost() == resource - 2) && HeroSpellReady)))
                {
                    action.type = HEARTHROCK_ACTIONTYPE.PLAY;
                    action.card1 = card;
                    return action;
                }
            }

            // if hero has less health, need more emergency taunt
            if ((hero.GetEntity().GetHealth() - attack_count_enemy) < 10)
            {
                // not perfect fit taunt
                foreach (Card card in crads)
                {

                    if (resource < card.GetEntity().GetCost())
                    {
                        continue;
                    }
                    // waste a cost
                    if (card.GetEntity().IsMinion() && card.GetEntity().HasTaunt() && GameState.Get().GetFriendlySidePlayer().GetBattlefieldZone().GetCards().Count < 7 && (card.GetEntity().GetCost() == resource - 1 || ((card.GetEntity().GetCost() == resource - 3) && HeroSpellReady)))
                    {
                        action.type = HEARTHROCK_ACTIONTYPE.PLAY;
                        action.card1 = card;
                        return action;
                    }
                }
            }

            // if hero has more health, play as much charge as possible
            if ((hero.GetEntity().GetHealth() - hero_enemy.GetEntity().GetHealth()) > 10)
            {
                foreach (Card card in crads)
                {
                    if (resource < card.GetEntity().GetCost())
                    {
                        continue;
                    }

                    // waste a cost
                    if (card.GetEntity().IsMinion() && GameState.Get().GetFriendlySidePlayer().GetBattlefieldZone().GetCards().Count < 7)
                    {
                        if (card.GetEntity().HasCharge())
                        {
                            action.type = HEARTHROCK_ACTIONTYPE.PLAY;
                            action.card1 = card;
                            return action;
                        }
                    }
                }
            }
            return null;
        }
Esempio n. 10
0
 private void OnRockTurnStart()
 {
     HoldBack(5000);
     ActionRocking = null;
     TurnReady = true;
     SingletonEndTurn = false;
     //
     OnRocking = false;
 }
Esempio n. 11
0
 private void OnRockTurnEnd()
 {
     if (SingletonEndTurn) return;
     SingletonEndTurn = true;
     HoldBack(3000);
     Notify("Job's Done!");
     ActionRocking = null;
     TurnReady = false;
     HearthrockRobot.RockEnd();
     InputManager.Get().DoEndTurnButton();
     //
     OnRocking = false;
 }
Esempio n. 12
0
        private void OnRockAI()
        {
            if (OnRocking) return;
            OnRocking = true;

            try
            {

                if (ActionRocking != null && ActionRocking.step == -1)
                {
                    ActionRocking = null;
                }
                if (ActionRocking != null)
                {
                    try
                    {
                        OnAction(ActionRocking);
                    }
                    catch
                    {
                        ActionRocking = null;
                    }
                    return;
                }

                // ActionRocking = should be null;

                HoldBack(250);
                if (EndTurnButton.Get().HasNoMorePlays())
                {
                    OnRockTurnEnd();
                    return;
                }

                RockAction action = HearthrockRobot.RockIt();
                if (action.type == HEARTHROCK_ACTIONTYPE.PLAY)
                {
                    SingletonEndTurn = false;
                    Notify("Play: " + action.card1.GetEntity().GetName());
                    ActionRocking = action;
                }
                else if (action.type == HEARTHROCK_ACTIONTYPE.ATTACK)
                {
                    SingletonEndTurn = false;
                    Notify("Attack: " + action.card1.GetEntity().GetName() + " > " + action.card2.GetEntity().GetName());
                    ActionRocking = action;
                }
                else
                {
                    OnRockTurnEnd();
                }

            }
            catch (Exception e){
                Log("OnRockAI ex " + e.ToString());
            }
            finally
            {
                OnRocking = false;
            }
        }
Esempio n. 13
0
        private void OnAction(RockAction action)
        {
            System.Random r = new System.Random();

            if (action.step == 0)
            {
                int delay = r.Next(400, 600);
                HoldBack(delay);
                /*
                Spell spell = action.card1.GetBattlecrySpell();
                if (spell != null)
                {
                }
                else
                {
                    Notify("No Spell ");
                }
                */

                //bool x = GameState.Get().HasResponse(action.card1.GetEntity());

                HearthstoneClickCard(action.card1);
                action.step = 1;
            }
            else if (action.step == 1)
            {
                int delay = r.Next(300, 600);
                if (action.type == HEARTHROCK_ACTIONTYPE.ATTACK)
                {
                    delay += 400;
                }
                HoldBack(delay);
                if (action.type == HEARTHROCK_ACTIONTYPE.PLAY)
                {
                    InputManager input_mgr = InputManager.Get();
                    input_mgr.DropHeldCard();
                    //MethodInfo dynMethod = input_mgr.GetType().GetMethod("DropHeldCard", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { }, null);
                    //dynMethod.Invoke(input_mgr, new object[] { });
                    action.step = 2;
                }
                else if (action.type == HEARTHROCK_ACTIONTYPE.ATTACK)
                {
                    HearthstoneClickCard(action.card2);
                    action.step = -1;
                }
            }
            else if (action.step == 2)
            {
                action.step = -1;
                return;
                // maybe can do sth to deal with card with spell
                if (InputManager.Get().heldObject == null)
                {
                    action.step = -1;
                    return;
                }
                int delay = r.Next(300, 600);
                HoldBack(delay);
                if (action.type == HEARTHROCK_ACTIONTYPE.PLAY)
                {
                    action.step = -1;
                }
            }
        }
Esempio n. 14
0
 private void ClearGameState()
 {
     MulliganState = 0;
     TurnReady = false;
     ActionRocking = null;
     OnRocking = false;
 }