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); }
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); }
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); }
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); }
/// <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); }
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]); } }