Skip to content

Commit 8b0689c

Browse files
Ruediger.LundeRuediger.Lunde
authored andcommitted
New GUI classes added including a framework for building agent applications and two examples (vacuum agent, map agent).
1 parent 5cbdc2d commit 8b0689c

23 files changed

+2512
-0
lines changed

src/aima/basic/Agent.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414
*/
1515
public abstract class Agent extends ObjectWithDynamicAttributes {
1616

17+
/**
18+
* Name of an action which indicates, the Agent is unwilling to generate any
19+
* more goals and should therefore DIE. This indicates final success.
20+
*/
21+
public static final String DIE = "DIE";
1722
// Used to define No Operations/Action is to be performed.
1823
public static final String NO_OP = "NoOP";
1924

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
package aima.gui.applications;
2+
3+
import java.awt.Color;
4+
import java.util.ArrayList;
5+
import java.util.Hashtable;
6+
import java.util.List;
7+
8+
import aima.basic.Agent;
9+
import aima.basic.vaccum.*;
10+
import aima.gui.framework.AgentAppController;
11+
import aima.gui.framework.AgentAppFrame;
12+
import aima.gui.framework.AgentAppModel;
13+
import aima.gui.framework.AgentView;
14+
import aima.gui.framework.SimpleAgentAppDemo;
15+
16+
/**
17+
* Simple graphical application for experiments with vacuum cleaner agents.
18+
* It can be used as a template for creating other graphical agent
19+
* applications.
20+
* @author R. Lunde
21+
*/
22+
public class VacuumAppDemo extends SimpleAgentAppDemo {
23+
24+
/** Returns a <code>VacuumModel</code>. */
25+
public AgentAppModel createModel() {
26+
return new VacuumModel();
27+
}
28+
/** Returns a <code>VacuumFrame</code>. */
29+
public AgentAppFrame createFrame() {
30+
return new VacuumFrame();
31+
}
32+
/** Returns a <code>VacuumController</code>. */
33+
public AgentAppController createController() {
34+
return new VacuumController();
35+
}
36+
37+
38+
/////////////////////////////////////////////////////////////////
39+
// inner classes
40+
41+
/**
42+
* Provides access to the used environment, the names
43+
* of the locations (squares) maintained by the environment, and the
44+
* current state of all locations.
45+
*/
46+
protected static class VacuumModel extends AgentAppModel {
47+
private TrivialVaccumEnvironment env;
48+
private Agent agent;
49+
public static String DIRTY = "Dirty";
50+
51+
public void setEnv(TrivialVaccumEnvironment env) { this.env = env; }
52+
public TrivialVaccumEnvironment getEnv() { return env; }
53+
public void setAgent(Agent agent) { this.agent = agent; }
54+
public Agent getAgent() { return agent; }
55+
56+
/** Returns the names of all locations used. */
57+
public List<String> getLocations() {
58+
List<String> result = new ArrayList<String>();
59+
if (env != null) {
60+
result.add("A");
61+
result.add("B");
62+
}
63+
return result;
64+
}
65+
/** Checks whether the specified location is dirty. */
66+
public boolean isDirty(String location) {
67+
return DIRTY.equals(env.getLocationStatus(location));
68+
}
69+
/** Checks whether the agent is currently at the specified location. */
70+
public boolean hasAgent(String location) {
71+
return agent != null && location.equals(env.getAgentLocation(agent));
72+
}
73+
}
74+
75+
/**
76+
* Adds some selectors to the base class and adjusts its size.
77+
*/
78+
protected static class VacuumFrame extends AgentAppFrame {
79+
public static String ENV_SEL = "EnvSelection";
80+
public static String AGENT_SEL = "AgentSelection";
81+
public VacuumFrame() {
82+
setAgentView(new VacuumView());
83+
setSelectors(
84+
new String[]{ENV_SEL, AGENT_SEL},
85+
new String[]{"Select Environment", "Select Agent"});
86+
setSelectorItems(ENV_SEL, new String[]{"A/B Environment"}, 0);
87+
setSelectorItems(AGENT_SEL, new String[]{
88+
"SimpleReflexVaccumAgent",
89+
"ReflexVaccumAgent",
90+
"ReflexVaccumAgentWithState",
91+
"TableDrivenVaccumAgent",
92+
"ModelBasedTVEVaccumAgent"}, 0);
93+
setTitle("Vacuum Agent Application");
94+
setSize(800, 400);
95+
setUpdateDelay(500);
96+
}
97+
}
98+
99+
/**
100+
* Displays the informations provided by the <code>VacuumModel</code>
101+
* on a panel using 2D-graphics.
102+
*/
103+
protected static class VacuumView extends AgentView {
104+
Hashtable<String, int[]> dirtLookup = new Hashtable<String, int[]>();
105+
106+
int[] getDirt(String location) {
107+
int[] coords = dirtLookup.get(location);
108+
if (coords == null) {
109+
java.util.Random rand = new java.util.Random();
110+
int size = rand.nextInt(8)+4;
111+
coords = new int[2*size];
112+
for (int i = 0; i < size; i++) {
113+
coords[2*i] = rand.nextInt(6)+1;
114+
coords[2*i+1] = rand.nextInt(8)+1;
115+
}
116+
}
117+
dirtLookup.put(location, coords);
118+
return coords;
119+
}
120+
121+
/**
122+
* Creates a 2D-graphics showing the agent in its environment.
123+
* Locations are represented as rectangles, dirt as grey ovals,
124+
* and the agent as red circle.
125+
*/
126+
public void paint(java.awt.Graphics g) {
127+
VacuumModel vmodel = (VacuumModel) model;
128+
List<String> locations = vmodel.getLocations();
129+
this.adjustTransformation(0, 0, 11*locations.size()-1, 10);
130+
java.awt.Graphics2D g2 = (java.awt.Graphics2D) g;
131+
g2.setColor(Color.white);
132+
g2.fillRect(0, 0, getWidth(), getHeight());
133+
for (int i = 0; i < locations.size(); i++) {
134+
String location = locations.get(i);
135+
g2.setColor(Color.black);
136+
g2.drawRect(x(11*i), y(0), scale(10), scale(10));
137+
if (vmodel.isDirty(location)) {
138+
int[] coords = getDirt(location);
139+
for (int j = 0; j < coords.length; j+=2) {
140+
g2.setColor(Color.lightGray);
141+
g2.fillOval(x(11*i+coords[j]), y(coords[j+1]), scale(3), scale(2));
142+
}
143+
}
144+
g2.setColor(Color.black);
145+
g2.drawString(location, x(11*i)+10, y(0)+20);
146+
if (vmodel.hasAgent(location)) {
147+
g2.setColor(Color.red);
148+
g2.fillOval(x(11*i+2), y(2), scale(6), scale(6));
149+
}
150+
}
151+
}
152+
}
153+
154+
/**
155+
* Defines how to react on user button events.
156+
*/
157+
protected static class VacuumController extends AgentAppController {
158+
/** Does nothing. */
159+
public void clearAgent() {
160+
}
161+
162+
/**
163+
* Creates a vacuum agent and a corresponding environment based
164+
* on the selection state of the selectors and finally updates
165+
* the model.
166+
*/
167+
public void prepareAgent() {
168+
AgentAppFrame.SelectionState selState = frame.getSelection();
169+
TrivialVaccumEnvironment env = null;
170+
Agent agent = null;
171+
switch(selState.getValue(VacuumFrame.ENV_SEL)) {
172+
case 0: env = new TrivialVaccumEnvironment(); break;
173+
}
174+
switch(selState.getValue(VacuumFrame.AGENT_SEL)) {
175+
case 0: agent = new SimpleReflexVaccumAgent(); break;
176+
case 1: agent = new ReflexVaccumAgent(); break;
177+
case 2: agent = new ReflexVaccumAgentWithState(); break;
178+
case 3: agent = new TableDrivenVaccumAgent(); break;
179+
case 4: agent = new ModelBasedTVEVaccumAgent(); break;
180+
}
181+
((VacuumModel) model).setEnv(env);
182+
((VacuumModel) model).setAgent(agent);
183+
if (env != null && agent != null) {
184+
env.addAgent(agent);
185+
env.registerView(model);
186+
frame.modelChanged();
187+
}
188+
}
189+
190+
/** Starts the agent and afterwards updates the status of the frame. */
191+
public void runAgent() {
192+
VacuumModel vmodel = (VacuumModel) model;
193+
frame.logMessage("<simulation-log>");
194+
vmodel.getEnv().stepUntilNoOp();
195+
frame.logMessage("Performance: " +
196+
vmodel.getEnv().getAgentperformance(vmodel.getAgent()));
197+
frame.logMessage("</simulation-log>");
198+
frame.setStatus("Task completed.");
199+
}
200+
}
201+
202+
203+
/////////////////////////////////////////////////////////////////
204+
// main method
205+
206+
/**
207+
* Starts the application.
208+
*/
209+
public static void main(String args[]) {
210+
new VacuumAppDemo().startApplication();
211+
}
212+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package aima.gui.applications.search.map;
2+
3+
import java.util.List;
4+
5+
import aima.basic.Agent;
6+
import aima.gui.framework.AgentAppController;
7+
import aima.search.framework.SearchFactory;
8+
import aima.search.map.AdaptableHeuristicFunction;
9+
import aima.search.map.DynAttributeNames;
10+
import aima.search.map.Scenario;
11+
12+
13+
/**
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.
20+
* @author R. Lunde
21+
*/
22+
public abstract class AbstractMapAgentController extends AgentAppController {
23+
/** A scenario. */
24+
protected Scenario scenario;
25+
/**
26+
* Some location names. For routing problems, only one location should
27+
* be specified.
28+
*/
29+
protected List<String> destinations;
30+
/** Search method to be used. */
31+
protected aima.search.framework.Search search;
32+
/** Heuristic function to be used when performing informed search. */
33+
protected AdaptableHeuristicFunction heuristic;
34+
35+
/** Clears the model's tour history. */
36+
public void clearAgent() {
37+
((AbstractMapAgentModel) model).clearTourHistory();
38+
frame.modelChanged();
39+
}
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)}.
45+
*/
46+
public void prepareAgent() {
47+
MapAgentFrame.SelectionState state = frame.getSelection();
48+
selectScenarioAndDest(
49+
state.getValue(MapAgentFrame.SCENARIO_SEL),
50+
state.getValue(MapAgentFrame.DESTINATION_SEL));
51+
prepareModel();
52+
search = SearchFactory.getInstance().createSearch(
53+
state.getValue(MapAgentFrame.SEARCH_SEL),
54+
state.getValue(MapAgentFrame.SEARCH_MODE_SEL));
55+
heuristic = createHeuristic(
56+
state.getValue(MapAgentFrame.HEURISTIC_SEL));
57+
scenario.getEnv().registerView(model);
58+
}
59+
60+
/** Starts the agent and updates the status bar of the frame. */
61+
public void runAgent() {
62+
startAgent();
63+
List agents = scenario.getEnv().getAgents();
64+
if (agents.size() == 1) {
65+
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);
72+
else
73+
frame.setStatus("Task completed.");
74+
}
75+
}
76+
77+
78+
/////////////////////////////////////////////////////////////////
79+
// abstract methods
80+
81+
/**
82+
* Template method, responsible for assigning values
83+
* to attributes {@link #scenario} and {@link #destinations}.
84+
*/
85+
abstract protected void selectScenarioAndDest(int scenarioIdx, int destIdx);
86+
87+
/**
88+
* Template method, responsible for preparing the model.
89+
* Scenario and destinations are already selected when
90+
* this method is called.
91+
*/
92+
abstract protected void prepareModel();
93+
94+
/**
95+
* Factory method, responsible for creating a heuristic function.
96+
*/
97+
abstract protected AdaptableHeuristicFunction createHeuristic(int heuIdx);
98+
99+
/**
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.
103+
*/
104+
protected abstract void startAgent();
105+
106+
}

0 commit comments

Comments
 (0)