/// <summary> /// Run a growth cycle for the universe. /// </summary> /// <param name="universe">The universe.</param> /// <param name="genome">The genome.</param> public void RunGrowth(PlantUniverse universe, double[] genome) { // Does this plant have enough roots to grow? if (universe.SurfaceCount < AIFH.DefaultPrecision) { return; } // The amount of leafy material per root nourishment. A higher number indicates // more root nourishment than leafs. double rootRatio = universe.RootCount/universe.SurfaceCount; bool allowRoot = rootRatio < 0.5; //rootRatio < 0.1; bool allowSurface = rootRatio > 0.5; // Reset the new composition to be the composition of the current universe for (int row = 0; row < PlantUniverse.UniverseHeight; row++) { for (int col = 0; col < PlantUniverse.UniverseWidth; col++) { _newComposition[row][col] = false; } } for (int row = 0; row < PlantUniverse.UniverseHeight; row++) { for (int col = 0; col < PlantUniverse.UniverseWidth; col++) { PlantUniverseCell cell = universe.GetCell(row, col); // see if we want to change the composition if (row < PlantUniverse.GroundLine) { double[] cellVec = universe.GetCellInfoVector(row, col); double d1 = _dist.Calculate(cellVec, 0, genome, 0, PlantUniverse.CellVectorLength); double d2 = _dist.Calculate(cellVec, 0, genome, PlantUniverse.CellVectorLength, PlantUniverse.CellVectorLength); if (d1 < d2) { cell.Leafyness = (cell.Leafyness*PlantUniverse.StemTransition); } } // Evaluate growth into each neighbor cell if (universe.CanGrow(row, col)) { EvaluateNeighbors(universe, row, col, genome, allowRoot, allowSurface); } } } // Copy the new composition back to the universe for (int row = 0; row < PlantUniverse.UniverseHeight; row++) { for (int col = 0; col < PlantUniverse.UniverseWidth; col++) { PlantUniverseCell cell = universe.GetCell(row, col); if (_newComposition[row][col]) { cell.Leafyness = row >= PlantUniverse.GroundLine ? 0 : 1.0; cell.Energy = 1.0; cell.Nourishment = 1.0; } } } }
/// <summary> /// Calculate the growth potential for a candidate cell. Evaluates the distance between the candidate cell's info /// vector and the two growth vectors in the genome. The minimum of these two vectors will be returned if /// it is below a specified minimum threshold. /// </summary> /// <param name="universe">The universe to evaluate.</param> /// <param name="row">The row to evaluate.</param> /// <param name="col">The column to evaluate.</param> /// <param name="genome">The genome.</param> /// <returns>The minimum distance.</returns> private double GetGrowthPotential(PlantUniverse universe, int row, int col, double[] genome) { double[] cellVec = universe.GetCellInfoVector(row, col); double d1 = _dist.Calculate(cellVec, 0, genome, PlantUniverse.CellVectorLength*2, PlantUniverse.CellVectorLength); double d2 = _dist.Calculate(cellVec, 0, genome, PlantUniverse.CellVectorLength*3, PlantUniverse.CellVectorLength); double result = Math.Min(d1, d2); if (result > PlantUniverse.MinGrowthDist) { result = -1; } return result; }