public static ChosenBlockers ChooseBlockers(BlockStrategyParameters p) { // 1. Pass // // assign minimal number of blockers to every attacker // keep assignments that have biggest positive gain var possibleAssignments = new List <BlockerAssignment>(); foreach (var attacker in p.Attackers) { var legalCandidates = p.BlockerCandidates.Where(blocker => attacker.CanBeBlockedBy(blocker)).ToList(); var minimalAssignments = legalCandidates.KSubsets(attacker.MinimalBlockerCount); foreach (var blockers in minimalAssignments) { possibleAssignments.Add(new BlockerAssignment(attacker, blockers, p.DefendersLife)); } } var assignments = new Dictionary <Card, BlockerAssignment>(); var usedAttackers = new HashSet <Card>(); foreach (var assignment in possibleAssignments.Where(x => x.Gain > 0).OrderByDescending(x => x.Gain)) { if (assignment.Blockers.Any(assignments.ContainsKey)) { continue; } if (usedAttackers.Contains(assignment.Attacker)) { continue; } foreach (var blocker in assignment.Blockers) { assignments[blocker] = assignment; } usedAttackers.Add(assignment.Attacker); } var unassignedBlockers = p.BlockerCandidates .Where(x => !assignments.ContainsKey(x)) .ToList(); // 2. Pass // Assign additional blockers to blocked attackers // if such an assignment would improove the gain return(ImprooveAssignementsByAddingAditionalBlockers(assignments.Values.Distinct(), unassignedBlockers)); }
public static ChosenBlockers ChooseBlockers(BlockStrategyParameters p) { // 1. Pass // // assign minimal number of blockers to every attacker // keep assignments that have biggest positive gain var possibleAssignments = new List<BlockerAssignment>(); foreach (var attacker in p.Attackers) { var legalCandidates = p.BlockerCandidates.Where(blocker => attacker.CanBeBlockedBy(blocker)).ToList(); var minimalAssignments = legalCandidates.KSubsets(attacker.MinimalBlockerCount); foreach (var blockers in minimalAssignments) { possibleAssignments.Add(new BlockerAssignment(attacker, blockers, p.DefendersLife)); } } var assignments = new Dictionary<Card, BlockerAssignment>(); var usedAttackers = new HashSet<Card>(); foreach (var assignment in possibleAssignments.Where(x => x.Gain > 0).OrderByDescending(x => x.Gain)) { if (assignment.Blockers.Any(assignments.ContainsKey)) continue; if (usedAttackers.Contains(assignment.Attacker)) continue; foreach (var blocker in assignment.Blockers) { assignments[blocker] = assignment; } usedAttackers.Add(assignment.Attacker); } var unassignedBlockers = p.BlockerCandidates .Where(x => !assignments.ContainsKey(x)) .ToList(); // 2. Pass // Assign additional blockers to blocked attackers // if such an assignment would improove the gain return ImprooveAssignementsByAddingAditionalBlockers(assignments.Values.Distinct(), unassignedBlockers); }