protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { if (Stack.CanTopSpellReducePlayersLifeToZero(p.Controller)) { var candidates1 = p.Candidates <Card>() .OrderBy(x => x.Score); return(Group(candidates1, p.MinTargetCount(), add: (target, targets) => targets.Cost.Add(target))); } var candidates = new List <Card>(); if (Turn.Step == Step.DeclareBlockers && Stack.IsEmpty) { candidates.AddRange( p.Candidates <Card>() .Where(x => Combat.CanBeDealtLeathalCombatDamage(x)) .Where(x => !Combat.CanKillAny(x))); } candidates.AddRange( p.Candidates <Card>() .Where(x => Stack.CanBeDestroyedByTopSpell(x))); return(Group(candidates, p.MinTargetCount(), add: (target, targets) => targets.Cost.Add(target))); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { IEnumerable <Card> candidates; if (Turn.Step == Step.FirstMain) { candidates = p.Candidates <Card>(ControlledBy.SpellOwner) .Where(x => x.CanAttack) .Select(x => new { Card = x.Card(), Score = CalculateAttackerScoreForThisTurn(x) }) .OrderByDescending(x => x.Score) .Where(x => x.Score > 0) .Select(x => x.Card); } else { candidates = p.Candidates <Card>(ControlledBy.SpellOwner) .Where(x => x.CanBlock()) .Select(x => new { Card = x, Score = CalculateBlockerScore(x) }) .OrderByDescending(x => x.Score) .Where(x => x.Score > 0) .Select(x => x.Card); } return(Group(candidates, 1)); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var costCandidates = p .Candidates <Card>(selector: c => c.Cost) .OrderBy(x => x.Score) .Take(1); var effectCandidates = p.Candidates <Card>(ControlledBy.Opponent, selector: c => c.Effect) .Where(x => !x.IsTapped) .OrderBy(x => { if (x.Is().Creature) { return(1); } if (x.Is().Land) { return(2); } return(3); }) .Take(1); return(Group(costCandidates, effectCandidates, add1: (t, trgs) => trgs.AddCost(t), add2: (t, trgs) => trgs.AddEffect(t))); }
private List <ITarget> PreventDamageAttackerWillDealToPlayerOrBlocker() { var playerCandidate = _p.Candidates <Player>(ControlledBy.SpellOwner, selector: c => c.Effect) .Where(x => _game.Combat.WillAnyAttackerDealDamageToDefender()); var creatureCandidates = _p.Candidates <Card>(ControlledBy.SpellOwner, selector: c => c.Effect) .Where(x => x.IsBlocker) .Where(x => { var prevented = QuickCombat.GetAmountOfDamageThatNeedsToBePreventedToSafeBlockerFromDying( blocker: x, attacker: _game.Combat.GetAttacker(x)); return(0 < prevented && prevented <= _amount); }) .OrderByDescending(x => x.Score); var candidates = new List <ITarget>(); candidates.AddRange(playerCandidate); candidates.AddRange(creatureCandidates); return(candidates); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var targetPicks = new List <ITarget>(); if (!Stack.IsEmpty && p.Candidates <ITarget>().Contains(Stack.TopSpell)) { var damageToPlayer = Stack.GetDamageTopSpellWillDealToPlayer(p.Controller); if (damageToPlayer > 0) { targetPicks.Add(Stack.TopSpell); } } if (Turn.Step == Step.DeclareBlockers && Stack.IsEmpty) { if (!p.Controller.IsActive) { var attacker = Combat.FindAttackerWhichWillDealGreatestDamageToDefender( card => p.Candidates <ITarget>().Contains(card)); if (attacker != null) { targetPicks.Add(attacker); } } } return(Group(targetPicks, 1)); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var results = new List <Result>(); var opponent = p.Candidates <Player>(ControlledBy.Opponent) .FirstOrDefault(); if (opponent != null) { for (var i = 0; i < _amounts.Count; i++) { results.Add(new Result { Damage = _amounts[i], Score = ScoreCalculator.CalculateLifelossScore(opponent.Life, _amounts[i]), Target = opponent }); } } var creatures = p.Candidates <Card>(ControlledBy.Opponent).ToArray(); for (var i = 0; i < _amounts.Count; i++) { foreach (var creature in creatures.Where(x => x.Life <= _amounts[i])) { results.Add(new Result { Damage = _amounts[i], Score = creature.Score, Target = creature }); } } var targets = results .GroupBy(x => x.Target) .Select(x => x.OrderBy(y => y.Damage).First()) .OrderByDescending(x => x.Score) .ToArray(); var picks = new List <ITarget>(); for (var i = 0; i < _amounts.Count; i++) { var pick = targets .FirstOrDefault(x => x.Damage <= _amounts[i] && !picks.Contains(x.Target)); if (pick == null) { return(None <Targets>()); } picks.Add(pick.Target); } return(Group(picks, p.TotalMinTargetCount())); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var battlefieldCandidates = p.Candidates <Card>(ControlledBy.SpellOwner) .OrderBy(x => x.Score); var graveyardCandidates = p.Candidates <Card>(ControlledBy.SpellOwner, selectorIndex: 1) .OrderBy(x => - x.Score); return(Group(battlefieldCandidates, graveyardCandidates)); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var costTargets = p.Candidates <Card>(selectorIndex: 0, selector: c => c.Cost) .OrderBy(x => x.Score) .Take(1); var effectTargets = p.Candidates <Card>(selectorIndex: 0, selector: c => c.Effect, controlledBy: ControlledBy.Opponent) .OrderByDescending(x => x.Score); return(Group(costTargets, effectTargets, add1: (t, trgs) => trgs.AddCost(t), add2: (t, trgs) => trgs.AddEffect(t))); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var costCandidates = new List <Card>(); var effectCandidates = new List <Card>(); if (IsBeforeYouDeclareAttackers(p.Controller)) { costCandidates = p.Candidates <Card>(selector: s => s.Cost) .OrderBy(x => x.Score) .Take(1) .ToList(); effectCandidates = p.Candidates <Card>(ControlledBy.Opponent, selector: s => s.Effect) .Select(x => new { Target = x, Score = x.Life <= _amount ? x.Score : 0 }) .Where(x => x.Score > 0) .OrderByDescending(x => x.Score) .Select(x => x.Target) .Take(1) .ToList(); } else if (!Stack.IsEmpty) { costCandidates = p.Candidates <Card>(selector: s => s.Cost) .Where(x => Stack.CanBeDestroyedByTopSpell(x.Card())) .OrderBy(x => x.Score) .Take(1) .ToList(); effectCandidates = p.Candidates <Card>(ControlledBy.Opponent, selector: s => s.Effect) .Select(x => new { Target = x, Score = x.Life <= _amount ? x.Score : 0 }) .Where(x => x.Score > 0) .OrderByDescending(x => x.Score) .Select(x => x.Target) .Take(1) .ToList(); } return(Group(costCandidates, effectCandidates, (t, tgs) => tgs.AddCost(t), (t, tgs) => tgs.AddEffect(t))); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var candidates = p.Candidates <Card>(ControlledBy.Opponent) .OrderByDescending(x => x.Toughness); return(Group(candidates, 1)); }
protected override IEnumerable <Targets> ForceSelectTargets(TargetingRuleParameters p) { var candidates = p.Candidates <Card>() .OrderBy(c => c.Score); return(Group(candidates, p.MinTargetCount())); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var candidates = p.Candidates <Player>() .Where(x => x == p.Controller.Opponent); return(Group(candidates, 1)); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var candidates = p.Candidates <Card>(ControlledBy.Opponent) .OrderByDescending(x => x.Score); return(Group(candidates, p.TotalMinTargetCount(), p.TotalMaxTargetCount())); }
protected IEnumerable <Card> GetCandidatesThatCanBeDestroyed(TargetingRuleParameters p, Func <TargetsCandidates, IList <TargetCandidates> > selector = null) { return(p.Candidates <Card>(ControlledBy.SpellOwner, selector: selector) .Where(x => Stack.CanBeDestroyedByTopSpell(x.Card()) || (Stack.IsEmpty && Turn.Step == Step.DeclareBlockers && Combat.CanBeDealtLeathalCombatDamage(x.Card())))); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var sourceTargetCandidates = GetDamageSourceAndDamageTargetCandidates(p); if (sourceTargetCandidates.DamageSource.Count == 0 || sourceTargetCandidates.DamageTarget.Count == 0) { return(None <Targets>()); } // for simplicity we consider only 'best' 1 legal assignment var damageSource = sourceTargetCandidates.DamageSource[0]; var damageTarget = sourceTargetCandidates.DamageTarget[0]; // cost should not be paid with damage target var cost = p.Candidates <Card>(selector: trgs => trgs.Cost) .OrderBy(x => x.Score) .Where(x => x != damageTarget) .FirstOrDefault(); if (cost == null) { return(None <Targets>()); } var targets = new Targets(); targets.AddCost(cost); targets.AddEffect(damageSource); targets.AddEffect(damageTarget); return(new[] { targets }); }
private void PreventDamageAttackerWillDealToBlocker(TargetingRuleParameters p, DamageSourceAndDamageTargetCandidates selectedCandidates) { var blockerAttackerPair = p.Candidates <Card>(selectorIndex: 1, selector: trgs => trgs.Effect) .Where(card => card.IsBlocker) .Select(blocker => { var attacker = Combat.GetAttacker(blocker); return(new { Target = blocker, Source = QuickCombat.CanBlockerBeDealtLeathalCombatDamage(attacker, blocker) ? attacker : null }); }) .Where(x => x.Source != null) .OrderByDescending(x => x.Target.Score) .FirstOrDefault(); if (blockerAttackerPair != null) { selectedCandidates.DamageTarget.Add(blockerAttackerPair.Target); selectedCandidates.DamageSource.Add(blockerAttackerPair.Source); } }
protected override IEnumerable <Targets> ForceSelectTargets(TargetingRuleParameters p) { var candidates = p.Candidates <Card>(ControlledBy.SpellOwner) .OrderBy(x => x.Score); return(Group(candidates, p.TotalMinTargetCount(), p.TotalMaxTargetCount())); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var candidates = p.Candidates <Card>(ControlledBy.SpellOwner) .Where(attacker => _filter(attacker)) .OrderByDescending(CalculateScore); return(Group(candidates, p.MinTargetCount())); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var costCandidates = p.Candidates <Card>(selectorIndex: 0, selector: c => c.Cost); var canTargetOpponent = p.Candidates <Player>(selectorIndex: 0, selector: c => c.Effect) .Any(x => x != p.Controller); // check to see if we can kill opponent by sacing any one creature var opponentsLife = p.Controller.Opponent.Life; if (canTargetOpponent && costCandidates.Any(x => opponentsLife <= x.Power)) { var targets = new Targets( cost: costCandidates.Where(x => opponentsLife <= x.Power).OrderBy(x => x.Score).First(), effect: p.Controller.Opponent ); return(new[] { targets }); } // pair your creatures and opponents // power -> lifepoints left var yourCreatures = costCandidates .OrderBy(x => x.Power) .ThenBy(x => x.Score) .ToList(); var opponentCreatures = p.Candidates <Card>(selectorIndex: 0, selector: c => c.Effect) .OrderBy(x => x.Life) .ToList(); var pairs = (from yourCreature in yourCreatures from opponentCreature in opponentCreatures where yourCreature.Power >= opponentCreature.Life select new Pair(yourCreature, opponentCreature)) .OrderByDescending(x => x.Score) .ToList(); return(pairs.Select(x => new Targets( cost: x.Yours, effect: x.Opponents) )); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var candidates = p.Candidates <Card>() .OrderBy(x => x.Score); return(Group(candidates, p.MinTargetCount(), add: (trg, trgs) => trgs.Cost.Add(trg))); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var candidates = p.Candidates <Card>(ControlledBy.SpellOwner) .Where(x => x.IsTapped && !x.Is().Land) .OrderByDescending(x => x.Score); return(Group(candidates, p.TotalMinTargetCount())); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var candidates = p.Candidates <Card>(ControlledBy.Opponent) .Where(x => (!_blockOnly && x.IsAbleToAttack) || (!_attackOnly && !x.Has().CannotBlock)) .OrderByDescending(x => 2 * x.Power + x.Toughness); return(Group(candidates, p.MinTargetCount(), p.MaxTargetCount())); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var candidates = p.Candidates <Card>(_controlledBy) .OrderBy(c => c.HasAttachments ? 1 : 0) .ThenBy(c => c.IsTapped ? 1 : 0); return(Group(candidates, 1)); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var candidates = p.Candidates <Card>() .OrderBy(x => ScoreCalculator.CalculateDiscardScore(x, Ai.IsSearchInProgress)); return(Group(candidates, p.MaxTargetCount(), add: (trg, trgs) => trgs.Cost.Add(trg))); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var costTargets = p.Candidates <Card>(selectorIndex: 0, selector: c => c.Cost) .OrderBy(x => x.IsTapped ? 0 : 1) .ThenBy(x => x.Score) .Take(1); return(Group(costTargets, p.MinTargetCount(), add: (t, trgs) => trgs.AddCost(t))); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var candidates = p.Candidates <Card>(ControlledBy.SpellOwner) .Where(c => c.IsAttacker || c.IsBlocker) .Where(c => _filter(c)) .OrderByDescending(c => c.CalculateCombatDamageAmount(singleDamageStep: false)); return(Group(candidates, p.TotalMinTargetCount())); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var candidates = p.Candidates <Card>() .Where(x => x.IsGoodTarget(p.Card, p.Card.Controller)) .OrderByDescending(x => x.Score) .ToList(); return(Group(candidates, p.TotalMinTargetCount(), p.TotalMaxTargetCount())); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var candidates = p.Candidates <Card>(ControlledBy.SpellOwner) .Where(c => c.CanBlock()) .Where(c => !c.Has().Flying&& !c.Has().Reach) .OrderByDescending(x => x.Power); return(Group(candidates, p.MinTargetCount())); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var candidates = p.Candidates <Card>(ControlledBy.SpellOwner) .OrderByDescending(x => x.IsTapped ? 1 : 0) .Select(x => x) .ToList(); return(Group(candidates, p.MinTargetCount())); }
protected override IEnumerable <Targets> ForceSelectTargets(TargetingRuleParameters p) { // triggered abilities force you to choose a target even if its // not favorable e.g Flaming Kavu var candidates = p.Candidates <Card>().OrderByDescending(x => x.Toughness); return(Group(candidates, p.MinTargetCount())); }