diff --git a/src/Search.java b/src/Search.java index cebb278..5b91845 100644 --- a/src/Search.java +++ b/src/Search.java @@ -1,3 +1,5 @@ +import java.util.*; + public class Search { /** * Finds the location of the nearest reachable cheese from the rat's position. @@ -29,6 +31,59 @@ public class Search { * @throws HungryRatException if there is no reachable cheese */ public static int[] nearestCheese(char[][] maze) throws EscapedRatException, CrowdedMazeException, HungryRatException { - return null; + boolean[][] visited = new boolean[maze.length][maze[0].length]; + + Queue que = new LinkedList<>(); + que.add(ratLocation(maze)); + while(!que.isEmpty()){ + int[] current = que.poll(); + if(visited[current[0]][current[1]]) continue; + + visited[current[0]][current[1]] = true; + + if(maze[current[0]][current[1]] == 'c') return current; + que.addAll(getNeighbors(maze, current)); + // for(int[] neighbor: getNeighbors(maze, current)){ + // que.add(neighbor); + // } + + } + + throw new HungryRatException(); + } + + public static List getNeighbors(char[][] maze, int[] current){ + int curR = current[0]; + int curC = current[1]; + int[][] directions = {{-1,0}, {1,0}, {0,-1}, { 0,1}}; //up down left right + List moves = new ArrayList<>(); + for(int[] dir: directions){ + int changeR = dir[0]; + int changeC = dir[1]; + + int newR = curR + changeR; + int newC = curC + changeC; + + if(newR>=0 && newR < maze.length && + newC >= 0 && newC < maze[newR].length && + maze[newR][newC] != 'w'){ + moves.add(new int[] {newR, newC}); + } + } + return moves; + } + + public static int[] ratLocation(char[][] maze) throws EscapedRatException, CrowdedMazeException{ + int [] location = null; + for(int r=0; r{ + Search.ratLocation(maze); + }); + } + + @Test + public void testFindRat_TwoRats(){ + char [][] maze = { + {'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', 'R'} + }; + + assertThrows(CrowdedMazeException.class, () ->{ + Search.ratLocation(maze); + }); + } + + @Test + public void testNearestCheese_noCheese(){ + char [][] maze = { + {'o', 'o', 'o', 'o', 'o', 'w', 'o', 'o'}, + {'w', 'o', 'o', 'w', 'w', 'o', 'w', 'o'}, + {'o', 'o', 'o', 'o', 'R', 'w', 'o', 'o'}, + {'o', 'o', 'w', 'w', 'w', 'o', 'o', 'o'}, + {'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'} + }; + + assertThrows(HungryRatException.class, () ->{ + Search.nearestCheese(maze); + }); + } + @Test + public void testNearestCheese_twoCheese(){ + char [][] maze = { + {'o', 'o', 'o', 'o', 'o', 'w', 'o', 'o'}, + {'w', 'o', 'o', 'w', 'c', 'o', 'w', 'o'}, + {'o', 'o', 'o', 'c', 'R', 'w', 'o', 'o'}, + {'o', 'o', 'w', 'w', 'w', 'o', 'o', 'o'}, + {'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'} + }; + + assertEquals(1, Search.nearestCheese(maze)[0]); + assertEquals(4, Search.nearestCheese(maze)[1]); + + } }