001 package aima.gui.applications.search.map; 002 003 import java.util.ArrayList; 004 import java.util.List; 005 006 import aima.basic.Agent; 007 import aima.gui.framework.AgentAppModel; 008 import aima.search.map.DynAttributeNames; 009 import aima.search.map.Map; 010 import aima.search.map.Point2D; 011 import aima.search.map.Scenario; 012 013 /** 014 * Provides a ready-to-use implementation of a model for route planning agent 015 * applications. It is based on a scenario description and a list of 016 * destinations. Some features are not used. Subclasses can support those 017 * features by overriding the methods {@link #hasInfos(String)}, and 018 * {@link #hasObjects(String)}. 019 * 020 * @author R. Lunde 021 */ 022 public class MapAgentModel extends AgentAppModel { 023 /** A scenario. */ 024 protected Scenario scenario; 025 /** A list of location names, possibly null. */ 026 protected List<String> destinations; 027 028 /** Stores the locations, the agent has already visited. */ 029 private final ArrayList<String> tourHistory = new ArrayList<String>(); 030 031 /** Returns a list of all already visited agent locations. */ 032 public List<String> getTourHistory() { 033 return tourHistory; 034 } 035 036 /** Clears the list of already visited locations. */ 037 public void clearTourHistory() { 038 tourHistory.clear(); 039 } 040 041 /** 042 * Reacts on environment changes and updates the tour history. The command 043 * string is always send to all registered model change listeners. If the 044 * command is a location name (with attached position info) or 045 * {@link aima.basic.Agent#NO_OP}, the 046 * agent's current location is added to the tour history and all listeners 047 * are informed about the change. 048 */ 049 @Override 050 public void envChanged(String command) { 051 for (AgentAppModel.ModelChangedListener listener : listeners) 052 listener.logMessage(command); 053 if (getLocCoords(command) != null || command.equals(Agent.NO_OP)) { 054 String loc = (String) getAgent().getAttribute( 055 DynAttributeNames.AGENT_LOCATION); 056 tourHistory.add(loc); 057 fireModelChanged(); 058 } 059 } 060 061 /** 062 * Assigns values to the attributes {@link #scenario} and 063 * {@link #destinations}, clears the history and informs all interested 064 * listeners about the model change. 065 * 066 * @param s 067 * A scenario or null. 068 * @param d 069 * List of location names or null. 070 */ 071 public void prepare(Scenario s, List<String> d) { 072 scenario = s; 073 destinations = d; 074 clearTourHistory(); 075 fireModelChanged(); 076 } 077 078 /** Checks whether there is a scenario available. */ 079 public boolean isEmpty() { 080 return scenario == null; 081 } 082 083 /** 084 * Returns all location names mentioned in the environment map or in the 085 * agent map. 086 */ 087 public List<String> getLocations() { 088 List<String> result = scenario.getEnvMap().getLocations(); 089 if (!result.containsAll(scenario.getAgentMap().getLocations())) { 090 result = new ArrayList<String>(result); 091 for (String loc : scenario.getAgentMap().getLocations()) 092 if (!result.contains(loc)) 093 result.add(loc); 094 } 095 return result; 096 } 097 098 /** Returns the map used by the agent. */ 099 public Map getAgentMap() { 100 return scenario.getAgentMap(); 101 } 102 103 /** Returns the map used by the environment. */ 104 public Map getEnvMap() { 105 return scenario.getEnvMap(); 106 } 107 108 /** Returns the agent. */ 109 public Agent getAgent() { 110 return (Agent) scenario.getEnv().getAgents().get(0); 111 } 112 113 /** Checks whether a given location is the initial location of the agent. */ 114 public boolean isStart(String loc) { 115 return scenario.getInitAgentLocation() == loc; 116 } 117 118 /** Checks whether a given location is one of the specified destinations. */ 119 public boolean isDestination(String loc) { 120 return destinations != null && destinations.contains(loc); 121 } 122 123 /** 124 * Returns the coordinates of the specified location. 125 */ 126 public Point2D getLocCoords(String loc) { 127 return scenario.getEnvMap().getPosition(loc); 128 } 129 130 /** 131 * Checks whether special informations can be perceived at the location. 132 * This implementation always returns false. 133 */ 134 135 public boolean hasInfos(String loc) { 136 return false; // not implemented yet 137 } 138 139 /** 140 * Checks whether interesting objects can be perceived at the location. 141 * This implementation always returns false. 142 */ 143 public boolean hasObjects(String loc) { 144 return false; // not implemented yet 145 } 146 }