private void OnUIViewMessage(UIViewMessage message) { if (PortalGraph != null && !PortalGraph.Enabled) { return; } if (ListenFor != ListenerType.UIView) { return; } if (DebugMode) { DDebug.Log("UIViewMessage received: " + message.Type + " " + message.View.ViewCategory + " / " + message.View.ViewName + " // Listening for: " + ViewCategory + " / " + ViewName, this); } if (message.Type == UIViewBehaviorType.Unknown) { return; } if (message.Type != UIViewTriggerAction) { return; } if (AnyValue || message.View.ViewCategory.Equals(ViewCategory) && message.View.ViewName.Equals(ViewName)) { m_activatedByEvent = true; PortalGraph.SetActiveNodeById(Id); } }
public override void OnEnter(Node previousActiveNode, Connection connection) { base.OnEnter(previousActiveNode, connection); if (ActiveGraph == null) { return; } if (!FirstOutputSocket.IsConnected) { return; } if (!SwitchBackMode) //Switch Back Node disabled -> Activate the first connected node { PortalGraph.SetActiveNodeByConnection(FirstOutputSocket.FirstConnection); return; } if (!m_activatedByEvent && HasSource) //node activated by a direct connection and has a source -> go back { PortalGraph.SetActiveNodeById(m_sourceNode.Id); m_sourceNode = null; //reset source after going back return; } UpdateSourceNode(m_activatedByEvent ? previousActiveNode : null); //update the source to the previously active node if activated by an event PortalGraph.SetActiveNodeByConnection(FirstOutputSocket.FirstConnection); }
protected override int Part1(string[] input) { var maze = new PortalMaze(input); var graph = PortalGraph.BuildWeightedGraphFromMaze(maze); var shortestPath = graph.ShortestPathDijkstra(maze.Entry, maze.Exit); return(shortestPath); }
private void OnGameEventMessage(GameEventMessage message) { if (PortalGraph != null && !PortalGraph.Enabled) { return; } if (message.EventName != GameEventToListenFor) { return; } PortalGraph.SetActiveNodeById(Id); }
public void Awake() { grid = FindObjectOfType <GridR>();//TODO replace mapData = new GridDataChunk[mapSize, mapSize]; for (int i = 0; i < mapSize; i++) { for (int j = 0; j < mapSize; j++) { mapData[i, j] = new GridDataChunk(FlowGrid.gridResolution, i, j); } } navGraph = generateGraph(); pathfinding = new AStarPathfinding(); }
private void OnUIButtonMessage(UIButtonMessage message) { if (PortalGraph != null && !PortalGraph.Enabled) { return; } if (ListenFor != ListenerType.UIButton) { return; } if (DebugMode) { DDebug.Log("UIButtonMessage received: " + message.Type + " " + message.ButtonName + " // Listening for: " + ButtonName, this); } if (message.Type != UIButtonTriggerAction) { return; } bool listeningForBackButton = ButtonName.Equals(UIButton.BackButtonName); if (listeningForBackButton && (message.ButtonName.Equals(UIButton.BackButtonName) || message.Button != null && message.Button.IsBackButton)) { m_activatedByEvent = true; PortalGraph.SetActiveNodeById(Id); return; } if (AnyValue) { m_activatedByEvent = true; PortalGraph.SetActiveNodeById(Id); return; } if (message.Button == null || !message.Button.ButtonCategory.Equals(ButtonCategory) || !message.Button.ButtonName.Equals(ButtonName)) { return; } m_activatedByEvent = true; PortalGraph.SetActiveNodeById(Id); }
private void OnUIDrawerMessage(UIDrawerMessage message) { if (PortalGraph != null && !PortalGraph.Enabled) { return; } if (ListenFor != ListenerType.UIDrawer) { return; } if (DebugMode) { DDebug.Log("UIDrawerMessage received: " + message.Type + " " + message.Drawer.DrawerName + " // Listening for: " + DrawerName, this); } if (message.Type != UIDrawerTriggerAction) { return; } if (AnyValue || message.Drawer.DrawerName.Equals(DrawerName)) { PortalGraph.SetActiveNodeById(Id); } }
private static PortalGraph BuildSimpleGraph(PortalMaze maze) { var walked = new SparseMap <PortalGraph.Vertex>(); var graph = new PortalGraph(); graph.AddVertex(maze.Entry); BuildSimpleGraph(graph.Root); return(graph); void BuildSimpleGraph(PortalGraph.Vertex node) { while (walked[node.Pos] == null) { walked[node.Pos] = node; var positions = node.Pos .LookAround() .Select(p => new { Pos = p, Dest = maze.Transform(p) }) .Where(x => maze.Map[x.Dest] == '.') .Where(x => walked[x.Dest] == null || !walked[x.Dest].Edges.ContainsKey(node)) .ToList(); foreach (var p in positions.Where(x => walked[x.Dest] != null).ToList()) { var existing = walked[p.Dest]; var portal = maze.Portals[p.Pos]; var portalValue = portal == null ? 0 : portal.IsDownward ? -1 : 1; var portalName = portal == null ? null : portal.Name; node.Value = portal; existing.Value = portal; node.Edges[existing] = portalValue; existing.Edges[node] = -portalValue; positions.Remove(p); } switch (positions.Count()) { case 0: return; case 1: var p = positions.First(); var next = graph.AddVertex(p.Dest); //graph.Vertices.Add(next); var portal = maze.Portals[p.Pos]; var portalValue = portal == null ? 0 : portal.IsDownward ? -1 : 1; node.Value = portal; next.Value = portal; node.Edges[next] = portalValue; next.Edges[node] = -portalValue; node = next; break; default: var forks = positions.Select(x => graph.AddVertex(x.Dest)).ToList(); foreach (var fork in forks) { BuildSimpleGraph(fork); } return; } } } }
public PortalGraph generateGraph() { PortalGraph graph = new PortalGraph(mapSize); for (int x = 0; x < 2 * mapSize - 2; x++) { bool horiz = x % 2 == 0; for (int y = 0; y < mapSize - 1 + (horiz ? -1 : 0); y++) { bool sideA; bool sideB; if (horiz)//TODO simplify these lines of code { sideA = FlowFieldHandler.grid.getBuilding((x / 2 * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing()), (y * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing()) + (FlowGrid.gridResolution - 1) * FlowFieldHandler.grid.getSpacing()) == -1; sideB = FlowFieldHandler.grid.getBuilding((x / 2 * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing()), (y * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing()) + (FlowGrid.gridResolution) * FlowFieldHandler.grid.getSpacing()) == -1; } else { sideA = FlowFieldHandler.grid.getBuilding(((x - 1) / 2 * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing()) + (FlowGrid.gridResolution - 1) * FlowFieldHandler.grid.getSpacing(), y * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing()) == -1; sideB = FlowFieldHandler.grid.getBuilding(((x - 1) / 2 * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing()) + (FlowGrid.gridResolution) * FlowFieldHandler.grid.getSpacing(), y * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing()) == -1; } bool foundPortal = sideA && sideB; int startIndex = -1; int size = -1; if (foundPortal) { startIndex = 0; size = 1; } for (int i = 1; i < FlowGrid.gridResolution; i++) { if (horiz) { sideA = FlowFieldHandler.grid.getBuilding((x / 2 * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing()) + i * FlowFieldHandler.grid.getSpacing(), (y * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing()) + (FlowGrid.gridResolution - 1) * FlowFieldHandler.grid.getSpacing()) == -1; sideB = FlowFieldHandler.grid.getBuilding((x / 2 * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing()) + i * FlowFieldHandler.grid.getSpacing(), (y * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing()) + (FlowGrid.gridResolution) * FlowFieldHandler.grid.getSpacing()) == -1; //Debug.Log("Horiz: " + new Vector2((x / 2 * FlowGrid.gridResolution * 10) + i * 10, (y * FlowGrid.gridResolution * 10) + (FlowGrid.gridResolution - 1) * 10)); //Debug.Log(FlowField.grid.getBuilding((x / 2 * FlowGrid.gridResolution * 10) + i * 10, (y * FlowGrid.gridResolution * 10) + (FlowGrid.gridResolution - 1) * 10)); //Debug.Log(FlowField.grid.getBuilding((x / 2 * FlowGrid.gridResolution * 10) + i * 10, (y * FlowGrid.gridResolution * 10) + (FlowGrid.gridResolution) * 10)); } else { sideA = FlowFieldHandler.grid.getBuilding(((x - 1) / 2 * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing()) + (FlowGrid.gridResolution - 1) * FlowFieldHandler.grid.getSpacing(), y * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing() + i * FlowFieldHandler.grid.getSpacing()) == -1; sideB = FlowFieldHandler.grid.getBuilding(((x - 1) / 2 * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing()) + (FlowGrid.gridResolution) * FlowFieldHandler.grid.getSpacing(), y * FlowGrid.gridResolution * FlowFieldHandler.grid.getSpacing() + i * FlowFieldHandler.grid.getSpacing()) == -1; //Debug.Log("Vert: " + new Vector2((x / 2 * FlowGrid.gridResolution * 10), (y * FlowGrid.gridResolution * 10) + (FlowGrid.gridResolution - 1) * 10 + i * 10)); //Debug.Log(FlowField.grid.getBuilding((x / 2 * FlowGrid.gridResolution * 10) + (FlowGrid.gridResolution - 1) * 10, (y * FlowGrid.gridResolution * 10 + i * 10))); //Debug.Log(FlowField.grid.getBuilding((x / 2 * FlowGrid.gridResolution * 10) + (FlowGrid.gridResolution) * 10, (y * FlowGrid.gridResolution * 10 + i * 10))); } if (sideA && sideB) { if (foundPortal) { size++; } else { foundPortal = true; startIndex = i; size = 1; } } else { if (foundPortal) { foundPortal = false; graph.AddPortal(x, y, size, startIndex); } } } if (foundPortal) { graph.AddPortal(x, y, size, startIndex); } } } for (int x = 0; x < mapSize; x++) { for (int y = 0; y < mapSize; y++) { List <int> portalIndices = graph.associatedNodes[x, y]; for (int i = 0; i < portalIndices.Count; i++) { int startX; int startY; int startPortalIndex = portalIndices[i]; PortalGraph.PortalNode start = graph.nodes[startPortalIndex]; bool isHoriz = start.isHorizontal; if (isHoriz) { startX = start.startIndex; startY = (start.side ? 0 : FlowGrid.gridResolution - 1); } else { startY = start.startIndex; startX = (start.side ? 0 : FlowGrid.gridResolution - 1); } for (int j = i + 1; j < portalIndices.Count; j++) { int targetX; int targetY; int targetPortalIndex = portalIndices[j]; PortalGraph.PortalNode target = graph.nodes[targetPortalIndex]; isHoriz = target.isHorizontal; if (isHoriz) { targetX = target.startIndex; targetY = (target.side ? 0 : FlowGrid.gridResolution - 1); } else { targetY = target.startIndex; targetX = (target.side ? 0 : FlowGrid.gridResolution - 1); } bool foundPath = pathfinding.calculatePath(mapData[x, y], mapData[x, y].AStarGrid[startX, startY], mapData[x, y].AStarGrid[targetX, targetY]); if (foundPath) { graph.Connect(startPortalIndex, targetPortalIndex); } } } } } return(graph); }