public static List <PlayerTask> OptionsOnlyMinionAttacksAndHeroAttacks(Game game1, int playerid)
        {
            List <PlayerTask> result = new List <PlayerTask>();

            result.Add(EndTurnTask.Any(game1.ControllerById(playerid)));
            foreach (Minion minion in game1.ControllerById(playerid).BoardZone)
            {
                if (!minion.CanAttack)
                {
                    continue;
                }

                IEnumerable <ICharacter> targets = minion.ValidAttackTargets;
                foreach (ICharacter target in targets)
                {
                    result.Add(MinionAttackTask.Any(game1.ControllerById(playerid), minion, target));
                }
            }

            if (game1.CurrentPlayer.Hero.CanAttack)
            {
                IEnumerable <ICharacter> targets = game1.CurrentPlayer.Hero.ValidAttackTargets;
                foreach (ICharacter target in targets)
                {
                    result.Add(HeroAttackTask.Any(game1.ControllerById(playerid), target));
                }
            }

            return(result);
        }
Esempio n. 2
0
        public static PlayerTask KettleOptionToPlayerTask(Game Game, int sendOptionId, int sendOptionMainOption, int sendOptionTarget, int sendOptionPosition, int sendOptionSubOption)
        {
            SabberStoneCore.Kettle.PowerAllOptions allOptions = Game.AllOptionsMap[sendOptionId];
            Console.WriteLine(allOptions.Print());

            List <PlayerTask> tasks = allOptions.PlayerTaskList;

            SabberStoneCore.Kettle.PowerOption powerOption = allOptions.PowerOptionList[sendOptionMainOption];
            OptionType optionType = powerOption.OptionType;

            PlayerTask task = null;

            switch (optionType)
            {
            case OptionType.END_TURN:
                task = EndTurnTask.Any(Game.CurrentPlayer);
                break;

            case OptionType.POWER:

                SabberStoneCore.Kettle.PowerSubOption mainOption = powerOption.MainOption;
                IPlayable source = Game.IdEntityDic[mainOption.EntityId];
                IPlayable target = sendOptionTarget > 0 ? Game.IdEntityDic[sendOptionTarget] : null;
                List <SabberStoneCore.Kettle.PowerSubOption> subObtions = powerOption.SubOptions;

                if (source.Zone?.Type == Zone.PLAY)
                {
                    task = MinionAttackTask.Any(Game.CurrentPlayer, source, target);
                }
                else
                {
                    switch (source.Card.Type)
                    {
                    case CardType.HERO:
                        task = HeroAttackTask.Any(Game.CurrentPlayer, target);
                        break;

                    case CardType.HERO_POWER:
                        task = HeroPowerTask.Any(Game.CurrentPlayer, target);
                        break;

                    default:
                        task = PlayCardTask.Any(Game.CurrentPlayer, source, target, sendOptionPosition,
                                                sendOptionSubOption);
                        break;
                    }
                }
                break;

            case OptionType.PASS:
                break;

            default:
                throw new NotImplementedException();
            }
            return(task);
        }
Esempio n. 3
0
        public static PlayerTask CreatePlayerTaskOption(Game game, PowerOption powerOption, int sendOptionTarget, int sendOptionPosition, int sendOptionSubOption)
        {
            //var allOptions = _game.AllOptionsMap[sendOptionId];
            //var tasks = allOptions.PlayerTaskList;
            //var powerOption = allOptions.PowerOptionList[sendOptionMainOption];
            var optionType = powerOption.OptionType;

            PlayerTask task = null;

            switch (optionType)
            {
            case OptionType.END_TURN:
                task = EndTurnTask.Any(game.CurrentPlayer);
                break;

            case OptionType.POWER:
                var mainOption = powerOption.MainOption;
                var source     = game.IdEntityDic[mainOption.EntityId];
                var target     = sendOptionTarget > 0 ? (ICharacter)game.IdEntityDic[sendOptionTarget] : null;
                var subObtions = powerOption.SubOptions;

                if (source.Zone?.Type == Zone.PLAY)
                {
                    task = MinionAttackTask.Any(game.CurrentPlayer, source, target);
                }
                else
                {
                    switch (source.Card.Type)
                    {
                    case CardType.HERO:
                        task = target != null
                                    ? (PlayerTask)HeroAttackTask.Any(game.CurrentPlayer, target)
                                    : PlayCardTask.Any(game.CurrentPlayer, source);
                        break;

                    case CardType.HERO_POWER:
                        task = HeroPowerTask.Any(game.CurrentPlayer, target);
                        break;

                    default:
                        task = PlayCardTask.Any(game.CurrentPlayer, source, target, sendOptionPosition, sendOptionSubOption);
                        break;
                    }
                }
                break;

            case OptionType.PASS:
                break;

            default:
                throw new NotImplementedException();
            }

            //Log.Info($"{task?.FullPrint()}");

            return(task);
        }
Esempio n. 4
0
        public static PlayerTask GetPlayerTask(Option option, Game g)
        {
            const bool SkipPrePhase = true;
            Controller c            = g.CurrentPlayer;

            switch (option.Type)
            {
            case Choose:
                return(ChooseTask.Pick(c, option.Choice));

            case Concede:
                return(ConcedeTask.Any(c));

            case EndTurn:
                return(EndTurnTask.Any(c));

            case HeroAttack:
                return(HeroAttackTask.Any(c, GetOpponentTarget(option.TargetPosition), SkipPrePhase));

            case Option.Types.PlayerTaskType.HeroPower:
                return(HeroPowerTask.Any(c, GetTarget(option.TargetPosition), option.SubOption, SkipPrePhase));

            case MinionAttack:
                return(MinionAttackTask.Any(c, c.BoardZone[option.SourcePosition - 1], GetOpponentTarget(option.TargetPosition), SkipPrePhase));

            case PlayCard:
                IPlayable source = c.HandZone[option.SourcePosition];
                if (source.Card.Type == CardType.MINION)
                {
                    return(PlayCardTask.Any(c, source, null, option.TargetPosition - 1, option.SubOption, SkipPrePhase));
                }
                else
                {
                    return(PlayCardTask.Any(c, source, GetTarget(option.TargetPosition),
                                            0, option.SubOption, SkipPrePhase));
                }

            default:
                throw new ArgumentOutOfRangeException();
            }

            ICharacter GetOpponentTarget(int position)
            {
                if (position == Option.OP_HERO_POSITION)
                {
                    return(c.Opponent.Hero);
                }
                return(c.Opponent.BoardZone[position - 9]);
            }

            ICharacter GetTarget(int position)
            {
                if (position == -1)
                {
                    return(null);
                }
                if (position >= Option.OP_HERO_POSITION)
                {
                    return(GetOpponentTarget(position));
                }
                if (position == Option.HERO_POSITION)
                {
                    return(c.Hero);
                }
                return(c.BoardZone[position - 1]);
            }
        }
        public PlayerTask ProcessPowerOptionsData(int sendOptionId, int sendOptionMainOption, int sendOptionTarget, int sendOptionPosition, int sendOptionSubOption)
        {
            var allOptions = _game.AllOptionsMap[sendOptionId];

            var tasks = allOptions.PlayerTaskList;

            var powerOption = allOptions.PowerOptionList[sendOptionMainOption];
            var optionType  = powerOption.OptionType;

            PlayerTask task = null;

            switch (optionType)
            {
            case OptionType.END_TURN:
                task = EndTurnTask.Any(_game.CurrentPlayer);
                break;

            case OptionType.POWER:
                var mainOption = powerOption.MainOption;
                var source     = _game.IdEntityDic[mainOption.EntityId];
                var target     = sendOptionTarget > 0 ? (ICharacter)_game.IdEntityDic[sendOptionTarget] : null;
                var subObtions = powerOption.SubOptions;

                if (source.Zone?.Type == Zone.PLAY)
                {
                    task = MinionAttackTask.Any(_game.CurrentPlayer, source, target);
                }
                else
                {
                    switch (source.Card.Type)
                    {
                    case CardType.HERO:
                        if (target != null)
                        {
                            task = HeroAttackTask.Any(_game.CurrentPlayer, target);
                        }
                        else
                        {
                            task = PlayCardTask.Any(_game.CurrentPlayer, source);
                        }
                        break;

                    case CardType.HERO_POWER:
                        task = HeroPowerTask.Any(_game.CurrentPlayer, target);
                        break;

                    default:
                        task = PlayCardTask.Any(_game.CurrentPlayer, source, target, sendOptionPosition,
                                                sendOptionSubOption);
                        break;
                    }
                }
                break;

            case OptionType.PASS:
                break;

            default:
                throw new NotImplementedException();
            }

            return(task);
        }
Esempio n. 6
0
        /// <summary>
        /// Returns a set of all options this player can perform execute at the moment.
        /// From this set one option is picked and executed by the game.
        /// </summary>
        /// <param name="playCards"></param>
        /// <returns></returns>
        public List <PlayerTask> Options(bool playCards = true)
        {
            var result = new List <PlayerTask>();

            if (this != Game.CurrentPlayer)
            {
                return(result);
            }

            if (Choice != null)
            {
                switch (Choice.ChoiceType)
                {
                case ChoiceType.GENERAL:
                    Choice.Choices.ToList().ForEach(p => result.Add(ChooseTask.Pick(this, p)));
                    return(result);

                case ChoiceType.MULLIGAN:
                    IEnumerable <IEnumerable <int> > choices = Util.GetPowerSet(Choice.Choices);
                    choices.ToList().ForEach(p => result.Add(ChooseTask.Mulligan(this, p.ToList())));
                    return(result);

                default:
                    throw new NotImplementedException();
                }
            }

            // no options till mulligan is done for both players
            if (Game.Step != Step.MAIN_ACTION)
            {
                return(result);
            }

            // add end turn task ...
            result.Add(EndTurnTask.Any(this));

            if (playCards)
            {
                foreach (IPlayable playableCard in HandZone)
                {
                    var minion = playableCard as Minion;

                    if (!playableCard.IsPlayableByPlayer)
                    {
                        continue;
                    }

                    List <IPlayable> playables = playableCard.ChooseOne && !Game.CurrentPlayer.ChooseBoth
                                                ? playableCard.ChooseOnePlayables.ToList()
                                                : new List <IPlayable> {
                        playableCard
                    };

                    foreach (IPlayable t in playables)
                    {
                        if (!t.IsPlayableByCardReq)
                        {
                            continue;
                        }

                        var targets   = t.ValidPlayTargets.ToList();
                        var subResult = new List <PlayCardTask>();
                        if (!targets.Any())
                        {
                            subResult.Add(PlayCardTask.Any(this, playableCard, null, -1,
                                                           playables.Count == 1 ? 0 : playables.IndexOf(t) + 1));
                        }

                        subResult.AddRange(
                            targets.Select(
                                target =>
                                PlayCardTask.Any(this, playableCard, target, -1,
                                                 playables.Count == 1 ? 0 : playables.IndexOf(t) + 1)));

                        if (minion != null)
                        {
                            var tempSubResult = new List <PlayCardTask>();
                            int positions     = BoardZone.Count + 1;
                            for (int j = 0; j < positions; j++)
                            {
                                subResult.ForEach(p =>
                                {
                                    PlayCardTask task = p.Copy();
                                    task.ZonePosition = j;
                                    tempSubResult.Add(task);
                                });
                            }
                            subResult = tempSubResult;
                        }
                        result.AddRange(subResult);
                    }
                }
            }

            foreach (Minion minion in BoardZone)
            {
                if (!minion.CanAttack)
                {
                    continue;
                }

                IEnumerable <ICharacter> targets = minion.ValidAttackTargets;
                targets.ToList().ForEach(p => result.Add(MinionAttackTask.Any(this, minion, p)));
            }

            if (Hero.CanAttack)
            {
                IEnumerable <ICharacter> targets = Hero.ValidAttackTargets;
                targets.ToList().ForEach(p => result.Add(HeroAttackTask.Any(this, p)));
            }

            if (Hero.Power.IsPlayable)
            {
                var targets = Hero.Power.GetValidPlayTargets().ToList();
                if (targets.Any())
                {
                    targets.ToList().ForEach(p => result.Add(HeroPowerTask.Any(this, p)));
                }
                else
                {
                    result.Add(HeroPowerTask.Any(this));
                }
            }

            return(result);
        }
Esempio n. 7
0
        public override PlayerTask GetMove(POGame game)
        {
            if (SelectHeroPower)
            {
                SelectHeroPower = false;
                List <IPlayable> choices  = game.CurrentPlayer.Choice.Choices.Select(id => game.getGame().IdEntityDic[id]).ToList();
                string           selected = HeroPowerPriorities.choose(choices.Select(c => c.Card.Name).Distinct().ToList());
                return(ChooseTask.Pick(game.CurrentPlayer, choices.First(c => c.Card.Name == selected).Id));
            }

            int mana = game.CurrentPlayer.BaseMana + game.CurrentPlayer.TemporaryMana - game.CurrentPlayer.UsedMana;
            List <PlayerTask> options         = game.CurrentPlayer.Options();
            List <PlayerTask> heroPowers      = options.Where(t => t.PlayerTaskType == PlayerTaskType.HERO_POWER).ToList();
            List <PlayerTask> playCards       = options.Where(t => t.PlayerTaskType == PlayerTaskType.PLAY_CARD && t.Source.Card.Cost <= mana).ToList();
            List <Minion>     ourMinionsReady = game.Minions.Where(m => m.Controller.Id == game.CurrentPlayer.Id && m.CanAttack).ToList();

            if (game.CurrentPlayer.MulliganState == Mulligan.INPUT)
            {
                // mulligan
                List <IPlayable> choices = game.CurrentPlayer.Choice.Choices.Select(id => game.getGame().IdEntityDic[id]).ToList();
                choices = choices.Where(c => c.Cost <= 3 && c.Card.Name != "Patches the Pirate").ToList();
                return(ChooseTask.Mulligan(game.CurrentPlayer, choices.Select(c => c.Id).ToList()));
            }
            else if (playCards.Count != 0)
            {
                // play card
                List <string> cardNames = playCards.Select(c => c.Source.Card.Name).Distinct().ToList();

                string selectedCard;
                if (game.CurrentPlayer.Hero.Weapon != null)
                {
                    // we have a weapon
                    selectedCard = CardPrioritiesWithWeapon.choose(cardNames);
                }
                else
                {
                    // we don't have a weapon
                    selectedCard = CardPrioritiesNoWeapon.choose(cardNames);
                }

                if (selectedCard == "Sir Finley Mrrgglton")
                {
                    SelectHeroPower = true;
                }

                return(playCards.First(t => t.Source.Card.Name == selectedCard));
            }
            else if (game.CurrentPlayer.Hero.CanAttack)
            {
                // hero attack
                List <Minion> enemyMinions = game.Minions.Where(m => m.Controller.Id == game.CurrentOpponent.Id).ToList();
                List <Minion> enemyTaunts  = enemyMinions.Where(m => m.HasTaunt == true).ToList();

                if (enemyTaunts.Count != 0)
                {
                    return(HeroAttackTask.Any(game.CurrentPlayer, enemyTaunts[0]));
                }
                else
                {
                    return(HeroAttackTask.Any(game.CurrentPlayer, game.CurrentOpponent.Hero));
                }
            }
            else if (ourMinionsReady.Count != 0)
            {
                // minion attack
                List <Minion> enemyMinions = game.Minions.Where(m => m.Controller.Id == game.CurrentOpponent.Id).ToList();
                List <Minion> enemyTaunts  = enemyMinions.Where(m => m.HasTaunt == true).ToList();

                if (enemyTaunts.Count != 0)
                {
                    int tauntHealth = enemyTaunts[0].Health;
                    int tauntAttack = enemyTaunts[0].AttackDamage;

                    // perfectTraders: survive the attack, kill the Taunt and don't have more overkill/wasted damage than 2
                    List <Minion> perfectTraders = ourMinionsReady.Where(m => m.Health > tauntAttack && m.AttackDamage >= tauntHealth && m.AttackDamage <= (tauntHealth + 2)).ToList();

                    // almost perfect Traders: survive the attack and kill the Taunt
                    List <Minion> almostPerfectTraders = ourMinionsReady.Where(m => m.Health > tauntAttack && m.AttackDamage >= tauntHealth).ToList();

                    // goodTraders: kill Taunt
                    List <Minion> goodTraders = ourMinionsReady.Where(m => m.AttackDamage > tauntHealth).ToList();

                    // survivingTraders: survive an attack but don't necessarily kill the taunt
                    List <Minion> survivingTraders = ourMinionsReady.Where(m => m.Health > tauntAttack).ToList();

                    // trade perfect
                    if (perfectTraders.Count != 0)
                    {
                        perfectTraders = perfectTraders.OrderBy(m => m.Health + m.AttackDamage).ToList();
                        return(MinionAttackTask.Any(game.CurrentPlayer, perfectTraders[0], enemyTaunts[0]));
                    }

                    // trade almost perfect
                    else if (almostPerfectTraders.Count != 0)
                    {
                        almostPerfectTraders = almostPerfectTraders.OrderBy(m => m.Health + m.AttackDamage).ToList();
                        return(MinionAttackTask.Any(game.CurrentPlayer, almostPerfectTraders[0], enemyTaunts[0]));
                    }

                    // trade good
                    else if (goodTraders.Count != 0)
                    {
                        // sort good traders and choose weakest to not waste potential
                        goodTraders = goodTraders.OrderBy(m => m.Health + m.AttackDamage).ToList();
                        return(MinionAttackTask.Any(game.CurrentPlayer, goodTraders[0], enemyTaunts[0]));
                    }

                    // trade so that minions survive
                    else if (survivingTraders.Count != 0)
                    {
                        return(MinionAttackTask.Any(game.CurrentPlayer, survivingTraders[0], enemyTaunts[0]));
                    }

                    // trade random
                    else
                    {
                        return(MinionAttackTask.Any(game.CurrentPlayer, ourMinionsReady[0], enemyTaunts[0]));
                    }
                }
                else
                {
                    return(MinionAttackTask.Any(game.CurrentPlayer, ourMinionsReady[0], game.CurrentOpponent.Hero));
                }
            }
            else if (mana >= 2 && heroPowers.Count != 0)
            {
                // hero power
                if (game.CurrentPlayer.Hero.HeroPower.Card.Name == "Lesser Heal" || game.CurrentPlayer.Hero.HeroPower.Card.Name == "Fireblast")
                {
                    return(options[0]);                    // end turn, because we don't know how to set the target
                }
                else
                {
                    return(heroPowers[0]);                    // use hero power
                }
            }
            else
            {
                // fallback: end turn
                return(options[0]);
            }
        }