Skip to content

Commit 4f20751

Browse files
Ruediger.LundeRuediger.Lunde
authored andcommitted
Some minor integration work:
- Travel distance tracking added to map Agents - MapEnvironment now checks whether a road exists before moving the Agent - Use of dynamic attribute name constants unified - Documentation improved
1 parent 0604a6e commit 4f20751

File tree

7 files changed

+105
-76
lines changed

7 files changed

+105
-76
lines changed

src/aima/gui/applications/search/map/AbstractMapAgentController.java

Lines changed: 50 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -9,98 +9,104 @@
99
import aima.search.map.DynAttributeNames;
1010
import aima.search.map.Scenario;
1111

12-
1312
/**
14-
* Provides a useful base class for agent application controller
15-
* implementations in the context of route planning agent application
16-
* development.
17-
* To get it ready to work, all you need to do is, to provide implementations
18-
* for the four abstract methods.
19-
* See {@link RoutePlanningAgentAppDemo} for an example.
13+
* Provides a useful base class for agent application controller implementations
14+
* in the context of route planning agent application development. To get it
15+
* ready to work, all you need to do is, to provide implementations for the four
16+
* abstract methods. See {@link RoutePlanningAgentAppDemo} for an example.
17+
*
2018
* @author R. Lunde
2119
*/
2220
public abstract class AbstractMapAgentController extends AgentAppController {
2321
/** A scenario. */
2422
protected Scenario scenario;
2523
/**
26-
* Some location names. For routing problems, only one location should
27-
* be specified.
24+
* Some location names. For routing problems, only one location should be
25+
* specified.
2826
*/
2927
protected List<String> destinations;
3028
/** Search method to be used. */
3129
protected aima.search.framework.Search search;
3230
/** Heuristic function to be used when performing informed search. */
3331
protected AdaptableHeuristicFunction heuristic;
34-
32+
3533
/** Clears the model's tour history. */
34+
@Override
3635
public void clearAgent() {
3736
((AbstractMapAgentModel) model).clearTourHistory();
3837
frame.modelChanged();
3938
}
40-
41-
/**
42-
* Performs necessary preparations for running the agent. The behavior is
43-
* strongly influenced by the abstract methods {@link #selectScenarioAndDest(int, int)},
44-
* {@link #prepareModel()} and {@link #createHeuristic(int)}.
39+
40+
/**
41+
* Template method, which performs necessary preparations for running the
42+
* agent. The behavior is strongly influenced by the primitive operations
43+
* {@link #selectScenarioAndDest(int, int)}, {@link #prepareModel()} and
44+
* {@link #createHeuristic(int)}.
4545
*/
46+
@Override
4647
public void prepareAgent() {
4748
MapAgentFrame.SelectionState state = frame.getSelection();
48-
selectScenarioAndDest(
49-
state.getValue(MapAgentFrame.SCENARIO_SEL),
50-
state.getValue(MapAgentFrame.DESTINATION_SEL));
49+
selectScenarioAndDest(state.getValue(MapAgentFrame.SCENARIO_SEL), state
50+
.getValue(MapAgentFrame.DESTINATION_SEL));
5151
prepareModel();
5252
search = SearchFactory.getInstance().createSearch(
5353
state.getValue(MapAgentFrame.SEARCH_SEL),
5454
state.getValue(MapAgentFrame.SEARCH_MODE_SEL));
55-
heuristic = createHeuristic(
56-
state.getValue(MapAgentFrame.HEURISTIC_SEL));
55+
heuristic = createHeuristic(state.getValue(MapAgentFrame.HEURISTIC_SEL));
5756
scenario.getEnv().registerView(model);
5857
}
59-
60-
/** Starts the agent and updates the status bar of the frame. */
58+
59+
/**
60+
* Template method, which calls {@link #startAgent()} and then updates the
61+
* status bar of the frame.
62+
*/
63+
@Override
6164
public void runAgent() {
6265
startAgent();
6366
List agents = scenario.getEnv().getAgents();
6467
if (agents.size() == 1) {
6568
Agent agent = (Agent) agents.get(0);
66-
String status =
67-
(String) agent.getAttribute(DynAttributeNames.AGENT_STATUS);
68-
Integer travelDistance =
69-
(Integer) agent.getAttribute(DynAttributeNames.AGENT_TRAVEL_DISTANCE);
70-
if (status != null && travelDistance != null)
71-
frame.setStatus("Task " + status + "; travel distance " + travelDistance);
69+
String status = (String) agent
70+
.getAttribute(DynAttributeNames.AGENT_STATUS);
71+
Integer travelDistance = (Integer) agent
72+
.getAttribute(DynAttributeNames.AGENT_TRAVEL_DISTANCE);
73+
StringBuffer statusMsg = new StringBuffer("Task ");
74+
if (status != null)
75+
statusMsg.append(status);
7276
else
73-
frame.setStatus("Task completed.");
77+
statusMsg.append("completed");
78+
if (travelDistance != null)
79+
statusMsg.append("; travel distance " + travelDistance);
80+
statusMsg.append(".");
81+
frame.setStatus(statusMsg.toString());
7482
}
7583
}
76-
77-
78-
/////////////////////////////////////////////////////////////////
84+
85+
// ///////////////////////////////////////////////////////////////
7986
// abstract methods
80-
87+
8188
/**
82-
* Template method, responsible for assigning values
83-
* to attributes {@link #scenario} and {@link #destinations}.
89+
* Primitive operation, responsible for assigning values to attributes
90+
* {@link #scenario} and {@link #destinations}.
8491
*/
8592
abstract protected void selectScenarioAndDest(int scenarioIdx, int destIdx);
86-
93+
8794
/**
88-
* Template method, responsible for preparing the model.
89-
* Scenario and destinations are already selected when
90-
* this method is called.
95+
* Primitive operation, responsible for preparing the model. Scenario and
96+
* destinations are already selected when this method is called.
9197
*/
9298
abstract protected void prepareModel();
93-
99+
94100
/**
95101
* Factory method, responsible for creating a heuristic function.
96102
*/
97103
abstract protected AdaptableHeuristicFunction createHeuristic(int heuIdx);
98104

99105
/**
100-
* Template method, responsible for creating and starting the agent.
101-
* Scenario, destinations are selected before as well
102-
* as search method and search heuristic.
106+
* Primitive operation, responsible for creating and starting the agent.
107+
* Scenario, destinations are selected before as well as search method and
108+
* search heuristic.
103109
*/
104110
protected abstract void startAgent();
105-
111+
106112
}

src/aima/gui/applications/search/map/MapAgentModel.java

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,43 +8,48 @@
88
import aima.search.map.Scenario;
99

1010
/**
11-
* Provides a ready-to-use implementation of a model for route planning
12-
* agent applications. It is based on a scenario description and a
13-
* list of destinations. Some features are not used. Subclasses
14-
* can support those features by overriding the methods
15-
* {@link #hasSignpost(String)}, {@link #hasInfos(String)}, and
16-
* {@link #hasObjects(String)}.
11+
* Provides a ready-to-use implementation of a model for route planning agent
12+
* applications. It is based on a scenario description and a list of
13+
* destinations. Some features are not used. Subclasses can support those
14+
* features by overriding the methods {@link #hasSignpost(String)},
15+
* {@link #hasInfos(String)}, and {@link #hasObjects(String)}.
16+
*
1717
* @author R. Lunde
1818
*/
1919
public class MapAgentModel extends AbstractMapAgentModel {
2020
/** A scenario. */
2121
protected Scenario scenario;
2222
/** A list of location names, possibly null. */
2323
protected List<String> destinations;
24-
24+
2525
/**
2626
* Assigns values to the attributes {@link #scenario} and
27-
* {@link #destinations}, clears the history and informs
28-
* all interested listeners about the model change.
29-
* @param s A scenario or null.
30-
* @param d List of location names or null.
27+
* {@link #destinations}, clears the history and informs all interested
28+
* listeners about the model change.
29+
*
30+
* @param s
31+
* A scenario or null.
32+
* @param d
33+
* List of location names or null.
3134
*/
3235
public void prepare(Scenario s, List<String> d) {
3336
scenario = s;
3437
destinations = d;
3538
clearTourHistory();
3639
fireModelChanged();
3740
}
38-
41+
3942
/** Checks whether there is a scenario available. */
43+
@Override
4044
public boolean isEmpty() {
4145
return scenario == null;
4246
}
43-
47+
4448
/**
45-
* Returns all location names mentioned in the environment map
46-
* or in the agent map.
49+
* Returns all location names mentioned in the environment map or in the
50+
* agent map.
4751
*/
52+
@Override
4853
public List<String> getLocations() {
4954
List<String> result = scenario.getEnvMap().getLocations();
5055
if (!result.containsAll(scenario.getAgentMap().getLocations())) {
@@ -55,34 +60,46 @@ public List<String> getLocations() {
5560
}
5661
return result;
5762
}
63+
64+
@Override
5865
public Map getAgentMap() {
5966
return scenario.getAgentMap();
6067
}
68+
69+
@Override
6170
public Map getEnvMap() {
6271
return scenario.getEnvMap();
6372
}
73+
74+
@Override
6475
public Agent getAgent() {
6576
return (Agent) scenario.getEnv().getAgents().get(0);
6677
}
78+
79+
@Override
6780
public boolean isStart(String loc) {
6881
return scenario.getInitAgentLocation() == loc;
6982
}
83+
84+
@Override
7085
public boolean isDestination(String loc) {
7186
return destinations != null && destinations.contains(loc);
7287
}
88+
89+
@Override
7390
public double[] getLocCoords(String loc) {
7491
return scenario.getEnvMap().getXY(loc);
7592
}
93+
7694
/** Always returns false. */
77-
public boolean hasSignpost(String loc) {
78-
return false;
79-
}
80-
/** Always returns false. */
95+
@Override
8196
public boolean hasInfos(String loc) {
8297
return false; // not implemented yet
8398
}
99+
84100
/** Always returns false. */
101+
@Override
85102
public boolean hasObjects(String loc) {
86-
return false;
103+
return false; // not implemented yet
87104
}
88105
}

src/aima/search/map/MapAgent.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public void setHeuristicFunction(HeuristicFunction heuristicFunction) {
6666
//
6767
@Override
6868
protected Object updateState(Percept p) {
69-
currentLocation = (String) p.getAttribute("In");
69+
currentLocation = (String) p.getAttribute(DynAttributeNames.PERCEPT_IN);
7070

7171
return currentLocation;
7272
}

src/aima/search/map/MapEnvironment.java

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@
1414
*/
1515

1616
public class MapEnvironment extends Environment {
17-
public static final String STATE_IN = "In";
18-
19-
private static final String LOCATION = "location";
2017

2118
private Map aMap = null;
2219

@@ -26,19 +23,28 @@ public MapEnvironment(Map aMap) {
2623

2724
public void addAgent(Agent a, String startLocation) {
2825
super.addAgent(a);
29-
a.setAttribute(LOCATION, startLocation);
26+
a.setAttribute(DynAttributeNames.AGENT_LOCATION, startLocation);
27+
a.setAttribute(DynAttributeNames.AGENT_TRAVEL_DISTANCE, 0);
3028
}
3129

3230
@Override
3331
public void executeAction(Agent a, String act) {
34-
if (!Agent.NO_OP.equals(act)) {
35-
a.setAttribute(LOCATION, act);
32+
String currLoc = (String) a
33+
.getAttribute(DynAttributeNames.AGENT_LOCATION);
34+
Integer distance = aMap.getDistance(currLoc, act);
35+
if (distance != null) {
36+
int currTD = (Integer) a
37+
.getAttribute(DynAttributeNames.AGENT_TRAVEL_DISTANCE);
38+
a.setAttribute(DynAttributeNames.AGENT_TRAVEL_DISTANCE, currTD
39+
+ distance);
40+
a.setAttribute(DynAttributeNames.AGENT_LOCATION, act);
3641
}
3742
}
3843

3944
@Override
4045
public Percept getPerceptSeenBy(Agent anAgent) {
41-
return new Percept(STATE_IN, anAgent.getAttribute(LOCATION));
46+
return new Percept(DynAttributeNames.PERCEPT_IN, anAgent
47+
.getAttribute(DynAttributeNames.AGENT_LOCATION));
4248
}
4349

4450
public Map getMap() {

src/aima/search/map/MapGoalTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public boolean isGoalState(Object currentState) {
2424
String location = currentState.toString();
2525
if (currentState instanceof Percept) {
2626
location = (String) ((Percept) currentState)
27-
.getAttribute(MapEnvironment.STATE_IN);
27+
.getAttribute(DynAttributeNames.PERCEPT_IN);
2828
}
2929

3030
return goalState.equals(location);

src/aima/search/map/MapStepCostFunction.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ public Double calculateStepCost(Object fromCurrentState,
3333
String toLoc = toNextState.toString();
3434
if (fromCurrentState instanceof Percept) {
3535
fromLoc = (String) ((Percept) fromCurrentState)
36-
.getAttribute(MapEnvironment.STATE_IN);
36+
.getAttribute(DynAttributeNames.PERCEPT_IN);
3737
toLoc = (String) ((Percept) toNextState)
38-
.getAttribute(MapEnvironment.STATE_IN);
38+
.getAttribute(DynAttributeNames.PERCEPT_IN);
3939
}
4040

4141
Integer distance = map.getDistance(fromLoc, toLoc);

src/aima/search/map/MapSuccessorFunction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public List getSuccessors(Object currentState) {
3030
String location = currentState.toString();
3131
if (currentState instanceof Percept) {
3232
location = (String) ((Percept) currentState)
33-
.getAttribute(MapEnvironment.STATE_IN);
33+
.getAttribute(DynAttributeNames.PERCEPT_IN);
3434
}
3535

3636
List<String> linkedLocations = map.getLocationsLinkedTo(location);

0 commit comments

Comments
 (0)