public void Start() { if (grid.Source == null || grid.Destination == null) { return; } totalVisited = 0; IsActive = true; openList = new BinaryHeap<double, GridCell>(); currentCell = grid.Source; currentCell.State = GridCellState.Closed; }
public override void Update(GameTime gameTime) { if (!IsActive) { return; } foreach (var currentAdjacentCell in grid.GetValidAdjacentCells(currentCell)) { if (currentAdjacentCell.State != GridCellState.Open) { currentAdjacentCell.State = GridCellState.Open; currentAdjacentCell.Parent = currentCell; currentAdjacentCell.H = Heuristic.GetEstimate(currentAdjacentCell.Position, grid.Destination.Position) * 10; currentAdjacentCell.H += GetTieBreaker(currentAdjacentCell); //currentAdjacentCell.H *= 1 + 1/1000f; currentAdjacentCell.G = currentCell.G + (currentCell.IsOrthagonalWith(currentAdjacentCell) ? 10 : 14); openList.Insert(currentAdjacentCell.F, currentAdjacentCell); } } if (openList.Count == 0) //A path cannot be found { IsActive = false; return; } totalVisited++; currentCell = openList.RemoveMin(); currentCell.State = GridCellState.Closed; if (grid.Destination.State == GridCellState.Closed) //A path has been found { var path = currentCell.GetPath(); IsActive = false; PathFound(this, new PathFoundEventArgs(path, path.Count(),totalVisited -1)); } base.Update(gameTime); }
void SetCellType(GridCell cell, GridCellType type) { if (cell == null) { return; } cell.Type = type; }
public bool IsOrthagonalWith(GridCell otherCell) { return Position.X == otherCell.Position.X || Position.Y == otherCell.Position.Y; }
double GetTieBreaker(GridCell cell) { /* * http://theory.stanford.edu/~amitp/GameProgramming/Heuristics.html#S12 */ int dx1 = cell.Position.X - grid.Destination.Position.X, dy1 = cell.Position.Y - grid.Destination.Position.Y, dx2 = grid.Source.Position.X - grid.Destination.Position.X, dy2 = grid.Source.Position.Y - grid.Destination.Position.Y, cross = Math.Abs(dx1 * dy2 - dx2 * dy1); return cross * 0.01; }