예제 #1
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);
            }
        }
예제 #2
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>());
        }