Path Finding Question

Im re-familiarizing myself with Java and have decided to crack at the Knights Tour puzzle. Now my code already finds one path (if possible) for every starting path, or returns nothing if it hits a dead end.
However id like to expand it to find all paths, anyone offer any help with this? below is the code of the main and the board classes, the co-ord basically is returning an X/Y value
package KnightsTour;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
public class KnightsTour
     public static void main (String args[])
          new KnightsTour();
     public KnightsTour()
          int boardWidth = 0, boardHeight = 0;
          System.out.println("Input Width :");
          boardWidth = getConsoleValue();
          System.out.println("Input Height :");
          boardHeight = getConsoleValue();
          long temp = System.currentTimeMillis();
          int totalPaths = getTotalPaths(boardWidth, boardHeight);
          System.out.println("\nSuccessful paths for board size :" + boardWidth + "x" + boardHeight + " is :" + totalPaths);
          System.out.println("\nTime taken to calculate was :" + (System.currentTimeMillis() - temp) + "ms");
     /* returns an Integer read from the console */
     private int getConsoleValue()
          int boardSize = 0;
          String line = null;
         try
           BufferedReader is = new BufferedReader(new InputStreamReader(System.in));
           line = is.readLine();
           boardSize = Integer.parseInt(line);
         catch (NumberFormatException ex)
           System.err.println("Not a valid number: " + line);
         catch (IOException e)
           System.err.println("Unexpected IO ERROR: " + e);
         return boardSize;
     /* returns value of number of Paths for a given board */
     public static int getTotalPaths(int width, int height)
          int totalPaths = 0;
          for(int w = 0; w < width; w++)
               for(int h = 0; h < height; h++)
                    Coordinate startingPos = new Coordinate(w, h);
                    System.out.println("\nStarting at " + startingPos );
                    Board board = new Board(height, width, startingPos);
                    List<Coordinate> results = resolvePuzzle(board);
                    if (results != null)
                         for (Coordinate c : results)
                              System.out.print(c + " ");
                         totalPaths++;
                    else
                         System.out.print("No Path Found");
          return totalPaths;
     /* a list of the moves made to resolve the puzzle */
     public static List<Coordinate> resolvePuzzle(Board currentBoard){
          if (currentBoard.isFinish())
               return currentBoard.getCurrentPath();
          List<Coordinate> possibleMove = currentBoard.getPossibleMove();
          if (possibleMove.size() == 0)
               return null;
          for (Coordinate c : possibleMove)
               currentBoard.move(c);
               List<Coordinate> results = resolvePuzzle(currentBoard);
               if (results == null)
                    currentBoard.undo();
               else
                    return results;
          return null;          
} the board
package KnightsTour;
import java.util.ArrayList;
import java.util.List;
public class Board
          private boolean [][] visitedBoard;
          private Coordinate currentPos = null;
          private List<Coordinate> knightMoves = new ArrayList<Coordinate>();
          private List<Coordinate> currentPath = new ArrayList<Coordinate>();
          public Board(int boardHeight, int boardWidth, Coordinate start)
               initKnight();
               visitedBoard = new boolean [boardWidth][boardHeight];
               move(start);
          /* a Knight has 8 different moves it can make, and this represents them all */
          public void initKnight()
               knightMoves.add(new Coordinate (-1, -2));
               knightMoves.add(new Coordinate (1, -2));
               knightMoves.add(new Coordinate (2, -1));
               knightMoves.add(new Coordinate (2, 1));
               knightMoves.add(new Coordinate (1, 2));
               knightMoves.add(new Coordinate (-1, 2));
               knightMoves.add(new Coordinate (-2, 1));
               knightMoves.add(new Coordinate (-2, -1));
          /* marks a square as visited and adds it the co-ord to the list */
          public void move (Coordinate newPos)
               currentPos = newPos;
               visitedBoard[newPos.getX()][newPos.getY()] = true;
               currentPath.add(newPos);
          /* when a dead end if found, the path is reversed to see if an alternate path exists */
          public void undo ()
               if(currentPath.size()-2 >= 0)
                    visitedBoard[currentPos.getX()][currentPos.getY()] = false;
                    Coordinate lastPos = currentPath.get(currentPath.size()-2);
                    currentPath.remove(currentPath.size() -1);
                    currentPos = lastPos;
          /* check the move list to see if a valid move is found */
          public List<Coordinate> getPossibleMove()
               List<Coordinate> possibleMoves = new ArrayList<Coordinate>();
               for (Coordinate c : knightMoves)
                    Coordinate futureMove = currentPos.getDelta(c);
                    if (!isCoordinateOutOfBound(futureMove) && !visitedBoard[futureMove.getX()][futureMove.getY()])
                         possibleMoves.add(futureMove);
               return possibleMoves;
          public List<Coordinate> getCurrentPath(){ return currentPath;}
          private boolean isCoordinateOutOfBound(Coordinate coor)
               return (coor.getX() < 0 || coor.getY() < 0 || coor.getX() >= visitedBoard.length || coor.getY() >= visitedBoard[0].length);
          /* has the Knight toured the board ? */
          boolean isFinish()
               for (boolean[] range: visitedBoard)
                    for (boolean column : range)
                         if (! column)
                              return false;
               return true;
     }

Dijkstra (and A*), doesn't in theory compute the shortest path between a source and a destination, but between a source and all the nodes. On those algorithms, once you've tested a node you know 1) it's distance to the source, 2) where the shortest path came from, so you cannot recompute a shortest path for a node.
Here you should test the node that has the lowest "distance from src + heuristic", so probably one of the node adjacent to the violets.

Similar Messages

  • Path finder & Line Question

    Hello Illustrators.
    I'm having an issue with the pathfinder tool. Im using the pathfiners DIVIDE and some of my lines go missing. from 1px stroke they go to just turn to a thin line other lines go thicker, other times some lines merge together
    distorting the shape of the of my design. I am expanding the lines fill and stroke to to clear all the unwanted lines hanging off the edges if that makes sense..The reason why im doing this is, because I need the inner parts
    within the black border strokes.
    thank you.

    Hello Forum.
    Heres a better understanding of what Im doing. on A side, Im drawing out lines using the line tool, and also the pen tool.
    then on B side, im joining the anchor points to make up the shape.
    on C i lay over the lines a rectangle so when I use the path finder tool, to make the shape fill up.
    and on D is the result which some lines break up,some go thickers, some go thiner, leaving gaps where the rectnagle was supposed to fill up.
    on D the lines have ruined, some have go thick for what reason?

  • Solution: A-Star Path Finding Algorithm (games)

    Hello everyone. I have developed several A-Star implementations for games, if you come across anyone with questions relating to path finding, please direct them to [email protected]

    I'll also be directing several rich Nigerians who need your help, too, if that is OK.

  • Path Finder 7 is it acceptable

    Is Path Finder 7 a safe and good software for Yosemite?

    We need to know what Mac you are using and what version of OS X, then we can get your question transferred to the correct forum.

  • I am English but live in Spain, When I got my new Macbook Pro I set the language to English, so far so good. Then I stupidly set the keyboard to British when it is obviously a Spanish keyboard. How can I reset it to Spanish. Sorry cant find question mark

    I am English but live in Spain, When I got my new Macbook Pro I set the language to English, so far so good. Then I stupidly set the keyboard to British when it is obviously a Spanish keyboard. How can I reset it to Spanish. Sorry cant find question mark

    LizMaddock,
    you can reset the input source to Spanish by selecting the Keyboard pane of System Preferences, selecting the Input Sources tab, and pressing the “+” button in the lower-left corner to select one of the Spanish input sources. The “Spanish – ISO” input source is most similar to the physical Spanish keyboard layout.

  • Two Finder questions

    Two Finder questions:
    1. Is there a way to get the status bar to show something more useful than how many files I have selected and how much space is left on a volume? It would be nice if it could tell me something like file size or the combined size of the selected items. Which brings me to...
    2. How can I 'Get info' for multiple items as a combined total? Since the status bar won't tell me, this would be the only other reasonable way to find out.
    I keep ending up in a situation where I know how much space is available on a memory stick, yet I don't know how many files I can put on it because I have no way of seeing how much space the selected files take up.
    Thanks for putting up with the noob questions.
    -Travis

    Excellent, one down.
    I also noticed that if you press ctrl instead of option, you get 'Get Summary Info' which results in the exact same window, but with a nicer title bar. Very important, that is.
    Thank you, that helps a lot.
    Any ideas on the status bar? Having come from Windows I'm used to it dynamically showing a lot of useful information. As it is, only telling me how many items there are and how much space there is on the volume, I may just nix it if it can't do more. A 'tweak' perhaps that's found more behind the scenes than in an option window somewhere?
    Thanks again, the forums here have made the transition very pleasant.
    -Travis

  • Path finding based on an image

    I know its possible to create a path finding algorithm based on an image... That is, if the color map is blue then there is water, if it is brown then there is land. So detection of land and water is not the problem.
    What I want to know is, is there an easy way to set up a path finder aside having a for loop try all the possibilities? The loop should follow logical paths rather than iterate through each turn...

    I'd try an image processing forum. This forum is typically for Java-specific issues and there might not be that many people who've done this here. Sorry I couldn't help. Have you read some image processing books?

  • Path Finder in a 2D Grid Map With Different Terrain Types

         I have been thinking for a while on path finding game algoritms and I can up with one idea witch I want to publish. The goal of my project is when I have a 2 dimensional grid map where squares can have different movement cost, like in Civilization II, to find the shortest way from one point in the map to another. I've used the Breathed First Search Engine. If you are not familiar to this search engine it is better to read about it first because I am not fcusing on it and I assume that you now how it works. You can read about it at the book "Practical Artificial Intelligence Programming in Java" writen by Mark Watson, witch is freely distributed at www.markwatson.com.
         Actually the idea of this 2D grid path finder is to use a third dimension witch have a size equal to the highest movement cost among all terrain types. This helps solving the problem with the different movement cost of the squates. By adding this abstract third dimension it is posible to use the Breadth First Search Engine.
         I this example the movementcost of a terrain type is always the same, no matter from witch square to with are you going (like in Civilization II but I haven't included roads or railroads). For example if you want to go from one square A to another square B with movement cost X (A and B are attached) you must go "up stairs" in the third dimension X - 1 times and then move to square B. But when you step on square B you are again at the lowest floor. So if you want to come back to the previous square A and it have movement cost Y first you must go floor Y and then jump in square A. And now you are again at the lowest floor at square A. When you move from one square to another you go always at the lowest floor. This is the way I handle with different movement costs.
         When you find the path to the goal point it is in 3 dimensions. So you must just project it in the 2D map and that's all you have the shortest path.
         I am sure this is not the best way to code this search engine but this is just the first scratch with no optimisation and so on. If I make a 100x100 randomly generated map it takes on my configuration(400Mhz Pentium II CPU with ASUS P2B MotherBoard on 100 MHz and 256 MB SD RAM on 133 MHz but because of my MB on 100MHz) around 1000 miliseconds (1000 miliseconds = 1 second) to find the shortest path from (1, 1) to (100, 100) witch is pretty good compare to the goTo function in Civilization II witch does not finds the shortest path at all and have made hundrets of gamers angry. This is amazing that nowadays there are so many games with bad path finding.
         This project includes:
    1. The PathFinder class witch does the jub.
    2. The Map class witch has a generator for a random map in it.
    3. The class TerrainType, every square on the map is based on this class.
    4. The class TerrainTypes witch is the set of all terrain types used in the map.
    5. The class PathFinderTest witch just test the path finder.
    To test this project put all files in one directory and run PathFinderTest.java.
    Map.java:
    import java.util.Vector;
    import java.util.Random;
    //This class just creates a random map and keeps it. I will not comment on this.
    class Map {
      //here is kept the information about the terrain types placed in the map. Where
      //every terrain type has a specific movement cost.
      private int[][] terrain;
      public TerrainTypes terrainTypes;
      private int landMass;
      private int width;
      private int height;
      private int highestMovementCost;
      public Map(int aWidth, int aHeight) {
        width = aWidth;
        height = aHeight;
        terrainTypes = new TerrainTypes();
        highestMovementCost = terrainTypes.getHighestMovementCost();
        terrain = new int[width][height];
        landMass = 0;
        generateRandomMap();
      public void clearGoalAndStartLocFromWater(int sx, int sy, int gx, int gy) {
        terrain[gx][gy] = 0;
        terrain[sx][sy] = 0;
      private void expandWater() {
        int waterConstant = 40;
        int waterExpansion = 2;
        int[][] moreWater = new int[width][height];
        Random randomizer = new Random();
        for (int t = 0; waterExpansion > t; t++) {
          for (int i = 0; i < width; i++) {
            for (int j = 0; j < height; j++) {
              if (i + 1 >= 0 && j >= 0 && i + 1 < width && j < height) {
                if (terrain[i + 1][j] != 4) {
                  if (randomizer.nextInt(waterConstant) == 0)
                    moreWater[i + 1][j] = 1;
              if (i + 1 >= 0 && j - 1 >= 0 && i + 1 < width && j - 1 < height) {
                if (terrain[i + 1][j - 1] != 4) {
                  if (randomizer.nextInt(waterConstant) == 0)
                    moreWater[i + 1][j - 1] = 1;
              if (i >= 0 && j - 1 >= 0 && i < width && j - 1 < height) {
                if (terrain[i][j - 1] != 4) {
                  if (randomizer.nextInt(waterConstant) == 0)
                    moreWater[i][j - 1] = 1;
              if (i - 1 >= 0 && j - 1 >= 0 && i - 1 < width && j - 1 < height) {
                if (terrain[i - 1][j - 1] != 4) {
                  if (randomizer.nextInt(waterConstant) == 0)
                    moreWater[i - 1][j - 1] = 1;
              if (i - 1 >= 0 && j >= 0 && i - 1 < width && j < height) {
                if (terrain[i - 1][j] != 4) {
                  if (randomizer.nextInt(waterConstant) == 0)
                    moreWater[i - 1][j] = 1;
              if (i - 1 >= 0 && j + 1 >= 0 && i - 1 < width && j + 1 < height) {
                if (terrain[i - 1][j + 1] != 4) {
                  if (randomizer.nextInt(waterConstant) == 0)
                    moreWater[i - 1][j + 1] = 1;
              if (i >= 0 && j + 1 >= 0 && i < width && j + 1 < height) {
                if (terrain[i][j + 1] != 4) {
                  if (randomizer.nextInt(waterConstant) == 0)
                    moreWater[i][j + 1] = 1;
              if (i + 1 >= 0 && j + 1 >= 0 && i + 1 < width && j + 1 < height) {
                if (terrain[i + 1][j + 1] != 4) {
                  if (randomizer.nextInt(waterConstant) == 0)
                    moreWater[i + 1][j + 1] = 1;
        for (int i = 0; i < width; i++) {
          for (int j = 0; j < height; j++) {
            if (moreWater[i][j] == 1) {
              terrain[i][j] = 4;
      private void generateRandomMap() {
        Random randomizer = new Random();
        for (int i = 0; i < width; i++) {
          for (int j = 0; j < height; j++) {
            if (randomizer.nextInt(3) == 1)
              terrain[i][j] = 0;
            else if (randomizer.nextInt(2) == 1)
              terrain[i][j] = 1;
            else if (randomizer.nextInt(2) == 1)
              terrain[i][j] = 3;
            else if (randomizer.nextInt(2) == 1)
              terrain[i][j] = 2;
            else if (randomizer.nextInt(2) == 1)
              terrain[i][j] = 2;
            else if (randomizer.nextInt(2) == 1)
              terrain[i][j] = 1;
            else if (randomizer.nextInt(2) == 1)
              terrain[i][j] = 3;
            else
              terrain[i][j] = randomizer.nextInt(5);
        expandWater();
        for (int i = 0; i < width; i++) {
          for (int j = 0; j < height; j++) {
            if (terrain[i][j] != 0)
              landMass++;
      public int getMapHeight() {
        return height;
      public int getMapWidth() {
        return width;
      public int getSquareID(int x, int y) {
        return terrain[x][y];
      public int getSquareMovementCost(int x, int y) {
        return terrainTypes.getMovementCost(terrain[x][y]);
    }PathFinder.java:
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.util.Vector;
    public class PathFinder {
      private BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));
      //The array t3D[][] represents the 2D square map where t3D.leght = map width
      //and t3D[x].lenght = map width (-1 < x < t3D.leght). The third dimension
      //is refered to the square's movement cost, witch is definite by terrain.
      //The fourth dimension will be with lenght = 3. When running the search engine
      //(expanding the explored squares) this 3 values will keep the position of
      //the previous square in 3 dimension, witch are width, height and the maximum
      //movement cost among all squares.
      private int[][][][] squares3DReference;
      //Keeps information witch squares are visited.
      private boolean[][][] visitedSquares;
      private Map map;
      //this is the queue used in the Breathed First Seatch.
      private Vector queue3D;
      //Here is saved the shortest path
      private Vector path2D;
      private int highestMovementCost;
      public PathFinder(Map aMap) {
        map = aMap;
        queue3D = new Vector();
        path2D = new Vector();
        squares3DReference = new int[map.getMapWidth()][map.getMapHeight()][][];
        visitedSquares = new boolean[map.getMapWidth()][map.getMapHeight()][];
        highestMovementCost = map.terrainTypes.getHighestMovementCost();
        buildAbstract3DTerrain();
      private void buildAbstract3DTerrain() {
        for (int x = 0; x < map.getMapWidth(); x++) {
          for (int y = 0; y <map.getMapHeight(); y++) {
            int movementCost = map.terrainTypes.getMovementCost(map.getSquareID(x, y));
            if ( movementCost > 0) {
              visitedSquares[x][y] = new boolean[highestMovementCost];
              squares3DReference[x][y] = new int[highestMovementCost][3];
              for (int z = 0; z < highestMovementCost; z++) {
                for (int t = 0; t < 3; t++) {
                  squares3DReference[x][y][z][t] = -1;
      private boolean isMoveValid(int x, int y, int z, int x2, int y2, int z2) {
        if ( x < 0 || y < 0 || z < 0 || x2 < 0 || y2 < 0 || z2 < 0 || x >= map.getMapWidth() || y >= map.getMapHeight() || z >= highestMovementCost ||  x2 >= map.getMapWidth() || y2 >= map.getMapHeight() || z2 >= highestMovementCost)
          return false;
        if (map.terrainTypes.getMovementCost(map.getSquareID(x2, y2)) < 1)
          return false;
        if (visitedSquares[x2][y2][z2])
          return false;
        if (x == x2 && y == y2)
          return true;
        else {
          if (z == map.terrainTypes.getMovementCost(map.getSquareID(x2, y2)) - 1)
            return true;
          else
            return false;
      private void clearPreviousSearchData() {
        queue3D.clear();
        path2D.clear();
        for (int x = 0; x < map.getMapWidth(); x++) {
          for (int y = 0; y < map.getMapHeight(); y++) {
            if (squares3DReference[x][y] != null) {
              for (int z = 0; z < highestMovementCost; z++) {
                visitedSquares[x][y][z] = false;
                for (int t = 0; t < 3; t++) {
                  squares3DReference[x][y][z][t] = -1;
      private Vector copyPath2D() {
        Vector path = new Vector();
        for (int i = 0; i < path2D.size(); i++) {
          path.add(path2D.get(i));
        return path;
      public Vector findPath(int sX, int sY, int gX, int gY) {
        int head = 0;
        int tail = 0;
        int x = sX;
        int y = sY;
        int z = 0;
        visitedSquares[x][y][z] = true;
        mainLoop: {
          while (tail <= head) {
            int[][] moves = getPosibleMoves(x, y, z);
            for (int i = 0; i < 9; i++) {
              if (moves[i] != null) {
                squares3DReference[moves[0]][moves[i][1]][moves[i][2]][0] = x;
    squares3DReference[moves[i][0]][moves[i][1]][moves[i][2]][1] = y;
    squares3DReference[moves[i][0]][moves[i][1]][moves[i][2]][2] = z;
    queue3D.add(moves[i]);
    if (moves[i][0] == gX && moves[i][1] == gY) {
    break mainLoop;
    visitedSquares[moves[i][0]][moves[i][1]][moves[i][2]] = true;
    head++;
    if (queue3D.size() == 0 || queue3D.size() == tail)
    break mainLoop;
    int[] nextInQueue = ((int[]) queue3D.get(tail));
    x = nextInQueue[0];
    y = nextInQueue[1];
    z = nextInQueue[2];
    tail++;
    if (squares3DReference[gX][gY][0][0] == -1) {
    clearPreviousSearchData();
    return path2D;
    fillpath2D(sX, sY, gX, gY);
    Vector path = copyPath2D();
    clearPreviousSearchData();
    return path;
    private int[][] getPosibleMoves(int x, int y, int z) {
    int[][] moves = new int[9][3];
    if (isMoveValid(x, y, z, x + 1, y, 0)) {
    moves[0][0] = x + 1;
    moves[0][1] = y;
    moves[0][2] = 0;
    else
    moves[0] = null;
    if (isMoveValid(x, y, z, x + 1, y - 1, 0)) {
    moves[1][0] = x + 1;
    moves[1][1] = y - 1;
    moves[1][2] = 0;
    else
    moves[1] = null;
    if (isMoveValid(x, y, z, x, y - 1, 0)) {
    moves[2][0] = x;
    moves[2][1] = y - 1;
    moves[2][2] = 0;
    else
    moves[2] = null;
    if (isMoveValid(x, y, z, x - 1, y - 1, 0)) {
    moves[3][0] = x - 1;
    moves[3][1] = y - 1;
    moves[3][2] = 0;
    else
    moves[3] = null;
    if (isMoveValid(x, y, z, x - 1, y, 0)) {
    moves[4][0] = x - 1;
    moves[4][1] = y;
    moves[4][2] = 0;
    else
    moves[4] = null;
    if (isMoveValid(x, y, z, x - 1, y + 1, 0)) {
    moves[5][0] = x - 1;
    moves[5][1] = y + 1;
    moves[5][2] = 0;
    else
    moves[5] = null;
    if (isMoveValid(x, y, z, x, y + 1, 0)) {
    moves[6][0] = x;
    moves[6][1] = y + 1;
    moves[6][2] = 0;
    else
    moves[6] = null;
    if (isMoveValid(x, y, z, x + 1, y + 1, 0)) {
    moves[7][0] = x + 1;
    moves[7][1] = y + 1;
    moves[7][2] = 0;
    else
    moves[7] = null;
    if (isMoveValid(x, y, z, x, y, z + 1)) {
    moves[8][0] = x;
    moves[8][1] = y;
    moves[8][2] = z + 1;
    else
    moves[8] = null;
    return moves;
    private void fillpath2D(int sX, int sY, int gX, int gY) {
    int[] gLoc = {gX, gY};
    path2D.add(gLoc);
    int x = gX;
    int y = gY;
    int z = 0;
    while (x != sX || y != sY) {
    int x2 = squares3DReference[x][y][z][0];
    int y2 = squares3DReference[x][y][z][1];
    int z2 = squares3DReference[x][y][z][2];
    x = x2;
    y = y2;
    z = z2;
    if (z == 0) {
    int[] loc = {x, y};
    path2D.insertElementAt(loc, 0);
    PathFinderTest.java
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.util.Vector;
    public class PathFinderTest {
      static BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));
      static Map map;
      static int startX;
      static int startY;
      static int goalX;
      static int goalY;
      public static void main(String[] args) throws Exception {
        System.out.print("Enter map size.\nx = ");
        int width = Integer.parseInt(consoleReader.readLine());
        System.out.print("y = ");
        int height = Integer.parseInt(consoleReader.readLine());
        System.out.print("Enter strting location.\nx = ");
        startX = Integer.parseInt(consoleReader.readLine()) - 1;
        System.out.print("y = ");
        startY = Integer.parseInt(consoleReader.readLine()) - 1;
        System.out.print("Enter goal location.\nx = ");
        goalX = Integer.parseInt(consoleReader.readLine()) - 1;
        System.out.print("y = ");
        goalY = Integer.parseInt(consoleReader.readLine()) - 1;
        if (goalX < 0 || goalY < 0 || startX < 0 || startY < 0 || goalX >= width || goalY >= height || startX >= width || startY >= height) {
          System.out.println("Invalid parameters found. Program will exit");
          System.exit(0);
        map = new Map(width, height);
        map.clearGoalAndStartLocFromWater(startX, startY, goalX, goalY);
        printSolution(new Vector());
        PathFinder pathFinder = new PathFinder(map);
        long before = System.currentTimeMillis();
        Vector path = pathFinder.findPath(startX, startY, goalX, goalY);
        long after = System.currentTimeMillis();
        long time = after - before;
        printSolution(path);
        if (path.size() == 0)
          System.out.println("No path found.");
        else
          System.out.println("Path found.");
        System.out.println("Finding the path took " + time + " milliseconds");
      static void printSolution(Vector path) {
        boolean[][] pathOnMap = new boolean[map.getMapWidth()][map.getMapHeight()];
        for (int i = 0; path.size() > i; i++) {
          int[] move = (int[]) path.get(i);
          pathOnMap[move[0]][move[1]] = true;
        for (int y = 0; y < map.getMapHeight(); y++) {
          for (int x = 0; x < map.getMapWidth(); x++) {
            System.out.print(" ");
            if (pathOnMap[x][y] == false)
              System.out.print(" ");
            else
              System.out.print("0");
            if (x == startX && y == startY)
              System.out.print("S");
            else if (x == goalX && y == goalY)
              System.out.print("G");
            else
              System.out.print(map.terrainTypes.getNameFirstLetter(map.getSquareID(x, y)));
          System.out.println();
        System.out.println();
    }TerrainType.java:
    public class TerrainType {
      private int movementCost;
      private String name;
      TerrainType(int aMovementCost, String aName) {
        movementCost = aMovementCost;
        name = aName;
      public int getMovementCost() {
        return movementCost;
      public String getName() {
        return name;
      public String getNameFirstLetter() {
        return name.substring(0, 1).toUpperCase();
    }TerrainTypes.java:
    import java.util.Vector;
    public class TerrainTypes {
      //Here are saved the terrain types with the map has. ElementAt 'i' in
      //setOfTypes is represented by the number in Map.terrain[x][y] witch is
      //equal to i, were x, y are random integer as soon as they do not
      //throw ArrayIndexOutOfBoundsException. Actually this is a coding to know
      //a specific square in the map to witch terrain type is refered in setOfTypes.
      private Vector setOfTypes;
      public TerrainTypes() {
        setOfTypes = new Vector();
        setOfTypes.add(new TerrainType(1, "Plains"));
        setOfTypes.add(new TerrainType(2, "Forst"));
        setOfTypes.add(new TerrainType(3, "Jungle"));
        setOfTypes.add(new TerrainType(4, "Mountain"));
        setOfTypes.add(new TerrainType(-1, "X"));
      public int getMovementCost(int i) {
        return ((TerrainType) setOfTypes.get(i)).getMovementCost();
      public String getName(int i) {
        return ((TerrainType) setOfTypes.get(i)).getName();
      public String getNameFirstLetter(int i) {
        return ((TerrainType) setOfTypes.get(i)).getNameFirstLetter();
      public int getHighestMovementCost() {
        int max = 1;
        for (int i = 0; setOfTypes.size() > i; i++) {
          int movementCost = ((TerrainType) setOfTypes.get(i)).getMovementCost();
          if ( movementCost > 0) {
            if (max < movementCost)
              max = movementCost;
        return max;
    }I hope this program will be helpful.
    Sogartar

    Why is such a smart guy like you not using A*
    It is a general known algorithm which will find the
    optimal solution in a finite search-space (within a minimal time).
    The calculation time for the A* algorithm is influenced by two parameters:
    1 - cumulative cost
    2 - minimal expected additional cost
    The calculation of these two costs has a great influence on the
    solution.
    I think the actual problems most games experience with shortest path calculatoin are
    1 - very little time to spent calculating the shortest path
    The quickest solution might be the best for the game
    If your solution takes 1 second for the calculation of a path for one element on the board (100x100)
    What would it take for the game to calculate the path for all elements controlled by the computer ??
    If the computer controls two players which each have 50 elements to control, it would take forever...
    Don't even consider the usage of a larger board (200x200 would take 4 seconds/element when
    algorithm has complexity O(n))
    2 - low priority.
    Users tend to forgive a bad shortest path-algorithm most of the time,
    but not a bad display, bad pictures,...
    This is why most shortest-path algorithms within games were
    developed as a depth first search,
    within some earlier games this was even developed as
    a rule which went straight to the endlocation and
    takes a right/left turn when blocked by water/wall/...
    So the actual steps you should take are:
    1 - develop a normal breath-first search (to get going)
    2 - develop a normal depth-first search (to compare speed and solution with)
    3 - develop a normal dijkstra algorithm (sometimes called A)
    4 - develop a best first algorithm (called A*)
    5 - develop other AI-algorithms building upon A* (tabu-search, limited memory A*,...)
    6 - develop some other AI-algorithms (Genetic Algorithms, Simulated Annealing,...)
    7 - compare and tweak/change all search-algorithms for
    7 - a - size of maps (small versus huge)
    7 - b - optimality of the solution
    7 - c - actual usage for your game
    8 - !!! very important !!!
    Share the developed path algorithms along with remarks about speed, map-size,...
    with the rest of us. I would be very interested in such library.
    kind regards,

  • Finder question: "right size this column"

    Finder question: how do I get the "right size this column" feature to work automatically each time I open Finder or move between columns?  The column widths reset each time I close/open Finder or move between columns.

    Finder columns:
    Option dragging the resize widget || will resize all columns, wide or narrow, all the same and seems to stick.
    Otherwise:
    Double clicking on the resize widget || will expand that column to show all.
    Option double click on the resize widget || will temporarily resize all columns to the largest width needed..
    The last option may help but it isn't permanent.
    S.

  • Floyds Algorithm for path finding

    I'm currently trying to figure out which path finding algorithm to use in my game. It seems most people prefer A* and I don't quite get it.
    I must be missing something because as I see it Floyds Algorithm is superior in many respects.
    1) You are guaranteed to get an optimal rout.
    2) It's all precomputed, so you just have to look up the rout in a matrix.
    What am I missing ?
    Kim

    A* is guaranteed to find the shortest path, as long as the function you use for the heuristic is an underestimate of the actual distance. For example, say you have a square grid where some tiles are blocked by obstacles while others aren't; then you can use the Euclidean distance (sqrt(deltaX^2 + deltaY^2)) between two tiles as your heuristic, since real paths will be as long as that, and A* will find the shortest path. Even if you use an overestimate for a heuristic, A* will find some path if a path exists; it will find it faster in fact, but it won't necessarily be the best path. Often people use overestimates on purpose in practice because this saves a lot of time and still finds pretty good paths.
    Floyd's algorithm has a worse running-time than A* because A* can get "hints" of which direction to go towards while Floyd's essentially checks all possibilities. It's true that you can use it to obtain the all-pairs shortest-paths matrix however, in which case it is certainly faster than using A* on every pair of points to find the path between them (since the heuristic only gives distance to one goal). The problem is that in most games the world changes at run-time however - for example someone builds a building or chops down a tree, or someone blocks a door, or there are people in the AI object's way. Also, sometimes you try to find the path that is not shortest but also "safest" in some way - increase costs of tiles where you've seen a lot of enemy activity for example in order to avoid them, and this information changes at runtime. Recalculating the all-pairs shortest-paths matrix gets expensive then, especially in the case of moving obstacles like human players. If you have a game where the obstacles are fixed however and the map size isn't so big that an N^3 algorithm (Floyd) wouldn't do it, then do precalculate the paths.

  • Help on path finding

    Hello everyone!
    Help me please!
    Have you ever played games like Baldur's gate or Diablo or classic adventure games (like Monkey island)?
    What I'm saying is:
    I'm trying to implement a way to move my character, on a 2D space, to the point I clicked on.
    If there is no obstacle between the start and the finish points, I can make it work pretty easily (I just let the charachter walk the straight line connecting the points).
    The problem is when I introduce obstacles.
    I'm trying to implement the A* algorithm for the path finding process.
    Since the character and the obstacles lay on a 2D plane not divided into tiles or any sort of sub-division, it is quite hard to calculate a path.
    What I thought of doing is:
    when I click on a destination point, I create a 2D grid surrounding the character, at its actual position, and the destination point.
    The intersections between the horizontal and the vertical lines of this grid, will be the possible nodes of the path to the destination. (I hope it's clear).
    The A* will calculate the best path among these nodes, considering whether a node is reachable (i.e. not overlapping an obstacle) or not.
    I still haven't implemented it, so it's just an idea, and I don't even know if it works!
    Is it possible there is no other way of doing that?
    How do the games I mentioned above work?
    My problem is finding a way to determine the possible nodes (2D points on the 2D plane) for the A* algorithm to work on.
    Please help, I'm stuck.
    Any suggestion?
    Thank you!
    P.S: If you need me to make it more clear, I'll give it a try!

    So far as I've tested it they haven't gotten stuck.
    The best way I can think of to do it is with the Line2D.Double class.
    - I draw a line between me and the enemy
    - create two lines that are equal to that first line
    - rotate the first line, from the enemy, to the left
    - rotate the first line, from the enemy, to the right
    - if both still intersect the obstacle, I rotate the two again
    - if one of them no longer intersects the obstacle, that new line becomes my path
    Once the clear path is found, I can use the endpoint of that line as the destination, rather than saying that MY coordinates are the destination. It takes a lot of math figuring so it gets messy written out, but in words it's very clean :)
    For simplicity you could try:
    - if he hits an obstacle do the following:
    - draw a line between the entity and the center of the obstacle
    - if you're on the left side of that line, make him turn left 90 degrees
    - if you're on the right side, turn right 90 degrees
    Based on how you're creating your obstacles you could think further how you want to do it, like tell them to move in that direction a set distance, that sort of thing.
    Or you could give them set paths to follow, that's another solution, and just have them be able to aim at you freely to fire, provided that's how they attack.

  • Help Using Path Finding Code

    Hi all.
    I found some open source code which implements the A Star algorithm to achieve path finding for the purpose of navigating something in a game (although it could really be used for anything). Problem is, I can't get it to work. I've e-mailed the author but no reply yet so I was hoping someone could shed some light on my situation.
    The code is meant to find a path on a 2 dimensional grid filled with obstacles using the following methods:
    PathFinder star = new PathFinder(grid);
    Path p = star.findShortest(startRow,startCol,goalRow,goalCol);
    I've made a simple Test class with a small 2D array but when I compile the code I recieve the error:
    Incompatible types.
    Found: int.
    Required: Test.Path
    on Path p = star.findShortest(1,1,2,2);
    I don't understand this error at all. The findShortest method takes 4 integers and I'm passing it 4 integers! Any ideas what this error means?
    Here's my Test class:
    import java.util.*;
    import javax.swing.plaf.basic.*;
    import java.awt.event.*;
    import javax.swing.*;
    import java.io.*;
    import javax.swing.filechooser.*;
    import java.util.Random;
    public class Test
            public static void main(String args[])
                    Test test = new Test();
                    test.run();
           public final static class Path
                    /** 2 for down, 0 is up, 1 is right and 3 is left */
                    public int giveMove() {
                        if (size() < 2)
                            return -1;
                        Position last = (Position)positions.get(size() - 1);
                        Position forlast = (Position)positions.get(size() - 2);
                        if (forlast.col - last.col == 1)
                            return 2; //down
                        else if (forlast.col - last.col == -1)
                            return 0; //up
                        else if (forlast.row - last.row == 1)
                            return 1;//right
                        else if (forlast.row - last.row == -1)
                            return 3; //left
                        return -1;
                    /** list of positions */
                    public List positions;
                    public int getCost() { return positions.size() - 1; }
                    public int size() { return positions.size(); }
                    public void add(Object o) { positions.add(o); }
                    /** add (r,c) to the path */
                    public void add(int r, int c) {
                        positions.add(new Position(r,c));
                    /** get first position */
                    public Position head() { return (Position) positions.get(0); }
                    public Path(ArrayList positions) { this.positions = positions; }
                    public Path(Position initial) {
                        positions = new ArrayList(1);
                        positions.add(initial);
                    public Path(int cap) { positions = new ArrayList(cap); }
                    public void set(Position front, Path old) {
                        positions.add(front);
                        Iterator i = old.positions.iterator();
                        while (i.hasNext())
                            positions.add(i.next());
            /** position on the grid */
           public static final  class Position
                    public int row, col;
                    public Position(int row, int col) {
                        this.row = row; this.col = col;
            public void run()
                    System.out.println("Test");
                    PathFinder star = new PathFinder(grid);
                    for(int counter = 0; counter < grid.length; counter++)
                            for (int j=0; j < grid[counter].length; j++)
                                    grid[counter][j] = 0;
                    Path p = star.findShortest(1, 1, 2, 2);
         private static int[][] grid = new int[2][2];    
    } Here's the PathFinder class I downloaded:
    import java.util.*;
    import javax.swing.plaf.basic.*;
    import java.awt.event.*;
    import javax.swing.*;
    import java.io.*;
    import javax.swing.filechooser.*;
    import java.util.Random;
    public final class PathFinder {
        /** the map grid to look on */
        private final int [][] grid;
        /** keep distances to each position here */
        private final int [][] distances;
        /** is gridposition (r, c) empty (empty is -1) ? */
        private boolean isEmpty(int r, int c) {
            return grid[r][c] == -1 ;
        /** pathfinder for grid */
        public PathFinder(int[][] grid) {
            this.grid = grid;
            this.distances = new int [grid.length][grid.length];
        /** clear distances */
        private void clear() {
            for (int i = 0 ; i < distances.length ; i++)
                for (int j = 0 ; j < distances.length ; j++)
    distances[i][j] = Integer.MAX_VALUE;
    /** position on the grid */
    public final static class Position {
    public int row, col;
    public Position(int row, int col) {
    this.row = row; this.col = col;
    /** path from start to a certain position */
    public final static class Path {
    /** 2 for down, 0 is up, 1 is right and 3 is left */
    public int giveMove() {
    if (size() < 2)
    return -1;
    Position last = (Position)positions.get(size() - 1);
    Position forlast = (Position)positions.get(size() - 2);
    if (forlast.col - last.col == 1)
    return 2; //down
    else if (forlast.col - last.col == -1)
    return 0; //up
    else if (forlast.row - last.row == 1)
    return 1;//right
    else if (forlast.row - last.row == -1)
    return 3; //left
    return -1;
    /** list of positions */
    public List positions;
    public int getCost() { return positions.size() - 1; }
    public int size() { return positions.size(); }
    public void add(Object o) { positions.add(o); }
    /** add (r,c) to the path */
    public void add(int r, int c) {
    positions.add(new Position(r,c));
    /** get first position */
    public Position head() { return (Position) positions.get(0); }
    public Path(ArrayList positions) { this.positions = positions; }
    public Path(Position initial) {
    positions = new ArrayList(1);
    positions.add(initial);
    public Path(int cap) { positions = new ArrayList(cap); }
    public void set(Position front, Path old) {
    positions.add(front);
    Iterator i = old.positions.iterator();
    while (i.hasNext())
    positions.add(i.next());
    /** gives the move to take for the shortest path from startRow to startCol
    * 0 up, 1 right, 2 down, 3 left
    * -1 if no move possible
    public final int findShortest
    (int startRow, int startCol, int goalRow, int goalCol) {
    clear();
    Position initial = new Position(startRow, startCol);
    //LinkedList list = new LinkedList();
    Position goal = new Position(goalRow, goalCol);
    BinaireHoop list = new BinaireHoop(200, new Path(goal), goal);
    list.add(new Path(initial));
    Position [] successors = new Position[4];
    int trie = 0;
    for ( ; ! list.isEmpty() && trie < 10000 ; trie++) {
    Path first = (Path) list.remove();
    Position firstPos = first.head();
    int r = firstPos.row; int c = firstPos.col;
    if (r == goalRow && c == goalCol) {  //goal found !             
    return first.giveMove();
    } else {
    int successorsCount = 0;
    if (isEmpty(r-1,c)) {
    successors[successorsCount++]
    = new Position(r-1, c);
    if (isEmpty(r+1,c)) {
    successors[successorsCount++]
    = new Position(r+1, c);
    if (isEmpty(r,c-1)) {
    successors[successorsCount++]
    = new Position(r, c-1);
    if (isEmpty(r,c+1)) {
    successors[successorsCount++]
    = new Position(r, c+1);
    while (successorsCount-- > 0) {
    Position succ = successors[successorsCount];
    int newPathCost = first.getCost() + 1;
    //add newPath if shorter than other path to this position
    if (distances[succ.row][succ.col] > newPathCost) { //shorter
    distances[succ.row][succ.col] = newPathCost;
    Path newPath = new Path(newPathCost + 1);
    newPath.set(succ, first);
    //add path to binary heap
    list.add(newPath);
    } // else longer: discard
    return -1;
    There's also a BinaireHoop class which the PathFinder class uses. I'll post that code if anyone thinks it's relevant but the error appears to be soley on my implementation. The Path and Position and just small subclass which for the sake of quickness I just placed into my Test class too instead of into a new class to themselves.
    Any thoughts appreciated! I would really like to get this working =)
    Thanks.

    Thanks for your reply. Doh, totally missed that one =)
    Anyway, I got the code working but it's still very buggy. I think this must just be a problem with the PathFinder class I downloaded.
    I create a 2D array
          int[][] array = {       
                                  {-1, -1, -1, -1, -1, -1, -1, -1},          
                                  {-1, -1, -1, -1, -1, -1, -1, -1},
                                  {-1, -1, -1, -1, -1, -1, -1, -1},
                                  {-1, -1, -1, -1, -1, -1, -1, -1},
                                  {-1, -1, -1, -1, -1, -1, -1, -1},
                                  {-1, -1, -1, -1, -1, -1, -1, -1},
                                  {-1, -1, -1, -1, -1, -1, -1, -1},
                                  {-1, -1, -1, -1, -1, -1, -1, -1}
                          };and choose starting and goal coordinates
    int p = star.findShortest(1, 1, 2, 2);The PathFinder will generate the coordinates to move to (I just stuck it all in a loop and updated the starting coordinates as appropriate to lead me to the goal). This is great!
    However, there seem to be a lot of bugs when I introduce "occupied squares". Basically, -1 in the array means that that square is empty whereas anything else means its full and the path finder should, in theory, generate a path around these obstacles. This isn't working correctly though.
    Sometimes a path wil be found around the obstacle, sometimes the path will go straight through it, and many times it just throws an array index out of bounds exception error!
    Anyone got any ideas? Or does anyone have any examples of a working path finder? =)
    Cheers

  • Can't mount drive? Finder or Path Finder

    By pressing Apple K or going Go, Connect servers from finder I am unable to make connects to network resoureces. I've shown this to several Apple employees at the Tech Talk in Chicago. None of them was able to figure it out.
    You click on the Connect button and its like the button isn't even there.
    I've tried installing Path Finder since it too has something like the Apple K screen. But it appears to have the same problem. I looked at my console log and am getting this each time I try to map a drive.
    "FSMountServerVolumeAsync: -36, ioErr, I/O error(bummers)"
    This happen with any user logged into the system.

    Follow my posts this is a serious problem. I guess I'm the only one getting this and can't believe that Apples intention was for my G4 667 make my MBP 2.16 chug away as if it were an Apple II. I guess I'm just the lucky one who gets to experience all the issues. It is a "generic" I/O error as it does not pertain to an individual item and can effect many.
    It is a kernel error in this I/O Kit. Please report it to Apple Feedback. As this very same I/O is preventing the normal process of Bug reporter.
    FWIW

  • Trash Icon in Path Finder?

    Where is the trash icon in Path Finder located? I want to customize it with a different image. thanks.

    It's much easier than going into the path. Simply follow these instructions:
    http://support.apple.com/kb/HT2493
    However in step 1 simply choose the Trash Icon in your dock and that should be fine.
    Regards,
    Roger

  • Massive mp3 file(path) move question

    Alright so I recently purchased a 2 terabyte network server for my home network. The purpose of this is to move all my music, movies, photos, etc. to the network drive in order to clear out all that space on my laptop's drive. At this point and time, I've only copied all my music to network drive. Figure the next step would be is to delete all my music off my local drive. But then got a little worried about iTunes. Now when I delete my music off my local drive, iTunes will be looking for the mp3s via the originated file path. Obviously the file is not going to be there. So when this happens in iTunes, the circularly enclosed exclamation point pops up and iTunes wants you to manually and find the file for it to play. So essentially my question is... Since I'm doing this on a large scale, Is there an easier way to get this done?
    Best solution I was able to come up with was to delete all the songs in iTunes and re-drag all the music back in there. BUT... the problem I have with that a good majority of the music's album artwork were manually put in by me (kind of uh...yeah about seeing the album artwork on the screen when I'm listening to my iPod). So I don't want lose all that it. Help! Kind of long, I know. Appreciate any help or suggestions.

    Thanks for responding Brian -
    The message I get is Error Code -2147467259
    Conn Execute.vi->InsertIntoFrom.vi<ERR>Exception occured in Microsoft OLE DB Provider for ODBC Drivers: [Microsoft][ODBC Microsoft Access Driver] Could not find file 'C:\Project\APDSS\DataBase\ExternalInterface.mdb'. in Conn Execute.vi->InsertIntoFrom.vi
    When my query looks like
    INSERT INTO InternalInterface SELECT Field1, Field2 FROM ExternalInterface.ExternalTable WHERE Id = '065649-101-750';

Maybe you are looking for