public JumpPointParam(BaseGrid iGrid, GridPos iStartPos, GridPos iEndPos, bool iAllowEndNodeUnWalkable = true, bool iCrossCorner = true, bool iCrossAdjacentPoint = true, HeuristicMode iMode = HeuristicMode.EUCLIDEAN) { switch (iMode) { case HeuristicMode.MANHATTAN: m_heuristic = new HeuristicDelegate(Heuristic.Manhattan); break; case HeuristicMode.EUCLIDEAN: m_heuristic = new HeuristicDelegate(Heuristic.Euclidean); break; case HeuristicMode.CHEBYSHEV: m_heuristic = new HeuristicDelegate(Heuristic.Chebyshev); break; default: m_heuristic = new HeuristicDelegate(Heuristic.Euclidean); break; } m_allowEndNodeUnWalkable = iAllowEndNodeUnWalkable; m_crossAdjacentPoint = iCrossAdjacentPoint; m_crossCorner = iCrossCorner; openList = new List<Node>(); m_searchGrid = iGrid; m_startNode = m_searchGrid.GetNodeAt(iStartPos.x, iStartPos.y); m_endNode = m_searchGrid.GetNodeAt(iEndPos.x, iEndPos.y); if (m_startNode == null) m_startNode = new Node(iStartPos.x, iStartPos.y, true); if (m_endNode == null) m_endNode = new Node(iEndPos.x, iEndPos.y, true); m_useRecursive = false; }
public JumpPointParam(BaseGrid iGrid, GridPos iStartPos, GridPos iEndPos, bool iCrossCorner = true, HeuristicMode iMode = HeuristicMode.EUCLIDEAN) { switch (iMode) { case HeuristicMode.MANHATTAN: heuristic = new HeuristicDelegate(Heuristic.Manhattan); break; case HeuristicMode.EUCLIDEAN: heuristic = new HeuristicDelegate(Heuristic.Euclidean); break; case HeuristicMode.CHEBYSHEV: heuristic = new HeuristicDelegate(Heuristic.Chebyshev); break; default: heuristic = new HeuristicDelegate(Heuristic.Euclidean); break; } crossCorner = iCrossCorner; openList = new List<Node>(); searchGrid = iGrid; startNode = searchGrid.GetNodeAt(iStartPos.x, iStartPos.y); endNode = searchGrid.GetNodeAt(iEndPos.x, iEndPos.y); }
public bool Equals(GridPos p) { // If parameter is null return false: if ((object)p == null) { return false; } // Return true if the fields match: return (x == p.x) && (y == p.y); }
public Node GetNode(GridPos iPos, bool? iWalkable = null) { if (m_nodes.ContainsKey(iPos)) return m_nodes[iPos]; else { if (iWalkable.HasValue && iWalkable.Value == true) { Node newNode = new Node(iPos.x, iPos.y, iWalkable); m_nodes.Add(iPos, newNode); return newNode; } return null; } }
public Node GetNode(int iX, int iY, bool? iWalkable = null) { GridPos pos = new GridPos(iX, iY); if (m_nodes.ContainsKey(pos)) return m_nodes[pos]; else { if (iWalkable.HasValue && iWalkable.Value == true) { Node newNode = new Node(pos.x, pos.y, iWalkable); m_nodes.Add(pos, newNode); return newNode; } return null; } }
public override Node GetNodeAt(GridPos iPos) { if (m_nodes.ContainsKey(iPos)) { return m_nodes[iPos]; } return null; }
public override bool SetWalkableAt(GridPos iPos, bool iWalkable) { return SetWalkableAt(iPos.x, iPos.y, iWalkable); }
protected bool isInside(GridPos iPos) { return isInside(iPos.x, iPos.y); }
public override bool IsWalkableAt(int iX, int iY) { GridPos pos = new GridPos(iX, iY); return IsWalkableAt(pos); }
public abstract bool SetWalkableAt(GridPos iPos, bool iWalkable);
private static GridPos jumpLoop(JumpPointParam iParam, int iX, int iY, int iPx, int iPy) { GridPos retVal = null; Stack <JumpSnapshot> stack = new Stack <JumpSnapshot>(); JumpSnapshot currentSnapshot = new JumpSnapshot(); JumpSnapshot newSnapshot = null; currentSnapshot.iX = iX; currentSnapshot.iY = iY; currentSnapshot.iPx = iPx; currentSnapshot.iPy = iPy; currentSnapshot.stage = 0; stack.Push(currentSnapshot); while (stack.Count != 0) { currentSnapshot = stack.Pop(); switch (currentSnapshot.stage) { case 0: if (!iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY)) { retVal = null; continue; } else if (iParam.SearchGrid.GetNodeAt(currentSnapshot.iX, currentSnapshot.iY).Equals(iParam.EndNode)) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } currentSnapshot.tDx = currentSnapshot.iX - currentSnapshot.iPx; currentSnapshot.tDy = currentSnapshot.iY - currentSnapshot.iPy; currentSnapshot.jx = null; currentSnapshot.jy = null; if (iParam.CrossCorner) { // check for forced neighbors // along the diagonal if (currentSnapshot.tDx != 0 && currentSnapshot.tDy != 0) { if ((iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - currentSnapshot.tDx, currentSnapshot.iY + currentSnapshot.tDy) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - currentSnapshot.tDx, currentSnapshot.iY)) || (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY - currentSnapshot.tDy) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY - currentSnapshot.tDy))) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } } // horizontally/vertically else { if (currentSnapshot.tDx != 0) { // moving along x if ((iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY + 1) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + 1)) || (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY - 1) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY - 1))) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } } else { if ((iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + 1, currentSnapshot.iY + currentSnapshot.tDy) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + 1, currentSnapshot.iY)) || (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - 1, currentSnapshot.iY + currentSnapshot.tDy) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - 1, currentSnapshot.iY))) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } } } // when moving diagonally, must check for vertical/horizontal jump points if (currentSnapshot.tDx != 0 && currentSnapshot.tDy != 0) { currentSnapshot.stage = 1; stack.Push(currentSnapshot); newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX + currentSnapshot.tDx; newSnapshot.iY = currentSnapshot.iY; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); continue; } // moving diagonally, must make sure one of the vertical/horizontal // neighbors is open to allow the path // moving diagonally, must make sure one of the vertical/horizontal // neighbors is open to allow the path if (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY) || iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + currentSnapshot.tDy)) { newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX + currentSnapshot.tDx; newSnapshot.iY = currentSnapshot.iY + currentSnapshot.tDy; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); continue; } else if (iParam.CrossAdjacentPoint) { newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX + currentSnapshot.tDx; newSnapshot.iY = currentSnapshot.iY + currentSnapshot.tDy; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); continue; } } else //if (!iParam.CrossCorner) { // check for forced neighbors // along the diagonal if (currentSnapshot.tDx != 0 && currentSnapshot.tDy != 0) { if ((iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY + currentSnapshot.tDy) && iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + currentSnapshot.tDy) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY)) || (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY + currentSnapshot.tDy) && iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + currentSnapshot.tDy))) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } } // horizontally/vertically else { if (currentSnapshot.tDx != 0) { // moving along x if ((iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + 1) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - currentSnapshot.tDx, currentSnapshot.iY + 1)) || (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY - 1) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - currentSnapshot.tDx, currentSnapshot.iY - 1))) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } } else { if ((iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + 1, currentSnapshot.iY) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + 1, currentSnapshot.iY - currentSnapshot.tDy)) || (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - 1, currentSnapshot.iY) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - 1, currentSnapshot.iY - currentSnapshot.tDy))) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } } } // when moving diagonally, must check for vertical/horizontal jump points if (currentSnapshot.tDx != 0 && currentSnapshot.tDy != 0) { currentSnapshot.stage = 3; stack.Push(currentSnapshot); newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX + currentSnapshot.tDx; newSnapshot.iY = currentSnapshot.iY; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); continue; } // moving diagonally, must make sure both of the vertical/horizontal // neighbors is open to allow the path if (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY) && iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + currentSnapshot.tDy)) { newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX + currentSnapshot.tDx; newSnapshot.iY = currentSnapshot.iY + currentSnapshot.tDy; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); continue; } } retVal = null; break; case 1: currentSnapshot.jx = retVal; currentSnapshot.stage = 2; stack.Push(currentSnapshot); newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX; newSnapshot.iY = currentSnapshot.iY + currentSnapshot.tDy; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); break; case 2: currentSnapshot.jy = retVal; if (currentSnapshot.jx != null || currentSnapshot.jy != null) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } // moving diagonally, must make sure one of the vertical/horizontal // neighbors is open to allow the path if (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY) || iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + currentSnapshot.tDy)) { newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX + currentSnapshot.tDx; newSnapshot.iY = currentSnapshot.iY + currentSnapshot.tDy; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); continue; } else if (iParam.CrossAdjacentPoint) { newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX + currentSnapshot.tDx; newSnapshot.iY = currentSnapshot.iY + currentSnapshot.tDy; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); continue; } retVal = null; break; case 3: currentSnapshot.jx = retVal; currentSnapshot.stage = 4; stack.Push(currentSnapshot); newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX; newSnapshot.iY = currentSnapshot.iY + currentSnapshot.tDy; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); break; case 4: currentSnapshot.jy = retVal; if (currentSnapshot.jx != null || currentSnapshot.jy != null) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } // moving diagonally, must make sure both of the vertical/horizontal // neighbors is open to allow the path if (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY) && iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + currentSnapshot.tDy)) { newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX + currentSnapshot.tDx; newSnapshot.iY = currentSnapshot.iY + currentSnapshot.tDy; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); continue; } retVal = null; break; } } return(retVal); }
public Node GetNode(GridPos iPos) { if (m_nodes.ContainsKey(iPos)) return m_nodes[iPos]; return null; }
internal override void _reset(GridPos iStartPos, GridPos iEndPos, BaseGrid iSearchGrid = null) { openList = new IntervalHeap <Node>(); }
public List <Node> GetNeighbors(Node iNode, bool iCrossCorners, bool iCrossAdjacentPoint) { int tX = iNode.x; int tY = iNode.y; List <Node> neighbors = new List <Node>(); bool tS0 = false, tD0 = false, tS1 = false, tD1 = false, tS2 = false, tD2 = false, tS3 = false, tD3 = false; GridPos pos = new GridPos(); if (this.IsWalkableAt(pos.Set(tX, tY - 1))) { neighbors.Add(GetNodeAt(pos)); tS0 = true; } if (this.IsWalkableAt(pos.Set(tX + 1, tY))) { neighbors.Add(GetNodeAt(pos)); tS1 = true; } if (this.IsWalkableAt(pos.Set(tX, tY + 1))) { neighbors.Add(GetNodeAt(pos)); tS2 = true; } if (this.IsWalkableAt(pos.Set(tX - 1, tY))) { neighbors.Add(GetNodeAt(pos)); tS3 = true; } if (iCrossCorners && iCrossAdjacentPoint) { tD0 = true; tD1 = true; tD2 = true; tD3 = true; } else if (iCrossCorners) { tD0 = tS3 || tS0; tD1 = tS0 || tS1; tD2 = tS1 || tS2; tD3 = tS2 || tS3; } else { tD0 = tS3 && tS0; tD1 = tS0 && tS1; tD2 = tS1 && tS2; tD3 = tS2 && tS3; } if (tD0 && this.IsWalkableAt(pos.Set(tX - 1, tY - 1))) { neighbors.Add(GetNodeAt(pos)); } if (tD1 && this.IsWalkableAt(pos.Set(tX + 1, tY - 1))) { neighbors.Add(GetNodeAt(pos)); } if (tD2 && this.IsWalkableAt(pos.Set(tX + 1, tY + 1))) { neighbors.Add(GetNodeAt(pos)); } if (tD3 && this.IsWalkableAt(pos.Set(tX - 1, tY + 1))) { neighbors.Add(GetNodeAt(pos)); } return(neighbors); }
private static GridPos JumpLoop(JumpPointParam iParam, int iX, int iY, int iPx, int iPy) { GridPos retVal = null; var stack = new Stack <JumpSnapshot>(); var currentSnapshot = new JumpSnapshot(); JumpSnapshot newSnapshot = null; currentSnapshot.iX = iX; currentSnapshot.iY = iY; currentSnapshot.iPx = iPx; currentSnapshot.iPy = iPy; currentSnapshot.stage = 0; stack.Push(currentSnapshot); while (stack.Count != 0) { currentSnapshot = stack.Pop(); switch (currentSnapshot.stage) { case 0: if (!iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY)) { retVal = null; continue; } else if (iParam.SearchGrid.GetNodeAt(currentSnapshot.iX, currentSnapshot.iY).Equals(iParam.EndNode)) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } currentSnapshot.tDx = currentSnapshot.iX - currentSnapshot.iPx; currentSnapshot.tDy = currentSnapshot.iY - currentSnapshot.iPy; if (iParam.DiagonalMovement == DiagonalMovement.Always || iParam.DiagonalMovement == DiagonalMovement.IfAtLeastOneWalkable) { // check for forced neighbors // along the diagonal if (currentSnapshot.tDx != 0 && currentSnapshot.tDy != 0) { if ((iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - currentSnapshot.tDx, currentSnapshot.iY + currentSnapshot.tDy) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - currentSnapshot.tDx, currentSnapshot.iY)) || (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY - currentSnapshot.tDy) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY - currentSnapshot.tDy))) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } } // horizontally/vertically else { if (currentSnapshot.tDx != 0) { // moving along x if ((iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY + 1) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + 1)) || (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY - 1) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY - 1))) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } } else { if ((iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + 1, currentSnapshot.iY + currentSnapshot.tDy) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + 1, currentSnapshot.iY)) || (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - 1, currentSnapshot.iY + currentSnapshot.tDy) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - 1, currentSnapshot.iY))) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } } } // when moving diagonally, must check for vertical/horizontal jump points if (currentSnapshot.tDx != 0 && currentSnapshot.tDy != 0) { currentSnapshot.stage = 1; stack.Push(currentSnapshot); newSnapshot = new JumpSnapshot { iX = currentSnapshot.iX + currentSnapshot.tDx, iY = currentSnapshot.iY, iPx = currentSnapshot.iX, iPy = currentSnapshot.iY, stage = 0 }; stack.Push(newSnapshot); continue; } // moving diagonally, must make sure one of the vertical/horizontal // neighbors is open to allow the path // moving diagonally, must make sure one of the vertical/horizontal // neighbors is open to allow the path if (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY) || iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + currentSnapshot.tDy)) { newSnapshot = new JumpSnapshot { iX = currentSnapshot.iX + currentSnapshot.tDx, iY = currentSnapshot.iY + currentSnapshot.tDy, iPx = currentSnapshot.iX, iPy = currentSnapshot.iY, stage = 0 }; stack.Push(newSnapshot); continue; } else if (iParam.DiagonalMovement == DiagonalMovement.Always) { newSnapshot = new JumpSnapshot { iX = currentSnapshot.iX + currentSnapshot.tDx, iY = currentSnapshot.iY + currentSnapshot.tDy, iPx = currentSnapshot.iX, iPy = currentSnapshot.iY, stage = 0 }; stack.Push(newSnapshot); continue; } } else if (iParam.DiagonalMovement == DiagonalMovement.OnlyWhenNoObstacles) { // check for forced neighbors // along the diagonal if (currentSnapshot.tDx != 0 && currentSnapshot.tDy != 0) { if ((iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY + currentSnapshot.tDy) && iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + currentSnapshot.tDy) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY)) || (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY + currentSnapshot.tDy) && iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + currentSnapshot.tDy))) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } } // horizontally/vertically else { if (currentSnapshot.tDx != 0) { // moving along x if ((iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + 1) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - currentSnapshot.tDx, currentSnapshot.iY + 1)) || (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY - 1) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - currentSnapshot.tDx, currentSnapshot.iY - 1))) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } } else { if ((iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + 1, currentSnapshot.iY) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + 1, currentSnapshot.iY - currentSnapshot.tDy)) || (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - 1, currentSnapshot.iY) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - 1, currentSnapshot.iY - currentSnapshot.tDy))) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } } } // when moving diagonally, must check for vertical/horizontal jump points if (currentSnapshot.tDx != 0 && currentSnapshot.tDy != 0) { currentSnapshot.stage = 3; stack.Push(currentSnapshot); newSnapshot = new JumpSnapshot { iX = currentSnapshot.iX + currentSnapshot.tDx, iY = currentSnapshot.iY, iPx = currentSnapshot.iX, iPy = currentSnapshot.iY, stage = 0 }; stack.Push(newSnapshot); continue; } // moving diagonally, must make sure both of the vertical/horizontal // neighbors is open to allow the path if (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY) && iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + currentSnapshot.tDy)) { newSnapshot = new JumpSnapshot { iX = currentSnapshot.iX + currentSnapshot.tDx, iY = currentSnapshot.iY + currentSnapshot.tDy, iPx = currentSnapshot.iX, iPy = currentSnapshot.iY, stage = 0 }; stack.Push(newSnapshot); continue; } } else // if(iParam.DiagonalMovement == DiagonalMovement.Never) { if (currentSnapshot.tDx != 0) { // moving along x if (!iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY)) { retVal = new GridPos(iX, iY); continue; } } else { if (!iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + currentSnapshot.tDy)) { retVal = new GridPos(iX, iY); continue; } } // must check for perpendicular jump points if (currentSnapshot.tDx != 0) { currentSnapshot.stage = 5; stack.Push(currentSnapshot); newSnapshot = new JumpSnapshot { iX = currentSnapshot.iX, iY = currentSnapshot.iY + 1, iPx = currentSnapshot.iX, iPy = currentSnapshot.iY, stage = 0 }; stack.Push(newSnapshot); continue; } else // tDy != 0 { currentSnapshot.stage = 6; stack.Push(currentSnapshot); newSnapshot = new JumpSnapshot { iX = currentSnapshot.iX + 1, iY = currentSnapshot.iY, iPx = currentSnapshot.iX, iPy = currentSnapshot.iY, stage = 0 }; stack.Push(newSnapshot); continue; } } retVal = null; break; case 1: if (retVal != null) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } currentSnapshot.stage = 2; stack.Push(currentSnapshot); newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX; newSnapshot.iY = currentSnapshot.iY + currentSnapshot.tDy; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); break; case 2: if (retVal != null) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } // moving diagonally, must make sure one of the vertical/horizontal // neighbors is open to allow the path if (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY) || iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + currentSnapshot.tDy)) { newSnapshot = new JumpSnapshot { iX = currentSnapshot.iX + currentSnapshot.tDx, iY = currentSnapshot.iY + currentSnapshot.tDy, iPx = currentSnapshot.iX, iPy = currentSnapshot.iY, stage = 0 }; stack.Push(newSnapshot); continue; } else if (iParam.DiagonalMovement == DiagonalMovement.Always) { newSnapshot = new JumpSnapshot { iX = currentSnapshot.iX + currentSnapshot.tDx, iY = currentSnapshot.iY + currentSnapshot.tDy, iPx = currentSnapshot.iX, iPy = currentSnapshot.iY, stage = 0 }; stack.Push(newSnapshot); continue; } retVal = null; break; case 3: if (retVal != null) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } currentSnapshot.stage = 4; stack.Push(currentSnapshot); newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX; newSnapshot.iY = currentSnapshot.iY + currentSnapshot.tDy; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); break; case 4: if (retVal != null) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } // moving diagonally, must make sure both of the vertical/horizontal // neighbors is open to allow the path if (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY) && iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + currentSnapshot.tDy)) { newSnapshot = new JumpSnapshot { iX = currentSnapshot.iX + currentSnapshot.tDx, iY = currentSnapshot.iY + currentSnapshot.tDy, iPx = currentSnapshot.iX, iPy = currentSnapshot.iY, stage = 0 }; stack.Push(newSnapshot); continue; } retVal = null; break; case 5: if (retVal != null) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } currentSnapshot.stage = 7; stack.Push(currentSnapshot); newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX; newSnapshot.iY = currentSnapshot.iY - 1; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); break; case 6: if (retVal != null) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } currentSnapshot.stage = 7; stack.Push(currentSnapshot); newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX - 1; newSnapshot.iY = currentSnapshot.iY; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); break; case 7: if (retVal != null) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } // keep going if (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY) && iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + currentSnapshot.tDy)) { newSnapshot = new JumpSnapshot { iX = currentSnapshot.iX + currentSnapshot.tDx, iY = currentSnapshot.iY + currentSnapshot.tDy, iPx = currentSnapshot.iX, iPy = currentSnapshot.iY, stage = 0 }; stack.Push(newSnapshot); continue; } retVal = null; break; } } return(retVal); }
public abstract bool SetWalkableAt(GridPos iPos, byte iWalkable);
public abstract bool IsWalkableAt(GridPos iPos);
public abstract Node GetNodeAt(GridPos iPos);
internal List<GridPos> StraightPath(GridPos mapCell1, GridPos mapCell2) { List<GridPos> Path = new List<GridPos>(); Path.Add(mapCell1); do { if (Path.Last().x < mapCell2.x && Path.Last().y < mapCell2.y) { Path.Add(new GridPos() { x = (short)(Path.Last().x + 1), y = (short)(Path.Last().y + 1) }); } else if (Path.Last().x > mapCell2.x && Path.Last().y > mapCell2.y) { Path.Add(new GridPos() { x = (short)(Path.Last().x - 1), y = (short)(Path.Last().y - 1) }); } else if (Path.Last().x < mapCell2.x && Path.Last().y > mapCell2.y) { Path.Add(new GridPos() { x = (short)(Path.Last().x + 1), y = (short)(Path.Last().y - 1) }); } else if (Path.Last().x > mapCell2.x && Path.Last().y < mapCell2.y) { Path.Add(new GridPos() { x = (short)(Path.Last().x - 1), y = (short)(Path.Last().y + 1) }); } else if (Path.Last().x > mapCell2.x) { Path.Add(new GridPos() { x = (short)(Path.Last().x - 1), y = (short)(Path.Last().y) }); } else if (Path.Last().x < mapCell2.x) { Path.Add(new GridPos() { x = (short)(Path.Last().x + 1), y = (short)(Path.Last().y) }); } else if (Path.Last().y > mapCell2.y) { Path.Add(new GridPos() { x = (short)(Path.Last().x), y = (short)(Path.Last().y - 1) }); } else if (Path.Last().y < mapCell2.y) { Path.Add(new GridPos() { x = (short)(Path.Last().x), y = (short)(Path.Last().y + 1) }); } } while ((Path.Last().x != mapCell2.x || Path.Last().y != mapCell2.y) && (!IsBlockedZone(Path.Last().x, Path.Last().y))); if (IsBlockedZone(Path.Last().x, Path.Last().y)) { if (Path.Any()) { Path.Remove(Path.Last()); } } Path.RemoveAt(0); return Path; }
private static GridPos jumpLoop(JumpPointParam iParam, int iX, int iY, int iPx, int iPy) { GridPos retVal = null; Stack<JumpSnapshot> stack = new Stack<JumpSnapshot>(); JumpSnapshot currentSnapshot = new JumpSnapshot(); JumpSnapshot newSnapshot = null; currentSnapshot.iX = iX; currentSnapshot.iY = iY; currentSnapshot.iPx = iPx; currentSnapshot.iPy = iPy; currentSnapshot.stage = 0; stack.Push(currentSnapshot); while (stack.Count != 0) { currentSnapshot = stack.Pop(); switch (currentSnapshot.stage) { case 0: if (!iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY)) { retVal = null; continue; } else if (iParam.SearchGrid.GetNodeAt(currentSnapshot.iX, currentSnapshot.iY).Equals(iParam.EndNode)) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } currentSnapshot.tDx = currentSnapshot.iX - currentSnapshot.iPx; currentSnapshot.tDy = currentSnapshot.iY - currentSnapshot.iPy; currentSnapshot.jx = null; currentSnapshot.jy = null; if (iParam.CrossCorner) { // check for forced neighbors // along the diagonal if (currentSnapshot.tDx != 0 && currentSnapshot.tDy != 0) { if ((iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - currentSnapshot.tDx, currentSnapshot.iY + currentSnapshot.tDy) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - currentSnapshot.tDx, currentSnapshot.iY)) || (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY - currentSnapshot.tDy) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY - currentSnapshot.tDy))) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } } // horizontally/vertically else { if (currentSnapshot.tDx != 0) { // moving along x if ((iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY + 1) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + 1)) || (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY - 1) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY - 1))) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } } else { if ((iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + 1, currentSnapshot.iY + currentSnapshot.tDy) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + 1, currentSnapshot.iY)) || (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - 1, currentSnapshot.iY + currentSnapshot.tDy) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - 1, currentSnapshot.iY))) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } } } // when moving diagonally, must check for vertical/horizontal jump points if (currentSnapshot.tDx != 0 && currentSnapshot.tDy != 0) { currentSnapshot.stage = 1; stack.Push(currentSnapshot); newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX + currentSnapshot.tDx; newSnapshot.iY = currentSnapshot.iY; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); continue; } // moving diagonally, must make sure one of the vertical/horizontal // neighbors is open to allow the path // moving diagonally, must make sure one of the vertical/horizontal // neighbors is open to allow the path if (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY) || iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + currentSnapshot.tDy)) { newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX + currentSnapshot.tDx; newSnapshot.iY = currentSnapshot.iY + currentSnapshot.tDy; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); continue; } else if (iParam.CrossAdjacentPoint) { newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX + currentSnapshot.tDx; newSnapshot.iY = currentSnapshot.iY + currentSnapshot.tDy; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); continue; } } else //if (!iParam.CrossCorner) { // check for forced neighbors // along the diagonal if (currentSnapshot.tDx != 0 && currentSnapshot.tDy != 0) { if ((iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY + currentSnapshot.tDy) && iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + currentSnapshot.tDy) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY)) || (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY + currentSnapshot.tDy) && iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + currentSnapshot.tDy))) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } } // horizontally/vertically else { if (currentSnapshot.tDx != 0) { // moving along x if ((iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + 1) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - currentSnapshot.tDx, currentSnapshot.iY + 1)) || (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY - 1) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - currentSnapshot.tDx, currentSnapshot.iY - 1))) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } } else { if ((iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + 1, currentSnapshot.iY) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + 1, currentSnapshot.iY - currentSnapshot.tDy)) || (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - 1, currentSnapshot.iY) && !iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX - 1, currentSnapshot.iY - currentSnapshot.tDy))) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } } } // when moving diagonally, must check for vertical/horizontal jump points if (currentSnapshot.tDx != 0 && currentSnapshot.tDy != 0) { currentSnapshot.stage = 3; stack.Push(currentSnapshot); newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX + currentSnapshot.tDx; newSnapshot.iY = currentSnapshot.iY; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); continue; } // moving diagonally, must make sure both of the vertical/horizontal // neighbors is open to allow the path if (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY) && iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + currentSnapshot.tDy)) { newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX + currentSnapshot.tDx; newSnapshot.iY = currentSnapshot.iY + currentSnapshot.tDy; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); continue; } } retVal = null; break; case 1: currentSnapshot.jx = retVal; currentSnapshot.stage = 2; stack.Push(currentSnapshot); newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX; newSnapshot.iY = currentSnapshot.iY + currentSnapshot.tDy; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); break; case 2: currentSnapshot.jy = retVal; if (currentSnapshot.jx != null || currentSnapshot.jy != null) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } // moving diagonally, must make sure one of the vertical/horizontal // neighbors is open to allow the path if (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY) || iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + currentSnapshot.tDy)) { newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX + currentSnapshot.tDx; newSnapshot.iY = currentSnapshot.iY + currentSnapshot.tDy; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); continue; } else if (iParam.CrossAdjacentPoint) { newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX + currentSnapshot.tDx; newSnapshot.iY = currentSnapshot.iY + currentSnapshot.tDy; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); continue; } retVal = null; break; case 3: currentSnapshot.jx = retVal; currentSnapshot.stage = 4; stack.Push(currentSnapshot); newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX; newSnapshot.iY = currentSnapshot.iY + currentSnapshot.tDy; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); break; case 4: currentSnapshot.jy = retVal; if (currentSnapshot.jx != null || currentSnapshot.jy != null) { retVal = new GridPos(currentSnapshot.iX, currentSnapshot.iY); continue; } // moving diagonally, must make sure both of the vertical/horizontal // neighbors is open to allow the path if (iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX + currentSnapshot.tDx, currentSnapshot.iY) && iParam.SearchGrid.IsWalkableAt(currentSnapshot.iX, currentSnapshot.iY + currentSnapshot.tDy)) { newSnapshot = new JumpSnapshot(); newSnapshot.iX = currentSnapshot.iX + currentSnapshot.tDx; newSnapshot.iY = currentSnapshot.iY + currentSnapshot.tDy; newSnapshot.iPx = currentSnapshot.iX; newSnapshot.iPy = currentSnapshot.iY; newSnapshot.stage = 0; stack.Push(newSnapshot); continue; } retVal = null; break; } } return retVal; }
protected void removeNode(GridPos iPos) { if (m_nodes.ContainsKey(iPos)) m_nodes.Remove(iPos); }
private static GridPos jump(JumpPointParam iParam, int iX, int iY, int iPx, int iPy) { if (!iParam.SearchGrid.IsWalkableAt(iX, iY)) { return(null); } else if (iParam.SearchGrid.GetNodeAt(iX, iY).Equals(iParam.EndNode)) { return(new GridPos(iX, iY)); } int tDx = iX - iPx; int tDy = iY - iPy; GridPos jx = null; GridPos jy = null; if (iParam.CrossCorner) { // check for forced neighbors // along the diagonal if (tDx != 0 && tDy != 0) { if ((iParam.SearchGrid.IsWalkableAt(iX - tDx, iY + tDy) && !iParam.SearchGrid.IsWalkableAt(iX - tDx, iY)) || (iParam.SearchGrid.IsWalkableAt(iX + tDx, iY - tDy) && !iParam.SearchGrid.IsWalkableAt(iX, iY - tDy))) { return(new GridPos(iX, iY)); } } // horizontally/vertically else { if (tDx != 0) { // moving along x if ((iParam.SearchGrid.IsWalkableAt(iX + tDx, iY + 1) && !iParam.SearchGrid.IsWalkableAt(iX, iY + 1)) || (iParam.SearchGrid.IsWalkableAt(iX + tDx, iY - 1) && !iParam.SearchGrid.IsWalkableAt(iX, iY - 1))) { return(new GridPos(iX, iY)); } } else { if ((iParam.SearchGrid.IsWalkableAt(iX + 1, iY + tDy) && !iParam.SearchGrid.IsWalkableAt(iX + 1, iY)) || (iParam.SearchGrid.IsWalkableAt(iX - 1, iY + tDy) && !iParam.SearchGrid.IsWalkableAt(iX - 1, iY))) { return(new GridPos(iX, iY)); } } } // when moving diagonally, must check for vertical/horizontal jump points if (tDx != 0 && tDy != 0) { jx = jump(iParam, iX + tDx, iY, iX, iY); jy = jump(iParam, iX, iY + tDy, iX, iY); if (jx != null || jy != null) { return(new GridPos(iX, iY)); } } // moving diagonally, must make sure one of the vertical/horizontal // neighbors is open to allow the path if (iParam.SearchGrid.IsWalkableAt(iX + tDx, iY) || iParam.SearchGrid.IsWalkableAt(iX, iY + tDy)) { return(jump(iParam, iX + tDx, iY + tDy, iX, iY)); } else if (iParam.CrossAdjacentPoint) { return(jump(iParam, iX + tDx, iY + tDy, iX, iY)); } else { return(null); } } else //if (!iParam.CrossCorner) { // check for forced neighbors // along the diagonal if (tDx != 0 && tDy != 0) { if ((iParam.SearchGrid.IsWalkableAt(iX + tDx, iY + tDy) && iParam.SearchGrid.IsWalkableAt(iX, iY + tDy) && !iParam.SearchGrid.IsWalkableAt(iX + tDx, iY)) || (iParam.SearchGrid.IsWalkableAt(iX + tDx, iY + tDy) && iParam.SearchGrid.IsWalkableAt(iX + tDx, iY) && !iParam.SearchGrid.IsWalkableAt(iX, iY + tDy))) { return(new GridPos(iX, iY)); } } // horizontally/vertically else { if (tDx != 0) { // moving along x if ((iParam.SearchGrid.IsWalkableAt(iX, iY + 1) && !iParam.SearchGrid.IsWalkableAt(iX - tDx, iY + 1)) || (iParam.SearchGrid.IsWalkableAt(iX, iY - 1) && !iParam.SearchGrid.IsWalkableAt(iX - tDx, iY - 1))) { return(new GridPos(iX, iY)); } } else { if ((iParam.SearchGrid.IsWalkableAt(iX + 1, iY) && !iParam.SearchGrid.IsWalkableAt(iX + 1, iY - tDy)) || (iParam.SearchGrid.IsWalkableAt(iX - 1, iY) && !iParam.SearchGrid.IsWalkableAt(iX - 1, iY - tDy))) { return(new GridPos(iX, iY)); } } } // when moving diagonally, must check for vertical/horizontal jump points if (tDx != 0 && tDy != 0) { jx = jump(iParam, iX + tDx, iY, iX, iY); jy = jump(iParam, iX, iY + tDy, iX, iY); if (jx != null || jy != null) { return(new GridPos(iX, iY)); } } // moving diagonally, must make sure both of the vertical/horizontal // neighbors is open to allow the path if (iParam.SearchGrid.IsWalkableAt(iX + tDx, iY) && iParam.SearchGrid.IsWalkableAt(iX, iY + tDy)) { return(jump(iParam, iX + tDx, iY + tDy, iX, iY)); } else { return(null); } } }
private void btnSearch_Click(object sender, EventArgs e) { for (int resultTrav = 0; resultTrav < m_resultLine.Count; resultTrav++) { m_resultLine[resultTrav].Dispose(); } m_resultLine.Clear(); for (int resultTrav = 0; resultTrav < m_resultBox.Count; resultTrav++) { m_resultBox[resultTrav].Dispose(); } m_resultBox.Clear(); GridPos startPos = new GridPos(); GridPos endPos = new GridPos(); for (int widthTrav = 0; widthTrav < width; widthTrav++) { for (int heightTrav = 0; heightTrav < height; heightTrav++) { if (m_rectangles[widthTrav][heightTrav].boxType != BoxType.Wall) { searchGrid.SetWalkableAt(new GridPos(widthTrav, heightTrav), true); } else { searchGrid.SetWalkableAt(new GridPos(widthTrav, heightTrav), false); } if (m_rectangles[widthTrav][heightTrav].boxType == BoxType.Start) { startPos.x = widthTrav; startPos.y = heightTrav; } if (m_rectangles[widthTrav][heightTrav].boxType == BoxType.End) { endPos.x = widthTrav; endPos.y = heightTrav; } } } jumpParam.CrossCorner = cbCrossCorners.Checked; jumpParam.CrossAdjacentPoint = cbCrossAdjacentPoint.Checked; jumpParam.UseRecursive = cbUseRecursive.Checked; jumpParam.Reset(startPos, endPos); List <GridPos> resultList = JumpPointFinder.FindPath(jumpParam); for (int resultTrav = 0; resultTrav < resultList.Count - 1; resultTrav++) { m_resultLine.Add(new GridLine(m_rectangles[resultList[resultTrav].x][resultList[resultTrav].y], m_rectangles[resultList[resultTrav + 1].x][resultList[resultTrav + 1].y])); } for (int widthTrav = 0; widthTrav < jumpParam.SearchGrid.width; widthTrav++) { for (int heightTrav = 0; heightTrav < jumpParam.SearchGrid.height; heightTrav++) { if (jumpParam.SearchGrid.GetNodeAt(widthTrav, heightTrav) == null) { continue; } if (jumpParam.SearchGrid.GetNodeAt(widthTrav, heightTrav).isOpened) { ResultBox resultBox = new ResultBox(widthTrav * 20, heightTrav * 20 + 50, ResultBoxType.Opened); m_resultBox.Add(resultBox); } if (jumpParam.SearchGrid.GetNodeAt(widthTrav, heightTrav).isClosed) { ResultBox resultBox = new ResultBox(widthTrav * 20, heightTrav * 20 + 50, ResultBoxType.Closed); m_resultBox.Add(resultBox); } } } this.Invalidate(); }
public AStarParam(BaseGrid iGrid, GridPos iStartPos, GridPos iEndPos, float iweight, DiagonalMovement iDiagonalMovement = DiagonalMovement.Always, HeuristicMode iMode = HeuristicMode.Euclidean) : base(iGrid, iStartPos, iEndPos, iDiagonalMovement, iMode) { Weight = iweight; }
internal override void _reset(GridPos iStartPos, GridPos iEndPos, BaseGrid iSearchGrid = null) { }
public void Reset(GridPos iStartPos, GridPos iEndPos) { openList.Clear(); startNode = null; endNode = null; searchGrid.Reset(); startNode = searchGrid.GetNodeAt(iStartPos.x, iStartPos.y); endNode = searchGrid.GetNodeAt(iEndPos.x, iEndPos.y); }
public override Node GetNodeAt(GridPos iPos) { return(GetNodeAt(iPos.x, iPos.y)); }
public override bool IsWalkableAt(GridPos iPos) { return IsWalkableAt(iPos.x, iPos.y); }
public override bool IsWalkableAt(GridPos iPos) { return(IsWalkableAt(iPos.x, iPos.y)); }
public override Node GetNodeAt(int iX, int iY) { GridPos pos = new GridPos(iX, iY); return GetNodeAt(pos); }
protected bool IsInside(GridPos iPos) { return(IsInside(iPos.x, iPos.y)); }
public override bool SetWalkableAt(int iX, int iY, bool iWalkable) { GridPos pos = new GridPos(iX, iY); if (iWalkable) { if (m_nodes.ContainsKey(pos)) { return true; } else { if (iX < m_gridRect.minX || m_notSet) m_gridRect.minX = iX; if (iX > m_gridRect.maxX || m_notSet) m_gridRect.maxX = iX; if (iY < m_gridRect.minY || m_notSet) m_gridRect.minY = iY; if (iY > m_gridRect.maxY || m_notSet) m_gridRect.maxY = iY; m_nodes.Add(new GridPos(pos.x, pos.y), m_nodePool.GetNode(pos.x, pos.y, iWalkable)); m_notSet = false; } } else { if (m_nodes.ContainsKey(pos)) { m_nodes.Remove(pos); m_nodePool.RemoveNode(pos); if (iX == m_gridRect.minX || iX == m_gridRect.maxX || iY == m_gridRect.minY || iY == m_gridRect.maxY) m_notSet = true; } } return true; }
protected void removeNode(int iX, int iY) { GridPos pos = new GridPos(iX, iY); removeNode(pos); }
public override bool IsWalkableAt(GridPos iPos) { return m_nodes.ContainsKey(iPos); }
public Node GetNode(int iX, int iY) { GridPos pos = new GridPos(iX, iY); return(GetNode(pos)); }
public List<GridPos> JPSPlus(JumpPointParam JumpPointParameters, GridPos cell1, GridPos cell2) { if (JumpPointParameters != null) { JumpPointParameters.Reset(cell1, cell2); return JumpPointFinder.GetFullPath(JumpPointFinder.FindPath(JumpPointParameters)); } return new List<GridPos>(); }
public Node SetNode(int iX, int iY, bool?iWalkable = null) { GridPos pos = new GridPos(iX, iY); return(SetNode(pos, iWalkable)); }
public override Node GetNodeAt(int iX, int iY) { GridPos pos = new GridPos(iX, iY); return(GetNodeAt(pos)); }
public Node GetNode(int iX, int iY) { GridPos pos = new GridPos(iX, iY); return GetNode(pos); }
public override bool IsWalkableAt(int iX, int iY) { GridPos pos = new GridPos(iX, iY); return(IsWalkableAt(pos)); }
public Node SetNode(int iX, int iY, bool? iWalkable = null) { GridPos pos = new GridPos(iX, iY); return SetNode(pos,iWalkable); }
public override bool IsWalkableAt(GridPos iPos) { return(m_nodes.ContainsKey(iPos)); }
public void Reset(GridPos iStartPos, GridPos iEndPos, BaseGrid iSearchGrid = null) { openList.Clear(); m_startNode = null; m_endNode = null; if (iSearchGrid != null) m_searchGrid = iSearchGrid; m_searchGrid.Reset(); m_startNode = m_searchGrid.GetNodeAt(iStartPos.x, iStartPos.y); m_endNode = m_searchGrid.GetNodeAt(iEndPos.x, iEndPos.y); if (m_startNode == null) m_startNode = new Node(iStartPos.x, iStartPos.y, 0); if (m_endNode == null) m_endNode = new Node(iEndPos.x, iEndPos.y, 0); }
public override bool SetWalkableAt(GridPos iPos, bool iWalkable) { return(SetWalkableAt(iPos.x, iPos.y, iWalkable)); }
public JumpSnapshot() { iX = 0; iY = 0; iPx = 0; iPy = 0; tDx = 0; tDy = 0; jx = null; jy = null; stage = 0; }
internal abstract void _reset(GridPos iStartPos, GridPos iEndPos, BaseGrid iSearchGrid = null);
public override Node GetNodeAt(GridPos iPos) { return(m_nodePool.GetNode(iPos)); }
public List<Node> GetNeighbors(Node iNode, bool iCrossCorners, bool iCrossAdjacentPoint) { int tX = iNode.x; int tY = iNode.y; List<Node> neighbors = new List<Node>(); bool tS0 = false, tD0 = false, tS1 = false, tD1 = false, tS2 = false, tD2 = false, tS3 = false, tD3 = false; GridPos pos = new GridPos(); if (this.IsWalkableAt(pos.Set(tX, tY - 1))) { neighbors.Add(GetNodeAt(pos)); tS0 = true; } if (this.IsWalkableAt(pos.Set(tX + 1, tY))) { neighbors.Add(GetNodeAt(pos)); tS1 = true; } if (this.IsWalkableAt(pos.Set(tX, tY + 1))) { neighbors.Add(GetNodeAt(pos)); tS2 = true; } if (this.IsWalkableAt(pos.Set(tX - 1, tY))) { neighbors.Add(GetNodeAt(pos)); tS3 = true; } if (iCrossCorners && iCrossAdjacentPoint) { tD0 = true; tD1 = true; tD2 = true; tD3 = true; } else if (iCrossCorners) { tD0 = tS3 || tS0; tD1 = tS0 || tS1; tD2 = tS1 || tS2; tD3 = tS2 || tS3; } else { tD0 = tS3 && tS0; tD1 = tS0 && tS1; tD2 = tS1 && tS2; tD3 = tS2 && tS3; } if (tD0 && this.IsWalkableAt(pos.Set(tX - 1, tY - 1))) { neighbors.Add(GetNodeAt(pos)); } if (tD1 && this.IsWalkableAt(pos.Set(tX + 1, tY - 1))) { neighbors.Add(GetNodeAt(pos)); } if (tD2 && this.IsWalkableAt(pos.Set(tX + 1, tY + 1))) { neighbors.Add(GetNodeAt(pos)); } if (tD3 && this.IsWalkableAt(pos.Set(tX - 1, tY + 1))) { neighbors.Add(GetNodeAt(pos)); } return neighbors; }
public override Node GetNodeAt(GridPos iPos) { return GetNodeAt(iPos.x, iPos.y); }
private void btnSearch_Click(object sender, EventArgs e) { for (int resultTrav = 0; resultTrav < m_resultLine.Count; resultTrav++) { m_resultLine[resultTrav].Dispose(); } m_resultLine.Clear(); for (int resultTrav = 0; resultTrav < m_resultBox.Count; resultTrav++) { m_resultBox[resultTrav].Dispose(); } m_resultBox.Clear(); GridPos startPos = new GridPos(); GridPos endPos = new GridPos(); for (int widthTrav = 0; widthTrav < width; widthTrav++) { for (int heightTrav = 0; heightTrav < height; heightTrav++) { if (m_rectangles[widthTrav][heightTrav].boxType != BoxType.Wall) { searchGrid.SetWalkableAt(new GridPos(widthTrav, heightTrav), true); } else { searchGrid.SetWalkableAt(new GridPos(widthTrav, heightTrav), false); } if(m_rectangles[widthTrav][heightTrav].boxType==BoxType.Start) { startPos.x=widthTrav; startPos.y=heightTrav; } if(m_rectangles[widthTrav][heightTrav].boxType==BoxType.End) { endPos.x=widthTrav; endPos.y=heightTrav; } } } jumpParam.CrossCorner = cbCrossCorners.Checked; jumpParam.CrossAdjacentPoint = cbCrossAdjacentPoint.Checked; jumpParam.UseRecursive = cbUseRecursive.Checked; jumpParam.Reset(startPos, endPos); List<GridPos> resultList = JumpPointFinder.FindPath(jumpParam); for (int resultTrav = 0; resultTrav < resultList.Count-1; resultTrav++) { m_resultLine.Add(new GridLine(m_rectangles[resultList[resultTrav].x][resultList[resultTrav].y],m_rectangles[resultList[resultTrav+1].x][resultList[resultTrav+1].y])); } for (int widthTrav = 0; widthTrav < jumpParam.SearchGrid.width; widthTrav++) { for (int heightTrav = 0; heightTrav < jumpParam.SearchGrid.height; heightTrav++) { if(jumpParam.SearchGrid.GetNodeAt(widthTrav, heightTrav)==null) continue; if (jumpParam.SearchGrid.GetNodeAt(widthTrav, heightTrav).isOpened) { ResultBox resultBox = new ResultBox(widthTrav * 20, heightTrav * 20 + 50, ResultBoxType.Opened); m_resultBox.Add(resultBox); } if (jumpParam.SearchGrid.GetNodeAt(widthTrav, heightTrav).isClosed) { ResultBox resultBox = new ResultBox(widthTrav * 20, heightTrav * 20 + 50, ResultBoxType.Closed); m_resultBox.Add(resultBox); } } } this.Invalidate(); }
public bool IsInside(GridPos iPos) { return(IsInside(iPos.x, iPos.y)); }