Files
G4G0-1/Semester 1/Programming 1/Java/examples/projects/chapter12/foxes-and-rabbits-v1/FieldStats.java
2024-01-15 20:14:10 +00:00

129 lines
3.6 KiB
Java
Executable File

import java.awt.Color;
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 and Michael Kölling
* @version 2016.02.29
*/
public class FieldStats
{
// Counters for each type of entity (fox, rabbit, etc.) in the simulation.
private HashMap<Class, Counter> counters;
// Whether the counters are currently up to date.
private boolean countsValid;
/**
* 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.
* @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(' ');
}
return buffer.toString();
}
/**
* 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;
}
}