private void DrawTile(object sender, NodeAddedToCollectionEventArgs args) { mainDispatcher.Invoke(() => { Node node = args.node; AStarTile tile = AStarValues.AStarTiles[node.RowIndex, node.ColumnIndex]; if (tile == null) { tile = new AStarTile(node.RowIndex, node.ColumnIndex); } Tile tileType = tile.TileType; if (tileType == Tile.Empty || tileType == Tile.EmptyClosed || tileType == Tile.EmptyOpen) { Tile newType = Tile.Empty; if (sender is OpenSet) { newType = Tile.EmptyOpen; } else if (sender is ClosedSet) { newType = Tile.EmptyClosed; } tile.TileType = newType; AStarValues.SetAStarTile(tile); } }, DispatcherPriority.Normal); }
private void RemoveTile(object sender, MouseEventArgs e) { if (AStarValues.AStarState == State.HasNotStarted) { Point mousePosition = e.GetPosition(canvas); double MousePosX = mousePosition.X; double MousePosY = mousePosition.Y; int RowIndex = GetRowIndex(MousePosY); int ColumnIndex = GetColumnIndex(MousePosX); AStarTile oldTile = AStarValues.AStarTiles[RowIndex, ColumnIndex]; if (oldTile == null) { return; } if (oldTile.TileType == Tile.Start) { AStarValues.StartTile = null; } else if (oldTile.TileType == Tile.Goal) { AStarValues.GoalTile = null; } var emptyTile = new AStarTile(RowIndex, ColumnIndex, Tile.Empty); AStarValues.SetAStarTile(emptyTile); } }
private void SetGoalTile(int RowIndex, int ColumnIndex) { var goalTile = new AStarTile(RowIndex, ColumnIndex, Tile.Goal); AStarValues.SetAStarTile(goalTile); AStarValues.GoalTile = goalTile; SetGoalTileValueChanged(this, EventArgs.Empty); }
private void SetStartTile(int RowIndex, int ColumnIndex) { var startTile = new AStarTile(RowIndex, ColumnIndex, Tile.Start); AStarValues.SetAStarTile(startTile); AStarValues.StartTile = startTile; SetStartTileValueChanged(this, EventArgs.Empty); }
public AStarVisualizer(UIElements.UIControl uiElements) { AStarValues.InitAStarTiles(); InitUIStartupValues(uiElements); InitObservers(uiElements); InitControllers(uiElements); InitRenderers(uiElements); InitAlgorithmThreadController(); }
private void ClearTiles_Pressed(object sender, EventArgs args) { int numRows = AStarValues.NumGridRows; int numColumns = AStarValues.NumGridColumns; AStarValues.StartTile = null; AStarValues.GoalTile = null; for (int i = 0; i < numRows; i++) { for (int j = 0; j < numColumns; j++) { var newTile = new AStarTile(i, j, Tile.Empty); AStarValues.SetAStarTile(newTile); } } }
private void ResetPathTiles(object sender, EventArgs args) { AStarTile[,] tiles = AStarValues.AStarTiles; foreach (AStarTile tile in tiles) { if (tile == null) { continue; } if (tile.TileType == Tile.EmptyClosed || tile.TileType == Tile.EmptyOpen) { tile.TileType = Tile.Empty; AStarValues.SetAStarTile(tile); } } }
private void SetWallTile(int RowIndex, int ColumnIndex) { var wallTile = new AStarTile(RowIndex, ColumnIndex, Tile.Wall); AStarValues.SetAStarTile(wallTile); }
/// <summary> /// /// </summary> /// <param name="origin">Point to start the path search</param> /// <param name="destination">Point to end the path search</param> /// <returns></returns> private static Move FindMove(Entity entity, TileMap map, Vector2 origin, Vector2 destination) { List <Vector2> path = new List <Vector2>(); // There's always a path if the origin is the destination if (origin == destination) { path.Add(origin); return(new Move(path)); } // Use A* to try and make a path to the destination. Return null // if no path is found, or a list of moves (in order) if found. // Make sure to cache the destination for future use. // If the unit can fly, dig, or jump, just make sure the destination is within reach // and currently doesn't contain anything // For other cases, try and use A* to find a path Dictionary <Vector2, AStarValues> openPoints = new Dictionary <Vector2, AStarValues>(); List <KeyValuePair <Vector2, AStarValues> > closedPoints = new List <KeyValuePair <Vector2, AStarValues> >(); AStarValues originValues = new AStarValues(); originValues.G = 0; originValues.Parent = origin; openPoints.Add(origin, originValues); KeyValuePair <Vector2, AStarValues> current = new KeyValuePair <Vector2, AStarValues>(origin, originValues); var relativePositions = GetRelativePositions(); while (openPoints.Count > 0) { current = openPoints.OrderBy(p => p.Value.F).First <KeyValuePair <Vector2, AStarValues> >(); // Drop the nextPoint from openPoints and add it to the closedPoints openPoints.Remove(current.Key); closedPoints.Add(current); if (current.Key == destination) { break; } // Add to our open list the new set of squares to use. foreach (Vector2 position in relativePositions) { Vector2 next = current.Key + position; if (closedPoints.Any(p => p.Key == next) || !map.HasTile(next) || map.ObjectsInMap.Any <RenderObject>(p => p.Location == next)) { continue; } AStarValues values = new AStarValues(); values.Parent = current.Key; // Use the current G value plus the G value to move to the next point to find the actual G value values.G = (int)GetMoveCost(position) + current.Value.G; if (values.G > entity.MoveDistance) { // The distance is too great. don't add to the open points continue; } if (next == destination) { openPoints[next] = values; break; } // H is calculated using the Manhatten method. Essentially, calculate the move cost from the proposed square // to the destination square using only horizontal and vertical movements. values.H = (int)GetMoveCost(destination - next); values.F = values.G + values.H; if (openPoints.ContainsKey(next)) { // Check the G score of the current path to this square. If this path is faster, then update the // value to include the current values for going this direction if (openPoints[next].G > values.G) { openPoints[next] = values; } } else { openPoints[next] = values; } } } // The origin always gets put into the closedList, so check for anything greater than 1 var lastPoint = closedPoints.Last(); if (lastPoint.Key != destination) { // Didn't find a path to the destination return(null); } var currentPoint = lastPoint; while (currentPoint.Key != origin) { path.Add(currentPoint.Key); currentPoint = closedPoints.First(v => v.Key == currentPoint.Value.Parent); } // Cache this path return(new Move(path)); }
public void RedrawTile() { AStarValues.SetAStarTile(this); }
/// <summary> /// /// </summary> /// <param name="origin">Point to start the path search</param> /// <param name="destination">Point to end the path search</param> /// <returns></returns> private static Move FindMove(Entity entity, TileMap map, Vector2 origin, Vector2 destination) { List<Vector2> path = new List<Vector2>(); // There's always a path if the origin is the destination if (origin == destination) { path.Add(origin); return new Move(path); } // Use A* to try and make a path to the destination. Return null // if no path is found, or a list of moves (in order) if found. // Make sure to cache the destination for future use. // If the unit can fly, dig, or jump, just make sure the destination is within reach // and currently doesn't contain anything // For other cases, try and use A* to find a path Dictionary<Vector2, AStarValues> openPoints = new Dictionary<Vector2, AStarValues>(); List<KeyValuePair<Vector2, AStarValues>> closedPoints = new List<KeyValuePair<Vector2, AStarValues>>(); AStarValues originValues = new AStarValues(); originValues.G = 0; originValues.Parent = origin; openPoints.Add(origin, originValues); KeyValuePair<Vector2, AStarValues> current = new KeyValuePair<Vector2, AStarValues>(origin, originValues); var relativePositions = GetRelativePositions(); while (openPoints.Count > 0) { current = openPoints.OrderBy(p => p.Value.F).First<KeyValuePair<Vector2, AStarValues>>(); // Drop the nextPoint from openPoints and add it to the closedPoints openPoints.Remove(current.Key); closedPoints.Add(current); if (current.Key == destination) { break; } // Add to our open list the new set of squares to use. foreach (Vector2 position in relativePositions) { Vector2 next = current.Key + position; if (closedPoints.Any(p => p.Key == next) || !map.HasTile(next) || map.ObjectsInMap.Any<RenderObject>(p => p.Location == next)) { continue; } AStarValues values = new AStarValues(); values.Parent = current.Key; // Use the current G value plus the G value to move to the next point to find the actual G value values.G = (int)GetMoveCost(position) + current.Value.G; if (values.G > entity.MoveDistance) { // The distance is too great. don't add to the open points continue; } if (next == destination) { openPoints[next] = values; break; } // H is calculated using the Manhatten method. Essentially, calculate the move cost from the proposed square // to the destination square using only horizontal and vertical movements. values.H = (int)GetMoveCost(destination - next); values.F = values.G + values.H; if (openPoints.ContainsKey(next)) { // Check the G score of the current path to this square. If this path is faster, then update the // value to include the current values for going this direction if (openPoints[next].G > values.G) { openPoints[next] = values; } } else { openPoints[next] = values; } } } // The origin always gets put into the closedList, so check for anything greater than 1 var lastPoint = closedPoints.Last(); if (lastPoint.Key != destination) { // Didn't find a path to the destination return null; } var currentPoint = lastPoint; while (currentPoint.Key != origin) { path.Add(currentPoint.Key); currentPoint = closedPoints.First(v => v.Key == currentPoint.Value.Parent); } // Cache this path return new Move(path); }