package sample;
import java.util.List;
import java.util.ArrayList;
import java.util.Set;
import java.util.HashSet;
import java.util.Collections;
import java.util.Map;
import rescuecore2.worldmodel.EntityID;
import rescuecore2.Constants;
import rescuecore2.log.Logger;
import rescuecore2.standard.components.StandardAgent;
import rescuecore2.standard.entities.StandardEntity;
import rescuecore2.standard.entities.Building;
import rescuecore2.standard.entities.Refuge;
import rescuecore2.standard.entities.Road;
import rescuecore2.standard.entities.Human;
import rescuecore2.standard.kernel.comms.ChannelCommunicationModel;
import rescuecore2.standard.kernel.comms.StandardCommunicationModel;
/**
Abstract base class for sample agents.
@param <E> The subclass of StandardEntity this agent wants to control.
*/
public abstract class AbstractSampleAgent<E extends StandardEntity> extends StandardAgent<E> {
private static final int RANDOM_WALK_LENGTH = 50;
private static final String SAY_COMMUNICATION_MODEL = StandardCommunicationModel.class.getName();
private static final String SPEAK_COMMUNICATION_MODEL = ChannelCommunicationModel.class.getName();
/**
The search algorithm.
*/
protected SampleSearch search;
/**
Whether to use AKSpeak messages or not.
*/
protected boolean useSpeak;
/**
Cache of building IDs.
*/
protected List<EntityID> buildingIDs;
/**
Cache of road IDs.
*/
protected List<EntityID> roadIDs;
/**
Cache of refuge IDs.
*/
protected List<EntityID> refugeIDs;
private Map<EntityID, Set<EntityID>> neighbours;
/**
Construct an AbstractSampleAgent.
*/
protected AbstractSampleAgent() {
}
@Override
protected void postConnect() {
super.postConnect();
buildingIDs = new ArrayList<EntityID>();
roadIDs = new ArrayList<EntityID>();
refugeIDs = new ArrayList<EntityID>();
for (StandardEntity next : model) {
if (next instanceof Building) {
buildingIDs.add(next.getID());
}
if (next instanceof Road) {
roadIDs.add(next.getID());
}
if (next instanceof Refuge) {
refugeIDs.add(next.getID());
}
}
search = new SampleSearch(model);
neighbours = search.getGraph();
useSpeak = config.getValue(Constants.COMMUNICATION_MODEL_KEY).equals(SPEAK_COMMUNICATION_MODEL);
Logger.debug("Communcation model: " + config.getValue(Constants.COMMUNICATION_MODEL_KEY));
Logger.debug(useSpeak ? "Using speak model" : "Using say model");
}
/**
Construct a random walk starting from this agent's current location to a random building.
@return A random walk.
*/
protected List<EntityID> randomWalk() {
List<EntityID> result = new ArrayList<EntityID>(RANDOM_WALK_LENGTH);
Set<EntityID> seen = new HashSet<EntityID>();
EntityID current = ((Human)me()).getPosition();
for (int i = 0; i < RANDOM_WALK_LENGTH; ++i) {
result.add(current);
seen.add(current);
List<EntityID> possible = new ArrayList<EntityID>(neighbours.get(current));
Collections.shuffle(possible, random);
boolean found = false;
for (EntityID next : possible) {
if (seen.contains(next)) {
continue;
}
current = next;
found = true;
break;
}
if (!found) {
// We reached a dead-end.
break;
}
}
return result;
}
}