package solutions; import de.tu_darmstadt.es.sopra.exercises.Game; import de.tu_darmstadt.es.sopra.model.external.factories.CommandFactory; import de.tu_darmstadt.es.sopra.model.external.interfaces.scenario.IScenario; import de.tu_darmstadt.es.sopra.model.external.interfaces.scenario.ILocation; import de.tu_darmstadt.es.sopra.model.external.interfaces.scenario.ITransporter; import de.tu_darmstadt.es.sopra.model.external.interfaces.scenario.IProductionFacility; import de.tu_darmstadt.es.sopra.model.external.interfaces.scenario.IScenarioElement; import de.tu_darmstadt.es.sopra.model.external.implementations.type.GoodType; import de.tu_darmstadt.es.sopra.model.external.implementations.type.LocationType; import de.tu_darmstadt.es.sopra.model.external.interfaces.command.ITransporterCommand; import java.util.Vector; /** * This class implements a solution of AB4.1.

* * @author Markus Schmidt * @version 1.2 */ public class Solution09 extends Game { private final String[] strAuthors = { "Markus", "Lukas", "Paulus", "Loddar" }; /** * A single command factory object for the whole runtime. */ private CommandFactory cmdFactory; /** * The object to compute shortest paths. */ private Solution08 impAPSP; /** * a flag to indicate the end of the exercise */ private boolean bolFinished; /** * transporter t1 */ private ITransporter traT1; /** * location of type pump */ private ILocation locPump; /** * location of type mill */ private ILocation locMill; /** * shortest path to solve exercise (Vector of location names). */ private Vector vecPath; /** * Constructor with no arguments.

* */ public Solution09() { super(); // Create command factory object, APSP object and Vector to store path. impAPSP = new Solution08(); cmdFactory = new CommandFactory(); vecPath = new Vector(); // init variables bolFinished = true; locPump = null; locMill = null; } /** * Returns informations of the team.

* * @return text with team information */ public String getTeam() { return "G1T9"; } /** * Returns version of this implementation.

* * @return version as text. */ public String getVersion() { return "1.0"; } /** * Returns authors of this solution.

* * @return String array with author names */ public String[] getAuthors() { return strAuthors; } /** * This method is called once before the first round.

* This is a good place to do some initialization for the whole game. * * @param scenario the scenario * @see #planningPhase */ public void preparationPhase(IScenario scenario) { Solution04 impSol4; IScenarioElement locT1; Vector vecPumps, vecMills; String strLoc1, strLoc2, strLocs[]; // create array of location names strLocs = (String[]) scenario.getLocations().keySet().toArray(new String[0]); // try to get location of transporter t1 and the transporter itself try { traT1 = scenario.getTransporter("t1"); locT1 = traT1.getVisitedScenarioElement(); } catch (Exception e) { traT1 = null; locT1 = null; } // try to get all pump locations and mill locations impSol4 = new Solution04(); vecPumps = impSol4.getLocationsOfType(scenario, LocationType.PUMP); vecMills = impSol4.getLocationsOfType(scenario, LocationType.MILL); // calculate if all necessary parts are available bolFinished = ((locT1 == null) || (traT1 == null) || (vecPumps == null) || (vecMills == null) || (vecPumps.size() == 0) || (vecMills.size() == 0)); if (!bolFinished) { // compute APSP impAPSP.computeAPSP(scenario, strLocs); // compute minimal duration out of all possible combinations computeShortestDuration(locT1, vecPumps, vecMills); // create Vector containing the whole path. strLoc1 = locT1.getId(); strLoc2 = locPump.getId(); if (strLoc1.equals(strLoc2)) vecPath.add(strLoc1); else vecPath.addAll(impAPSP.getShortestPath(strLoc1, strLoc2)); vecPath.addAll(impAPSP.getShortestPath(strLoc2, locMill.getId())); } } /** * This method is called at the start of every round.

* * * @param scenario the scenario * @param round the current round (first round is 1). * @see #preparationPhase */ public void planningPhase(IScenario scenario, int round) { // check scenario if (bolFinished) finished(); else { if (round == 1) doRound1(scenario); else doRounds2_N(scenario); } } /** * Do all actions for round 1.

* * @param scenario a scenario */ private void doRound1(IScenario scenario) { IProductionFacility proPump; String strLocation; try { // create command to produce water and start production proPump = (IProductionFacility) locPump; proPump.assignCommand(cmdFactory.getProduceCommand(proPump)); // start transporter if not at pump location strLocation = vecPath.remove(0); if (!strLocation.equals(locPump.getId())) // send transporter to first destination travel(scenario); } catch (Exception e) { } } /** * Do all actions for rounds greater than 1.

* * @param scenario a scenario */ private void doRounds2_N(IScenario scenario) { ITransporterCommand cmdTrans; String strLocation; int intTransportedLoad; // get current location and transporter load strLocation = traT1.getVisitedScenarioElement().getId(); intTransportedLoad = traT1.getTransportedGoodSet().getTotalQuantity(); try { // check for upload: location must be pump if (strLocation.equals(locPump.getId())) { // check transporter load if (intTransportedLoad == 0) { // production must be finished if (!((IProductionFacility)locPump).hasCommand()) { cmdTrans = cmdFactory.getUploadCommand(traT1, 20, GoodType.WATER); traT1.assignCommand(cmdTrans); } } else { // upload finished. // remove current location and travel to next location vecPath.remove(0); travel(scenario); } } // check for unload: location must be mill AND good loaded else if ((strLocation.equals(locMill.getId())) && (intTransportedLoad == 20)) { // unload 20 units of water cmdTrans = cmdFactory.getUnloadCommand(traT1, 20, GoodType.WATER); traT1.assignCommand(cmdTrans); // set flag to finish bolFinished = true; } // on the road. try to travel to next location else { if ((traT1.getCommand() == null) && (!vecPath.isEmpty())) travel(scenario); } } catch (Exception e) { } } /** * create and assign a command to travel to next destination.

* * @param scenario a scenario */ private void travel(IScenario scenario) { ILocation locTemp; try { // create and assign travel command to next destination locTemp = scenario.getLocation(vecPath.get(0)); traT1.assignCommand(cmdFactory.getTravelCommand(traT1, locTemp)); // remove used destination vecPath.remove(0); } catch (Exception e) { } } /** * Computes the whole duration to solve the exercise with the given locations.

* * @param trans location of transporter * @param pump location of pump * @param mill location of mill */ private void computeShortestDuration(IScenarioElement transporter, Vector pumps, Vector mills) { int intI, intJ, intMinDuration, intDuration; // init minimal duration intMinDuration = Integer.MAX_VALUE; // calculate duration of all possible combinations for (intI = 0; intI < pumps.size(); intI++) for (intJ = 0; intJ < mills.size(); intJ++) { // get duration for the current combination intDuration = getDuration(transporter, pumps.get(intI), mills.get(intJ)); // shorter duration found? if (intDuration < intMinDuration) { // set combination with shortest duration locPump = pumps.get(intI); locMill = mills.get(intJ); intMinDuration = intDuration; } } } /** * Returns the whole duration to solve the exercise with the given locations.

* * @param trans location of transporter * @param pump location of pump * @param mill location of mill * @return duration */ private int getDuration(IScenarioElement trans, ILocation pump, ILocation mill) { int intT2P, intP2M; // get durations to travel between two locations intT2P = impAPSP.getShortestPathDuration(trans.getId(), pump.getId()); intP2M = impAPSP.getShortestPathDuration(pump.getId(), mill.getId()); // is duration to reach pump higher than production time? if (intT2P > 2) return intT2P + 1 + intP2M + 1; else return 2 + 1 + intP2M + 1; } }