Package com.ir.search

Source Code of com.ir.search.AStarSearch

package com.ir.search;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.PriorityQueue;

import com.ir.objects.Node;
import com.ir.objects.Path;
import com.ir.objects.Piece;
import com.ir.objects.Square;

/**
* The A* Search Algorithm - finds the shortest path between two Nodes using heuristics
* @author Mark Feaver
*
*/
public class AStarSearch {
  // The shortest path, initially empty
  private Path path = new Path();
  // The g-score associated with each square
  private HashMap<Square, Integer> gScore = new HashMap<Square, Integer>();
  // The f-score associated with each square
  private HashMap<Square, Integer> fScore = new HashMap<Square, Integer>();
 
  // The set of tentative nodes to be evaluated
  private PriorityQueue<Node> openSet = new PriorityQueue<Node>();
  // The set of Nodes already evaluated
  private List<Square> closedSet = new ArrayList<Square>();
 
  // The map of navigated nodes.
  private HashMap<Square, Square> cameFrom = new HashMap<Square, Square>();
 
  private Piece chessPiece = null;
  private Square start = null;
  private Square end = null;
 
  /**
   * Constructor. Takes a start position, end position, and the chess piece
   * @param start - the starting square
   * @param end - the end square
   * @param chessPiece - a chess piece on a board
   */
  public AStarSearch(Square start, Square end, Piece chessPiece){
    this.start = start;
    this.end = end;
    this.chessPiece = chessPiece;
  }
 
 
  /**
   * The core functionality of the A* Search. Uses the start and end squares to
   * search for the shortest path between the two
   * @return the shortest Path
   */
  public Path Search(){
    gScore.put(start, 0);
   
    // Estimated total cost from start to goal through y.
    fScore.put(start, (gScore.get(start) + chessPiece.getHeuristicMoves(start, end)));
   
    // The open set initially contains the start node
    Node startNode = new Node(start, fScore.get(start));
    openSet.add(startNode);
   
    // While we still have nodes to explore
    while (!openSet.isEmpty()){
      // Get the node with the lowest f-score from the priority queue
      Node current = openSet.poll();
      Square currentSquare = current.getSquare();
     
      // If we've found the goal, return the path we took to get there
      if (currentSquare.equals(end))
        return reconstructPath(currentSquare);

      // Add current to closedset, and move the chess piece to that square
      closedSet.add(currentSquare);
      chessPiece.move(currentSquare);
     
      // For each neighbour from the current chess piece position
      for (Square neighbour : chessPiece.getValidMoves()){
        if (closedSet.contains(neighbour))
          continue;
       
        // A tentative g score, used to determine whether we explore a node or not
        int tentativeGScore = gScore.get(currentSquare) + 1;
       
        // Here we clone the openSet and modify the clone, as we are
        // unable to iterate through a PriorityQueue.
        PriorityQueue<Node> clone = new PriorityQueue<Node>(openSet);
        boolean isInSet = false;
       
        while (!clone.isEmpty()){
          Node n = clone.poll();
            if (n.getSquare().equals(neighbour)){
              isInSet = true;
              break;
            }
        }
       
        // If neighbor not in openset or tentative_g_score < g_score[neighbor]
        if (!isInSet || tentativeGScore < gScore.get(neighbour)){
          // Calculate a new f-score for the square, and update its "path" (cameFrom)
          cameFrom.put(neighbour, currentSquare);
          gScore.put(neighbour, tentativeGScore);
          fScore.put(neighbour, tentativeGScore + chessPiece.getHeuristicMoves(neighbour, end));
         
            // Add the neighbour to the open set
          Node n = new Node(neighbour, fScore.get(neighbour));
          openSet.add(n);
        }
      }
    }
    // If no path was found, return failure
    return null;
  }
 
  /**
   * Reconstruct the path from the current square to the starting square
   * @param currentSquare - the square the chess piece is currently on
   * @return the path to the current square
   */
  public Path reconstructPath(Square currentSquare){
    path.addSquare(currentSquare);
    Square c = null;
    while ((c = cameFrom.get(currentSquare)) != null){
      path.addSquare(c);
      currentSquare = c;
    }
    return path;
  }
}
TOP

Related Classes of com.ir.search.AStarSearch

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.