/// <summary> /// Counts and collects the cells of the shortest path, then prints them out. /// </summary> /// <param name="weightedMatrix">The weighted mirror of the primary map data matrix. Each cell has a "step" cost from the End (0) to Start.</param> /// /// <param name="beginHere">The designated starting osition, in the input file it is marked with " 2 ".</param> /// /// <param name="endHere">The designated goal osition, in the input file it is marked with " 1 ".</param> public static List <int[]> PathCounter(int[,] weightedMatrix, int[] beginHere, int[] endHere) { int[] currentPosition = new int[2]; currentPosition = beginHere; int rowi = currentPosition[0]; int coli = currentPosition[1]; int[] peekAt = new int[2]; int xi = peekAt[0]; int yi = peekAt[1]; List <int[]> path = new List <int[]>(); path.Add(beginHere); Console.WriteLine($"\nStart coordinates (x, y): {beginHere[1]}, {beginHere[0]} ;\n" + $"End coordinates (x, y): {endHere[1]}, {endHere[0]} ."); bool isThisTheEnd; //int c = 1; // Used for "TracePath_Test". do { for (int i = 1; i <= 4; i++) { peekAt = MatrixHelper.SwitchView(rowi, coli, i); xi = peekAt[0]; yi = peekAt[1]; if ((xi < weightedMatrix.GetLength(0) && yi < weightedMatrix.GetLength(1) && xi >= 0 && yi >= 0) && (weightedMatrix[xi, yi] != -1)) { if (weightedMatrix[xi, yi] == weightedMatrix[rowi, coli] - 1) { int[] t = new int[2]; Array.Copy(peekAt, t, 2); rowi = t[0]; coli = t[1]; path.Add(t); //TracePath_Test(path, currentCycle: c); // Prints out the traced path every step cycle. } } isThisTheEnd = (xi == endHere[0] && yi == endHere[1]); if (isThisTheEnd) { EndPrint(path); return(path); } } isThisTheEnd = (xi == endHere[0] && yi == endHere[1]); }while(!isThisTheEnd); // DO - WHILE Console.WriteLine($"\n\nTracing ended."); return(path); }
/// <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]); } }