예제 #1
0
 private MultiTreeNode <IActionHandler <ActionTag> > GetCheapestNode(MultiTreeNode <IActionHandler <ActionTag> > left,
                                                                     MultiTreeNode <IActionHandler <ActionTag> > right)
 {
     if (left == null || left.Data == null)
     {
         return(right);
     }
     if (right == null || right.Data == null)
     {
         return(left);
     }
     if (left.OtherData.GetHashtableElement <int>(CurrCost) > right.OtherData.GetHashtableElement <int>(CurrCost))
     {
         return(right);
     }
     else if (left.OtherData.GetHashtableElement <int>(CurrCost) < right.OtherData.GetHashtableElement <int>(CurrCost))
     {
         return(left);
     }
     else
     {
         if (left.Data.Action.Priority > right.Data.Action.Priority)
         {
             return(left);
         }
         else
         {
             return(right);
         }
     }
 }
예제 #2
0
        public void ZeroChildrenCountAfterPop()
        {
            var n = new MultiTreeNode <int>(1);

            n.PopChild();
            Assert.AreEqual(n.Count, 0, "Child count was incorrect");
        }
예제 #3
0
        public void OneChild()
        {
            var n = new MultiTreeNode <string>("1");

            n.AddChild(new MultiTreeNode <string>("2"));
            Assert.AreEqual(n.GetChildren().Select(t => t.Data), new[] { "2" });
        }
예제 #4
0
        private bool TryFindSubnodeByName(MultiTreeNode <IPeripheral, IRegistrationPoint> from, string path, out MultiTreeNode <IPeripheral, IRegistrationPoint> subnode,
                                          string currentMatching, out string longestMatching)
        {
            lock (collectionSync)
            {
                var subpath = path.Split(new [] { PathSeparator }, 2);
                subnode         = null;
                longestMatching = currentMatching;
                foreach (var currentChild in from.Children)
                {
                    string name;
                    if (!TryGetLocalName(currentChild.Value, out name))
                    {
                        continue;
                    }

                    if (name == subpath[0])
                    {
                        subnode = currentChild;
                        if (subpath.Length == 1)
                        {
                            return(true);
                        }
                        return(TryFindSubnodeByName(currentChild, subpath[1], out subnode, Subname(currentMatching, subpath[0]), out longestMatching));
                    }
                }
                return(false);
            }
        }
예제 #5
0
        public void BuildFamilyTree()
        {
            SocialSystem socialSystem = CivilManager.GetSystem <SocialSystem>();

            _tree = new MultiTreeNode <HumanRecord>(null);

            if (HumanRecord.MarriageRecord != null)
            {
                var grandFathers = socialSystem.HumanRecords.GetGrandFathers(HumanRecord, MaxDepth);
                for (int i = grandFathers.Count - 1; i >= 0; i--)
                {
                    var grandNode = new MultiTreeNode <HumanRecord>(grandFathers[i]);
                    _tree.Cildren.Add(grandNode);

                    var siblings = socialSystem.HumanRecords.GetSiblings(grandFathers[i]);
                    foreach (var sibling in siblings)
                    {
                        var siblingNode = new MultiTreeNode <HumanRecord>(sibling);
                        _tree.Cildren.Add(siblingNode);
                        addHumanChilds(siblingNode, MaxDepth);
                    }

                    addHumanChilds(grandNode, MaxDepth);
                }
            }
            else
            {
                var selfNode = new MultiTreeNode <HumanRecord>(HumanRecord);
                _tree.Cildren.Add(selfNode);
                addHumanChilds(selfNode, MaxDepth);
            }
        }
예제 #6
0
        /// <summary>
        /// 根据层次数据构建多叉树
        /// </summary>
        /// <returns></returns>
        public override MultiTreeNode CreateFakeMultiTree()
        {
            //构建根节点
            MultiTreeNode root = new MultiTreeNode();

            root.Childrens = new List <MultiTreeNode>();

            #region 构建 Hashtable
            Dictionary <string, MultiTreeNode> dic = new Dictionary <string, MultiTreeNode>();
            foreach (OrgModel item in Orgs)
            {
                MultiTreeNode node = new MultiTreeNode();
                node.Childrens = new List <MultiTreeNode>();
                string id = item.OrgId.ToString();
                node.Id       = id;
                node.ParentId = item.ParentOrgId.HasValue ? item.ParentOrgId.Value.ToString() : string.Empty;
                node.Name     = item.OrgName;

                dic.Add(id, node);
            }
            #endregion

            #region Childrens
            foreach (string key in dic.Keys)
            {
                MultiTreeNode node     = dic[key];
                string        parentId = node.ParentId;
                if (string.IsNullOrEmpty(parentId))
                {
                    //获得根节点
                    root = node;
                }
                else
                {
                    try
                    {
                        //可能异常:给定关键字不在字典中
                        MultiTreeNode pNode = dic[parentId];

                        pNode.Childrens.Add(node);
                    }
                    catch (Exception ex)
                    {
                        LogHelper.GetInstance().WriteLog(string.Format("异常:{0}\n{1}", ex.Message, ex.StackTrace), LogType.错误);
                    }
                }
            }
            #endregion

            #region 设置 NChildren
            foreach (string key in dic.Keys)
            {
                MultiTreeNode node = dic[key];
                node.NChildren = node.Childrens.Count;
            }
            #endregion

            return(root);
        }
예제 #7
0
 public ConditionBlock(ICodeBlock parentBlock, MultiTreeNode <Value> condition,
                       ICodeBlock ifCode, ICodeBlock elseCode = null)
 {
     ParentBlock = parentBlock;
     Condition   = condition;
     IfCode      = ifCode;
     ElseCode    = elseCode;
 }
예제 #8
0
        public void PopChild()
        {
            var n = new MultiTreeNode <string>("1");

            n.AddChild(new MultiTreeNode <string>("2"));
            n.AddChild(new MultiTreeNode <string>("3"));
            Assert.AreEqual(n.GetChildren().Select(t => t.Data), new[] { "3", "2" });
            Assert.AreEqual(n.PopChild().Data, "3");
            Assert.AreEqual(n.GetChildren().Select(t => t.Data), new[] { "2" }, "Incorrect GetChildren after ChildPop");
        }
예제 #9
0
        public void SeveralChildren()
        {
            var n = new MultiTreeNode <string>("1");

            n.AddChild(new MultiTreeNode <string>("2"));
            n.AddChild(new MultiTreeNode <string>("3"));
            n.AddChild(new MultiTreeNode <string>("4"));
            n.AddChild(new MultiTreeNode <string>("5"));
            Assert.AreEqual(n.GetChildren().Select(t => t.Data), new[] { "5", "4", "3", "2" });
        }
예제 #10
0
        public void ChildByIdx()
        {
            var n = new MultiTreeNode <int>(0);

            for (var i = 1; i <= 4; i++)
            {
                n.AddChild(new MultiTreeNode <int>(i));
            }

            Assert.AreEqual(n[3].Data, 1, "Child by idx was incorrect");
        }
예제 #11
0
        public void ManyChildrenCount()
        {
            var n = new MultiTreeNode <int>(0);

            for (var i = 1; i <= 4; i++)
            {
                n.AddChild(new MultiTreeNode <int>(i));
            }

            Assert.AreEqual(n.Count, 4, "Child count was incorrect");
        }
예제 #12
0
        public void ParentsAreOk()
        {
            var n = new MultiTreeNode <int>(0);

            for (var i = 1; i <= 4; i++)
            {
                n.AddChild(new MultiTreeNode <int>(i));
            }

            foreach (var ch in n.GetChildren())
            {
                Assert.AreSame(ch.Parent, n, "Parent is incorrect");
            }
        }
예제 #13
0
        public void ChildByIncorrectIdx()
        {
            var n = new MultiTreeNode <int>(0);

            n.AddChild(new MultiTreeNode <int>(1));
            try
            {
                var x = n[3].Data;
            }
            catch (ArgumentException)
            {
                return;
            }
            Assert.Fail();
        }
예제 #14
0
        private void addHumanChilds(MultiTreeNode <HumanRecord> node, uint depth)
        {
            SocialSystem socialSystem = CivilManager.GetSystem <SocialSystem>();

            if (depth == 0)
            {
                return;
            }

            var children = socialSystem.HumanRecords.GetChildren(node.Data);

            foreach (var child in children)
            {
                var childNode = new MultiTreeNode <HumanRecord>(child);
                node.Cildren.Add(childNode);
                addHumanChilds(childNode, depth - 1);
            }
        }
예제 #15
0
 private void FindPaths(string nameSoFar, IPeripheral peripheralToFind, MultiTreeNode <IPeripheral, IRegistrationPoint> currentNode, List <string> paths)
 {
     foreach (var child in currentNode.Children)
     {
         var    currentPeripheral = child.Value;
         string localName;
         if (!TryGetLocalName(currentPeripheral, out localName))
         {
             continue;
         }
         var name = Subname(nameSoFar, localName);
         if (currentPeripheral == peripheralToFind)
         {
             paths.Add(name);
             return; // shouldn't be attached to itself
         }
         FindPaths(name, peripheralToFind, child, paths);
     }
 }
예제 #16
0
        private MultiTreeNode <HumanRecord> findNode(MultiTreeNode <HumanRecord> node, Human human, ref int level)
        {
            if (node.Data == null)
            {
                return(null);
            }

            if (human == node.Data.Human)
            {
                return(node);
            }

            foreach (var childNode in node.Cildren)
            {
                level++;
                var curNode = findNode(childNode, human, ref level);
                if (curNode != null)
                {
                    return(curNode);
                }
            }

            return(null);
        }
예제 #17
0
        /// <summary>
        /// 目标由GoalMgr提供
        /// </summary>
        /// <param name="goal"></param>
        /// <returns></returns>
        public override LinkedList <IActionHandler <ActionTag> > BuildPlan(IGoal <GoalTag> goal)
        {
            LogTool.Log($"制定计划 ------");
            var plan       = new LinkedList <IActionHandler <ActionTag> >();
            var lastAction = BuildActionTree();

            if (lastAction != null)
            {
                if (lastAction.Data == null)
                {
                    plan.AddLast(agent.AgentActionMgr.GetHandler(ActionTag.Idle));
                }

                while (lastAction.Data != null)
                {
                    plan.AddLast(lastAction.Data);
                    lastAction = lastAction.Parent;
                }
            }
            else
            {
                LogTool.LogError($"当前节点为空");
            }

            LogTool.Log($"------ 最终生成计划 ------");
            foreach (var handler in plan)
            {
                LogTool.Log($"计划项: {handler.Action.Label}");
            }

            LogTool.Log($"------ 生成计划结束");
            return(plan);

            //构建Action树
            MultiTreeNode <IActionHandler <ActionTag> > BuildActionTree()
            {
                //初始化默认父节点
                var topTree = new MultiTreeNode <IActionHandler <ActionTag> >(null);

                topTree.OtherData.AddHashtableElement(CurrCost, 0);
                var currNode     = topTree;
                var tuple        = agent.Context.Condition.GetDiffecentTargetTags(goal);
                var restCurrKeys = tuple.Item1.ToList();
                var resetTarget  = tuple.Item2.ToList();
                MultiTreeNode <IActionHandler <ActionTag> > subNode      = null;
                MultiTreeNode <IActionHandler <ActionTag> > cheapestNode = null;

                //循环创建多叉树
                while (!IsNodeEnd(restCurrKeys))
                {
                    //获取状态差异的Handlers
                    var handlers = GetSubHandlers();
                    foreach (var handler in handlers)
                    {
                        subNode = new MultiTreeNode <IActionHandler <ActionTag> >(handler);
                        subNode.OtherData.AddHashtableElement(CurrCost, GetAllCost());
                        subNode.Parent = currNode;
                        cheapestNode   = GetCheapestNode(subNode, cheapestNode);
                    }

                    currNode     = cheapestNode;
                    tuple        = AIConditionExtend.GetDiffecentCondition(resetTarget, currNode.Data.Action.Effects);
                    restCurrKeys = tuple.Item1.ToList();
                    resetTarget  = tuple.Item2.ToList();
                    cheapestNode = null;
                }

                return(currNode);

                int GetAllCost()
                {
                    var configCost = 0f;

                    if (subNode.Data != null)
                    {
                        foreach (var costParameter in subNode.Data.Action.Cost)
                        {
                            configCost += (costParameter.value * costParameter.CostPriority) / 100;
                        }
                    }

                    var currCost = currNode.OtherData.GetHashtableElement <int>(CurrCost);
                    //上一个节点消耗 + 配置消耗 + 比较之前节点消耗
                    var count = AIConditionExtend.GetDiffecentCondition(resetTarget, subNode.Data.Action.Effects);

                    return(currCost + (int)configCost + count.Item1.Count);
                }

                //获取当前节点所有可能的子节点
                List <IActionHandler <ActionTag> > GetSubHandlers()
                {
                    var handlers = new List <IActionHandler <ActionTag> >();

                    if (currNode == null)
                    {
                        return(handlers);
                    }
                    var maps = agent.AgentActionMgr.EffectActionMap;

                    //下面进行查找相对应的Handler
                    foreach (var key in restCurrKeys)
                    {
                        if (maps.ContainsKey(key))
                        {
                            foreach (var handler in maps[key])
                            {
                                //筛选能够执行的动作
                                if (!handlers.Contains(handler) &&
                                    handler.Action.GetEffectsValue(key).IsRight == resetTarget.GetDiffecentCondition(key).IsRight)
                                {
                                    handlers.Add(handler);
                                }
                            }
                        }
                        else
                        {
                            LogTool.LogError($"当前没有动作能够实现从当前状态切换到目标状态,无法实现的键值为: {key}");
                        }
                    }

                    handlers = handlers.OrderByDescending(handler => handler.Action.Priority).ToList();
                    return(handlers);
                }
            }
        }
예제 #18
0
        public void EmptyNode()
        {
            var n = new MultiTreeNode <string>("test");

            Assert.AreEqual(n.GetChildren(), new MultiTreeNode <string>[] { });
        }
예제 #19
0
 public WhileBlock(ICodeBlock parentBlock, MultiTreeNode <Value> condition, ICodeBlock code)
 {
     ParentBlock = parentBlock;
     Condition   = condition;
     Code        = code;
 }