-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFieldStats.java
executable file
·139 lines (130 loc) · 4.11 KB
/
FieldStats.java
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
import java.util.HashMap;
/**
* This class collects and provides some statistical data on the state
* of a field. It is flexible: it will create and maintain a counter
* for any class of object that is found within the field.
*
* @author David J. Barnes, Michael Kölling, Syraj Alkhalil and Cosmo Colman
* @version 2022.02.27 (2)
*/
public class FieldStats {
private final HashMap<Class, Counter> counters; // Counters for each type of entity (fox, rabbit, etc.) in the simulation.
private boolean countsValid; // Whether the counters are currently up-to-date.
/**
* Construct a FieldStats object.
*/
public FieldStats() {
// Set up a collection for counters for each type of animal that
// we might find
counters = new HashMap<>();
countsValid = true;
}
/**
* Get details of what is in the field.
*
* @param field the current field
* @return A string describing what is in the field.
*/
public String getPopulationDetails(Field field) {
StringBuffer buffer = new StringBuffer();
if(!countsValid) {
generateCounts(field);
}
for(Class key : counters.keySet()) {
Counter info = counters.get(key);
buffer.append(info.getName());
buffer.append(": ");
buffer.append(info.getCount());
buffer.append(' ');
buffer.append(' ');
buffer.append(' ');
buffer.append(' ');
}
return buffer.toString();
}
/**
* Get total amount of entities on the field.
* @return The total amount of entities.
*/
public int getTotalCount(Field field) {
int total = 0;
if(!countsValid) {
generateCounts(field);
}
for(Class key : counters.keySet()) {
Counter info = counters.get(key);
total += info.getCount();
}
return total;
}
/**
* Invalidate the current set of statistics; reset all
* counts to zero.
*/
public void reset() {
countsValid = false;
for(Class key : counters.keySet()) {
Counter count = counters.get(key);
count.reset();
}
}
/**
* Increment the count for one class of animal.
* @param animalClass The class of animal to increment.
*/
public void incrementCount(Class animalClass) {
Counter count = counters.get(animalClass);
if(count == null) {
// We do not have a counter for this species yet.
// Create one.
count = new Counter(animalClass.getName());
counters.put(animalClass, count);
}
count.increment();
}
/**
* Indicate that an animal count has been completed.
*/
public void countFinished() {
countsValid = true;
}
/**
* Determine whether the simulation is still viable.
* I.e., should it continue to run.
* @return true If there is more than one species alive.
*/
public boolean isViable(Field field) {
// How many counts are non-zero.
int nonZero = 0;
if(!countsValid) {
generateCounts(field);
}
for(Class key : counters.keySet()) {
Counter info = counters.get(key);
if(info.getCount() > 0) {
nonZero++;
}
}
return nonZero > 1;
}
/**
* Generate counts of the number of foxes and rabbits.
* These are not kept up to date as foxes and rabbits
* are placed in the field, but only when a request
* is made for the information.
*
* @param field The field to generate the stats for.
*/
private void generateCounts(Field field) {
reset();
for(int row = 0; row < field.getDepth(); row++) {
for(int col = 0; col < field.getWidth(); col++) {
Object animal = field.getObjectAt(row, col);
if(animal != null) {
incrementCount(animal.getClass());
}
}
}
countsValid = true;
}
}