コード例 #1
0
            // Unserialize MissionRule
            private static void UnserializeMissionRules(XElement elementMissionGrammar)
            {
                List <Mission.MissionGroup> groups = new List <Mission.MissionGroup>();
                XElement elementMissionGraph       = elementMissionGrammar.Element("MissionRules");

                foreach (var elementGroup in elementMissionGraph.Elements("RuleGroup"))
                {
                    Mission.MissionGroup group = new MissionGrammarSystem.MissionGroup();
                    group.Name        = elementGroup.Element("Name").Value;
                    group.Description = elementGroup.Element("Description").Value;
                    group.Rules       = new List <Mission.MissionRule>();
                    foreach (var elementRule in elementGroup.Elements("Rule"))
                    {
                        Mission.MissionRule rule = new Mission.MissionRule();
                        rule.Name             = elementRule.Element("Name").Value;
                        rule.Description      = elementRule.Element("Description").Value;
                        rule.SourceRule       = UnserializeMissionGraph(elementRule.Element("SourceRule"));
                        rule.ReplacementRule  = UnserializeMissionGraph(elementRule.Element("ReplacementRule"));
                        rule.Enable           = bool.Parse(elementRule.Element("Enable").Value);
                        rule.Valid            = bool.Parse(elementRule.Element("Valid").Value);
                        rule.Weight           = int.Parse(elementRule.Element("Weight").Value);
                        rule.QuantityLimitMin = int.Parse(elementRule.Element("QuantityLimitMin").Value);
                        rule.QuantityLimitMax = int.Parse(elementRule.Element("QuantityLimitMax").Value);

                        group.Rules.Add(rule);
                    }
                    groups.Add(group);
                }
                Mission.MissionGrammar.Groups = groups;
            }
コード例 #2
0
 // No 9. OverflowedAnyNode.
 private static bool ValidateOverflowedAnyNode(MissionRule rule, GraphGrammar graphGrammar)
 {
     // Sort nodes in ordering.
     GraphGrammarNode[] sourceNodes = rule.SourceRule.Nodes.OrderBy(n => n.Ordering).ToArray();
     // if replaceRule have any node that dont match the source ordering.
     return(!rule.ReplacementRule.Nodes.Exists(n => (Alphabet.IsAnyNode(n.AlphabetID) &&
                                                     (n.Ordering > sourceNodes.Length ? true : !Alphabet.IsAnyNode(sourceNodes[n.Ordering - 1].AlphabetID)))));
 }
コード例 #3
0
 // Validate the graph grammar (one of pair of rule).
 public static KeyValuePair <ValidationLabel, string> Validate(MissionRule rule, GraphGrammar graphGrammar)
 {
     // Initial the error to none.
     _error = ValidationLabel.NoError;
     // Execute each method.
     foreach (var method in _validationMethods)
     {
         if (!method.Value.Invoke(rule, graphGrammar))
         {
             _error = (method.Key);
             break;
         }
     }
     // Return Error Message.
     return(new KeyValuePair <ValidationLabel, string>(_error, SelectErrorType(_error)));
 }
コード例 #4
0
 // No 6. MultipleRelations.
 private static bool ValidateMultipleRelations(MissionRule rule, GraphGrammar graphGrammar)
 {
     if (graphGrammar.Connections.Count > 1)
     {
         foreach (GraphGrammarConnection connection in graphGrammar.Connections)
         {
             if ((graphGrammar.Connections.Where(e => (e != connection &&
                                                       (e.StartpointStickyOn == connection.StartpointStickyOn && e.EndpointStickyOn == connection.EndpointStickyOn) ||
                                                       (e.StartpointStickyOn == connection.EndpointStickyOn && e.EndpointStickyOn == connection.StartpointStickyOn)))).Any())
             {
                 return(false);
             }
         }
     }
     return(true);
 }
コード例 #5
0
 // No 3. IsolatedNode.
 private static bool ValidateIsolatedNode(MissionRule rule, GraphGrammar graphGrammar)
 {
     if (graphGrammar.Nodes.Count > 1)
     {
         if (graphGrammar.Connections.Count < graphGrammar.Nodes.Count - 1)
         {
             return(false);
         }
         foreach (GraphGrammarNode node in graphGrammar.Nodes)
         {
             // Connection.StickOn will remain the last node it sticked on, so use position to inforce validation.
             if (!graphGrammar.Connections.Where(c => (c.StartpointStickyOn == node || c.EndpointStickyOn == node)).Any())
             {
                 return(false);
             }
         }
     }
     return(true);
 }
コード例 #6
0
 // No 5. ExactlyDuplicated.
 private static bool ValidateExactlyDuplicated(MissionRule rule, GraphGrammar graphGrammar)
 {
     // Check the number of connections & nodes first.
     if (rule.SourceRule.Nodes.Count != rule.ReplacementRule.Nodes.Count ||
         rule.SourceRule.Connections.Count != rule.ReplacementRule.Connections.Count)
     {
         return(true);
     }
     // If find any difference in connections, then defined they are not isomorphic.
     foreach (var connectionA in rule.SourceRule.Connections)
     {
         if (!rule.ReplacementRule.Connections.Exists(connectionB =>
                                                      connectionB.AlphabetID == connectionA.AlphabetID &&
                                                      // Check the ordering they sticky on. If null, expresses zero.
                                                      (connectionB.StartpointStickyOn == null ? 0 : connectionB.StartpointStickyOn.Ordering) == (connectionA.StartpointStickyOn == null ? 0 : connectionA.StartpointStickyOn.Ordering) &&
                                                      (connectionB.EndpointStickyOn == null ? 0 : connectionB.EndpointStickyOn.Ordering) == (connectionA.EndpointStickyOn == null ? 0 : connectionA.EndpointStickyOn.Ordering)
                                                      ))
         {
             return(true);
         }
     }
     // If find any difference in nodes, then defined they are not isomorphic.
     foreach (var nodeA in rule.SourceRule.Nodes)
     {
         if (!rule.ReplacementRule.Nodes.Exists(nodeB =>
                                                nodeB.AlphabetID == nodeA.AlphabetID &&
                                                nodeB.Ordering == nodeA.Ordering &&
                                                nodeB.Children.Count == nodeA.Children.Count &&
                                                nodeB.Parents.Count == nodeA.Parents.Count
                                                ))
         {
             return(true);
         }
     }
     // It's illegal and isomorphic.
     return(false);
 }
コード例 #7
0
 // Remove the specified mission rule.
 public void RemoveRule(MissionRule rule)
 {
     _rules.Remove(rule);
     return;
 }
コード例 #8
0
 // Add a mission rule from another rule.
 public void AddRule(MissionRule rule)
 {
     _rules.Add(rule);
     return;
 }
コード例 #9
0
 // No 4. IsolatedConnection.
 private static bool ValidateIsolatedConnection(MissionRule rule, GraphGrammar graphGrammar)
 {
     return(!(graphGrammar.Connections.Where(c => c.StartpointStickyOn == null || c.EndpointStickyOn == null).Any()));
 }
コード例 #10
0
 // No 2. EmptyLeft.
 private static bool ValidateEmptyLeft(MissionRule rule, GraphGrammar graphGrammar)
 {
     // Is there no node in sourceRule?
     return(rule.SourceRule.Nodes.Count != 0 ? true : false);
 }
コード例 #11
0
 // No 1. LeftMoreThanRight.
 private static bool ValidateLeftMoreThanRight(MissionRule rule, GraphGrammar graphGrammar)
 {
     // Are Nodes of sourceRule more than nodes of replacementRule?
     return(rule.SourceRule.Nodes.Count <= rule.ReplacementRule.Nodes.Count ? true : true);
 }
コード例 #12
0
 // No 8. OrphanNode.
 private static bool ValidateOrphanNode(MissionRule rule, GraphGrammar graphGrammar)
 {
     // If node has no parent, it is an orphan.
     // Indegree = 0 quantity cannot > 1.
     return(graphGrammar.Nodes.FindAll(n => n.Parents.Count == 0).Count == 1);
 }
コード例 #13
0
        // No 7. CyclicLink.
        private static bool ValidateCyclicLink(MissionRule rule, GraphGrammar graphGrammar)
        {
            // Store the parents and children to avoid the repeat call method.
            Dictionary <GraphGrammarNode, List <GraphGrammarNode> > parentsTable  = new Dictionary <GraphGrammarNode, List <GraphGrammarNode> >();
            Dictionary <GraphGrammarNode, List <GraphGrammarNode> > childrenTable = new Dictionary <GraphGrammarNode, List <GraphGrammarNode> >();

            foreach (var node in graphGrammar.Nodes)
            {
                parentsTable[node]  = node.Parents;
                childrenTable[node] = node.Children;
            }
            // Kahn's Algorithm
            // Array that record the removed edges.
            bool[,] _usedEdge = new bool[graphGrammar.Nodes.Count, graphGrammar.Nodes.Count];
            // Non-indegree queue.
            Queue <GraphGrammarNode> nonIndegree = new Queue <GraphGrammarNode>();

            // Push non-indegree node to queue.
            foreach (var node in graphGrammar.Nodes.FindAll(x => parentsTable[x].Count == 0 &&
                                                            // children can not be node itself.
                                                            (!childrenTable[x].Exists(p => p.Ordering == x.Ordering))))
            {
                nonIndegree.Enqueue(node);
            }

            // Bfs.
            while (nonIndegree.Count > 0)
            {
                // Pop.
                GraphGrammarNode popNode = nonIndegree.Dequeue();
                // Remove the edge between this node and children node.
                foreach (var childNode in childrenTable[popNode])
                {
                    // Remove edge.
                    _usedEdge[popNode.Ordering - 1, childNode.Ordering - 1] = true;
                    // Check this child if it is non-indegree or not.
                    bool hasInput = false;
                    foreach (var parentNode in parentsTable[childNode])
                    {
                        if (!_usedEdge[parentNode.Ordering - 1, childNode.Ordering - 1])
                        {
                            hasInput = true;
                            break;
                        }
                    }
                    // If it is non-indegree then push it.
                    if (!hasInput)
                    {
                        nonIndegree.Enqueue(childNode);
                    }
                }
            }
            // Return false when any edge exist. It represents that this is a cyclic link.
            foreach (var node in graphGrammar.Nodes)
            {
                foreach (var childNode in childrenTable[node])
                {
                    if (!_usedEdge[node.Ordering - 1, childNode.Ordering - 1])
                    {
                        return(false);
                    }
                }
            }
            // Otherwise, this is not cyclic link.
            return(true);
        }