-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAgent.pde
117 lines (94 loc) · 3.11 KB
/
Agent.pde
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
import java.util.Deque;
import java.util.Collection;
import java.util.Map;
import java.util.HashMap;
abstract class Agent {
Grid grid;
int cellSize;
PVector position;
CellIndex target;
float speed;
Deque<CellIndex> route;
Direction currentDirection;
Map<PathSegment, Integer> paths;
boolean canVisit = false;
boolean drawPath = false;
Agent(Grid _grid, CellIndex start) {
grid = _grid;
cellSize = grid.scale;
position = new PVector(start.x * cellSize, start.y * cellSize, start.z * cellSize);
target = start;
speed = 5;
paths = new HashMap<PathSegment, Integer>();
if (canVisit) {
grid.cells[target.x][target.y][target.z].visit();
}
}
protected CellIndex findClosestUnvistedCell(CellIndex currentPosition) {
Collection<KdTree.XYZPoint> closestUnvisted = grid
.unvistedCells
.nearestNeighbourSearch(1, new KdTree.XYZPoint(
currentPosition.x,
currentPosition.y,
currentPosition.z
));
KdTree.XYZPoint point = closestUnvisted.toArray(new KdTree.XYZPoint[1])[int(random(0, closestUnvisted.size()))];
return new CellIndex((int)point.x, (int)point.y, (int)point.z);
}
protected void setTarget(CellIndex newTarget) {
CellIndex previousTarget = target;
target = newTarget;
PathSegment path = new PathSegment(previousTarget, newTarget);
paths.merge(path, Integer.valueOf(1),(currentCount, one) -> currentCount + one);
currentDirection = previousTarget.equals(newTarget)
? currentDirection
: Direction.between(newTarget, previousTarget);
}
protected void updateTarget() {
throw new RuntimeException("`updateTarget` must be overridden by a base class.");
}
protected void updateVisitedCellColour() {
throw new RuntimeException("`updateVisitedCellColour` must be overridden by a base class.");
}
void move() {
if (
position.x == (target.x * cellSize) &&
position.y == (target.y * cellSize) &&
position.z == (target.z * cellSize)
){
if (canVisit) {
grid.cells[target.x][target.y][target.z].visit();
grid.unvistedCells.remove(new KdTree.XYZPoint(target.x, target.y, target.z));
}
updateVisitedCellColour();
if (grid.unvistedCells.size() == 0) {
return;
}
updateTarget();
}
PVector targetVector = new PVector(target.x * cellSize, target.y * cellSize, target.z * cellSize);
PVector direction = PVector.sub(targetVector, position);
direction.normalize();
float distance = min(PVector.dist(targetVector, position), speed);
position.add(direction.mult(distance));
}
protected void drawAgent() {
throw new RuntimeException("`drawAgent` must be overridden by a base class.");
}
protected void drawPath() {
throw new RuntimeException("`drawPath` must be overridden by a base class.");
}
void draw() {
pushMatrix();
// Translate to centre of cell.
translate(cellSize / 2, cellSize / 2, cellSize / 2);
if (drawPath) {
drawPath();
}
pushMatrix();
translate(position.x, position.y, position.z);
drawAgent();
popMatrix();
popMatrix();
}
}