/// <summary> /// Adds a condition to the rule. /// </summary> /// <param name="levelToCheckFor"> The level the neighbours should be. </param> /// <param name="probabilities"> How to compare. </param> public void SetCondition(Enums.HeightLevel levelToCheckFor, double[] probabilities) { this.Conditions.Add( probabilities == null ? this.Condition = new Tuple <Enums.HeightLevel, double[]>(levelToCheckFor, new[] { 1d }) : this.Condition = new Tuple <Enums.HeightLevel, double[]>(levelToCheckFor, probabilities)); }
/// <summary> /// Initializes a new instance of the <see cref="RuleProbabilistic"/> class. /// </summary> /// <param name="transformTo"> What to transform to if the rule holds. </param> public RuleProbabilistic(Enums.HeightLevel transformTo) : this() { this.TransformTo = transformTo; }
/// <summary> /// Initializes a new instance of the <see cref="RuleProbabilistic"/> class. /// </summary> /// <param name="transformTo"> What to transform to if the rule holds. </param> /// <param name="self"> The height level the position being checked should have, in order for the rule to be applied. </param> public RuleProbabilistic(Enums.HeightLevel transformTo, Enums.HeightLevel self) : this() { this.Self = self; this.TransformTo = transformTo; }
/// <summary> /// Finds the position of the nearest tile of the given type. /// </summary> /// <param name="x"> The x-coordinate of the start position. </param> /// <param name="y"> The y-coordinate of the start position. </param> /// <param name="map"> The map to work on. </param> /// <param name="toFind"> The type of tile to find. </param> /// <param name="adhereToPathfinding"> Determines if we are adhering to pathfinding or not. </param> /// <returns> The position of the nearest found tile of the given type or null. </returns> public static Position FindNearestTileOfType(int x, int y, Enums.HeightLevel[,] map, Enums.HeightLevel toFind, bool adhereToPathfinding = false) { var tileList = new List <Enums.HeightLevel>(); var visitedPositions = new List <Position>(); var openPositions = new List <Position>(); Position result = null; openPositions.Add(new Position(x, y)); while (!(openPositions.Count <= 0)) { if (result != null) { break; } var currentPos = openPositions[0]; openPositions.Remove(currentPos); visitedPositions.Add(currentPos); tileList.Add(map[currentPos.Item1, currentPos.Item2]); var neighbours = MapPathfinding.Neighbours(map, currentPos); foreach (var neighbour in neighbours) { if (map[neighbour.Item1, neighbour.Item2] == toFind) { result = neighbour; } if (visitedPositions.Contains(neighbour) || openPositions.Contains(neighbour)) { continue; } if (adhereToPathfinding && map[neighbour.Item1, neighbour.Item2] == Enums.HeightLevel.Cliff) { continue; } if (adhereToPathfinding && map[neighbour.Item1, neighbour.Item2] == Enums.HeightLevel.Impassable) { continue; } openPositions.Add(neighbour); } } return(result); }
/// <summary> /// Adds a condition to the rule. /// </summary> /// <param name="number"> The number of neighbours that should satisfy the condition. </param> /// <param name="levelToCheckFor"> The level the neighbours should be. </param> /// <param name="comparisonType"> How to compare. </param> public void AddCondition(int number, Enums.HeightLevel levelToCheckFor, RuleEnums.Comparison comparisonType = RuleEnums.Comparison.GreaterThanEqualTo) { this.Conditions.Add(new Tuple <int, Enums.HeightLevel, RuleEnums.Comparison>(number, levelToCheckFor, comparisonType)); }
/// <summary> /// Initializes a new instance of the <see cref="RuleDeterministic"/> class. /// </summary> /// <param name="transformTo"> What to transform to if the rule holds. </param> /// <param name="self"> The height level the position being checked should have, in order for the rule to be applied. </param> public RuleDeterministic(Enums.HeightLevel transformTo, Enums.HeightLevel self) : this() { this.Self = self; this.TransformTo = transformTo; }
/// <summary> /// Initializes a new instance of the <see cref="RuleDeterministic"/> class. /// </summary> /// <param name="transformTo"> What to transform to if the rule holds. </param> public RuleDeterministic(Enums.HeightLevel transformTo) : this() { this.TransformTo = transformTo; }
/// <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); }