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 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 IEnumerable <Targets> SelectTargetsDistribute(TargetingRuleParameters p, List <Card> candidates) { var minCount = p.TotalMinTargetCount(); var maxCount = p.TotalMaxTargetCount(); if (candidates.Count < minCount) { return(None <Targets>()); } var targetsCount = Math.Min(candidates.Count, maxCount); var targets = candidates .Take(targetsCount) .Cast <ITarget>() .ToList(); var amount = p.DistributeAmount / targetsCount; var distribution = Enumerable.Range(amount, targetsCount).ToList(); var reminder = p.DistributeAmount % targetsCount; for (int i = 0; i < reminder; i++) { distribution[i]++; } return(Group(targets, distribution)); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var candidates = GetCandidatesForProtectionFromTopSpell(p) .OrderByDescending(x => x.Score); return(Group(candidates, p.MinTargetCount())); }
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> 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 }); }
public void Process(ActivationContext c) { var excludeSelf = ConsiderTargetingSelf ? null : c.Card; var candidates = c.Selector.GenerateCandidates(c.TriggerMessage, excludeSelf); var parameters = new TargetingRuleParameters(candidates, c, Game); var targetsCombinations = (TargetLimit.HasValue ? SelectTargets(parameters).Take(TargetLimit.Value) : SelectTargets(parameters)) .ToList(); if (targetsCombinations.Count == 0) { if (c.CanCancel) { c.CancelActivation = true; return; } targetsCombinations = ForceSelectTargets(parameters) .Take(Ai.CurrentTargetCount) .ToList(); } c.SetPossibleTargets(targetsCombinations); }
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 candidates = p.Candidates <Player>() .Where(x => x == p.Controller.Opponent); 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 <Card>(ControlledBy.Opponent) .Where(c => c.IsAttacker || c.CanBlock()) .Select(c => { for (var i = 0; i < _abilities.Count; i++) { var ability = _abilities[i]; if (c.Has().Has(ability)) { return new { Card = c, Rank = i } } ; } return(new { Card = c, Rank = -1 }); }) .Where(x => x.Rank != -1) .OrderBy(x => x.Rank) .ThenByDescending(x => x.Card.Power * 2 + x.Card.Toughness) .Select(x => x.Card); return(Group(candidates, p.MinTargetCount())); }
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())))); }
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> 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) { 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> 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>() .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 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 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 = GetCandidatesThatCanBeDestroyed(p) .Where(x => !x.Has().Indestructible) .OrderByDescending(x => x.Card().Score); return(Group(candidates, p.MinTargetCount())); }
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 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 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) .Where(c => c.IsAttacker || c.IsBlocker) .Where(c => _filter(c)) .OrderByDescending(c => c.CalculateCombatDamageAmount(singleDamageStep: false)); return(Group(candidates, p.TotalMinTargetCount())); }
private IEnumerable <Targets> SelectTargets2Selectors(TargetingRuleParameters p) { Asrt.True(p.EffectTargetTypeCount <= 2, "More than 2 effect selectors currently not supported."); var candidates1 = GetCandidatesByDescendingDamageScore(p, selectorIndex: 0).ToList(); var candidates2 = GetCandidatesByDescendingDamageScore(p, selectorIndex: 1).ToList(); return(Group(candidates1, candidates2)); }
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())); }
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 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))); }