/** * In this class we determine the path that Freddy the Frog must follow to go from the * starting cell to the end cell, where Franny is. * @author Atika Hussain **/ public class FrogPath { private Pond pond; public FrogPath(String filename) { try { pond = new Pond(filename); } catch (Exception e) { System.out.println("Error"); } } /** * Finds the best route for Freddy to get to Franny by checking priority cells * @param currCell * @return returns the lowest value from priority Queue **/ public Hexagon findBest(Hexagon currCell) { ArrayUniquePriorityQueue priorityQueue = new ArrayUniquePriorityQueue<>(); for (int i = 0; i < 6; i++) { Hexagon neighbor = currCell.getNeighbour(i); if(neighbor != null && correctCell(neighbor)) { priorityQueue.add(neighbor, priorityFinder(neighbor)); } } if ( currCell.isStart() || currCell.isLilyPadCell() ) { for(int j = 0; j< 6; j++) { Hexagon neighbor = currCell.getNeighbour(j); if(neighbor != null) { for (int k = 0; k < 6; k++) { Hexagon newCell = neighbor.getNeighbour(k); if (newCell != null && correctCell(newCell)) { priorityQueue.add(newCell, calculatePriority(newCell, currCell)); } } } } } if(priorityQueue.isEmpty()) { return null; } return priorityQueue.removeMin() ; } /** * This helper method checks if Freddy can enter the current cell and whether its a valid cell or not. * @param currCell * @return true is the if the cell is correct **/ private boolean correctCell(Hexagon currCell) { if (currCell == pond.getStart()) { return false; } if (currCell.isReedsCell()) { return true; } for (int i = 0; i < 6; i++) { try { if (currCell.getNeighbour(i).isAlligator()) return false; } catch (Exception e) { } if (currCell.isAlligator() || currCell.isMudCell() || currCell.isMarked()) { return false; } } return true; } /** * This helper method find the priority of each cell and returns the priority of the current cell * @param currCell * @return it returns the priority based on the cell **/ private double priorityFinder(Hexagon currCell) { int numFlies = getNumFlies(currCell); double priority = getBasePriority(numFlies); if (currCell.isEnd()) { priority = 3.0; } else if (currCell.isReedsCell()) { priority = 5.0; } else if (currCell.isLilyPadCell()) { priority = 4.0; } else if (currCell.isWaterCell()) { priority = 6.0; } else if (currCell.isReedsCell() && nearAlligator(currCell)) { priority = 10.0; } return priority; } /** * This helper method find the number of flies in a cell * @param currCell * @return the number of flies **/ private int getNumFlies(Hexagon currCell) { int numFlies = 0; if (currCell instanceof FoodHexagon) { FoodHexagon foodHexag currCell; numFlies = foodHexagon.getNumFlies(); } return numFlies; } /** * This helper method returns the priority of each cell given for the * number of flies in that cell * @param numFlies * @return basePriority based on the numebr of cells **/ private double getBasePriority(int numFlies) { double basePriority = 0.0; if (numFlies == 3) { basePriority = 0.0; } else if (numFlies == 2) { basePriority = 1.0; } else if (numFlies == 1) { basePriority = 3.0; } return basePriority; } /** * This helper method adds priorities for the cells which are straight * @param cell , currCell * @return addPriority based on if the cell is straight **/ private double calculatePriority(Hexagon cell, Hexagon currCell) { double addPriority = priorityFinder(cell); int condition; if (Straight(cell, currCell)) { c } else { c } if (c 0) { addPriority += 0.5; } else if (c 1) { addPriority +=1.0; } return addPriority; } /** * this helper method checks the straight cell * @param cell, currCell * @return **/ private boolean Straight(Hexagon cell, Hexagon currCell) { int check = 0; for (int i = 0; i < 6; i++) { for (int j = 0; j < 6; j++) { if (cell.getNeighbour(i) == currCell.getNeighbour(j)) { check++; if (check > 1) { break; } } } if (check > 1) { break; } } return check == 1; } /** * This helper method checks for reed cells near alligator * @return true or false if the adjacent cell to alligators is a reed cell **/ public boolean nearAlligator(Hexagon currCell) { boolean nearAlligator = false; for (int i = 0; i < 6 && !nearAlligator; i++) { Hexagon neighbor = currCell.getNeighbour(i); if (neighbor != null && neighbor.isAlligator()) { nearAlligator = true; } } return nearAlligator; } /** * This method keeps track of the cells that the frog has visited in its * path from the starting cell toward the end cell. * @return **/ public String findPath() { ArrayStack S = new ArrayStack<>(); int fliesEaten = 0; Hexagon start = pond.getStart(); S.push(start); start.markInStack(); StringBuilder pathBuilder = new StringBuilder(); while (!S.isEmpty()) { Hexagon curr = S.peek(); pathBuilder.append(curr.getID()).append(" "); if (curr.isEnd()) { break; } if (curr instanceof FoodHexagon) { int numFlies = ((FoodHexagon)curr).getNumFlies(); if (numFlies > 0) { fliesEaten = fliesEaten + numFlies; ((FoodHexagon)curr).removeFlies(); } } Hexagon next = findBest(curr); if (next == null) { S.pop(); curr.markOutStack(); } else { S.push(next); next.markInStack(); } } if (S.isEmpty()) return "No solution"; return pathBuilder.toString() + "ate " + fliesEaten + " flies"; } public static void main (String[] args) { if (args.length != 1) { System.out.println("No map file specified in the arguments"); return; } FrogPath fp = new FrogPath(args[0]); Hexagon.TIME_DELAY = 500; // Change this time delay as desired. String result = fp.findPath(); System.out.println(result); } }