Advertisement
thesagab

Untitled

Apr 27th, 2017
133
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 6.89 KB | None | 0 0
  1. /* Nama     : Anindito Bhagawanta
  2.  * NPM      : 1606879230
  3.  * Kelas    : DDP 2 - B
  4.  * Asisten  : B-4
  5.  */
  6.  
  7. import java.util.*;
  8.  
  9. /**
  10.  * Class yang digunakan untuk mencari shortest path dari suatu koordinat
  11.  * Metode shortest path menggunakan breadth-first search (BFS)
  12.  * Referensi BFS http://stackoverflow.com/questions/16366448/maze-solving-with-breadth-first-search
  13.  * @author Anindito Bhagawanta
  14.  * @version 1.0
  15.  */
  16. public class Pathfinding {
  17.  
  18.     private static Map map = new Map();
  19.     private static Character[][] modifiedMap = map.getMap();
  20.     private static boolean[][] visited = new boolean[Map.HEIGHT][Map.WIDTH];
  21.  
  22.     /**
  23.      * Inner class untuk merepresentasikan koordinat titik
  24.      * Memiliki parent sebagai penunjuk titik sebelumnya
  25.      */
  26.     private static class Point {
  27.         int x;
  28.         int y;
  29.         Point parent;
  30.  
  31.         public Point(int x, int y, Point parent) {
  32.             this.x = x;
  33.             this.y = y;
  34.             this.parent = parent;
  35.         }
  36.  
  37.         public Point getParent() {
  38.             return this.parent;
  39.         }
  40.  
  41.         public String toString() {
  42.             // biar bener dituker x dan y nya
  43.             return "x = " + y + ", y = " + x;
  44.         }
  45.     }
  46.  
  47.     /**
  48.      * Mencari koordinat X dari string
  49.      * @param coordinate string suatu koordinat
  50.      * @return koordinat X, -1 jika panjang string != 4
  51.      */
  52.     private static int getCoordinateX(String coordinate){
  53.         if (coordinate.length() != 4) return -1;
  54.         String x = coordinate.substring(0, 2);
  55.         int coor = (x.charAt(0) - 'A') * 10 + Character.getNumericValue(x.charAt(1));
  56.         return coor;
  57.     }
  58.     /**
  59.      * Mencari koordinat Y dari string
  60.      * @param coordinate string suatu koordinat
  61.      * @return koordinat Y, -1 jika panjang string != 4
  62.      */
  63.     private static int getCoordinateY(String coordinate){
  64.         if (coordinate.length() != 4) return -1;
  65.         String y = coordinate.substring(2, 4);
  66.         int coor = (y.charAt(0) - 'Q')  * 10 + Character.getNumericValue(y.charAt(1));
  67.         return coor;
  68.     }
  69.  
  70.     /**
  71.      * Metode BFS untuk mencari jarak terpendek dari koordinat yang diberikan
  72.      * @param x x awal
  73.      * @param y y awal
  74.      * @param xEnd x akhir
  75.      * @param yEnd y akhir
  76.      * @return point tempat tujuan, null jika tidak ditemukan jalan
  77.      */
  78.     private static Point getPathBFS(int x, int y, int xEnd, int yEnd) {
  79.         // queue untuk menyimpan point yang disimpan
  80.         // setiap loop while diambil 1 point untuk mengecek jalan
  81.         // fungsi queue adalah untuk melakukan pencarian secara meluas (breadth-first)
  82.         Queue<Point> q = new LinkedList<>();
  83.         // reset ulang boolean
  84.         for (int i=0;i<Map.HEIGHT;++i) for (int j=0;j<Map.WIDTH;++j) visited[i][j]=false;
  85.         q.add(new Point(x,y, null));
  86.  
  87.         modifiedMap[xEnd][yEnd] = 'F';
  88.         visited[x][y] = true;
  89.         modifiedMap[x][y] = 'S';
  90.         while(!q.isEmpty()) {
  91.             Point p = q.remove();
  92.             //System.out.println(q.size() + " " + p.x + " " + p.y);
  93.             //Jika sampai finish
  94.             if (modifiedMap[p.x][p.y] == 'F') {
  95.                 //System.out.println("Exit is reached!");
  96.                 return p;
  97.             }
  98.             // cek jalan
  99.             if(isFree(p.x+1,p.y)) {
  100.                 //System.out.println("haha");
  101.                 Point nextP = new Point(p.x+1,p.y, p);
  102.                 visited[nextP.x][nextP.y] = true;
  103.                 q.add(nextP);
  104.             }
  105.  
  106.             if(isFree(p.x-1,p.y)) {
  107.                 //System.out.println("haha");
  108.                 Point nextP = new Point(p.x-1,p.y, p);
  109.                 visited[nextP.x][nextP.y] = true;
  110.                 q.add(nextP);
  111.             }
  112.  
  113.             if(isFree(p.x,p.y+1)) {
  114.                 //System.out.println("haha");
  115.                 Point nextP = new Point(p.x,p.y+1, p);
  116.                 visited[nextP.x][nextP.y] = true;
  117.                 q.add(nextP);
  118.             }
  119.  
  120.             if(isFree(p.x,p.y-1)) {
  121.                 //System.out.println("haha");
  122.                 Point nextP = new Point(p.x,p.y-1, p);
  123.                 visited[nextP.x][nextP.y] = true;
  124.                 q.add(nextP);
  125.             }
  126.  
  127.         }
  128.         // jika tidak ada jalan ke finish
  129.         return null;
  130.     }
  131.  
  132.     /**
  133.      * Cek jalan koordinat
  134.      * @param x x
  135.      * @param y y
  136.      * @return true jika merupakan jalan
  137.      */
  138.     private static boolean isFree(int x, int y) {
  139.         if((x >= 0 && x < Map.HEIGHT) && (y >= 0 && y < Map.WIDTH)
  140.                 && (modifiedMap[x][y] == ' ' || modifiedMap[x][y] == 'F') && (!visited[x][y])) {
  141.             return true;
  142.         }
  143.         return false;
  144.     }
  145.  
  146.     /**
  147.      * Print map yang berisi jalan yang ditandai dengan tiitk
  148.      */
  149.     private static void printModifiedMap(){
  150.         map.print();
  151.     }
  152.  
  153.     /**
  154.      * Mereset ulang map
  155.      */
  156.     private static void resetMap(){
  157.         map = new Map();
  158.         modifiedMap = map.getMap();
  159.     }
  160.  
  161.     /**
  162.      * Menghitung jarak terpendek dari koordinat yang diberikan
  163.      * @param from string asal
  164.      * @param to string tujuan
  165.      * @return jarak (dalam satuan 100m), -1 jika tidak valid
  166.      */
  167.     public static int calculateDistance(String from, String to){
  168.         int xStart = getCoordinateX(from);
  169.         int xEnd = getCoordinateX(to);
  170.         int yStart = getCoordinateY(from);
  171.         int yEnd = getCoordinateY(to);
  172.         // jika bukan koordinat yang valid (ex: G8U9)
  173.         if(!(xStart > 0 && xStart < Map.HEIGHT) || !(yStart > 0 && yStart < Map.WIDTH)){
  174.             System.out.println(from + " bukan koordinat yang valid!");
  175.             return -1;
  176.         }
  177.         if(!(xEnd > 0 && xEnd < Map.HEIGHT) || !(yEnd > 0 && yEnd < Map.WIDTH)){
  178.             System.out.println(to + " bukan koordinat yang valid!");
  179.             return -1;
  180.         }
  181.         // jika menemui tembok
  182.         if (modifiedMap[xStart][yStart] == '#') {
  183.             System.out.println("Input tidak valid: " + from + " bukan jalan");
  184.             return -1;
  185.         }
  186.         if(modifiedMap[xEnd][yEnd] == '#'){
  187.             System.out.println("Input tidak valid: " + to + " bukan jalan");
  188.             return -1;
  189.         }
  190.         //jika asal = tujuan (special case)
  191.         if(from.equals(to)){
  192.             modifiedMap[xEnd][yEnd] = 'F';
  193.             printModifiedMap();
  194.             resetMap();
  195.             return 0;
  196.         }
  197.         // working case
  198.         int dist = 0;
  199.         Point p = getPathBFS(xStart, yStart, xEnd, yEnd);
  200.         if (p == null) return -1;
  201.         // lakukan traceback dari finish ke tujuan
  202.         while(p.getParent() != null) {
  203.             //System.out.println(p);
  204.             modifiedMap[p.x][p.y] = '.';
  205.             dist++;
  206.             p = p.getParent();
  207.         }
  208.         modifiedMap[xEnd][yEnd] = 'F';
  209.         printModifiedMap();
  210.         resetMap();
  211.         return dist;
  212.     }
  213.  
  214. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement