/** * <code>pickTarget</code> picks the best <code>GoalSpot</code> based on:<br> * <ul> * <li> TPD (Total Player Distance): How far are all players away from the <code>GoalSpot</code>?</li> * <li> SD (Spot Distance): How far away is the MovingSpot away from the <code>GoalSpot</code>?</li> * <li> FDC (Fastest Danger Cost): How dangerous is the fastest path to the <code>GoalSpot</code>?</li> * <li> ST (Surround Threat): How dangerous is the area around the <code>GoalSpot</code>?</li> * <li> HD (Highest Danger): What is the highest danger level while moving over the FDC-path to the <code>GoalSpot</code>?</li> * </ul> * @param allGoals the array of all the GoalSpots on the Playfield * @return target the GoalSpot that is the best choice to move to */ public GoalSpot pickTarget(List <GoalSpot> allGoals) { // Create the empty array that will contain all the PossibleTargets. List <PossibleTarget> possibleTargets = new List <PossibleTarget>(); // Create all the PossibleTargets (out of GoalSpots) and set the correct values for HD, TPD, SD, FDC and ST. for (int i = 0; i < allGoals.Count; i++) { //System.out.println("\nGOAL " + i); GoalSpot current = allGoals[i]; possibleTargets[i] = new PossibleTarget(current); PossibleTarget possible = possibleTargets[i]; int calculatedCost = 0; double penalty = 1; // Calculate the Fastest Danger Cost to this spot calculatedCost = current.calculateDangerCost(x, y, possible); //TODO: Move to the calculateSurround() in GoalSpot // Check if the GoalSpot is located against the wall and add a penalty if (current.getX() == 0 || current.getX() == playfield.width - 1 || current.getY() == playfield.height || current.getY() == 0) { penalty = 1.6; } // Set all the values for the variables in PossibleTarget possible.setTPD(current.getTPD()); possible.setSD(current.getSD()); possible.setPenalty(penalty); possible.setCalcCost(calculatedCost); int weightedSurThreat = (int)(current.calculateSurround() * penalty); possible.setSurThreat(weightedSurThreat); //System.out.println("HD: " + possible.getHighestDanger()); //System.out.println("TPD: " + current.getTPD()); //System.out.println("SD: " + current.getSD()); //System.out.println("ST: " + weightedSurThreat); //System.out.println("FDC: " + calculatedCost); } // Loop through all factors and rate them for each of the PossibleTargets foreach (Factor factor in factors) { possibleTargets = rateFactor(possibleTargets, factor); } // Create a new list BestOptions to compare the ratings List <PossibleTarget> bestOptions = new List <PossibleTarget>(); // Compare ratings between all the PossibleTargets bestOptions = compareRatings(possibleTargets); // Check if bestOptions.size() is 1, as that means there is only one best Spot -> return this spot if (bestOptions.Count == 1) { //System.out.println("Found directly!"); return(bestOptions[0].toGoalSpot()); } // Else: Continue with all the best options left // Make new list to be rated on independent factors (bestOptions = backup) //List<PossibleTarget> compareOptions = bestOptions; // Loop through all the factors and compare them for all the remaining best options //System.out.println("Compare again: "); foreach (Factor current in factors) { //System.out.println(bestOptions.get(0).toString()); //System.out.println(bestOptions.get(1).toString()); List <PossibleTarget> compareOptions = compareFactor(current, bestOptions); // If the list has a size of 1 then, a result has been found and return this GoalSpot if (compareOptions.Count == 1) { return(compareOptions[0].toGoalSpot()); // Else reset compareOptions with bestOptions and then try again for the next factor /*} else { * compareOptions = bestOptions; */ } } //System.out.println("Random: "); //If all else fails, pick a random target from the original PossibleTargets return(pickRandomGoal(bestOptions)); }