Example #1
0
        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);
        }
Example #2
0
 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);
     }
 }
Example #3
0
        /// <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;
        }
Example #4
0
        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);
        }
Example #5
0
        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);
        }
Example #6
0
 private static bool IsNotEndNode(int rr, int cc, GridMapCell end)
 {
     return(rr != end.Row || cc != end.Column);
 }
Example #7
0
        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);
        }