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.

Similar Messages

  • Path finding algorithm for bomberman

    Hi everyone,
    I have another question regarding the bomberman game im making. Everything is just about done except for adding some decent sound and making my monsters a little bit more intelligent in the way they find me. Im using a 2d array as the map so ive just done some basic logic (ie: if im above the monster then it will move up, if im below then it will move down. If it gets stuck then try another direction. This works fine but there are times when it becomes clear that the monsters are complete idiots!!
    If I have the time or effort I might implement a full state-space search using breadth-first although to be honest I was hoping there might be a simpler means. Im not looking for my monsters to be insanely intelligent, but if they look as if they know what they are doing ill be happy.
    I would appreciate any ideas you have. Or is a full state-space search the only way to go?
    R

    heh, your zones idea is called "waypoints". Or is it me misunderstanding you?
    Well, way points is definetly the best way to go (fastest) as all the paths from one tile to another are pre-computed into a grid and thus minimal computation is required during the actual game.
    This is ofcourse very game dependant. I.e. for RPG games, A*/Dijkstras is the way to go as the terrain is merly computed from an image, i.e high/low parts and its far far easier using a realtime pathfinding algo than a pre-computed one.
    However, for games such as yours and many FPS games, having a precomputed grid for each room (in your case, level) is much easier. I.e. each block can be a waypoint. Btw, im sure you can make this pre-computation automatic by running some sort of program over your level to generate all of the way-points instead of you doing them byhand for each level. I think thats what the game Hollow does (Its an FPS).
    Hope this helps,
    -Digiwired

  • 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.

  • 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,

  • 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

  • TS3510 I only have one apple ID and facetime has worked with it before, but now I get the message "Unable to verify email because it is already in use". I have looked ofr a solution but can't find one. can anyone help please?

    I only have one apple ID and facetime has worked with it before, but now I get the message "Unable to verify email because it is already in use". I have looked ofr a solution but can't find one. can anyone help please?

    I spoke with Apple Support this morning and they believe anything MobileMe related is due to the conversion over to iCloud that's taking place.
    As for other email clients, check with your host to see if settings have changed on their end. I use inmotionhosting.com and over the weekend the updated their outgoing requirements so that a password authentication is now needed.
    Hope that helps get some on the right path to resolving their issues!

  • How to find good games/apps in the store besides the public reviews?

    Hi all, I'm trying to find good games/apps in the store to put on my 32gig touch. I know about the reviews for the games/apps but with so many negative comments for some, for example F***G c**p, reboots the ipod touch every time I play it or run it for apps (insert Maker's name ere) want a refund don't download & giving it 1 star & the list just goes on, out of the one's I've thought I would either buy or download (for the free one's) I've not even botherd as I think to myself. With so many negative comment's the app/game must be rubbish. Doesn't apple review the comments put on the games/apps reviews?. So is there another way to find out what is good/bad in the app store besides trawling though 95% of negative comments? cheers
    Message was edited by: dj-toonz

    I tried to follow the instructions using iphone 5. When you get to step 5,  swipe your finger over the apps. It won't work. Does anyone have iphone 5 and try to hide unwanted apps sucessuflly. Please share with us. Thanks

  • I can't find any game in The last of Us

    I checked tiwce, & I'm sure it's not from my side. If it's really my side then, why I can play in on it at PS3?

    I can't find any game in the last of us? this is a repeating issue from last Monday. My friends can play normal but i can not!!! What is going on? Is it because of the last up date or what? I'm wondering why there is no up grading in some game server at all time? I want to play now? Do you think I'm paying $65 per year to be stand by quarter of it because of your problems? I want a solution, otherwise, there is no meaning to renew my membership.

  • In the navigation Toolbar following the yellow bookmark star you find a small blue triangle. When you click it a number of bookmarks show up. How can I add new booksmark to be displayed out of my unsorted bookmarks? Thanks.

    Dear Sir, Mam,
    In the navigation toolbar on the right side of the bookmark yellow star you find a small blue triangle. When you click it, some of the selected bookmarks show up and can be called up immediately.
    I have deleted some without problem, but I could not add new ones. I would like to have there at least 10 items.
    Please explain how to add new bookmarked items to this shortcut list. Thank you, sincerely Th. Brandt. [email protected]

    Is that the Bookmarks Menu button ?
    *https://support.mozilla.org/kb/how-do-i-use-bookmarks
    *https://support.mozilla.org/kb/common-questions-after-updating-firefox
    *http://kb.mozillazine.org/Sorting_and_rearranging_bookmarks_-_Firefox
    *https://support.mozilla.org/kb/Sorting+bookmarks

  • BGP Best Path Selection Algorithm

    How is the administrative distance positioned in the bgp route decision ?
    i.e If a route is learned from iBGP with higher "local prefernece" and eBGP with lower "local prefernece" - which path will be installed in the routing table
    the path learned from eBGP or the path with higer local prefernce ?

    For your scenario the path with the higher local pref will be installed in the routing table althogh its ibgp.
    if a router recieves the same prefix from 2 neighbors 1 from ibgp and the other from ebgp
    the router will compare them with the bgp path selection algorithm
    the one that wins will be installed in the routing table with the admin distance of the kind of route it is so if the ibgp route won the path selection you will see in the routing table the admin distance of 200,if the ebgp route won you'll see 20 in the admin distance.
    so remember the ibgp/ebgp comparision is the 9th in the path selection algorithm so an ibgp route can win the path selection by (local pref weight....)
    and if the ibgp won then you'll see the ibgp admin dstance in your routing tables.

  • Where can i find the games tab for my ipod 3rd generation on itunes 10?

    i am trying to get games on my ipod 3rd generation but i cannot find the games tab!

    iPod ClickWheel Games were removed from the store some time ago now and are no longer available.
    tt2

  • Where do I find the game I purchased off i-tunes on my i-pod?

    I downloaded Ms. Pac Man from I-tunes onto my ipod and I can't find the game anywhere. Any suggestions where to look?

    I have the same problem, I cannot put my game onto ipod but shows up in the main game directory. If I manually sync, does that mean that my other folders will automatically be updated and changed?
    Help please!

  • HT4314 i can't find the game center app on my macbook pro retina 13 inch. how can i install it again?

    i can't find the game center app on my macbook pro retina 13 inch. how can i install it again?

    i tried it but not satisfactory results...
    it looks like it is not installed on my mac
    thanks anyway for the fast response

Maybe you are looking for

  • Flash player crashes and other issues.

    My wife is having issues with Zynga Bingo and Flashplayer.  Over the past 3 days (starting approx 20 July) she will be able to play for a bit and then it will just lock up on her.  Now it won't run at all, Flashplayer keeps giving an error stating it

  • Can Second Monitor Play VLC Videos?

    I use a mid 2012 Mac Pro; run Mavericks.  I plan to use my TV as a second monitor.  I know that I have to use AppleTV to connect wirelessly to my TV.  Will AppleTV allow me to play "VLC" videos?

  • Touch screen failure

    I bought my Xperia z3 in December in Orlando but I live in Brazil.  And when I came back I detected a failure on a lane of my touch screen. I already contacted the Brazilian technical support but they can do nothing because the warranty is not intern

  • Essbase Error 1016016

    Hi all,<BR><BR>Here's another error I can't find any information on. I received the error while running a script in the MaxL shell in an aggregate storage cube. I was using the "export database to data file" statement. The report is being created, bu

  • Adobe flash videos now only show up/play once fully loaded.

    All online flash related videos used to start playing once I hit play. They would continue to load as they played. This changed a month or so ago. Now after I hit play I just get the blank screen UNTIL the video fully loads. Then it plays. I thought