package gis2;
import maps.gml.GMLMap;
import maps.gml.GMLBuilding;
import maps.gml.GMLShape;
import maps.MapReader;
import maps.MapException;
import java.util.Random;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.io.XMLWriter;
import org.dom4j.io.OutputFormat;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
/**
A class for generating random scenarios.
*/
public class RandomScenarioGenerator {
private static final int DEFAULT_MIN_CIVS = 50;
private static final int DEFAULT_MAX_CIVS = 200;
private static final int DEFAULT_MIN_PLATOONS = 0;
private static final int DEFAULT_MAX_PLATOONS = 30;
private static final int DEFAULT_MIN_CENTRES = 0;
private static final int DEFAULT_MAX_CENTRES = 5;
private static final int DEFAULT_MIN_REFUGES = 0;
private static final int DEFAULT_MAX_REFUGES = 5;
private static final int DEFAULT_MIN_FIRES = 1;
private static final int DEFAULT_MAX_FIRES = 10;
private int minCivs;
private int maxCivs;
private int minFBs;
private int maxFBs;
private int minFSs;
private int maxFSs;
private int minPOs;
private int maxPOs;
private int minPFs;
private int maxPFs;
private int minATs;
private int maxATs;
private int minACs;
private int maxACs;
private int minFires;
private int maxFires;
private int minRefuges;
private int maxRefuges;
/**
Construct a RandomScenarioGenerator with default parameters.
*/
public RandomScenarioGenerator() {
minCivs = DEFAULT_MIN_CIVS;
maxCivs = DEFAULT_MAX_CIVS;
minFBs = DEFAULT_MIN_PLATOONS;
maxFBs = DEFAULT_MAX_PLATOONS;
minPFs = DEFAULT_MIN_PLATOONS;
maxPFs = DEFAULT_MAX_PLATOONS;
minATs = DEFAULT_MIN_PLATOONS;
maxATs = DEFAULT_MAX_PLATOONS;
minFSs = DEFAULT_MIN_CENTRES;
maxFSs = DEFAULT_MAX_CENTRES;
minPOs = DEFAULT_MIN_CENTRES;
maxPOs = DEFAULT_MAX_CENTRES;
minACs = DEFAULT_MIN_CENTRES;
maxACs = DEFAULT_MAX_CENTRES;
minFires = DEFAULT_MIN_FIRES;
maxFires = DEFAULT_MAX_FIRES;
minRefuges = DEFAULT_MIN_REFUGES;
maxRefuges = DEFAULT_MAX_REFUGES;
}
/**
Entry point.
@param args Command line arguments: <map directory> [-civ min max] [-fb min max] [-fs min max] [-pf min max] [-po min max] [-at min max] [-ac min max] [-refuge min max] [-fire min max].
*/
public static void main(String[] args) {
String dirName = args[0];
RandomScenarioGenerator generator = new RandomScenarioGenerator();
// CHECKSTYLE:OFF:ModifiedControlVariable
for (int i = 1; i < args.length; ++i) {
if ("-civ".equals(args[i])) {
int min = Integer.parseInt(args[i + 1]);
int max = Integer.parseInt(args[i + 2]);
i += 2;
generator.setCivilians(min, max);
}
else if ("-fb".equals(args[i])) {
int min = Integer.parseInt(args[i + 1]);
int max = Integer.parseInt(args[i + 2]);
i += 2;
generator.setFireBrigades(min, max);
}
else if ("-fs".equals(args[i])) {
int min = Integer.parseInt(args[i + 1]);
int max = Integer.parseInt(args[i + 2]);
i += 2;
generator.setFireStations(min, max);
}
else if ("-pf".equals(args[i])) {
int min = Integer.parseInt(args[i + 1]);
int max = Integer.parseInt(args[i + 2]);
i += 2;
generator.setPoliceForces(min, max);
}
else if ("-po".equals(args[i])) {
int min = Integer.parseInt(args[i + 1]);
int max = Integer.parseInt(args[i + 2]);
i += 2;
generator.setPoliceOffices(min, max);
}
else if ("-at".equals(args[i])) {
int min = Integer.parseInt(args[i + 1]);
int max = Integer.parseInt(args[i + 2]);
i += 2;
generator.setAmbulanceTeams(min, max);
}
else if ("-ac".equals(args[i])) {
int min = Integer.parseInt(args[i + 1]);
int max = Integer.parseInt(args[i + 2]);
i += 2;
generator.setAmbulanceCentres(min, max);
}
else if ("-refuge".equals(args[i])) {
int min = Integer.parseInt(args[i + 1]);
int max = Integer.parseInt(args[i + 2]);
i += 2;
generator.setRefuges(min, max);
}
else if ("-fire".equals(args[i])) {
int min = Integer.parseInt(args[i + 1]);
int max = Integer.parseInt(args[i + 2]);
i += 2;
generator.setFires(min, max);
}
}
// CHECKSTYLE:ON:ModifiedControlVariable
try {
File dir = new File(dirName);
GMLMap map = (GMLMap)MapReader.readMap(new File(dir, "map.gml"));
Scenario s = generator.makeRandomScenario(map, new Random());
Document doc = DocumentHelper.createDocument();
s.write(doc);
XMLWriter writer = new XMLWriter(new FileOutputStream(new File(dir, "scenario.xml")), OutputFormat.createPrettyPrint());
writer.write(doc);
writer.flush();
writer.close();
}
catch (IOException e) {
e.printStackTrace();
}
catch (MapException e) {
e.printStackTrace();
}
}
/**
Set the minimum and maximum number of civilians.
@param min The new minimum.
@param max The new maximum.
*/
public void setCivilians(int min, int max) {
minCivs = min;
maxCivs = max;
}
/**
Set the minimum and maximum number of fire brigades.
@param min The new minimum.
@param max The new maximum.
*/
public void setFireBrigades(int min, int max) {
minFBs = min;
maxFBs = max;
}
/**
Set the minimum and maximum number of fire stations.
@param min The new minimum.
@param max The new maximum.
*/
public void setFireStations(int min, int max) {
minFSs = min;
maxFSs = max;
}
/**
Set the minimum and maximum number of police forces.
@param min The new minimum.
@param max The new maximum.
*/
public void setPoliceForces(int min, int max) {
minPFs = min;
maxPFs = max;
}
/**
Set the minimum and maximum number of police offices.
@param min The new minimum.
@param max The new maximum.
*/
public void setPoliceOffices(int min, int max) {
minPOs = min;
maxPOs = max;
}
/**
Set the minimum and maximum number of ambulance teams.
@param min The new minimum.
@param max The new maximum.
*/
public void setAmbulanceTeams(int min, int max) {
minATs = min;
maxATs = max;
}
/**
Set the minimum and maximum number of ambulance centres.
@param min The new minimum.
@param max The new maximum.
*/
public void setAmbulanceCentres(int min, int max) {
minACs = min;
maxACs = max;
}
/**
Set the minimum and maximum number of refuges.
@param min The new minimum.
@param max The new maximum.
*/
public void setRefuges(int min, int max) {
minRefuges = min;
maxRefuges = max;
}
/**
Set the minimum and maximum number of fires.
@param min The new minimum.
@param max The new maximum.
*/
public void setFires(int min, int max) {
minFires = min;
maxFires = max;
}
/**
Generate a random scenario.
@param map The map to generate a scenario for.
@param random A source of randomness.
@return A new Scenario.
*/
public Scenario makeRandomScenario(GMLMap map, Random random) {
Scenario result = new Scenario();
int civ = random.nextInt(maxCivs - minCivs + 1) + minCivs;
int fb = random.nextInt(maxFBs - minFBs + 1) + minFBs;
int fs = random.nextInt(maxFSs - minFSs + 1) + minFSs;
int pf = random.nextInt(maxPFs - minPFs + 1) + minPFs;
int po = random.nextInt(maxPOs - minPOs + 1) + minPOs;
int at = random.nextInt(maxATs - minATs + 1) + minATs;
int ac = random.nextInt(maxACs - minACs + 1) + minACs;
int fire = random.nextInt(maxFires - minFires + 1) + minFires;
int refuge = random.nextInt(maxRefuges - minRefuges + 1) + minRefuges;
List<GMLBuilding> buildings = new ArrayList<GMLBuilding>(map.getBuildings());
Collections.shuffle(buildings, random);
Iterator<GMLBuilding> it = buildings.iterator();
placeRefuges(it, result, refuge);
placeCentres(it, result, fs, po, ac);
placeFires(it, result, fire);
placeAgents(map, result, random, fb, pf, at, civ);
return result;
}
private void placeRefuges(Iterator<GMLBuilding> it, Scenario result, int num) {
for (int i = 0; i < num; ++i) {
result.addRefuge(it.next().getID());
}
}
private void placeCentres(Iterator<GMLBuilding> it, Scenario result, int fire, int police, int ambulance) {
for (int i = 0; i < fire; ++i) {
result.addFireStation(it.next().getID());
}
for (int i = 0; i < police; ++i) {
result.addPoliceOffice(it.next().getID());
}
for (int i = 0; i < ambulance; ++i) {
result.addAmbulanceCentre(it.next().getID());
}
}
private void placeFires(Iterator<GMLBuilding> it, Scenario result, int num) {
for (int i = 0; i < num; ++i) {
result.addFire(it.next().getID());
}
}
private void placeAgents(GMLMap map, Scenario result, Random random, int fire, int police, int ambulance, int civ) {
List<GMLShape> all = new ArrayList<GMLShape>(map.getAllShapes());
List<GMLBuilding> buildings = new ArrayList<GMLBuilding>(map.getBuildings());
for (int i = 0; i < fire; ++i) {
int id = all.get(random.nextInt(all.size())).getID();
result.addFireBrigade(id);
}
for (int i = 0; i < police; ++i) {
int id = all.get(random.nextInt(all.size())).getID();
result.addPoliceForce(id);
}
for (int i = 0; i < ambulance; ++i) {
int id = all.get(random.nextInt(all.size())).getID();
result.addAmbulanceTeam(id);
}
for (int i = 0; i < civ; ++i) {
int id = buildings.get(random.nextInt(buildings.size())).getID();
result.addCivilian(id);
}
}
}