public bool TryAddToClosestAvailable(int x, int y, GridMapCell cell) { int iterationLimit = Math.Max(NumCols, NumRows); for (int depth = 1; depth < iterationLimit; ++depth) { int bottomRow = x + depth; int topRow = x - depth; int rightCol = y + depth; int leftCol = y - depth; for (int i = -depth; i <= depth; ++i) { int col = y + i; if (HorizontalTryAdd(col, topRow, bottomRow, cell)) { return(true); } int row = x + i; if (VerticalTryAdd(row, leftCol, rightCol, cell)) { return(true); } } } return(false); }
public void AddOrUpdate(int x, int y, GridMapCell cell) { Clip(ref x, ref y); _map[x, y] = cell; cell.Row = x; cell.Column = y; if (cell.Id != null) { _cellByIdCache.Add(cell.Id.Value, cell); } }
/// <summary> /// Adds extra empty cell around each element in matrix, therefore enlargening the matrix /// </summary> public void Enlarge() { int nRows = EnlargeRow(NumRows); int nCols = EnlargeColumn(NumCols); var newMap = new GridMapCell[nRows, nCols]; ForEach(cell => { cell.Row = EnlargeRow(cell.Row); cell.Column = EnlargeColumn(cell.Column); newMap[cell.Row, cell.Column] = cell; }); _map = newMap; }
private bool HorizontalTryAdd(int col, int topRow, int bottomRow, GridMapCell cell) { if (col <= 0 || col >= NumCols) { return(false); } if (bottomRow < NumRows && !IsTaken(bottomRow, col)) { AddOrUpdate(bottomRow, col, cell); return(true); } if (topRow >= 0 && !IsTaken(topRow, col)) { AddOrUpdate(topRow, col, cell); return(true); } return(false); }
private bool VerticalTryAdd(int row, int leftCol, int rightCol, GridMapCell cell) { if (row <= 0 || row >= NumRows) { return(false); } if (leftCol >= 0 && !IsTaken(row, leftCol)) { AddOrUpdate(row, leftCol, cell); return(true); } if (rightCol < NumCols && !IsTaken(row, rightCol)) { AddOrUpdate(row, rightCol, cell); return(true); } return(false); }
private static bool IsNotEndNode(int rr, int cc, GridMapCell end) { return(rr != end.Row || cc != end.Column); }
public static List <GridPoint> GetShortestPath(GridMapCell start, GridMapCell end, GridMap map, Func <int, int, bool> isObstacle) { var shortestPath = new List <GridPoint>(); var q = new Queue <GridPoint>(); var prev = new GridPoint[map.NumRows, map.NumCols]; q.Enqueue(start); prev[start.Row, start.Column] = start; bool pathFound = false; while (q.Count > 0) { var point = q.Dequeue(); if (point.Row == end.Row && point.Column == end.Column) { pathFound = true; break; } for (int i = 0; i < 4; ++i) { int rr = point.Row + dr[i]; int cc = point.Column + dc[i]; // Skip invalid cells. Assume R and C for the number of roms and columns if (rr < 0 || cc < 0) { continue; } if (rr >= map.NumRows || cc >= map.NumCols) { continue; } // Skip visited locations or blocked cells if (prev[rr, cc] != null) { continue; } if (IsNotEndNode(rr, cc, end) && (isObstacle?.Invoke(rr, cc) ?? false)) { continue; } // (rr, cc) is a neighbouring cell of (r,c) q.Enqueue(new GridPoint(rr, cc)); prev[rr, cc] = point; } } if (pathFound) { shortestPath.Add(end); var currPrev = prev[end.Row, end.Column]; while (currPrev != null && currPrev != start) { shortestPath.Add(currPrev); currPrev = prev[currPrev.Row, currPrev.Column]; } shortestPath.Add(currPrev); } return(shortestPath); }