namespace Holo.Virtual.Rooms.Pathfinding { using Holo.Virtual.Rooms; using System; using System.Collections; public class DenDribbelaerPathfinder { private Heap Closed = new Heap(); private mapNode Goal; private int maxX; private int maxY; private Heap Open = new Heap(); private double[,] squareHeights; private virtualRoom.squareState[,] squareStates; private bool[,] squareUnitFlags; private mapNode Start; private ArrayList Successors = new ArrayList(); public DenDribbelaerPathfinder(virtualRoom.squareState[,] squareStates, double[,] squareHeights, bool[,] squareUnitFlags) { this.squareStates = squareStates; this.squareHeights = squareHeights; this.squareUnitFlags = squareUnitFlags; this.maxX = squareUnitFlags.GetLength(1) - 1; this.maxY = squareUnitFlags.GetLength(0) - 1; } public Coord getNext(int X, int Y, int goalX, int goalY) { if ((X == goalX) && (Y == goalY)) { return new Coord(-1, 0); } int maxCycles = (this.maxX * this.maxY) ^ 2; int Cycles = 0; ArrayList Solution = new ArrayList(); this.Goal = new mapNode(goalX, goalY, 0.0, null, null, null); this.Start = new mapNode(X, Y, 0.0, null, this.Goal, null); this.Goal.Start = this.Goal; this.Start.Start = this.Start; this.Open.Add(this.Start); while (this.Open.Count > 0) { if (Cycles >= maxCycles) { return new Coord(-1, 0); } Cycles++; mapNode Current = (mapNode) this.Open.Pop(); if ((Current.X == this.Goal.X) && (Current.Y == this.Goal.Y)) { while (Current != null) { Solution.Insert(0, Current); Current = Current.Parent; } break; } foreach (mapNode Successor in Current.Successors(this)) { mapNode openNode = null; if (this.Open.Contains(Successor)) { openNode = (mapNode) this.Open[this.Open.IndexOf(Successor)]; if (Successor.totalCost > openNode.totalCost) { continue; } } mapNode closedNode = null; if (this.Closed.Contains(Successor)) { closedNode = (mapNode) this.Closed[this.Closed.IndexOf(Successor)]; if (Successor.totalCost > closedNode.totalCost) { continue; } } this.Open.Remove(Successor); this.Closed.Remove(Successor); this.Open.Push(Successor); } this.Closed.Add(Current); } if (Solution.Count == 0) { return new Coord(-1, 0); } mapNode Next = (mapNode) Solution[1]; return new Coord(Next.X, Next.Y); } public dribbelaerPath getPath(int X, int Y, int goalX, int goalY) { if ((X == goalX) && (Y == goalY)) { return null; } int maxCycles = (this.maxX * this.maxY) ^ 2; int Cycles = 0; dribbelaerPath Path = new dribbelaerPath(); this.Goal = new mapNode(goalX, goalY, 0.0, null, null, null); this.Start = new mapNode(X, Y, 0.0, null, this.Goal, null); this.Goal.Start = this.Goal; this.Start.Start = this.Start; this.Open.Add(this.Start); while (this.Open.Count > 0) { if (Cycles >= maxCycles) { return null; } Cycles++; mapNode Current = (mapNode) this.Open.Pop(); if ((Current.X == this.Goal.X) && (Current.Y == this.Goal.Y)) { while (Current != null) { Path.Coords.Push(new Coord(Current.X, Current.Y)); Current = Current.Parent; } break; } foreach (mapNode Successor in Current.Successors(this)) { mapNode openNode = null; if (this.Open.Contains(Successor)) { openNode = (mapNode) this.Open[this.Open.IndexOf(Successor)]; if (Successor.totalCost > openNode.totalCost) { continue; } } mapNode closedNode = null; if (this.Closed.Contains(Successor)) { closedNode = (mapNode) this.Closed[this.Closed.IndexOf(Successor)]; if (Successor.totalCost > closedNode.totalCost) { continue; } } this.Open.Remove(Successor); this.Closed.Remove(Successor); this.Open.Push(Successor); } this.Closed.Add(Current); } if (Path.Coords.Count == 0) { return null; } return Path; } public bool Passable(int X, int Y, int goalX, int goalY) { try { if (this.squareUnitFlags[goalX, goalY] || ((this.squareStates[goalX, goalY] != virtualRoom.squareState.Open) && (this.squareStates[goalX, goalY] != virtualRoom.squareState.Rug))) { return false; } return true; } catch { return false; } } } }