package iamrescue.agent.police.newstrategy; import iamrescue.belief.IAMWorldModel; import iamrescue.util.comparators.IDComparator; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; import javolution.util.FastMap; import rescuecore2.misc.Pair; import rescuecore2.standard.entities.Human; import rescuecore2.standard.entities.PoliceForce; import rescuecore2.standard.entities.StandardEntity; import rescuecore2.standard.entities.StandardEntityURN; import rescuecore2.standard.entities.StandardPropertyURN; import rescuecore2.worldmodel.EntityID; public class ClosestTargetAllocator { private static final int MAX_AGENTS_PER_TARGET = 4; private IAMWorldModel worldModel; private List<EntityID> police; private List<StandardEntity> refuges; public ClosestTargetAllocator(IAMWorldModel worldModel) { this.worldModel = worldModel; Collection<StandardEntity> policeCollection = worldModel .getEntitiesOfType(StandardEntityURN.POLICE_FORCE); police = new ArrayList<EntityID>(policeCollection.size()); for (StandardEntity standardEntity : policeCollection) { police.add(standardEntity.getID()); } Collections.sort(police, IDComparator.DEFAULT_INSTANCE); Collection<StandardEntity> refugeCollection = worldModel .getEntitiesOfType(StandardEntityURN.REFUGE); refuges = new ArrayList<StandardEntity>(refugeCollection.size()); for (StandardEntity standardEntity : refugeCollection) { refuges.add(standardEntity); } } public EntityID computeAllocation(List<StandardEntity> stuckPositions, Set<EntityID> stuckAgents, GoalGenerator goalGenerator, EntityID myself) { // Collections.sort(stuckAgents, IDComparator.DEFAULT_INSTANCE); Map<EntityID, Integer> alreadyAllocated = new FastMap<EntityID, Integer>(); for (int i = 0; i < police.size(); i++) { Human thisPolice = (Human)worldModel.getEntity(police.get(i)); if (!thisPolice.isPositionDefined()) { System.out.println("Crap: " + thisPolice.getFullDescription()); System.out.println(worldModel.getProvenance(thisPolice.getID(), StandardPropertyURN.POSITION)); continue; } EntityID closest = findClosestUnsaturatedGoal(stuckPositions, Collections.EMPTY_SET, alreadyAllocated, thisPolice); // EntityID closest = null; GoalContainer goals = null; if (closest == null) { goals = goalGenerator.generateGoals(); closest = findClosestUnsaturatedGoal(goals.getBlockedAgents(), stuckAgents, alreadyAllocated, thisPolice); } if (closest == null) { closest = findClosestUnsaturatedGoal(goals .getBlockedCivilians(), stuckAgents, alreadyAllocated, thisPolice); } if (closest == null) { closest = findClosestUnsaturatedGoal(goals .getBlockedUnsearchedBuildings(), stuckAgents, alreadyAllocated, thisPolice); } if (closest == null) { closest = findClosestUnsaturatedGoal(goals .getBlockedBurningBuildings(), stuckAgents, alreadyAllocated, thisPolice); } if (thisPolice.getID().equals(myself)) { return closest; } } return null; } private EntityID findClosestUnsaturatedGoal( List<? extends StandardEntity> targets, Set<EntityID> ignored, Map<EntityID, Integer> alreadyAllocated, StandardEntity source) { double closestSquaredDistance = Double.MAX_VALUE; StandardEntity closest = null; Pair<Integer, Integer> locationSource = source.getLocation(worldModel); for (StandardEntity target : targets) { if (ignored.contains(target.getID())) { // Ignore this continue; } if (target instanceof PoliceForce) { if (!target.getID().equals(source.getID())) { // Do not help other police forces continue; } else { // Add closest refuge to self for (StandardEntity refuge : refuges) { Integer already = alreadyAllocated.get(refuge.getID()); if (already == null || already < MAX_AGENTS_PER_TARGET) { Pair<Integer, Integer> location = refuge .getLocation(worldModel); double dx = location.first() - locationSource.first(); double dy = location.second() - locationSource.second(); double squaredDistance = dx * dx + dy * dy; if (squaredDistance < closestSquaredDistance) { closestSquaredDistance = squaredDistance; closest = refuge; } } } } } else { // Not police Integer already = alreadyAllocated.get(target.getID()); if (already == null || already < MAX_AGENTS_PER_TARGET) { Pair<Integer, Integer> location = target .getLocation(worldModel); if (location == null) { System.out.println("Crap: " + target.getFullDescription()); } double dx = location.first() - locationSource.first(); double dy = location.second() - locationSource.second(); double squaredDistance = dx * dx + dy * dy; if (squaredDistance < closestSquaredDistance) { closestSquaredDistance = squaredDistance; closest = target; } } } } if (closest != null) { Integer already = alreadyAllocated.get(closest.getID()); if (already == null) { already = 0; } alreadyAllocated.put(closest.getID(), already + 1); } if (closest == null) { return null; } else { return closest.getID(); } } }