private void CreateGoalPriority(Level level, GoalGraph goalGraph, CancellationToken cancel) { Dictionary <GoalNode, Dictionary <GoalNode, List <GoalNode> > > nodeGraphs = new Dictionary <GoalNode, Dictionary <GoalNode, List <GoalNode> > >(); foreach (var goal in level.Goals) { GoalNode node = goalGraph.GetGoalNodeFromPosition(goal.Ent.Pos); nodeGraphs.Add(node, CreateDirectedEdgesToStart(node)); } Graph groupedGraph = Graph.CreateSimplifiedGraph <EmptyEdgeInfo>(goalGraph); //GraphShower.ShowGraph(groupedGraph); List <List <GoalNode> > boxGroups = new List <List <GoalNode> >(); List <List <GoalNode> > agentGroups = new List <List <GoalNode> >(); foreach (var iNode in groupedGraph.Nodes) { var node = (Node <NodeGroup, EmptyEdgeInfo>)iNode; var boxes = node.Value.Nodes.Cast <GoalNode>().Where(x => x.Value.EntType == EntityType.BOX); if (boxes.Any()) { boxGroups.Add(boxes.ToList()); } var agents = node.Value.Nodes.Cast <GoalNode>().Where(x => x.Value.EntType == EntityType.AGENT); if (agents.Any()) { agentGroups.Add(agents.ToList()); } } HashSet <Entity> toIgnore = new HashSet <Entity>(); HashSet <GoalNode> toIgnoreNodes = new HashSet <GoalNode>(); Dictionary <GoalNode, (int pathsCount, Dictionary <GoalNode, int> pathNodes)> cachedPathResults = new Dictionary <GoalNode, (int pathsCount, Dictionary <GoalNode, int> pathNodes)>(); while (toIgnore.Count < level.Goals.Length) { Dictionary <GoalNode, float> nodeCounter = new Dictionary <GoalNode, float>(); foreach (var inode in goalGraph.Nodes) { var node = (GoalNode)inode; if (node.Value.EntType.IsGoal() && !toIgnore.Contains(node.Value.Ent)) { nodeCounter.Add((GoalNode)node, 0); } } foreach (Goal goal in level.Goals) { cancel.ThrowIfCancellationRequested(); if (toIgnore.Contains(goal.Ent)) { continue; } GoalNode start = goalGraph.GetGoalNodeFromPosition(goal.Ent.Pos); (int pathsCount, Dictionary <GoalNode, int> pathNodes)pathResult; if (!cachedPathResults.TryGetValue(start, out pathResult) || toIgnoreNodes.Any(x => pathResult.pathNodes.ContainsKey(x))) { Dictionary <GoalNode, int> shortestPathsVisitedNodesCount = new Dictionary <GoalNode, int>(); int pathsCount = 0; if (goal.EntType == EntityType.AGENT_GOAL) { foreach (var agentGroup in agentGroups) { cancel.ThrowIfCancellationRequested(); int agentsWithSameType = 0; foreach (var agentNode in agentGroup) { if (agentNode.Value.Ent.Type == goal.Ent.Type) { agentsWithSameType++; } } if (agentsWithSameType > 0) { pathsCount += GetShortestPathsData(agentGroup.First(), nodeGraphs[start], shortestPathsVisitedNodesCount, toIgnore, agentsWithSameType); } } } else if (goal.EntType == EntityType.BOX_GOAL) { foreach (var boxGroup in boxGroups) { cancel.ThrowIfCancellationRequested(); int boxesWithSameType = 0; foreach (var boxNode in boxGroup) { if (boxNode.Value.Ent.Type == goal.Ent.Type) { boxesWithSameType++; } } if (boxesWithSameType > 0) { pathsCount += GetShortestPathsData(boxGroup.First(), nodeGraphs[start], shortestPathsVisitedNodesCount, toIgnore, boxesWithSameType); } } } else { throw new Exception($"Unknown entity type: {goal.EntType}"); } pathResult = (pathsCount, shortestPathsVisitedNodesCount); cachedPathResults[start] = pathResult; } foreach (var pathNode in pathResult.pathNodes) { nodeCounter[pathNode.Key] += (1f / (pathResult.pathsCount)) * pathNode.Value; } } //foreach (var stuff in nodeCounter) //{ // Console.WriteLine("Key: " + stuff.Key + " Priotity: " + stuff.Value); //} //Console.ReadLine(); GoalNode[] newPriorityGroup = nodeCounter.GroupBy(x => x.Value).OrderBy(x => x.First().Value).First().Select(x => x.Key).ToArray(); PriorityLayers.Add(newPriorityGroup); foreach (var priorityNode in newPriorityGroup) { toIgnore.Add(priorityNode.Value.Ent); toIgnoreNodes.Add(goalGraph.GetGoalNodeFromPosition(priorityNode.Value.Ent.Pos)); } } }
public GoalPriority(Level level, GoalGraph goalGraph, CancellationToken cancel) { CreateGoalPriority(level, goalGraph, cancel); }