/// <summary> /// Return an info vector about a cell. This allows cells to be identified by instructions in the genome. /// The vector contains four doubles. All doubles range from [0,1]. /// Element 0: The height of the cell. 1.0 for the last row and 0.0 for the first row. /// Element 1: The amount of sunlight (for surface cells) or water (for underground cells) exposure for this cell. /// Element 2: Crowding by neighbors. /// Element 3: Nourishment for this cell. /// </summary> /// <param name="row">The row.</param> /// <param name="col">The column.</param> /// <returns>The info vector.</returns> public double[] GetCellInfoVector(int row, int col) { var result = new double[CellVectorLength]; PlantUniverseCell cell = GetCell(row, col); // Height result[0] = row / UniverseHeight; // Sunlight if (row < GroundLine) { result[1] = cell.CalculatedSunlight; } else { result[1] = cell.CalculatedWater; } // Crowd result[2] = CalculateMeanNeighborsCrowd(row, col); // Nourishment result[3] = cell.Nourishment; // return(result); }
/// <summary> /// Paint the plant. /// </summary> /// <returns></returns> public void Paint() { // Loop over all cells. for (int row = 0; row < PlantUniverse.UniverseHeight; row++) { for (int col = 0; col < PlantUniverse.UniverseWidth; col++) { PlantUniverseCell cell = Universe.GetCell(row, col); Brush brush; // For empty cells display either the ground or sky color. // Roots are always white. if (row >= PlantUniverse.GroundLine) { brush = cell.IsAlive ? Brushes.White : _dirtColor; } else { if (cell.IsAlive) { var idx = (int)((_gradient.Length - 1) * cell.Leafyness); brush = _gradient[idx]; } else { brush = _skyColor; } } _grid[row][col].Fill = brush; } } }
/// <summary> /// Construct the universe and create the grid. /// </summary> public PlantUniverse() { _grid = new PlantUniverseCell[UniverseHeight][]; for (int row = 0; row < _grid.Length; row++) { _grid[row] = new PlantUniverseCell[UniverseWidth]; for (int col = 0; col < _grid[row].Length; col++) { _grid[row][col] = new PlantUniverseCell(); } } }
/// <summary> /// Returns true, if the specified cell can grow. /// </summary> /// <param name="row">The row.</param> /// <param name="col">The column.</param> /// <returns>True, if the specified cell is allowed to grow.</returns> public bool CanGrow(int row, int col) { PlantUniverseCell cell = GetCell(row, col); if (cell.IsAlive) { if (row >= GroundLine) { return(CountNeighbors(row, col) < 4); } return(cell.Energy > GrowthThreshold && cell.Nourishment > GrowthThreshold); } return(false); }
/// <summary> /// Calculate the degree of crowding in a cell. Leafy cells /// produce more crowding than stem. /// </summary> /// <param name="row">The row.</param> /// <param name="col">The column.</param> /// <returns>The crowd imposed by this cell.</returns> public double CalculateCrowd(int row, int col) { if (!IsValid(row, col)) { return(0); } PlantUniverseCell cell = GetCell(row, col); if (!cell.IsAlive) { return(0); } return(cell.Leafyness); }