Newer
Older
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
package model;
import java.util.*;
public class FirefighterBoard implements Board<List<ModelElement>> {
private final int columnCount;
private final int rowCount;
private final int initialFireCount;
private final int initialFirefighterCount;
List<Position> firefighterPositions;
Set<Position> firePositions;
List<Position> firefighterNewPositions;
int step = 0;
public FirefighterBoard(int columnCount, int rowCount, int initialFireCount, int initialFirefighterCount) {
this.columnCount = columnCount;
this.rowCount = rowCount;
this.initialFireCount = initialFireCount;
this.initialFirefighterCount = initialFirefighterCount;
initializeElements();
}
public void initializeElements() {
firefighterPositions = new ArrayList<>();
firePositions = new HashSet<>();
for (int index = 0; index < initialFireCount; index++)
firePositions.add(randomPosition());
for (int index = 0; index < initialFirefighterCount; index++)
firefighterPositions.add(randomPosition());
}
private Position randomPosition() {
return new Position((int) (Math.random() * rowCount), (int) (Math.random() * columnCount));
}
@Override
public List<ModelElement> getState(Position position) {
List<ModelElement> result = new ArrayList<>();
for(Position firefighterPosition : firefighterPositions)
if (firefighterPosition.equals(position))
result.add(ModelElement.FIREFIGHTER);
if(firePositions.contains(position))
result.add(ModelElement.FIRE);
return result;
}
@Override
public int rowCount() {
return rowCount;
}
@Override
public int columnCount() {
return columnCount;
}
public List<Position> updateToNextGeneration() {
List<Position> result = activateFirefighters();
result.addAll(activateFires());
step++;
return result;
}
private List<Position> activateFires() {
List<Position> result = new ArrayList<>();
if (step % 2 == 0) {
List<Position> newFirePositions = new ArrayList<>();
for (Position fire : firePositions) {
newFirePositions.addAll(neighbors(fire));
}
firePositions.addAll(newFirePositions);
result.addAll(newFirePositions);
}
return result;
}
private List<Position> activateFirefighters() {
List<Position> result = new ArrayList<>();
firefighterNewPositions = new ArrayList<>();
for (Position firefighterPosition : firefighterPositions) {
Position newFirefighterPosition = neighborClosestToFire(firefighterPosition);
result.add(firefighterPosition);
result.add(newFirefighterPosition);
firefighterNewPositions.add(newFirefighterPosition);
extinguish(newFirefighterPosition);
List<Position> neighborFirePositions = neighbors(newFirefighterPosition).stream().filter(firePositions::contains).toList();
for(Position firePosition : neighborFirePositions)
extinguish(firePosition);
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
}
firefighterPositions = firefighterNewPositions;
return result;
}
@Override
public void reset() {
initializeElements();
}
private void extinguish(Position position) {
firePositions.remove(position);
}
private List<Position> neighbors(Position position) {
List<Position> list = new ArrayList<>();
if (position.row() > 0) list.add(new Position(position.row() - 1, position.column()));
if (position.column() > 0) list.add(new Position(position.row(), position.column() - 1));
if (position.row() < rowCount - 1) list.add(new Position(position.row() + 1, position.column()));
if (position.column() < columnCount - 1) list.add(new Position(position.row(), position.column() + 1));
return list;
}
private Position neighborClosestToFire(Position position) {
Set<Position> seen = new HashSet<>();
HashMap<Position, Position> firstMove = new HashMap<>();
Queue<Position> toVisit = new LinkedList<>(neighbors(position));
for (Position initialMove : toVisit)
firstMove.put(initialMove, initialMove);
while (!toVisit.isEmpty()) {
Position current = toVisit.poll();
if (firePositions.contains(current))
return firstMove.get(current);
for (Position adjacent : neighbors(current)) {
if (seen.contains(adjacent)) continue;
toVisit.add(adjacent);
seen.add(adjacent);
firstMove.put(adjacent, firstMove.get(current));
}
}
return position;
}
}