Ejemplo n.º 1
0
        /// <summary>
        /// Gets the set of floating objects within a reaction radius from a given position.
        /// Only objects unused in this simulation step are considered.
        /// Only objects with no obstacle between them and the given position are considered.
        /// </summary>
        /// <param name="position">Position whose neighborhood is searched</param>
        /// <param name="targetMultiset">OPTIMIZATION: Objects are collected only until this multiset is reached</param>
        private FloatingObjectsSet GetNearObjects(Point3D position, NamedMultiset targetMultiset)
        {
            var missingObjects = new NamedMultiset(targetMultiset.ToDictionary());
            var nearObjectsSet = new FloatingObjectsSet();

            if (!missingObjects.Any())
            {
                return(nearObjectsSet);
            }

            Vector3D radiusVector = new Vector3D(v_MSystem.Mobility, v_MSystem.Mobility, v_MSystem.Mobility);

            var gridKeys = KeysInBox(new Box3D(position - radiusVector, position + radiusVector)).ToList();

            gridKeys.Shuffle();     // Random order of grid boxes where objects are sought for

            foreach (var key in gridKeys)
            {
                foreach (var fltObject in v_Grid[key].OldSet)
                {
                    if (missingObjects.Contains(fltObject.Name) &&
                        fltObject.Position.DistanceTo(position) < fltObject.Type.Mobility &&
                        !v_tilesWorld.IntersectsWith(fltObject.Position, position, false))
                    {
                        nearObjectsSet.Add(fltObject);
                        missingObjects.Remove(fltObject.Name);
                        if (!missingObjects.Any())
                        {
                            return(nearObjectsSet);
                        }
                    }
                }
            }
            return(nearObjectsSet);
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Adds the multiset of floating objects at a given position.
 /// </summary>
 public void AddAt(NamedMultiset multiset, Point3D position)
 {
     foreach (var name in multiset)
     {
         Add(new FloatingObjectInWorld(v_MSystem.FloatingObjects[name], position), true);
     }
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Gets the set of floating objects within the reaction distance from any position of a given connector.
        /// Only objects unused in this simulation step are considered.
        /// TODO low priority: return floating objects close to the whole shape of the connector except endpoints
        /// </summary>
        public FloatingObjectsSet GetNearObjects(ConnectorOnTileInSpace connector, NamedMultiset targetMultiset)
        {
            FloatingObjectsSet objectsSet = new FloatingObjectsSet();

            foreach (var position in connector.Positions)
            {
                objectsSet.UnionWith(GetNearObjects(connector.SidePoint(position), targetMultiset));
            }
            return(objectsSet);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Computes union of a sequence of multisets
        /// </summary>
        /// <param name="list"></param>
        public static NamedMultiset Union(IEnumerable <NamedMultiset> list)
        {
            var result = new NamedMultiset();

            foreach (var element in list)
            {
                result.UnionWith(element);
            }
            return(result);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Metabolic evolution rule constructor.
        /// </summary>
        /// <param name="priority">Priority of the evolution rule.</param>
        /// <param name="leftSideObjects">List of left side objects.</param>
        /// <param name="rightSideObjects">List of right side objects.</param>
        /// <param name="delay">Number of steps which must be done before rule is applied to tiles.</param>
        /// <exception cref="ArgumentException">
        /// If format of the metabolic rule is invalid
        /// </exception>
        public EvoMetabolicRule(int priority, List <ISimulationObject> leftSideObjects, List <ISimulationObject> rightSideObjects, int delay)
            : base(RuleType.Metabolic, priority, leftSideObjects, rightSideObjects, delay)
        {
            string errorMessage = string.Format("{0}\n{1} ", "Invalid metabolic rule format:", this);

            // The rules must contain exactly one protein.
            try
            {
                RProtein = LeftSideObjects.OfType <Protein>().Single();
                if (RProtein != RightSideObjects.OfType <Protein>().Single())
                {
                    throw new ArgumentException(errorMessage);
                }
            }
            catch (InvalidOperationException)
            {
                throw new ArgumentException(errorMessage);
            }


            // The objects before protein are "out" (must be on the outer side of 2D object).
            // The objects after protein are "in" (must be on the inner side of 2D object).
            MLeftOutNames  = new NamedMultiset(LeftSideObjects.TakeWhile(obj => obj is FloatingObject));
            MLeftInNames   = new NamedMultiset(LeftSideObjects.SkipWhile(obj => obj is FloatingObject).OfType <FloatingObject>());
            MRightOutNames = new NamedMultiset(RightSideObjects.TakeWhile(obj => obj is FloatingObject));
            MRightInNames  = new NamedMultiset(RightSideObjects.SkipWhile(obj => obj is FloatingObject).OfType <FloatingObject>());

            // Both left and right-hand side of the rule must contain at least one floating object
            if (MLeftInNames.Count + MLeftOutNames.Count > 0 && MRightInNames.Count + MRightOutNames.Count > 0)
            {
                if (MLeftOutNames.Count + MRightOutNames.Count == 0 || MLeftInNames.Count + MRightInNames.Count == 0)
                {
                    SubType = MetabolicRuleType.Catalyzed;
                }
                else if (MLeftInNames.Equals(MRightOutNames) && MLeftOutNames.Equals(MRightInNames))
                {
                    if (MLeftInNames.Count == 0 || MLeftOutNames.Count == 0)
                    {
                        SubType = MetabolicRuleType.Symport;
                    }
                    else
                    {
                        SubType = MetabolicRuleType.Antiport;
                    }
                }
            }


            if (SubType == MetabolicRuleType.Undefined)
            {
                throw new ArgumentException(errorMessage);
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Removes the multiset of names of floating objects from a given set of floating objects in space
        /// </summary>
        /// <param name="multiset">Multiset of floating object names to be removed</param>
        /// <param name="targetSet">Set of floating objects from which the multiset is removed - all must be of type "FloatingObjectsInWorld"</param>
        /// <exception cref="ArgumentNullException">If the set contains object which is not "FloatingObjectsInWorld"</exception>
        /// <exception cref="ArgumentException">If the multiset could not be removed</exception>
        public void RemoveFrom(NamedMultiset multiset, FloatingObjectsSet targetSet)
        {
            // Deep copy of the original multiset
            NamedMultiset myMultiset = new NamedMultiset(multiset.ToDictionary());

            foreach (var fltObject in targetSet)
            {
                if (myMultiset.Remove(fltObject.Name))
                {
                    Remove(fltObject as FloatingObjectInWorld);
                }
            }

            if (myMultiset.Count > 0)
            {
                throw new ArgumentException($"{myMultiset} could not be removed from the world!");
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Non-metabolic evolution rule constructor.
        /// </summary>
        /// <param name="type">Type of the evolution rule.</param>
        /// <param name="priority">Priority of the evolution rule.</param>
        /// <param name="leftSideObjects">List of left side objects.</param>
        /// <param name="rightSideObjects">List of right side objects.</param>
        /// <param name="delay">Number of steps which must be done before rule is applied to tiles.</param>
        /// <exception cref="ArgumentException">
        /// If format of the non-metabolic rule is invalid
        /// </exception>
        public EvoNonMetabolicRule(RuleType type, int priority, List <ISimulationObject> leftSideObjects, List <ISimulationObject> rightSideObjects, int delay)
            : base(type, priority, leftSideObjects, rightSideObjects, delay)
        {
            string errorMessage = $"{"Invalid rule format:"}\n{this} ";
            bool   correct      = false;

            switch (type)
            {
            case RuleType.Create:
            case RuleType.Insert:
                correct =     //leftSideObjects.Count >= 1 &&
                          leftSideObjects.TrueForAll(obj => obj is FloatingObject) &&
                          rightSideObjects.SingleOrDefault() is Tile;
                break;

            case RuleType.Destroy:
                correct = leftSideObjects.Count >= 2 &&
                          leftSideObjects.OfType <Tile>().Count() == 1 &&
                          leftSideObjects.TrueForAll(obj => obj is FloatingObject || obj is Tile) &&
                          rightSideObjects.TrueForAll(obj => obj is FloatingObject);
                break;

            case RuleType.Divide:
                correct = leftSideObjects.Count >= 3 &&
                          leftSideObjects.OfType <Glue>().Count() == 2 &&
                          leftSideObjects.TrueForAll(obj => obj is FloatingObject || obj is Glue) &&
                          rightSideObjects.Count() == 2 &&
                          rightSideObjects[0] == leftSideObjects.OfType <Glue>().First() &&
                          rightSideObjects[1] == leftSideObjects.OfType <Glue>().Last();
                break;
            }
            if (!correct)
            {
                throw new ArgumentException(errorMessage);
            }

            MLeftSideFloatingNames  = new NamedMultiset(LeftSideObjects.OfType <FloatingObject>());
            MRightSideFloatingNames = new NamedMultiset(RightSideObjects.OfType <FloatingObject>());
        }
Ejemplo n.º 8
0
 /// <summary>
 /// Gets the set of floating objects within a reaction distance from a given position on a tile.
 /// Only objects unused in this simulation step are considered.
 /// If the tile is 2D, only floating objects on the inner/outer side are returned as specified by the parameter "isInside"
 /// Otherwise the parameter "isInside" is ignored.
 /// </summary>
 public FloatingObjectsSet GetNearObjects(ProteinOnTileInSpace protein, Tile.SideType side, NamedMultiset targetMultiset)
 {
     return(GetNearObjects(protein.m_tile.SidePoint(protein.Position, side), targetMultiset));
 }
Ejemplo n.º 9
0
 /// <summary>
 /// Gets the set of floating objects within a reaction distance from the center of a tile.
 /// Only objects unused in this simulation step are considered.
 /// TODO low priority: return floating objects close to the whole shape of the tile except border
 /// </summary>
 public FloatingObjectsSet GetNearObjects(TileInSpace tile, NamedMultiset targetMultiset)
 {
     return(GetNearObjects(tile.Position, targetMultiset));
 }