public void CalculatePathmap() { RefreshNodes(); var openNodes = new Queue<TDPNode>(); foreach (var entity in _entities) { var node = GetNode(entity.X, entity.Y); openNodes.Enqueue(node); node.IsClosed = true; } while (openNodes.Count > 0) { var currentNode = openNodes.Dequeue(); var x = currentNode.X; var y = currentNode.Y; var width = _field.Width - 1; var height = _field.Height - 1; var neighbors = new TDPNode[8]; if (x < width) { neighbors[0] = GetNode(x + 1, y + 0); if (y < height) neighbors[4] = GetNode(x + 1, y + 1); if (y > 0) neighbors[6] = GetNode(x + 1, y + -1); } if (x > 0) { neighbors[1] = GetNode(x + -1, y + 0); if (y < height) neighbors[5] = GetNode(x - 1, y + 1); if (y > 0) neighbors[7] = GetNode(x - 1, y + -1); } if (y < height) neighbors[2] = GetNode(x + 0, y + 1); if (y > 0) neighbors[3] = GetNode(x + 0, y + -1); for (var i = 0; i < neighbors.Length; i++) { var neighbor = neighbors[i]; if (neighbor == null) continue; if (neighbor.IsClosed) continue; if (IsObstacle(neighbor.X, neighbor.Y)) { neighbor.IsObstacle = true; continue; } neighbor.Parent = currentNode; neighbor.G = i > 4 ? neighbor.Parent.G + 14 : neighbor.Parent.G + 10; neighbor.IsVisited = true; neighbor.IsClosed = true; openNodes.Enqueue(neighbor); } } WasUpdatedThisTurn = true; }
private TDPNode JPSJump(TDPNode mStartNode, TDPNode mEndNode, TDPNode mTargetNode) { if (mStartNode == null) return null; var dx = mStartNode.X - mEndNode.X; var dy = mStartNode.Y - mEndNode.Y; if (IsObstacle(mStartNode.X, mStartNode.Y)) return null; if (mStartNode == mTargetNode) return mStartNode; if (dx != 0 && dy != 0) { if ((!IsObstacle(mStartNode.X - dx, mStartNode.Y + dy) && IsObstacle(mStartNode.X - dx, mStartNode.Y)) || (!IsObstacle(mStartNode.X + dx, mStartNode.Y - dy) && IsObstacle(mStartNode.X, mStartNode.Y - dy))) return mStartNode; } else { if (dx != 0) { if ((!IsObstacle(mStartNode.X + dx, mStartNode.Y + 1) && IsObstacle(mStartNode.X, mStartNode.Y + 1)) || (!IsObstacle(mStartNode.X + dx, mStartNode.Y - 1) && IsObstacle(mStartNode.X, mStartNode.Y - 1))) return mStartNode; } else { if ((!IsObstacle(mStartNode.X + 1, mStartNode.Y + dy) && IsObstacle(mStartNode.X + 1, mStartNode.Y)) || (!IsObstacle(mStartNode.X - 1, mStartNode.Y + dy) && IsObstacle(mStartNode.X - 1, mStartNode.Y))) return mStartNode; } } if (dx != 0 && dy != 0) { var jx = JPSJump(GetNode(mStartNode.X + dx, mStartNode.Y), mStartNode, mTargetNode); var jy = JPSJump(GetNode(mStartNode.X, mStartNode.Y + dy), mStartNode, mTargetNode); if (jx != null || jy != null) return mStartNode; } if (!IsObstacle(mStartNode.X + dx, mStartNode.Y) || !IsObstacle(mStartNode.X, mStartNode.Y + dy)) return JPSJump(GetNode(mStartNode.X + dx, mStartNode.Y + dy), mStartNode, mTargetNode); return null; }
private void InitializeNodes() { _nodes = new TDPNode[_field.Width,_field.Height]; for (var iY = 0; iY < _field.Height; iY++) for (var iX = 0; iX < _field.Width; iX++) _nodes[iX, iY] = new TDPNode(iX, iY); }
private IEnumerable<TDPNode> JPSFindNeighbors(TDPNode mNode) { var result = new List<TDPNode>(); if (mNode.Parent == null) return GetAdjacentNodes(mNode.X, mNode.Y); var dx = (mNode.X - mNode.Parent.X)/Math.Max(Math.Abs(mNode.X - mNode.Parent.X), 1); var dy = (mNode.Y - mNode.Parent.Y)/Math.Max(Math.Abs(mNode.Y - mNode.Parent.Y), 1); if (dx != 0 && dy != 0) { if (!IsObstacle(mNode.X, mNode.Y + dy)) result.Add(GetNode(mNode.X, mNode.Y + dy)); if (!IsObstacle(mNode.X + dx, mNode.Y)) result.Add(GetNode(mNode.X + dx, mNode.Y)); if (!IsObstacle(mNode.X, mNode.Y + dy) || !IsObstacle(mNode.X + dx, mNode.Y)) result.Add(GetNode(mNode.X + dx, mNode.Y + dy)); if (IsObstacle(mNode.X - dx, mNode.Y) && !IsObstacle(mNode.X, mNode.Y + dy)) result.Add(GetNode(mNode.X - dx, mNode.Y + dy)); if (IsObstacle(mNode.X, mNode.Y - dy) && !IsObstacle(mNode.X + dx, mNode.Y)) result.Add(GetNode(mNode.X + dx, mNode.Y - dy)); } else { if (dx == 0) { if (!IsObstacle(mNode.X, mNode.Y + dy)) { if (!IsObstacle(mNode.X, mNode.Y + dy)) result.Add(GetNode(mNode.X, mNode.Y + dy)); if (IsObstacle(mNode.X + 1, mNode.Y)) result.Add(GetNode(mNode.X + 1, mNode.Y + dy)); if (IsObstacle(mNode.X - 1, mNode.Y)) result.Add(GetNode(mNode.X - 1, mNode.Y + dy)); } } else { if (!IsObstacle(mNode.X + dx, mNode.Y)) { if (!IsObstacle(mNode.X + dx, mNode.Y)) result.Add(GetNode(mNode.X + dx, mNode.Y)); if (IsObstacle(mNode.X, mNode.Y + 1)) result.Add(GetNode(mNode.X + dx, mNode.Y + 1)); if (IsObstacle(mNode.X, mNode.Y - 1)) result.Add(GetNode(mNode.X + dx, mNode.Y - 1)); } } } return result; }