diff --git a/src/Location.java b/src/Location.java new file mode 100644 index 0000000..6e81a67 --- /dev/null +++ b/src/Location.java @@ -0,0 +1,3 @@ +public record Location(int row, int col) { + +} diff --git a/src/Search.java b/src/Search.java index cebb278..bbe42c9 100644 --- a/src/Search.java +++ b/src/Search.java @@ -1,4 +1,25 @@ +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.Set; + public class Search { + + public static void main(String[] args) { + char[][] grid = { + {'o', 'o', 'o', 'o', 'c', 'w', 'c', 'o'}, + {'w', 'o', 'o', 'w', 'w', 'c', 'w', 'o'}, + {'o', 'o', 'o', 'o', 'R', 'w', 'o', 'o'}, + {'o', 'o', 'w', 'w', 'w', 'o', 'o', 'o'}, + {'o', 'o', 'o', 'o', 'c', 'o', 'o', 'o'} + }; + + System.out.println(nearestCheese(grid)); + } /** * Finds the location of the nearest reachable cheese from the rat's position. * Returns a 2-element int array: [row, col] of the closest 'c'. If there are multiple @@ -28,7 +49,89 @@ public class Search { * @throws CrowdedMazeException if there is more than one rat in the maze * @throws HungryRatException if there is no reachable cheese */ - public static int[] nearestCheese(char[][] maze) throws EscapedRatException, CrowdedMazeException, HungryRatException { - return null; + public static Location nearestCheese(char[][] maze) throws EscapedRatException, CrowdedMazeException, HungryRatException { + Location start = ratLocation(maze); + Queue queue = new LinkedList<>(); + queue.add(start); + + Set visited = new HashSet<>(); + Map prevs = new HashMap<>(); + + while (!queue.isEmpty()) { + Location current = queue.poll(); + + if (maze[current.row()][current.col()] == 'c') { + List path = new ArrayList<>(); + Location pointer = current; + + while (!pointer.equals(start)) { + path.add(pointer); + pointer = prevs.get(pointer); + } + + path.add(start); + + System.out.println(path.reversed()); + + return current; + } + + + for (Location neighbor : neighbors(maze, current)) { + if (!visited.contains(neighbor)) { + queue.add(neighbor); + visited.add(neighbor); + prevs.put(neighbor, current); + } + } + } + + + throw new HungryRatException(); + } + + public static List neighbors(char[][] maze, Location current) { + List result = new ArrayList<>(); + + int[][] moves = new int[][] { + {-1 , 0}, // UP + {1 , 0}, // DOWN + {0 , -1}, // LEFT + {0 , 1} // RIGHT + }; + + for (int[] move : moves) { + int newR = current.row() + move[0]; + int newC = current.col() + move[1]; + + if (newR >= 0 && newR < maze.length // checking newR + && newC >= 0 && newC < maze[0].length // checking newC + && maze[newR] [newC] != 'w') { + result.add(new Location(newR, newC)); + } + } + + return result; + } + + private static Location ratLocation(char[][] maze) throws EscapedRatException, CrowdedMazeException{ + Location location = null; + for (int row = 0; row < maze.length; row++) { + for (int col = 0; col < maze[row].length; col++) { + if (maze[row][col] == 'R') { + if (location == null) { + location = new Location(row, col); + } else { + throw new CrowdedMazeException(); + } + } + } + } + if (location == null) { + throw new EscapedRatException(); + } + + return location; + } -} \ No newline at end of file +}