Beispiel #1
0
        static void Main(string[] args)
        {
            int[,] matrix = MatrixHelper.ReadMap();
            int size = matrix.GetLength(0);

            int[]        startPosition = Surveyor.GetStartEndPositions(matrix, startEndValue: 2);
            int[]        endPosition   = Surveyor.GetStartEndPositions(matrix, startEndValue: 1);
            List <int[]> shortestPath;

            int[,] listToArray;             // couldn't find another way to convert only once but use in 2 places, needed for easier List<int[]> to int[,] comparison.

            PrintHeader(width: size);

            PrintContent(matrix, pathList: listToArray = null);             // Basic map representation; with color coded walls, start & end positions.

            PrintFooter(width: size);

            Console.Write($"\nThe designated starting position coordinates (x, y) are:  [ {startPosition[1]} , {startPosition[0]} ].\n" +
                          $"The designated ending position coordinates (x, y) are:  [ {endPosition[1]} , {endPosition[0]} ].\n" +
                          "--------------------\n");

            int[,] weightedMatrix = Surveyor.Surveying(matrix);

            Console.WriteLine("Survey complete. Looking for optimal path..\n" +
                              "--------------------\n" +
                              $"Survey data integrity (OK if > 1): {weightedMatrix.Length} .");

            shortestPath = PathFinder.PathCounter(weightedMatrix, startPosition, endPosition);

            PrintResult(weightedMatrix, startPosition, endPosition, pathList: shortestPath);

            Console.WriteLine("\n--------------------\n");

            listToArray = ListToArray(shortestPath);

            PrintContent(matrix, pathList: listToArray);              // Basic map representation; with color coded walls, start & end positions, plus the shortest path.

            Console.WriteLine("\n--------------------\nEnd.\n");
        }
Beispiel #2
0
        /// <summary>
        /// Look around the current cell clockwise, using the 4 primary directions: up (x, y+1), right (x+1, y), down (x, y-1) and left (x-1, y).
        /// </summary>
        /// <param name="mapData">The matrix previously extracted from the input file.</param>
        /// <returns>The surveyed copy of the map where instead of 0-s the passable cell values are the cell-step distance from the starting cell.</returns>
        public static int[,] Surveying(int[,] mapData)
        {
            int[,] surveyData = new int[mapData.GetLength(0), mapData.GetLength(0)];
            addDefaultSurveyData(surveyData);

            int[] startPos = GetStartEndPositions(mapData, startEndValue: 2);             // The "startEndValue" value is found inside the "MapData" file.
            int[] endPos   = GetStartEndPositions(mapData, startEndValue: 1);

            // Buffer, put here the just checked clear cells (did not already have a cost, no walls) to peek around next cycle.
            Queue <int[]> waiting = new Queue <int[]>();


            // ----- The below arrays are Declared & Initialized here because they are parameters for more than one following code brackets. ----- //
            // --------------------------------- //
            // Start cell row & column indexes.
            int srowi = startPos[0];
            int scoli = startPos[1];

            // Set current position to the coordinates where the Survey will start -- from the End Goal ("endPos").
            int[] curPos = endPos;
            int   rowi   = curPos[0];
            int   coli   = curPos[1];

            // Store coordinates of the cell we are looking at at any given time, around the current cell we are at.
            int[] lookingAt = new int[2];
            int   xi        = lookingAt[0];
            int   yi        = lookingAt[1];
            // --------------------------------- //


            bool lookAtIsStart, lessThanIntMaxSize, isInsideBounds, isPassableCell;

            surveyData[rowi, coli] = 0;             // Surveyor start coordinate's cell cost ; also the first discovered cell.

            waiting.Enqueue(curPos);

            while (waiting.Count != 0)
            {
                Array.Copy(waiting.Dequeue(), curPos, 2);                 // Take the next one from the queue as the current position to look around.
                rowi = curPos[0];
                coli = curPos[1];

                for (int cy = 1; cy <= 4; cy++)                // Looking cycle: up, right, down, left.
                {
                    lookingAt = MatrixHelper.SwitchView(rowi, coli, cy);
                    xi        = lookingAt[0];
                    yi        = lookingAt[1];

                    isInsideBounds = isInside(mapData, xi, yi);

                    if (isInsideBounds == false)
                    {
                        isPassableCell = false;
                    }
                    else
                    {
                        isPassableCell = isPassable(mapData, surveyData, xi, yi);
                    }

                    if (isInsideBounds == true && isPassableCell == true)
                    {
                        // Booleans.
                        lessThanIntMaxSize = (surveyData[rowi, coli] + 1 <= int.MaxValue);
                        lookAtIsStart      = (xi == srowi && yi == scoli);

                        if (lookAtIsStart)
                        {
                            // Check against too large matrix size.
                            // Since each cell is given an "integer" type weight, if the area is too big the value could reach past the type's maximum value.
                            if (lessThanIntMaxSize)
                            {
                                surveyData[xi, yi] = surveyData[rowi, coli] + 1;

                                return(surveyData);
                            }
                            else
                            {
                                throw new OverflowException("ERROR.. There are too many cells to map with BFS.");
                            }
                        }

                        if (lessThanIntMaxSize)
                        {
                            surveyData[xi, yi] = surveyData[rowi, coli] + 1;

                            int[] t = new int[2];
                            Array.Copy(lookingAt, t, lookingAt.Length);

                            waiting.Enqueue(t);                             // Place what was just marked in the queue to be looked around later.
                        }
                        else
                        {
                            throw new OverflowException("ERROR.. There are too many cells to map with BFS.");
                        }
                    }
                }
            }

            lookAtIsStart = (xi == srowi && yi == scoli);
            if (lookAtIsStart)
            {
                Console.WriteLine($"FINALLY.. Print out weighted matrix; {yi}, {xi} .");
                return(surveyData);
            }
            else
            {
                Console.WriteLine("ERROR.. Target coordinates cannot be reached!\n" +
                                  "Check \"MapData.txt\" making sure there is NO obstruction between the desired Start and End positions.");
                return(new int[0, 0]);
            }
        }