/// <summary> /// Checks if these fitness values dominate another set of fitness values. /// </summary> /// <param name="mfv">The other set of fitness values.</param> /// <returns>True if these fitness values dominate the input values, false if not.</returns> public bool Dominates(MapFitnessValues mfv) { if (this.BaseSpaceFitness < mfv.BaseSpaceFitness) { return(false); } if (this.BaseHeightLevelFitness < mfv.BaseHeightLevelFitness) { return(false); } if (this.PathBetweenStartBasesFitness < mfv.PathBetweenStartBasesFitness) { return(false); } if (this.NewHeightReachedFitness < mfv.NewHeightReachedFitness) { return(false); } if (this.DistanceToNaturalExpansionFitness < mfv.DistanceToNaturalExpansionFitness) { return(false); } if (this.DistanceToNonNaturalExpansionFitness < mfv.DistanceToNonNaturalExpansionFitness) { return(false); } if (this.ExpansionsAvailableFitness < mfv.ExpansionsAvailableFitness) { return(false); } if (this.ChokePointFitness < mfv.ChokePointFitness) { return(false); } if (this.XelNagaPlacementFitness < mfv.XelNagaPlacementFitness) { return(false); } if (this.StartBaseOpennessFitness < mfv.StartBaseOpennessFitness) { return(false); } if (this.BaseOpennessFitness < mfv.BaseOpennessFitness) { return(false); } return(this.BaseSpaceFitness > mfv.BaseSpaceFitness || this.BaseHeightLevelFitness > mfv.BaseHeightLevelFitness || this.PathBetweenStartBasesFitness > mfv.PathBetweenStartBasesFitness || this.NewHeightReachedFitness > mfv.NewHeightReachedFitness || this.DistanceToNaturalExpansionFitness > mfv.DistanceToNaturalExpansionFitness || this.DistanceToNonNaturalExpansionFitness > mfv.DistanceToNonNaturalExpansionFitness || this.ExpansionsAvailableFitness > mfv.ExpansionsAvailableFitness || this.ChokePointFitness > mfv.ChokePointFitness || this.XelNagaPlacementFitness > mfv.XelNagaPlacementFitness || this.StartBaseOpennessFitness > mfv.StartBaseOpennessFitness || this.BaseOpennessFitness > mfv.BaseOpennessFitness); }
/// <summary> /// Calculates the fitness for the map. /// </summary> /// <returns> A double representing the fitness of the map. The higher, the better. </returns> public double CalculateFitness() { this.bases = new List <Position>(); // Find a startbase. No need to find all start bases, as the other base should be a complete mirror of this base. for (var tempY = this.ySize - 1; tempY >= 0; tempY--) { for (var tempX = 0; tempX < this.xSize; tempX++) { // Find start base 1 if (this.map.MapItems[tempX, tempY] == Enums.Item.StartBase && this.startBasePosition2 == null) { this.startBasePosition2 = new Tuple <int, int>(tempX + 2, tempY - 2); } // Find start base 2 if (this.map.MapItems[tempX, tempY] == Enums.Item.StartBase && this.startBasePosition1 == null && this.startBasePosition2 != null) { if (Math.Abs(tempX - this.startBasePosition2.Item1) > 3 || Math.Abs(tempY - this.startBasePosition2.Item2) > 3) { this.startBasePosition1 = new Position(tempX + 2, tempY - 2); } } // Check for highest level if ((this.map.HeightLevels[tempX, tempY] == Enums.HeightLevel.Height1 || this.map.HeightLevels[tempX, tempY] == Enums.HeightLevel.Height2) && this.map.HeightLevels[tempX, tempY] > this.heighestLevel) { this.heighestLevel = this.map.HeightLevels[tempX, tempY]; } var tempPos = new Position(tempX, tempY); // Check if the area is a base if (this.map.MapItems[tempX, tempY] == Enums.Item.Base && !MapHelper.CloseToAny(tempPos, this.bases, 5)) { this.bases.Add(new Position(tempX + 2, tempY - 2)); } // Save the first XelNaga tower found if (this.map.MapItems[tempX, tempY] == Enums.Item.XelNagaTower && this.xelNagaPosition2 == null) { this.xelNagaPosition2 = tempPos; } // Save the second XelNaga tower found if (this.map.MapItems[tempX, tempY] == Enums.Item.XelNagaTower && this.xelNagaPosition2 != null && this.xelNagaPosition1 == null && !MapHelper.CloseTo(tempPos, this.xelNagaPosition2, 4)) { this.xelNagaPosition1 = tempPos; } } } // If no start bases are found, the map is not feasible and running fitness calculations is not worth it. if (this.startBasePosition1 == null || this.startBasePosition2 == null) { this.FitnessValues = new MapFitnessValues( -this.mfo.MaxTotalFitness, -this.mfo.MaxTotalFitness, -this.mfo.MaxTotalFitness, -this.mfo.MaxTotalFitness, -this.mfo.MaxTotalFitness, -this.mfo.MaxTotalFitness, -this.mfo.MaxTotalFitness, -this.mfo.MaxTotalFitness, -this.mfo.MaxTotalFitness, -this.mfo.MaxTotalFitness, -this.mfo.MaxTotalFitness); return(this.FitnessValues.TotalFitness); } this.pathBetweenStartBases = this.mapPathfinding.FindPathFromTo( this.startBasePosition1, this.startBasePosition2, this.mfo.PathfindingIgnoreDestructibleRocks); var baseSpace = this.BaseSpace(); var baseHeight = this.BaseHeightLevel(); var pathBetweenStartBasesFitness = this.PathBetweenStartBases(); var newHeightReached = this.NewHeightReached(); var distanceToNaturalExpansion = this.DistanceToNaturalExpansion(); var distanceToNonNaturalExpansions = this.DistanceToNonNaturalExpansions(); var expansionsAvailable = this.ExpansionsAvailable(); var chokePoints = this.ChokePoints(); var xelNagaPlacement = this.XelNagaPlacement(); var startBaseOpeness = this.StartBaseOpeness(); var baseOpeness = this.BaseOpeness(); this.FitnessValues = new MapFitnessValues( baseSpace, baseHeight, pathBetweenStartBasesFitness, newHeightReached, distanceToNaturalExpansion, distanceToNonNaturalExpansions, expansionsAvailable, chokePoints, xelNagaPlacement, startBaseOpeness, baseOpeness); return(this.FitnessValues.TotalFitness); }