예제 #1
0
        private void Flee(Strand strand, Chemoeffector noxious)
        {
            double distance;

            distance = Geometry.GetDistance(strand.Position, noxious.Position);

            if (distance <= 1)
            {
                this.ProcessCollision(strand, noxious, _repellents, _repellentCollisionAction, () => this.AddRepellent());
            }
            else
            {
                if (distance < strand.PreviousSensor)
                {
                    this.Tumble(strand);
                    this.CheckCollisions(strand);
                }
                else
                {
                    double newDistance;
                    Point  heading;
                    heading = strand.Heading;
                    this.Tumble(strand);
                    strand.Move();
                    newDistance = Geometry.GetDistance(strand.Position, noxious.Position);
                    if (newDistance < distance)
                    {
                        strand.Heading = heading;
                    }
                    strand.UndoMove();
                }

                strand.PreviousSensor = distance;
            }
        }
예제 #2
0
 private void CheckFission(Strand strand)
 {
     if (_binaryFission && _environmentRandom.NextDouble() < 0.001 && strand.Strength % 2 == 0)
     {
         strand.Strength /= 2;
         _strands.Add(strand.Copy());
     }
 }
예제 #3
0
        private void Tumble(Strand strand)
        {
            double dir;

            //int x;
            //int y;

            dir = _movementRandom.NextDouble();
            //x = strand.Heading.X;
            //y = strand.Heading.Y;

            if (dir < 0.33)
            {
                // counter-clockwise
                strand.Heading = Compass.GetPrevious(strand.Heading);
            }
            else if (dir > 0.66)
            {
                // clockwise
                strand.Heading = Compass.GetNext(strand.Heading);
            }

            //if (dir < 0.125)
            //{
            //  x = -1;
            //}
            //else if (dir > 0.125 && dir < 0.250)
            //{
            //  x = 1;
            //}
            //else if (dir > 0.250 && dir < 0.375 && y != 0)
            //{
            //  x = 0;
            //}
            //else if (dir > 0.375 && dir < 0.5)
            //{
            //  y = -1;
            //}
            //else if (dir > 0.5 && dir < 0.625)
            //{
            //  y = 1;
            //}
            //else if (dir > 0.625 && dir < 0.75 && x != 0)
            //{
            //  y = 0;
            //}

            //strand.Heading = new Point(x, y);
        }
예제 #4
0
        private void MoveStrand(Strand strand)
        {
            Chemoeffector noxious;

            strand.Move();

            noxious = this.GetClosestRepellor(strand);

            if (noxious != null)
            {
                this.Flee(strand, noxious);
            }
            else
            {
                Chemoeffector food;

                food = this.GetClosestAttractor(strand);

                if (food != null)
                {
                    this.Approach(strand, food);
                }
                else if (strand.PreviousSensor != 0)
                {
                    strand.Heading = Compass.GetOpposite(strand.Heading);
                    this.Tumble(strand);
                    strand.PreviousSensor = 0;
                    this.CheckCollisions(strand);
                }
                else
                {
                    this.Tumble(strand);
                    strand.PreviousSensor = 0;
                    this.CheckCollisions(strand);
                }
            }
        }
예제 #5
0
        private void Approach(Strand strand, Chemoeffector food)
        {
            double distance;

            distance = Geometry.GetDistance(strand.Position, food.Position);

            if (distance <= 1)
            {
                this.ProcessCollision(strand, food, _attractors, _attractorCollisionAction, this.CheckRespawn);

                strand.PreviousSensor = 0;
            }
            else
            {
                if (distance > strand.PreviousSensor)
                {
                    this.Tumble(strand);
                    this.CheckCollisions(strand);
                }
                else
                {
                    double newDistance;
                    Point  heading;
                    heading = strand.Heading;
                    this.Tumble(strand);
                    strand.Move();
                    newDistance = Geometry.GetDistance(strand.Position, food.Position);
                    if (newDistance >= distance)
                    {
                        strand.Heading = heading;
                    }
                    strand.UndoMove();
                }

                strand.PreviousSensor = distance;
            }
        }
예제 #6
0
        private void ProcessCollision(Strand strand, Chemoeffector chemoeffector, ChemoeffectorCollection container, CollisionAction action, Action createNew)
        {
            if (action == CollisionAction.ReduceSelf)
            {
                chemoeffector.Strength--;
                strand.Strength++;
            }
            else if (action == CollisionAction.ReduceOther)
            {
                strand.Strength--;
            }

            if (chemoeffector.Strength <= 0 || action == CollisionAction.DestroySelf)
            {
                container.Remove(chemoeffector);

                createNew();
            }

            if (strand.Strength <= 0 || action == CollisionAction.DestroyOther)
            {
                _strands.Remove(strand);
            }
        }
예제 #7
0
        private Chemoeffector GetStrongestChemoeffector(Strand strand, ChemoeffectorCollection container)
        {
            Chemoeffector result;
            int           strength;

            result   = null;
            strength = 0;

            for (int i = 0; i < container.Count; i++)
            {
                Chemoeffector chemoeffector;

                chemoeffector = container[i];

                if (Geometry.DoesPointIntersectCircle(strand.Position, chemoeffector.Position, (chemoeffector.Strength / 2) + 4) && // add a bit of a buffer so even the smallest have a gradient
                    chemoeffector.Strength > strength)
                {
                    strength = chemoeffector.Strength;
                    result   = chemoeffector;
                }
            }

            return(result);
        }
예제 #8
0
        private void CheckCollisions(Strand strand)
        {
            for (int i = 0; i < _repellents.Count; i++)
            {
                if (Geometry.GetDistance(strand.Position, _repellents[i].Position) <= 1)
                {
                    this.ProcessCollision(strand, _repellents[i], _repellents, _repellentCollisionAction, () => this.AddRepellent());
                }
            }

            for (int i = 0; i < _attractors.Count; i++)
            {
                if (Geometry.GetDistance(strand.Position, _attractors[i].Position) <= 1)
                {
                    this.ProcessCollision(strand, _attractors[i], _attractors, _attractorCollisionAction, this.CheckRespawn);
                    break;
                }
            }

            if (_solidStrands)
            {
                for (int i = 0; i < _strands.Count; i++)
                {
                    Strand other;

                    other = _strands[i];

                    if (!object.ReferenceEquals(strand, other) && strand.Position == other.Position)
                    {
                        strand.UndoMove();
                        strand.Heading = _movementRandom.NextDouble() >= 0.5 ? Compass.GetNextQuarter(strand.Heading) : Compass.GetPreviousQuarter(strand.Heading);
                        break;
                    }
                }
            }
        }
예제 #9
0
 private Chemoeffector GetStrongestRepellor(Strand strand)
 {
     return(this.GetStrongestChemoeffector(strand, _repellents));
 }
예제 #10
0
 private Chemoeffector GetStrongestAttractor(Strand strand)
 {
     return(this.GetStrongestChemoeffector(strand, _attractors));
 }