using System;
using System.Collections.ObjectModel;
namespace Holo.Virtual.Rooms.Pathfinding
{
///
/// Represents a node on the map for Astar pathfinding. This class implements the IComparable interface. :o
///
public class mapNode : IComparable
{
#region Declares
///
/// The X position of this node.
///
internal int X;
///
/// The Y position of this node.
///
internal int Y;
///
/// The mapNode object of the parent node of this node.
///
internal mapNode Parent;
internal mapNode Start;
///
/// The mapNode object of the goal node of this node.
///
private mapNode Goal;
///
/// The cost for the pathfinder to pass this node.
///
internal double Cost;
///
/// The estimated cost for the pathfinder from this node to the goal node.
///
private double _esToGoal;
#endregion
#region Constructors
///
/// Intializes a new mapNode.
///
/// The X position of this node.
/// The Y position of t his node.
/// The cost for the pathfinder to pass this node.
/// The mapNode object of the parent node of this node.
/// The mapNode object of the goal node of this node.
public mapNode(int X, int Y, double Cost, mapNode Parent, mapNode Goal, mapNode Start)
{
this.Parent = Parent;
this.Start = Start;
this.Goal = Goal;
this.X = X;
this.Y = Y;
this.Cost = Cost;
}
#endregion
#region Properties
///
/// The heuristic estimated cost to the goal. (Manhattan calculation)
///
internal double goalEstimate
{
get
{
if (Goal == null)
return 0;
else
{
int a1 = 2 * this.X;
int a2 = 2 * this.Y + this.X % 2 - this.X;
int a3 = -2 * this.Y - this.X % 2 - this.X;
int b1 = 2 * Goal.X;
int b2 = 2 * Goal.Y + Goal.X % 2 - Goal.X;
int b3 = -2 * Goal.Y - Goal.X % 2 - Goal.X;
return Math.Max(Math.Abs(a1 - b1), Math.Max(Math.Abs(a2 - b2), Math.Abs(a3 - b3)));
}
}
set { _esToGoal = value; }
}
///
/// The total cost of this node to the goal.
///
internal double totalCost
{
get { return Cost + goalEstimate; }
}
#endregion
#region IComparable additions
///
/// Compares this node's total cost to the total cost of another mapNode and returns the result.
///
/// The mapNode object to compare the total cost with.
int IComparable.CompareTo(Object obj)
{
return -totalCost.CompareTo(((mapNode)obj).totalCost);
}
#endregion
#region Methods
///
/// Creates a mapNode object for a certain coordinate, with this node's cost. The parent node of the new node will be set to this node.
///
/// The X position of the new node.
/// The Y position of the new node.
private mapNode createNode(int X, int Y)
{
int dx1 = this.X - Goal.X;
int dy1 = this.X - Goal.Y;
int dx2 = Start.X - Goal.X;
int dy2 = Start.Y - Goal.Y;
double Tie = Math.Abs((dx1 * dy2) - (dx2 * dy1)) * 0.005;
return new mapNode(X, Y, this.Cost + Tie, this, this.Goal,this.Start);
}
///
/// Returns an objectmodel collection of the type mapNode, which contains all the successor nodes to this node.
///
internal Collection Successors(DenDribbelaerPathfinder Pathfinder)
{
Collection tmp = new Collection();
if (Pathfinder.Passable(X, Y, X - 1, Y))
tmp.Add(createNode(X - 1, Y)); // Left
if (Pathfinder.Passable(X, Y, X + 1, Y))
tmp.Add(createNode(X + 1, Y)); // Right
if (Pathfinder.Passable(X, Y, X, Y + 1))
tmp.Add(createNode(X, Y + 1)); // Up
if (Pathfinder.Passable(X, Y, X, Y - 1))
tmp.Add(createNode(X, Y - 1)); // Down
if (Pathfinder.Passable(X, Y, X - 1, Y + 1))
tmp.Add(createNode(X - 1, Y + 1)); // Left up
if (Pathfinder.Passable(X, Y, X - 1, Y - 1))
tmp.Add(createNode(X - 1, Y - 1)); // Left down
if (Pathfinder.Passable(X, Y, X, Y + 1))
tmp.Add(createNode(X, Y + 1)); // Mid up
if (Pathfinder.Passable(X, Y, X, Y - 1))
tmp.Add(createNode(X, Y - 1)); // Mid down
if (Pathfinder.Passable(X, Y, X + 1, Y + 1))
tmp.Add(createNode(X + 1, Y + 1)); // Right up
if (Pathfinder.Passable(X, Y, X + 1, Y - 1))
tmp.Add(createNode(X + 1, Y - 1)); // Right down
return tmp;
}
#endregion
}
}