public bool Equals(Node other) { if (ReferenceEquals(null, other)) { return false; } if (ReferenceEquals(this, other)) { return true; } return other.Index == this.Index && other.Position.Equals(this.Position) && Equals(other.Parent, this.Parent) && other.Walkable.Equals(this.Walkable) && other.G == this.G && other.H == this.H; }
public AStar(int[,] levelMap, int tileSize) { this.tileSize = tileSize; this.Nodes = new List<Node>(); verticalTileCount = levelMap.GetUpperBound(0) + 1; horizontalTileCount = levelMap.GetUpperBound(1) + 1; for (var i = 0; i < levelMap.Length; i++) { var node = new Node(i) { Position = this.IndexToCenterPosition(i) }; if (levelMap[i / this.horizontalTileCount, i % this.horizontalTileCount] == 0) { node.Walkable = true; } this.Nodes.Add(node); } }
private int ComputeCostG(Node sourceNode, Node targetNode) { // Vertical or horizontal -> Cost 10 if (sourceNode.Index == targetNode.Index + 1 || sourceNode.Index == targetNode.Index - 1 || sourceNode.Index == targetNode.Index + horizontalTileCount || sourceNode.Index == targetNode.Index - horizontalTileCount) { return 10; } // Diagonal -> Cost 14 return 14; }
private Node SolvePathCore(Node startNode, Node endNode) { this.openList.Clear(); this.closedList.Clear(); startNode.Parent = null; this.openList.Add(startNode); startNode.G = 0; startNode.H = this.ComputeCostH(startNode, endNode); while (this.openList.Count > 0) { var current = this.openList.OrderBy(node => node.F).First(); if (current == endNode) { return current; } this.openList.Remove(current); this.closedList.Add(current); foreach (var neighbour in this.GetNeighbourNodes(current)) { var g_score_temp = current.G + this.ComputeCostG(current, neighbour); if (this.closedList.Contains(neighbour) && g_score_temp < neighbour.G) { neighbour.G = g_score_temp; neighbour.Parent = current; } else if (this.openList.Contains(neighbour) && g_score_temp < neighbour.G) { neighbour.G = g_score_temp; neighbour.Parent = current; } else if (!this.openList.Contains(neighbour) && !this.closedList.Contains(neighbour)) { this.openList.Add(neighbour); neighbour.Parent = current; neighbour.G = current.G + this.ComputeCostG(neighbour, current); neighbour.H = this.ComputeCostH(neighbour, endNode); } } } return null; }
private void ReconstructPath(Node node) { if (node == null) { this.path = new Queue<Vector2>(); return; } var current = node.Parent; while (current != null && !IsPathFound) { this.path.Enqueue(current.Position); this.ReconstructPath(current); } IsPathFound = true; }
private IEnumerable<Node> GetNeighbourNodes(Node current) { var nodeIndices = new List<int>(); //var nodeIndices = new List<int> // { // this.GetNodeIndexN(current.Index), // this.GetNodeIndexNE(current.Index), // this.GetNodeIndexE(current.Index), // this.GetNodeIndexSE(current.Index), // this.GetNodeIndexS(current.Index), // this.GetNodeIndexSW(current.Index), // this.GetNodeIndexW(current.Index), // this.GetNodeIndexNW(current.Index), // }; if (this.GetNodeIndexN(current.Index) != -1) { nodeIndices.Add(this.GetNodeIndexN(current.Index)); } else { nodeIndices.Add(this.GetNodeIndexNW(current.Index)); nodeIndices.Add(this.GetNodeIndexN(current.Index)); nodeIndices.Add(this.GetNodeIndexNE(current.Index)); } if (this.GetNodeIndexE(current.Index) != -1) { nodeIndices.Add(this.GetNodeIndexE(current.Index)); } else { nodeIndices.Add(this.GetNodeIndexNE(current.Index)); nodeIndices.Add(this.GetNodeIndexE(current.Index)); nodeIndices.Add(this.GetNodeIndexSE(current.Index)); } if (this.GetNodeIndexS(current.Index) != -1) { nodeIndices.Add(this.GetNodeIndexS(current.Index)); } else { nodeIndices.Add(this.GetNodeIndexSE(current.Index)); nodeIndices.Add(this.GetNodeIndexS(current.Index)); nodeIndices.Add(this.GetNodeIndexSW(current.Index)); } if (this.GetNodeIndexW(current.Index) != -1) { nodeIndices.Add(this.GetNodeIndexW(current.Index)); } else { nodeIndices.Add(this.GetNodeIndexSW(current.Index)); nodeIndices.Add(this.GetNodeIndexW(current.Index)); nodeIndices.Add(this.GetNodeIndexNW(current.Index)); } // Native List<T>.RemoveAll() not supported on Xbox360 nodeIndices.RemoveAll2(nodeIndex => nodeIndex == -1); var adjacentNodes = this.Nodes.Where(node => nodeIndices.Contains(node.Index) && node.Walkable); return adjacentNodes.ToList(); }
private int ComputeCostH(Node sourceNode, Node targetNode) { var targetX = targetNode.Index % horizontalTileCount; var targetY = targetNode.Index / horizontalTileCount; var sourceX = sourceNode.Index % horizontalTileCount; var sourceY = sourceNode.Index / horizontalTileCount; // Manhattan method return 10*(Math.Abs(targetX - sourceX) + Math.Abs(targetY - sourceY)); }