-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathWorldModel.java
More file actions
191 lines (163 loc) · 4.24 KB
/
WorldModel.java
File metadata and controls
191 lines (163 loc) · 4.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
import java.util.Arrays;
import java.util.List;
import java.util.LinkedList;
public class WorldModel
{
private Background[][] background;
private WorldEntity[][] occupancy;
private List<WorldEntity> entities;
private int numRows;
private int numCols;
private OrderedList<Action> actionQueue;
public WorldModel(int numRows, int numCols, Background background)
{
this.background = new Background[numRows][numCols];
this.occupancy = new WorldEntity[numRows][numCols];
this.numRows = numRows;
this.numCols = numCols;
this.entities = new LinkedList<>();
this.actionQueue = new OrderedList<>();
for (int row = 0; row < numRows; row++)
{
Arrays.fill(this.background[row], background);
}
}
public boolean withinBounds(Point pt)
{
return pt.x >= 0 && pt.x < numCols && pt.y >= 0 && pt.y < numRows;
}
public int getNumRows()
{
return numRows;
}
public int getNumCols()
{
return numCols;
}
public List<WorldEntity> getEntities()
{
return entities;
}
public boolean isOccupied(Point pt)
{
return withinBounds(pt) && getCell(occupancy, pt) != null;
}
public WorldEntity findNearest(Point pt, Class type)
{
List<WorldEntity> ofType = new LinkedList<>();
for (WorldEntity entity : entities)
{
if (type.isInstance(entity))
{
ofType.add(entity);
}
}
return nearestEntity(ofType, pt);
}
public void addEntity(WorldEntity entity)
{
Point pt = entity.getPosition();
if (withinBounds(pt))
{
WorldEntity old = getCell(occupancy, pt);
if (old != null)
{
old.remove(this);
}
setCell(occupancy, pt, entity);
entities.add(entity);
}
}
public void moveEntity(WorldEntity entity, Point pt)
{
if (withinBounds(pt))
{
Point oldPt = entity.getPosition();
setCell(occupancy, oldPt, null);
removeEntityAt(pt);
setCell(occupancy, pt, entity);
entity.setPosition(pt);
}
}
public void removeEntity(WorldEntity entity)
{
removeEntityAt(entity.getPosition());
}
public void removeEntityAt(Point pt)
{
if (withinBounds(pt) && getCell(occupancy, pt) != null)
{
WorldEntity entity = getCell(occupancy, pt);
entity.setPosition(new Point(-1, -1));
entities.remove(entity);
setCell(occupancy, pt, null);
}
}
public Background getBackground(Point pt)
{
return withinBounds(pt) ? getCell(background, pt) : null;
}
public void setBackground(Point pt, Background bgnd)
{
if (withinBounds(pt))
{
setCell(background, pt, bgnd);
}
}
public WorldEntity getTileOccupant(Point pt)
{
return withinBounds(pt) ? getCell(occupancy, pt) : null;
}
public void scheduleAction(Action action, long time)
{
actionQueue.insert(action, time);
}
public void unscheduleAction(Action action)
{
actionQueue.remove(action);
}
public void updateOnTime(long time)
{
OrderedList.ListItem<Action> next = actionQueue.head();
while (next != null && next.ord < time)
{
actionQueue.pop();
next.item.execute(time);
next = actionQueue.head();
}
}
private static WorldEntity nearestEntity(List<WorldEntity> entities,
Point pt)
{
if (entities.size() == 0)
{
return null;
}
WorldEntity nearest = entities.get(0);
double nearest_dist = distance_sq(nearest.getPosition(), pt);
for (WorldEntity entity : entities)
{
double dist = distance_sq(entity.getPosition(), pt);
if (dist < nearest_dist)
{
nearest = entity;
nearest_dist = dist;
}
}
return nearest;
}
private static double distance_sq(Point p1, Point p2)
{
double dx = p1.x - p2.x;
double dy = p1.y - p2.y;
return dx * dx + dy * dy;
}
private static <T> T getCell(T[][] grid, Point pt)
{
return grid[pt.y][pt.x];
}
private static <T> void setCell(T[][] grid, Point pt, T v)
{
grid[pt.y][pt.x] = v;
}
}