Skip to content

Commit ed65db1

Browse files
committed
Extension point for 2D vacuum environments added.
1 parent c357f48 commit ed65db1

File tree

6 files changed

+106
-78
lines changed

6 files changed

+106
-78
lines changed

aima-core/src/main/java/aima/core/environment/vacuum/ModelBasedReflexVacuumAgent.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ protected DynamicState updateState(DynamicState state,
6262
private static Set<Rule> getRuleSet() {
6363
// Note: Using a LinkedHashSet so that the iteration order (i.e. implied
6464
// precedence) of rules can be guaranteed.
65-
Set<Rule> rules = new LinkedHashSet<Rule>();
65+
Set<Rule> rules = new LinkedHashSet<>();
6666

6767
rules.add(new Rule(new ANDCondition(new EQUALCondition(
6868
ATTRIBUTE_STATE_LOCATION_A,
Lines changed: 80 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
package aima.core.environment.vacuum;
22

3-
import java.util.Arrays;
4-
import java.util.List;
5-
import java.util.Random;
6-
73
import aima.core.agent.Action;
84
import aima.core.agent.Agent;
95
import aima.core.agent.EnvironmentState;
106
import aima.core.agent.Percept;
117
import aima.core.agent.impl.AbstractEnvironment;
128
import aima.core.agent.impl.DynamicAction;
139
import aima.core.search.agent.NondeterministicSearchAgent;
10+
import aima.core.util.Util;
11+
12+
import java.util.Arrays;
13+
import java.util.List;
14+
import java.util.Random;
1415

1516
/**
1617
* Artificial Intelligence A Modern Approach (3rd Edition): pg 58.<br>
@@ -25,6 +26,7 @@
2526
* @author Ravi Mohan
2627
* @author Ciaran O'Reilly
2728
* @author Mike Stampone
29+
* @author Ruediger Lunde
2830
*/
2931
public class VacuumEnvironment extends AbstractEnvironment {
3032
// Allowable Actions within the Vacuum Environment
@@ -38,23 +40,21 @@ public enum LocationState {
3840
Clean, Dirty
3941
}
4042

41-
//
43+
private final List<String> locations;
4244
protected VacuumEnvironmentState envState = null;
4345
protected boolean isDone = false;
4446

4547
/**
46-
* Constructs a vacuum environment with two locations, in which dirt is
48+
* Constructs a vacuum environment with two locations A and B, in which dirt is
4749
* placed at random.
4850
*/
4951
public VacuumEnvironment() {
50-
Random r = new Random();
51-
envState = new VacuumEnvironmentState(
52-
0 == r.nextInt(2) ? LocationState.Clean : LocationState.Dirty,
53-
0 == r.nextInt(2) ? LocationState.Clean : LocationState.Dirty);
52+
this(Util.randomBoolean() ? LocationState.Clean : LocationState.Dirty,
53+
Util.randomBoolean() ? LocationState.Clean : LocationState.Dirty);
5454
}
5555

5656
/**
57-
* Constructs a vacuum environment with two locations, in which dirt is
57+
* Constructs a vacuum environment with two locations A and B, in which dirt is
5858
* placed as specified.
5959
*
6060
* @param locAState
@@ -65,25 +65,69 @@ public VacuumEnvironment() {
6565
* <em>Clean</em> or <em>Dirty</em>.
6666
*/
6767
public VacuumEnvironment(LocationState locAState, LocationState locBState) {
68-
envState = new VacuumEnvironmentState(locAState, locBState);
68+
this(Arrays.asList(LOCATION_A, LOCATION_B), locAState, locBState);
69+
}
70+
71+
protected VacuumEnvironment(List<String> locations, LocationState... locStates) {
72+
this.locations = locations;
73+
envState = new VacuumEnvironmentState();
74+
for (int i = 0; i < locations.size() && i < locStates.length; i++)
75+
envState.setLocationState(locations.get(i), locStates[i]);
76+
}
77+
78+
public List<String> getLocations() {
79+
return locations;
6980
}
7081

7182
public EnvironmentState getCurrentState() {
7283
return envState;
7384
}
74-
75-
public List<String> getLocations() {
76-
return Arrays.asList(LOCATION_A, LOCATION_B);
85+
86+
public LocationState getLocationState(String location) {
87+
return envState.getLocationState(location);
88+
}
89+
90+
public String getAgentLocation(Agent a) {
91+
return envState.getAgentLocation(a);
7792
}
7893

7994
@Override
80-
public void executeAction(Agent a, Action agentAction) {
95+
public void addAgent(Agent a) {
96+
int idx = new Random().nextInt(locations.size());
97+
envState.setAgentLocation(a, locations.get(idx));
98+
super.addAgent(a);
99+
}
81100

101+
public void addAgent(Agent a, String location) {
102+
// Ensure the agent state information is tracked before
103+
// adding to super, as super will notify the registered
104+
// EnvironmentViews that is was added.
105+
envState.setAgentLocation(a, location);
106+
super.addAgent(a);
107+
}
108+
109+
@Override
110+
public Percept getPerceptSeenBy(Agent anAgent) {
111+
if (anAgent instanceof NondeterministicSearchAgent) {
112+
// This agent expects a fully observable environment. It gets a clone of the environment state.
113+
return envState.clone();
114+
}
115+
// Other agents get a local percept.
116+
String agentLocation = envState.getAgentLocation(anAgent);
117+
return new LocalVacuumEnvironmentPercept(agentLocation, envState.getLocationState(agentLocation));
118+
}
119+
120+
@Override
121+
public void executeAction(Agent a, Action agentAction) {
82122
if (ACTION_MOVE_RIGHT == agentAction) {
83-
envState.setAgentLocation(a, LOCATION_B);
123+
int pos = locations.indexOf(getAgentLocation(a));
124+
if (pos < locations.size()-1)
125+
envState.setAgentLocation(a, locations.get(pos + 1));
84126
updatePerformanceMeasure(a, -1);
85127
} else if (ACTION_MOVE_LEFT == agentAction) {
86-
envState.setAgentLocation(a, LOCATION_A);
128+
int pos = locations.indexOf(getAgentLocation(a));
129+
if (pos > 0)
130+
envState.setAgentLocation(a, locations.get(pos - 1));
87131
updatePerformanceMeasure(a, -1);
88132
} else if (ACTION_SUCK == agentAction) {
89133
if (LocationState.Dirty == envState.getLocationState(envState
@@ -99,42 +143,34 @@ public void executeAction(Agent a, Action agentAction) {
99143
}
100144
}
101145

102-
@Override
103-
public Percept getPerceptSeenBy(Agent anAgent) {
104-
if (anAgent instanceof NondeterministicSearchAgent) {
105-
// This agent expects a fully observable environment. It gets a clone of the environment state.
106-
return envState.clone();
107-
}
108-
// Other agents get a local percept.
109-
String agentLocation = envState.getAgentLocation(anAgent);
110-
return new LocalVacuumEnvironmentPercept(agentLocation, envState.getLocationState(agentLocation));
111-
}
112-
113146
@Override
114147
public boolean isDone() {
115148
return super.isDone() || isDone;
116149
}
117150

118-
@Override
119-
public void addAgent(Agent a) {
120-
int idx = new Random().nextInt(2);
121-
envState.setAgentLocation(a, idx == 0 ? LOCATION_A : LOCATION_B);
122-
super.addAgent(a);
151+
152+
// Information for grid views...
153+
154+
public int getXDimension() {
155+
return locations.size();
123156
}
124157

125-
public void addAgent(Agent a, String location) {
126-
// Ensure the agent state information is tracked before
127-
// adding to super, as super will notify the registered
128-
// EnvironmentViews that is was added.
129-
envState.setAgentLocation(a, location);
130-
super.addAgent(a);
158+
public int getYDimension() {
159+
return 1;
131160
}
132161

133-
public LocationState getLocationState(String location) {
134-
return envState.getLocationState(location);
162+
// 1 means left
163+
public int getX(String location) {
164+
return getLocations().indexOf(location) % getXDimension() + 1;
135165
}
136166

137-
public String getAgentLocation(Agent a) {
138-
return envState.getAgentLocation(a);
167+
// 1 means bottom
168+
public int getY(String location) {
169+
return getYDimension() - getLocations().indexOf(location) / getXDimension();
170+
}
171+
172+
// (1, 1) is bottom left
173+
public String getLocation(int x, int y) {
174+
return locations.get((getYDimension() - y) * getXDimension() + x - 1);
139175
}
140176
}

aima-core/src/main/java/aima/core/environment/vacuum/VacuumEnvironmentState.java

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,6 @@ public VacuumEnvironmentState() {
2727
agentLocations = new LinkedHashMap<>();
2828
}
2929

30-
/**
31-
* Constructor
32-
*
33-
* @param locAState
34-
* @param locBState
35-
*/
36-
public VacuumEnvironmentState(VacuumEnvironment.LocationState locAState,
37-
VacuumEnvironment.LocationState locBState) {
38-
this();
39-
state.put(VacuumEnvironment.LOCATION_A, locAState);
40-
state.put(VacuumEnvironment.LOCATION_B, locBState);
41-
}
42-
4330
public String getAgentLocation(Agent a) {
4431
return agentLocations.get(a);
4532
}

aima-core/src/main/java/aima/core/util/Util.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55

66
/**
77
* @author Ravi Mohan
8+
* @author Ruediger Lunde
89
*
910
*/
1011
public class Util {
1112
public static final String NO = "No";
1213
public static final String YES = "Yes";
13-
//
14+
1415
private static Random random = new Random();
1516

1617
private static final double EPSILON = 0.000000000001;
@@ -91,9 +92,12 @@ public static <T> T selectRandomlyFromSet(Set<T> set) {
9192
return iterator.next();
9293
}
9394

95+
public static int randomInt(int bound) {
96+
return random.nextInt(bound);
97+
}
98+
9499
public static boolean randomBoolean() {
95-
int trueOrFalse = random.nextInt(2);
96-
return (!(trueOrFalse == 0));
100+
return random.nextInt(2) == 1;
97101
}
98102

99103
public static double[] normalize(double[] probDist) {

aima-gui/src/main/java/aima/gui/fx/views/AbstractGridEnvironmentViewCtrl.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ protected AbstractGridEnvironmentViewCtrl(StackPane viewRoot, ToIntFunction<Envi
5151
splitPane.setStyle("-fx-background-color: white");
5252
envStateView.setMinWidth(0.0);
5353
envStateView.setCenter(gridPane);
54-
//viewRoot.setAlignment(Pos.BOTTOM_CENTER);
5554
squareSize.bind(Bindings.min(envStateView.widthProperty().subtract(20).divide(xDimension),
5655
envStateView.heightProperty().subtract(20).subtract(actionLabel.heightProperty()).divide(yDimension)));
5756
squareSize.addListener((obs, o, n) -> updateFontSize());
@@ -66,8 +65,9 @@ protected AbstractGridEnvironmentViewCtrl(StackPane viewRoot, ToIntFunction<Envi
6665
envStateView.setBottom(actionLabel);
6766
}
6867

68+
/** (1, 1) is bottom left. */
6969
protected SquareButton getSquareButton(int x, int y) {
70-
return squareButtons.get((y - 1) * xDimension.get() + x - 1);
70+
return squareButtons.get((yDimension.get() - y) * xDimension.get() + x - 1);
7171
}
7272

7373
@Override
@@ -102,14 +102,12 @@ private void updateDimensions() {
102102
gridPane.getColumnConstraints().add(cc);
103103

104104
squareButtons.clear();
105-
for (int y = 1; y <= yDim; y++) {
105+
for (int y = yDim; y >= 1; y--) {
106106
for (int x = 1; x <= xDim; x++) {
107107
final int x1 = x;
108108
final int y1 = y;
109109
SquareButton btn = new SquareButton();
110110
btn.getIdLabel().setText(x1 + ", " + y1);
111-
if (squareSize.get() < 80)
112-
btn.getIdLabel().setVisible(false);
113111
btn.setOnAction(ev -> onEdit(x1, y1));
114112
squareButtons.add(btn);
115113
gridPane.add(btn, x - 1, yDim - y);
@@ -119,8 +117,10 @@ private void updateDimensions() {
119117
}
120118

121119
private void updateFontSize() {
122-
for (SquareButton btn : squareButtons)
120+
for (SquareButton btn : squareButtons) {
123121
btn.getLabel().setFont(Font.font(squareSize.get() * fontSizeFactor));
122+
btn.getIdLabel().setVisible(squareSize.get() >= 80);
123+
}
124124
}
125125

126126
/** Can be called from any thread. */

aima-gui/src/main/java/aima/gui/fx/views/VacuumEnvironmentViewCtrl.java

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ public class VacuumEnvironmentViewCtrl extends AbstractGridEnvironmentViewCtrl {
3030
private Map<Agent, Arc> agentSymbols = new HashMap<>();
3131

3232
public VacuumEnvironmentViewCtrl(StackPane viewRoot) {
33-
super(viewRoot, env -> ((VacuumEnvironment) env).getLocations().size(), env -> 1);
33+
super(viewRoot, env -> ((VacuumEnvironment) env).getXDimension(),
34+
env -> ((VacuumEnvironment) env).getYDimension());
3435
}
3536

3637
@Override
@@ -39,10 +40,10 @@ public void initialize(Environment env) {
3940
agentOrientations.clear();
4041
agentSymbols.clear();
4142
super.initialize(env);
42-
List<String> locations = ((VacuumEnvironment) env).getLocations();
43-
for (int x = 1; x <= locations.size(); x++) {
44-
SquareButton btn = getSquareButton(x, 1);
45-
btn.getIdLabel().setText(locations.get((x - 1)));
43+
VacuumEnvironment vEnv = (VacuumEnvironment) env;
44+
for (String loc : vEnv.getLocations()) {
45+
SquareButton btn = getSquareButton(vEnv.getX(loc), vEnv.getY(loc));
46+
btn.getIdLabel().setText(loc);
4647
}
4748
}
4849

@@ -62,17 +63,17 @@ else if (action == VacuumEnvironment.ACTION_MOVE_RIGHT)
6263
@Override
6364
protected void update() {
6465
VacuumEnvironment vEnv = ((VacuumEnvironment) env);
65-
List<String> locations = vEnv.getLocations();
66-
for (int x = 1; x <= locations.size(); x++) {
67-
SquareButton btn = getSquareButton(x, 1);
68-
if (vEnv.getLocationState(locations.get(x-1)).equals(LocationState.Dirty))
66+
for (String loc : vEnv.getLocations()) {
67+
SquareButton btn = getSquareButton(vEnv.getX(loc), vEnv.getY(loc));
68+
if (vEnv.getLocationState(loc).equals(LocationState.Dirty))
6969
btn.getLabel().setText("Dirty");
7070
else
7171
btn.getLabel().setText(""); // "Clean"
7272
btn.getPane().getChildren().clear();
7373
}
7474
for (Agent agent : vEnv.getAgents()) {
75-
SquareButton btn = getSquareButton(locations.indexOf(vEnv.getAgentLocation(agent)) + 1, 1);
75+
String loc = vEnv.getAgentLocation(agent);
76+
SquareButton btn = getSquareButton(vEnv.getX(loc), vEnv.getY(loc));
7677
Integer orientation = agentOrientations.get(agent);
7778
if (orientation == null)
7879
orientation = 0;
@@ -87,7 +88,7 @@ protected void onEdit(int x, int y) {
8788
else {
8889
VacuumEnvironment vEnv = (VacuumEnvironment) env;
8990
VacuumEnvironmentState state = (VacuumEnvironmentState) vEnv.getCurrentState();
90-
String loc = vEnv.getLocations().get(x-1);
91+
String loc = vEnv.getLocation(x, y);
9192
state.setLocationState(loc,
9293
state.getLocationState(loc) == LocationState.Clean ? LocationState.Dirty : LocationState.Clean);
9394
update();

0 commit comments

Comments
 (0)