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.TotalMinTargetCount(), 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.TotalMinTargetCount(), add: (target, targets) => targets.Cost.Add(target))); }
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.TotalMinTargetCount())); }
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.TotalMinTargetCount())); }
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.Opponent) .OrderByDescending(x => x.Score); return(Group(candidates, p.TotalMinTargetCount(), p.TotalMaxTargetCount())); }
protected override IEnumerable <Targets> ForceSelectTargets(TargetingRuleParameters p) { var candidates = p.Candidates <Card>() .OrderBy(c => c.Score); return(Group(candidates, p.TotalMinTargetCount())); }
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.TotalMinTargetCount())); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var candidates = p.Candidates <Card>() .OrderBy(x => x.Score); return(Group(candidates, p.TotalMinTargetCount(), add: (trg, trgs) => trgs.Cost.Add(trg))); }
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.TotalMinTargetCount(), p.TotalMaxTargetCount())); }
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.SpellOwner) .Where(attacker => _filter(attacker)) .OrderByDescending(CalculateScore); return(Group(candidates, p.TotalMinTargetCount())); }
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> 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.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.TotalMinTargetCount())); }
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.TotalMinTargetCount(), 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> ForceSelectTargets(TargetingRuleParameters p) { var candidates = p.Candidates <Card>() .OrderBy(_forceRank) .ToList(); if (p.DistributeAmount > 0) { return(SelectTargetsDistribute(p, candidates)); } if (p.HasEffectCandidates) { return(Group(candidates, p.TotalMinTargetCount())); } return(Group(candidates, p.TotalMinTargetCount(), add: (trg, trgs) => trgs.AddCost(trg))); }
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.Has().Deathtouch) .Where(c => c.Power > 0) .Where(c => c.CanAttack || c.CanBlock()) .OrderBy(x => x.Power); return(Group(candidates, p.TotalMinTargetCount())); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { if (p.EffectTargetTypeCount > 1) { return(SelectTargets2Selectors(p)); } var candidates = GetCandidates(p).ToList(); if (p.DistributeAmount > 0) { return(SelectTargetsDistribute(p, candidates)); } if (p.HasEffectCandidates) { return(Group(candidates, p.TotalMinTargetCount(), p.TotalMaxTargetCount())); } return(Group(candidates, p.TotalMinTargetCount(), p.TotalMaxTargetCount(), (trg, trgs) => trgs.AddCost(trg))); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { if (IsAfterOpponentDeclaresAttackers(p.Controller)) { var attackerCandidates = p.Candidates <Card>(ControlledBy.Opponent) .Where(x => x.IsAttacker) .OrderByDescending(CalculateAttackerScoreForThisTurn); return(Group(attackerCandidates, p.TotalMinTargetCount(), p.TotalMaxTargetCount())); } if (IsAfterOpponentDeclaresBlockers(p.Controller)) { var blockerCandidates = p.Candidates <Card>(ControlledBy.Opponent) .Where(x => x.IsBlocker) .OrderByDescending(x => { var attacker = Combat.FindBlocker(x).Attacker; if (attacker == null) { return(0); } var blockers = attacker.Blockers.Select(b => b.Card); if (QuickCombat.CanAttackerBeDealtLeathalDamage(attacker, blockers)) { return(attacker.Card.Score); } return(0); } ); return(Group(blockerCandidates, p.TotalMinTargetCount(), p.TotalMaxTargetCount())); } return(None <Targets>()); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var candidates = p.Candidates <Card>(ControlledBy.Opponent) .Select(x => new { Card = x, Score = x.Has().DoesNotUntap ? 0 : CalculateAttackingPotential(x) }) .OrderByDescending(x => x.Score) .Select(x => x.Card) .ToList(); return(Group(candidates, p.TotalMinTargetCount(), p.TotalMaxTargetCount())); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var power = _power(p) ?? p.MaxX; var toughness = _toughness(p) ?? p.MaxX; var candidates = p.Candidates <Card>(ControlledBy.SpellOwner); if (IsBeforeYouDeclareAttackers(p.Controller)) { candidates = candidates.Select(x => new { Card = x.Card(), Score = CalculateAttackingPotential(x) }) .OrderByDescending(x => x.Score) .Select(x => x.Card) .ToList(); } else if (IsAfterOpponentDeclaresBlockers(p.Controller)) { candidates = GetBestAttackersForPTGain(power, toughness, candidates); } else if (IsAfterYouDeclareBlockers(p.Controller)) { candidates = GetBestBlockersForPTGain(power, toughness, candidates); } else if (_untilEot == false && IsEndOfOpponentsTurn(p.Controller)) { candidates = candidates .OrderBy(x => x.Toughness); } else if (_untilEot == false && Stack.CanBeDestroyedByTopSpell(p.Card)) { candidates = candidates .OrderBy(x => x.Toughness); } else if (toughness > 0) { candidates = candidates .Where(x => Stack.CanBeDealtLeathalDamageByTopSpell(x.Card())); } return(Group(candidates, p.TotalMinTargetCount())); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var amount = _getAmount(p); var candidates = p.Candidates <Card>(ControlledBy.Opponent) .Select(x => new { Target = x, Score = x.Life <= amount ? 2 * x.Score : x.Score }) .OrderByDescending(x => x.Score) .Select(x => x.Target); return(Group(candidates, p.TotalMinTargetCount())); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var candidates = p.Candidates <Card>(ControlledBy.Opponent) .Where(x => p.Controller.IsActive ? x.CanBlock() : x.CanAttack) .Select(x => new { Card = x, Damage = CalculateAttackerScoreForThisTurn(x) }) .Where(x => x.Damage > 0) .OrderByDescending(x => x.Damage) .ThenByDescending(x => x.Card.Score) .Select(x => x.Card); return(Group(candidates, p.TotalMinTargetCount(), p.TotalMaxTargetCount())); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var targetCandidates = GetCandidatesThatCanBeDestroyed(p) .OrderByDescending(x => x.Score) .ToList(); if (targetCandidates.Count == 1 && targetCandidates[0] == p.Card) { // if owner is the only one that can be killed // target the owner return(Group(targetCandidates, 1)); } // otherwise return all except the owner return(Group(targetCandidates.Where(x => x != p.Card), p.TotalMinTargetCount())); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { if (p.DistributeAmount > 0) { return(SelectTargetsDistribute(p)); } if (p.EffectTargetTypeCount > 1) { // e.g shower of sparks return(SelectTargets2Selectors(p)); } var candidates = GetCandidatesByDescendingDamageScore(_getAmount(p), p); return(Group(candidates, p.TotalMinTargetCount())); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var power = _power ?? p.MaxX; var toughness = _toughness ?? p.MaxX; var candidates = p.Candidates <Card>(ControlledBy.SpellOwner);; if (p.Controller.IsActive && Turn.Step == Step.DeclareBlockers) { candidates = GetBestAttackersForPTGain(power, toughness, candidates); } else if (!p.Controller.IsActive && Turn.Step == Step.DeclareBlockers) { candidates = GetBestBlockersForPTGain(power, toughness, candidates); } return(Group(candidates, p.TotalMinTargetCount(), p.TotalMaxTargetCount())); }
protected override IEnumerable <Targets> SelectTargets(TargetingRuleParameters p) { var candidates = new List <Card>(); if (Turn.Step == Step.DeclareBlockers && Stack.IsEmpty) { candidates.AddRange( p.Candidates <Card>() .Where(x => _filter(x)) .Where(x => Combat.CanBeDealtLeathalCombatDamage(x)) .Where(x => !Combat.CanKillAny(x))); } candidates.AddRange( p.Candidates <Card>() .Where(x => _filter(x)) .Where(x => Stack.CanBeDestroyedByTopSpell(x))); return(Group(candidates, p.TotalMinTargetCount(), add: (trg, trgs) => trgs.AddCost(trg))); }