static void MakeDungeon(int seed) { stage = new Stage(23, 23); RoomDecorator rd = new RoomDecorator(stage); rd.ReadAll("rooms.txt"); Generator g = new Generator(seed); g.DecorateRoom += rd.DecorateRoom; g.numRoomTries = 500; g.generate(stage); DijkstraMap dm = new DijkstraMap(stage, 0); //dm.Compute(1,1,true); dm.Compute(stage.GetAll(Tiles.Brazier), false); dm.Display(); dm.CalculatePath(21, 21); var path = dm.GetReversePath().ToList(); PrintDungeon(seed); }
public static void InitializeGridMap(GameManager manager) { if (manager == null) { return; } gridMap = new DijkstraMap <Grid>(); }
public static List <Vec> Pathfind(Vec start, Vec[] goal) { DijkstraMap dm = new DijkstraMap(stage, Mathf.Sqrt(2.0f)); dm.Compute(goal, false); if (dm.CalculatePath(start.x, start.y)) { return(dm.GetPath().ToList()); } return(new List <Vec>()); }
void Start() { currentSpeed = speed; // Get reference to the map attached to the mapObject if (mapObject == null) { Debug.LogError("Pathfinding map object not initialised!"); return; } map = mapObject.GetComponent <DijkstraMap>(); }
void OnMouseOver() { if (Input.GetMouseButtonDown(1)) { if (isTower) { GetComponent <Tower>().pathingGrid.GetComponent <DijkstraMap>().RemoveStructureReference(transform.position.x, transform.position.y); } else { DijkstraMap map = GetComponent <Wall>().pathingGrid.GetComponent <DijkstraMap>(); map.RemoveStructureReference(transform.position.x, transform.position.y); GetComponent <Wall>().GetComponent <Collider2D>().enabled = false; map.CalcMap(); } Destroy(gameObject); } }
private Point?GetExploreDestination() { //todo, clean up later var potentiallyReachable = FloodFill.ScanToArray(Player.Position, point => !point.IsMapEdge() && (!Map.Seen[point] || TileDefinition.IsPassable(TileTypeAt(point)))); var dm2 = new DijkstraMap(p => (Map.Seen[p] || p.IsMapEdge())? -1 : 1) //todo, seen==blocked? { IsSource = p => (Map.Seen[p] || p.IsMapEdge()) }; dm2.Scan(); //CharacterScreens.PrintDijkstraTest(dm2); foreach (Point p in Map.GetAllPoints(false)) { if (dm2[p] == DijkstraMap.Unexplored || dm2[p] == DijkstraMap.Blocked) { continue; } dm2[p] = -(dm2[p] * dm2[p]); } dm2.RescanWithCurrentValues(); //CharacterScreens.PrintDijkstraTest(dm2); var dm = new DijkstraMap(p => (!Map.Seen[p] || !TileDefinition.IsPassable(TileTypeAt(p)))? -1 : 1) { IsSource = p => !Map.Seen[p] && potentiallyReachable[p], GetSourceValue = p => - (dm2[p]) }; dm.Scan(); //CharacterScreens.PrintDijkstraTest(dm2); //CharacterScreens.PrintDijkstraTest(dm); List <Point> playerPath = dm.GetDownhillPath(Player.Position, true, earlyStopCondition: p => !Map.Seen[p]); if (playerPath.Count == 0) { return(null); } else { return(playerPath[playerPath.Count - 1]); } }
//Updates the world every frame. public void tick(GameTime time) { Player player = manager.GetPlayer(); int pX = player.location.IntX / Tile.SIDE_LENGTH; //The actual player location. int pY = player.location.IntY / Tile.SIDE_LENGTH; //The actual player location. int width = Game1.Instance.GraphicsDevice.Viewport.Width / Tile.SIDE_LENGTH + 10; int height = Game1.Instance.GraphicsDevice.Viewport.Height / Tile.SIDE_LENGTH + 10; if (playerMap == null) { playerMap = new DijkstraMap(this, width, height, pX - 5, pY - 5, 1, new int[] { 5, 5 }); fleeMap = playerMap.Clone().GenerateFleeMap(this); } int[] pLoc = playerMap.Goals[0]; //The player location for AI's. if (pX != pLoc[0] || pY != pLoc[1]) { playerMap = new DijkstraMap(this, width, height, pX - 5, pY - 5, 1, new int[] { 5, 5 }); fleeMap = playerMap.Clone().GenerateFleeMap(this); } manager.Update(time); }
private List <Point> GetPathToNearbyReachable(Point potentialDestination, DijkstraMap playerMovementMap, ref PointArray <bool> knownReachable, ref DijkstraMap distanceToKnownReachable) { Point destination = potentialDestination; // First, figure out whether the destination cell is known-reachable: if (knownReachable == null) { knownReachable = FloodFill.ScanToArray(Player.Position, CellIsKnownPassable); } PointArray <bool> knownReachable2 = knownReachable; // Can't use a ref parameter inside a lambda, but using a 2nd variable works. if (!knownReachable[destination]) { // If not, then find the nearest known reachable spaces: if (distanceToKnownReachable == null) { distanceToKnownReachable = new DijkstraMap(point => 1) { IsSource = point => knownReachable2[point] }; distanceToKnownReachable.Scan(); } if (distanceToKnownReachable[destination] > 1) // If distance is 1, then we can reach it anyway { destination = destination.EnumeratePointsAtChebyshevDistance(distanceToKnownReachable[destination], true, false) // We know the distance already, so check only those cells... .Where(nearby => nearby.ExistsBetweenMapEdges() && knownReachable2[nearby]) // ...make sure only reachable ones are considered... .WhereLeast(nearby => destination.GetHalfStepMetricDistance(nearby)) // ...get the nearest ones to the targeted point... .WhereLeast(nearby => Player.Position.GetHalfStepMetricDistance(nearby))[0]; // ...and finally get whichever one of those is closest to the player. } } if (destination == Player.Position) { return(new List <Point>()); } List <Point> path = playerMovementMap.GetDownhillPath(destination, preferCardinalDirections: true, includePathSource: true, includePathDestination: false, ignorePathSourceCost: true); path.Reverse(); return(path); }
private void ChooseAutoexploreAction(PlayerTurnEvent e) { var potentiallyReachable = FloodFill.ScanToArray(Player.Position, point => !point.IsMapEdge() && (!Map.Seen[point] || TileDefinition.IsPassable(TileTypeAt(point)))); var distanceToKnown = new DijkstraMap(p => (Map.Seen[p] || p.IsMapEdge())? -1 : 1) { IsSource = p => (Map.Seen[p] || p.IsMapEdge()) }; distanceToKnown.Scan(); foreach (Point p in Map.GetAllPoints(false)) { if (distanceToKnown[p] == DijkstraMap.Unexplored || distanceToKnown[p] == DijkstraMap.Blocked) { continue; } distanceToKnown[p] = -(distanceToKnown[p] * distanceToKnown[p]); } distanceToKnown.RescanWithCurrentValues(); var exploreMap = new DijkstraMap(p => (!Map.Seen[p] || !TileDefinition.IsPassable(TileTypeAt(p)))? -1 : 1) // todo, needs items, shrines, etc. eventually { IsSource = p => !Map.Seen[p] && potentiallyReachable[p], GetSourceValue = p => - (distanceToKnown[p]) }; exploreMap.Scan(); List <Point> playerPath = exploreMap.GetDownhillPath(Player.Position, true, earlyStopCondition: p => true); if (playerPath.Count == 0) { return; } else { e.ChosenAction = new WalkAction(Player, playerPath[0]); } }
public static TimeSpan TimeForSingleSourceDijkstra(int mapWidth, int mapHeight, int iterations) { Stopwatch s = new Stopwatch(); var map = new ArrayMap <bool>(mapWidth, mapHeight); Generators.RectangleMapGenerator.Generate(map); DijkstraMap dMap = new DijkstraMap(map); dMap.AddGoal(5, 5); dMap.Calculate(); // warm-up value s.Start(); for (int i = 0; i < iterations; i++) { dMap.Calculate(); } s.Stop(); return(s.Elapsed); }
public void LookMode(PlayerTurnEvent e, bool startInTravelMode = false, TravelDestinationPriority travelPriority = TravelDestinationPriority.Explore) { bool travelMode = startInTravelMode; List <Point> travelDestinations = GetTravelDestinations(travelPriority); //todo, start this as null or not? DijkstraMap playerMovementMap = new DijkstraMap(point => (!Map.Seen[point] || !TileDefinition.IsPassable(TileTypeAt(point)))? -1 : 10); playerMovementMap.Scan(Player.Position); PointArray <bool> knownReachable = null; DijkstraMap distanceToKnownReachable = null; int travelIndex = 0; Point p = travelDestinations[0]; while (true) { Screen.HoldUpdates(); Screen.Clear(MessageBuffer.RowOffset, ColOffset, 4, MapDisplayWidth); Screen.Clear(GameRunUI.EnviromentalDescriptionRow, ColOffset, 1, MapDisplayWidth); Screen.Clear(GameRunUI.CommandListRow, ColOffset, 1, MapDisplayWidth); GameRunUI.DrawGameUI( sidebar: DrawOption.Normal, messages: DrawOption.DoNotDraw, environmentalDesc: DrawOption.DoNotDraw, commands: DrawOption.DoNotDraw ); string moveCursorMsg = travelMode? "Travel mode -- Move cursor to choose destination." : "Move cursor to look around."; Screen.Write(MessageBuffer.RowOffset, ColOffset, moveCursorMsg); Screen.Write(MessageBuffer.RowOffset + 2, ColOffset, "[Tab] to cycle between interesting targets [m]ore details"); Screen.Write(MessageBuffer.RowOffset + 2, ColOffset + 1, "Tab", Color.Cyan); Screen.Write(MessageBuffer.RowOffset + 2, ColOffset + 53, 'm', Color.Cyan); if (travelMode) { Screen.Write(MessageBuffer.RowOffset + 3, ColOffset, "[x] to confirm destination [Space] to cancel travel mode"); Screen.Write(MessageBuffer.RowOffset + 3, ColOffset + 1, 'x', Color.Cyan); Screen.Write(MessageBuffer.RowOffset + 3, ColOffset + 38, "Space", Color.Cyan); } else { Screen.Write(MessageBuffer.RowOffset + 3, ColOffset, "[x] to enter travel mode"); Screen.Write(MessageBuffer.RowOffset + 3, ColOffset + 1, 'x', Color.Cyan); } Highlight highlight; if (travelMode) { List <Point> path = GetPathToNearbyReachable(p, playerMovementMap, ref knownReachable, ref distanceToKnownReachable); highlight = new Highlight(MapHighlightType.Path) { Source = Player.Position, Destination = p, LineOrPath = path }; } else { highlight = new Highlight(MapHighlightType.SinglePoint) { Destination = p }; } MapRenderer.UpdateAllSettings(p, highlight); MapRenderer.DrawMap(e); bool hasLOS = e.CellsVisibleThisTurn[p]; bool seen = Map.Seen[p]; string lookDescription = hasLOS? GetDescriptionAtCell(p) : seen?GetLastKnownDescriptionAtCell(p) : ""; if (lookDescription.Length > MapDisplayWidth) { int splitIdx = 0; for (int idx = MapDisplayWidth - 1; idx >= 0; --idx) { if (lookDescription[idx] == ' ') { splitIdx = idx; break; } } int firstLineRow = Option.IsSet(BoolOptionType.MessagesAtBottom)? GameRunUI.CommandListRow : GameRunUI.EnviromentalDescriptionRow; // Start printing at whichever is higher onscreen string firstLine = lookDescription.Substring(0, splitIdx); string secondLine = lookDescription.Substring(splitIdx + 1); // Remove the space if (secondLine.Length > MapDisplayWidth) { firstLine = hasLOS? "You see many things here." : "You remember seeing many things here."; //todo, what should this say? secondLine = "(Press 'm' for more details)"; //secondLine = "(Use the '[m]ore details' command for the full list)"; todo...any better options? } Screen.Write(firstLineRow, ColOffset, firstLine, Color.Green); Screen.Write(firstLineRow + 1, ColOffset, secondLine, Color.Green); } else { Screen.Write(GameRunUI.EnviromentalDescriptionRow, ColOffset, lookDescription, Color.Green); } Screen.ResumeUpdates(); bool needsRedraw = false; while (!needsRedraw) { ConsoleKeyInfo key = Input.ReadKey(); bool shift = (key.Modifiers & ConsoleModifiers.Shift) == ConsoleModifiers.Shift; switch (key.Key) { case ConsoleKey.Tab: if (shift) { travelIndex--; } else { travelIndex++; } if (travelIndex < 0) { travelIndex = travelDestinations.Count - 1; } else if (travelIndex >= travelDestinations.Count) { travelIndex = 0; } p = travelDestinations[travelIndex]; needsRedraw = true; break; case ConsoleKey.Escape: return; // Done case ConsoleKey.Spacebar: if (travelMode) { travelMode = false; needsRedraw = true; } else { return; } break; case ConsoleKey.Enter: if (travelMode) { goto case ConsoleKey.X; // Allow Enter to confirm travel destination, or cancel look mode. } else { goto case ConsoleKey.Escape; } case ConsoleKey.X: if (travelMode) { List <Point> path = GetPathToNearbyReachable(p, playerMovementMap, ref knownReachable, ref distanceToKnownReachable); if (path.Count > 0) { GameEventHandler.Path = path; GameEventHandler.NextPathIndex = 0; } //if(false) GameEventHandler.Autoexplore = true; //todo, option here return; } else { travelMode = true; needsRedraw = true; } break; case ConsoleKey.NumPad8: p = p.PointInDir(Dir8.N, shift? 6 : 1); needsRedraw = true; break; case ConsoleKey.NumPad6: p = p.PointInDir(Dir8.E, shift? 6 : 1); needsRedraw = true; break; case ConsoleKey.NumPad4: p = p.PointInDir(Dir8.W, shift? 6 : 1); needsRedraw = true; break; case ConsoleKey.NumPad2: p = p.PointInDir(Dir8.S, shift? 6 : 1); needsRedraw = true; break; case ConsoleKey.NumPad9: p = p.PointInDir(Dir8.NE, shift? 6 : 1); needsRedraw = true; break; case ConsoleKey.NumPad3: p = p.PointInDir(Dir8.SE, shift? 6 : 1); needsRedraw = true; break; case ConsoleKey.NumPad1: p = p.PointInDir(Dir8.SW, shift? 6 : 1); needsRedraw = true; break; case ConsoleKey.NumPad7: p = p.PointInDir(Dir8.NW, shift? 6 : 1); needsRedraw = true; break; default: break; } if (!p.ExistsOnMap()) { int newX, newY; if (p.X < 0) { newX = 0; } else if (p.X >= GameUniverse.MapWidth) { newX = GameUniverse.MapWidth - 1; } else { newX = p.X; } if (p.Y < 0) { newY = 0; } else if (p.Y >= GameUniverse.MapHeight) { newY = GameUniverse.MapHeight - 1; } else { newY = p.Y; } p = new Point(newX, newY); } } } }