Ejemplo n.º 1
0
        public void DoWork()
        {
            var physics = new PlantPhysics();
            var growth = new PlantGrowth();
            var universe = new PlantUniverse();

            universe.Reset();

            _display.Universe = universe;

            for (int i = 0; i < PlantUniverse.EvaluationCycles && !_done; i++)
            {
                physics.RunPhysics(universe);
                growth.RunGrowth(universe, SamplePlant);

                if (!Dispatcher.CheckAccess())
                {
                    Dispatcher.Invoke(() => _display.Paint());
                }
                else
                {
                    _display.Paint();
                }

                Thread.Sleep(100);
            }
            Thread.Sleep(100);
        }
Ejemplo n.º 2
0
        /// <inheritdoc />
        public double CalculateScore(IMLMethod algo)
        {
            var genome = (DoubleArrayGenome) algo;
            var universe = new PlantUniverse();
            universe.Reset();
            var physics = new PlantPhysics();
            var growth = new PlantGrowth();

            // Run the generations.
            for (int i = 0; i < PlantUniverse.EvaluationCycles; i++)
            {
                physics.RunPhysics(universe);
                growth.RunGrowth(universe, genome.Data);
            }

            // Count the amount of green.
            int count = 0;
            double sum = 0;
            for (int row = 0; row < PlantUniverse.UniverseHeight; row++)
            {
                for (int col = 0; col < PlantUniverse.UniverseWidth; col++)
                {
                    PlantUniverseCell cell = universe.GetCell(row, col);
                    if (cell.IsAlive)
                    {
                        if (row >= PlantUniverse.GroundLine)
                        {
                            sum += 0.5;
                        }
                        else
                        {
                            sum += cell.Leafyness;
                        }
                    }
                    count++;
                }
            }
            return sum/count;
        }
Ejemplo n.º 3
0
        /**
     * Distribute the sunlight energy in the universe.
     *
     * @param universe The universe.
     */

        private void DistributeEnergy(PlantUniverse universe)
        {
            // Distribute sun energy downward
            var sunlight = new double[PlantUniverse.UniverseWidth];
            for (int i = 0; i < sunlight.Length; i++)
            {
                sunlight[i] = 1.0;
            }

            for (int row = 0; row < PlantUniverse.UniverseHeight; row++)
            {
                for (int col = 0; col < PlantUniverse.UniverseWidth; col++)
                {
                    // no sun underground
                    double decay = row >= PlantUniverse.GroundLine ? 0 : 1;

                    PlantUniverseCell cell = universe.GetCell(row, col);
                    cell.CalculatedSunlight = sunlight[col];

                    // Collect resources for live cells
                    if (cell.IsAlive)
                    {
                        // Live cells cause the sunlight to decay (shade)
                        decay *= PlantUniverse.Decay*cell.Leafyness;

                        // Set the energy based on sunlight level and composition of the live cell
                        double myEnergy = cell.CalculatedSunlight*cell.Leafyness;
                        double transEnergy = universe.CalculateTransferEnergy(row, col)*(1.0 - cell.Leafyness);
                        double e = Math.Max(myEnergy, transEnergy);
                        e = Math.Max(PlantUniverse.MinLivingEnergy, e);
                        cell.Energy = e;
                    }

                    sunlight[col] *= decay;
                }
            }
        }
Ejemplo n.º 4
0
        /**
         * Distribute nourishment in the universe.
         *
         * @param universe The universe.
         */

        private void DistributeNourishment(PlantUniverse universe)
        {
            double rootCount = 0;
            double surfaceCount = 0;

            // Distribute sun energy downward
            var waterTable = new double[PlantUniverse.UniverseWidth];
            for (int i = 0; i < waterTable.Length; i++)
            {
                waterTable[i] = 1.0;
            }

            for (int row = PlantUniverse.UniverseHeight - 1; row >= 0; row--)
            {
                for (int col = 0; col < PlantUniverse.UniverseWidth; col++)
                {
                    double decay;

                    // no water above ground
                    decay = row < PlantUniverse.GroundLine ? 0 : 1;

                    PlantUniverseCell cell = universe.GetCell(row, col);
                    cell.CalculatedWater = waterTable[col];

                    // Collect resources for live cells
                    if (cell.IsAlive)
                    {
                        // Live cells cause the water to decay (roots collect)
                        decay *= PlantUniverse.Decay;

                        // Set the energy based on sunlight level and composition of the live cell
                        double myWater = cell.CalculatedWater*cell.Leafyness;
                        double transWater = universe.CalculateTransferNourishment(row, col)*(1.0 - cell.Leafyness);
                        double n = Math.Max(myWater, transWater);
                        n = Math.Max(PlantUniverse.MinLivingEnergy, n);
                        cell.Nourishment = n;

                        // update the root and surface counts
                        if (row >= PlantUniverse.GroundLine)
                        {
                            rootCount += cell.Nourishment;
                        }
                        else
                        {
                            surfaceCount += cell.Leafyness;
                        }
                    }

                    waterTable[col] *= decay;
                }
            }

            universe.RootCount = rootCount;
            universe.SurfaceCount = surfaceCount;
        }
Ejemplo n.º 5
0
 public void RunPhysics(PlantUniverse universe)
 {
     DistributeEnergy(universe);
     DistributeNourishment(universe);
 }
Ejemplo n.º 6
0
        private void Window_Loaded_1(object sender, RoutedEventArgs e)
        {
            pop = InitPopulation();
            score = new PlantScore();
            this.genetic = new BasicEA(pop, score);

            //this.genetic.Speciation = new ArraySpeciation<DoubleArrayGenome>();

            genetic.AddOperation(0.9, new Splice(PlantUniverse.GenomeSize / 3));
            genetic.AddOperation(0.1, new MutatePerturb(0.1));

            // Display

            this.universe = new PlantUniverse();
            this.universe.Reset();


            DoubleArrayGenome bestGenome = (DoubleArrayGenome)genetic.BestGenome;
            PlantPhysics physics = new PlantPhysics();
            PlantGrowth growth = new PlantGrowth();

            for (int i = 0; i < 100; i++)
            {
                physics.RunPhysics(universe);
                growth.RunGrowth(universe, bestGenome.Data);
            }

            this.display = new DisplayPlant(CanvasOutput);
            this.display.Universe = this.universe;
            Thread t = new Thread(DoWork);
            t.Start();
        }
Ejemplo n.º 7
0
        /// <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;
                    }
                }
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        ///     Evaluate neighbors to see where to grow into.
        /// </summary>
        /// <param name="universe">The universe.</param>
        /// <param name="row">The row.</param>
        /// <param name="col">The column.</param>
        /// <param name="genome">The genome.</param>
        /// <param name="allowRoot">Are roots allowed?</param>
        /// <param name="allowSurface">Is surface growth allowed.</param>
        private void EvaluateNeighbors(PlantUniverse universe, int row, int col, double[] genome, bool allowRoot,
            bool allowSurface)
        {
            int growthTargetRow = row;
            int growthTargetCol = col;
            double growthTargetScore = double.PositiveInfinity;

            for (int i = 0; i < _colTransform.Length; i++)
            {
                int evalCol = col + _colTransform[i];
                int evalRow = row + _rowTransform[i];

                if (!allowRoot && evalRow >= PlantUniverse.GroundLine)
                {
                    continue;
                }

                if (!allowSurface && evalRow < PlantUniverse.GroundLine)
                {
                    continue;
                }

                if (universe.IsValid(evalRow, evalCol))
                {
                    double p = GetGrowthPotential(universe, evalRow, evalCol, genome);
                    if (p > 0)
                    {
                        if (p < growthTargetScore)
                        {
                            growthTargetScore = p;
                            growthTargetRow = evalRow;
                            growthTargetCol = evalCol;
                        }
                    }
                }
            }

            // Grow new cell, if requested, did we ever set target row & col to anything?
            if (growthTargetRow != row || growthTargetCol != col)
            {
                _newComposition[growthTargetRow][growthTargetCol] = true;
            }
        }
Ejemplo n.º 9
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;
        }