package ch.fusun.baron.basic.turntask;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import ch.fusun.baron.city.City;
import ch.fusun.baron.city.api.CityService;
import ch.fusun.baron.core.injection.Inject;
import ch.fusun.baron.farm.Farm;
import ch.fusun.baron.farm.FarmService;
import ch.fusun.baron.map.Tile;
import ch.fusun.baron.map.api.GameMapService;
import ch.fusun.baron.player.api.Country;
import ch.fusun.baron.player.api.CountryService;
import ch.fusun.baron.property.api.PropertyService;
import ch.fusun.baron.turn.TurnTask;
/**
* Checks if there is enough food for all citizens and kills surplus
*/
public class CitySurvivalTurnTask implements TurnTask {
@Inject
private FarmService farmService;
@Inject
private GameMapService mapService;
@Inject
private PropertyService propertyService;
@Inject
private CityService cityService;
@Inject
private CountryService countryService;
/**
* Constructor
*/
public CitySurvivalTurnTask() {
}
@Override
public void execute() {
for (Country country : countryService.getCountries()) {
Collection<Farm> farms = getFarmsForCountry(country);
Collection<City> cities = getCitiesForCountry(country);
for (City city : cities) {
Tile location = cityService.getLocation(city);
int food = getNumberOfFarmsNearestTo(location, cities, farms);
city.setPopulation(Math.min(city.getPopulation(), food));
if (city.isDead()) {
cityService.removeCity(city);
}
}
}
}
private Collection<City> getCitiesForCountry(Country country) {
List<City> cities = new LinkedList<City>();
for (Tile tile : mapService.getTiles()) {
City city = cityService.getCity(tile);
if (city != null) {
if (country.equals(propertyService.getOwnership(tile))) {
cities.add(city);
}
}
}
return cities;
}
private Collection<Farm> getFarmsForCountry(Country country) {
List<Farm> farms = new LinkedList<Farm>();
for (Tile tile : mapService.getTiles()) {
Farm farm = farmService.getFarm(tile);
if (farm != null) {
if (country.equals(propertyService.getOwnership(tile))) {
farms.add(farm);
}
}
}
return farms;
}
private int getNumberOfFarmsNearestTo(Tile location,
Collection<City> cities, Collection<Farm> farms) {
int food = 0;
for (Farm farm : farms) {
Tile farmLocation = farmService.getLocation(farm);
double shortestDistance = Double.MAX_VALUE;
Tile nearestLocation = new Tile(Integer.MAX_VALUE,
Integer.MAX_VALUE);
for (City city : cities) {
Tile cityLocation = cityService.getLocation(city);
if (farmLocation.absoluteDistanceTo(cityLocation) <= shortestDistance) {
nearestLocation = cityLocation;
shortestDistance = farmLocation
.absoluteDistanceTo(cityLocation);
}
}
if (nearestLocation.equals(location)) {
food++;
}
}
return food;
}
}