A* algorithm: need help fixing path that come in contact with obstacle

I am using A* as a pathfinding technique for my AI; it works fine until it gets close to an obstacle (in my case rocks). Right now it just continues the loop if it finds a neighbor thats a rock. It should not actually do this. It should check it.

Allowed Moves: FORWARD,LEFT,RIGHT (LEFT & RIGHT at diagonals) turns are basically two phases: FORWARD, turn face then FORWARD (counts as one move with no additional cost)

The AI should know to turn left or right on the rock in the direction of the goal while also taking other rocks into account.

The line that checks for rocks is: if(at == 1 || at == 2) continue;

I guess you could use the neighborlist to check the sides of the ship.

However it shouldn’t always check it. Only when it comes in contact with a rock

Scenario 1: (ship should turn left (one move) once then continue on path) enter image description here

Scenario 2: (ship should either turn left or right twice (two moves) to unblock itself) enter image description here

Scenario 3: (ship should turn left or right depending on which path is shorter: doing two lefts will hit rock twice but distance is shorter than if it went right by 1 tile)

enter image description here

In each of these scenarios the face of the ship is the only thing that changes; unless its a forward move into the rock then there is no change. If right/left were used in any other situation (regular tiles) it would change position also.

public class AStarSearch {          private ServerContext context;     private List<AStarNode> openList;     private List<AStarNode> closedList;          private double ORTHOGONAL_COST = 1.0;     private double DIAGONAL_COST = ORTHOGONAL_COST * Math.sqrt(2.0);          public AStarSearch(ServerContext context) {         this.context = context;     }      private Comparator<AStarNode> nodeSorter = new Comparator<AStarNode>() {          @Override         public int compare(AStarNode n0, AStarNode n1) {             if(n1.fCost < n0.fCost) return 1;             if(n1.fCost > n0.fCost) return -1;             return 0;         }              };      public List<AStarNode> findPath(Player bot, Position goal){         openList = new ArrayList<AStarNode>();         closedList = new ArrayList<AStarNode>();         List<AStarNode> neighbors = new ArrayList<AStarNode>();         AStarNode current = new AStarNode(bot, bot.getFace(), MoveType.NONE, null, 0, bot.distance(goal));         openList.add(current);          while(openList.size() > 0) {             Collections.sort(openList, nodeSorter);             current = openList.get(0);             if(current.position.equals(goal)) {                 List<AStarNode> path = new ArrayList<AStarNode>();                 while(current.parent != null) {                     path.add(current);                     current = current.parent;                 }                 openList.clear();                 closedList.clear();                 Collections.reverse(path);                 return path;             }             openList.remove(current);             closedList.add(current);                          int x = current.position.getX();             int y = current.position.getY();             switch (current.face) {                 case NORTH:                     neighbors.add(new AStarNode(new Position(x, y), VesselFace.NORTH, MoveType.NONE,current,0,0));                     neighbors.add(new AStarNode(new Position(x, y+1), VesselFace.NORTH, MoveType.FORWARD,current,0,0));                     neighbors.add(new AStarNode(new Position(x-1, y+1), VesselFace.WEST, MoveType.LEFT,current,0,0));                     neighbors.add(new AStarNode(new Position(x+1, y+1), VesselFace.EAST, MoveType.RIGHT,current,0,0));                     break;                 case EAST:                     neighbors.add(new AStarNode(new Position(x, y), VesselFace.EAST, MoveType.NONE,current,0,0));                     neighbors.add(new AStarNode(new Position(x+1, y), VesselFace.EAST, MoveType.FORWARD,current,0,0));                     neighbors.add(new AStarNode(new Position(x+1, y+1), VesselFace.NORTH, MoveType.LEFT,current,0,0));                     neighbors.add(new AStarNode(new Position(x+1, y-1), VesselFace.SOUTH, MoveType.RIGHT,current,0,0));                     break;                 case SOUTH:                     neighbors.add(new AStarNode(new Position(x, y), VesselFace.SOUTH, MoveType.NONE,current,0,0));                     neighbors.add(new AStarNode(new Position(x, y-1), VesselFace.SOUTH, MoveType.FORWARD,current,0,0));                     neighbors.add(new AStarNode(new Position(x-1, y-1), VesselFace.WEST, MoveType.RIGHT,current,0,0));                     neighbors.add(new AStarNode(new Position(x+1, y-1), VesselFace.EAST, MoveType.LEFT,current,0,0));                     break;                 case WEST:                     neighbors.add(new AStarNode(new Position(x, y), VesselFace.WEST, MoveType.NONE,current,0,0));                     neighbors.add(new AStarNode(new Position(x-1, y), VesselFace.WEST, MoveType.FORWARD,current,0,0));                     neighbors.add(new AStarNode(new Position(x-1, y+1), VesselFace.NORTH, MoveType.RIGHT,current,0,0));                     neighbors.add(new AStarNode(new Position(x-1, y-1), VesselFace.SOUTH, MoveType.LEFT,current,0,0));                     break;             }             for(AStarNode neighborNode : neighbors) {                 // Compute the cost to get *to* the action tile.                 double costToReach = current.position.distance(neighborNode.position);                  int at = context.getMap().getTile(neighborNode.position.getX(), neighborNode.position.getY());                 if(at == 1 || at == 2) continue; // this is the line where it checks if tile is rock or not                  double gCost = current.gCost + costToReach;                 double hCost = heuristicDistance(neighborNode.position,goal);                 AStarNode node = new AStarNode(neighborNode.position, neighborNode.face,neighborNode.move, current, gCost, hCost);                 if(positionInList(closedList, neighborNode.position) && gCost >= node.gCost) continue;                 if(!positionInList(openList, neighborNode.position) || gCost < node.gCost) openList.add(node);             }         }         closedList.clear();         return null;     }          private double getActionCost(Position node, int currentTile) {         if(currentTile > 3 && currentTile < 11) {             return 0.2;         }else {             return 1;            }     }      private double heuristicDistance(Position current, Position goal) {         int xDifference = Math.abs(goal.getX() - current.getX());         int yDifference = Math.abs(goal.getY() - current.getY());          int diagonal = Math.min(xDifference, yDifference);         int orthogonal = xDifference + yDifference - 2 * diagonal;          return orthogonal * ORTHOGONAL_COST + diagonal * DIAGONAL_COST;     }          private boolean positionInList(List<AStarNode> list, Position position) {         for(AStarNode n : list) {             if(n.position.equals(position)) return true;         }         return false;     }  } 

AStarNode:

public class AStarNode {      public Position position;     public VesselFace face;     public MoveType move;     public AStarNode parent;     public double fCost, gCost, hCost;          public AStarNode(Position position, VesselFace face, MoveType move, AStarNode parent, double gCost, double hCost) {         this.position = position;         this.face = face;         this.move = move;         this.parent = parent;         this.gCost = gCost;         this.hCost = hCost;         this.fCost = this.gCost + this.hCost;     }    }   

There will be no additional cost of running into a rock as long as its a shorter route. Also, if a ship tries to turn left or right from its current position; but there is a rock at that tile it will move up one tile and changes its direction.

The overall question/goal: How do I fix my current code to account for these situations; please provide an implementation or instructions.

Where did the ability “Paper cut” come from?

One of the players in my group uses PCGen to make her sheets, and she seems to have accidentally added a weird property to her bow for free. It claims to be from the Bestiary 3 and be called “Paper Cut”, but there’s no cost associated with it. It seems like it deals bleed damage on hit. What is this meant to be, some kind of monster ability? Is this a weird PC Gen only thing? Or a transcription error?

Here’s the weapon in question:

enter image description here

Does Divine Word’s Killing Effect Come Before or After the Banishing Effect (For Fiends)

This question is stated right in the title.

In this case, a cleric might cast Divine Word with a fiend with 20 or less HP in the area, and the fiend can hear the cleric.

As we all know, if a fiend fails its save against Divine Word is banished to its home plane. However, all creatures with 20 HP or less is killed instantly. Would, say, a demon that failed its save while under 20 HP be killed first, or sent to the Abyss, then killed there? Same thing with devils, night hags, rakshasas, yugoloths, et cetera. The yugoloth home plane is Gehenna, for specifics.

Where does the Transform Vampires/Werewolves into lawn furniture rote come from?

I remember the 90s when Mage players would tell Vampire players that a Mage can very easily transform a Vampire or Werewolf into lawn chairs, and that they could get quite a good collection. I didn’t know much about Mage those days, and I always supposed that was covered in some supplement.

These days, after reading some Mage books, I’m not so sure.

Was that infamous rote published in an official book? Which?

If not, anyone knows its origin? How did it spread so fast?

You can find the rote on page 610 of M20 as a kind of a joke. But I’m asking about the old days.

Where does poisonous “oil of taggit” come from?

Is there any lore in D&D, whether in 5th Edition or prior, about where the poison "oil of taggit" comes from? What kind of thing is a "taggit"? An animal or plant? A mineral? In 5th Edition, it’s listed in the Dungeon Master’s Guide on page 258, but as far as I can tell, it’s been in the game since at least 3rd Edition, and possibly before.

I know what effect taggit oil has — it causes long-term unconsciousness — but I can’t find any information about what it is derived from, nor any etymology that might shed light on the question.

Where does a dragons magic come from?

Wizards learn spells in spell books Learning the techniques needed to cast, sorcerors have an innate magical ability, warlocks are given powers by a deity or other powerful being.

Clerics and druids receive there magic from a deity, nature or the land.

But where do dragons learn there magic? Are they inherent casters like a sorceror, or do they have books and libraries like a wizard? Does a dragon know all the spells available to it picking which are prepared each day like a cleric Druid or bard, or like a wizard Or sorceror do they need to pre select which spells they have access to each day preparing from a fixed list?

BufferOverFlow – How come ESP points to the end of the payload

I just don’t understand how ESP points to the shellcode

let’s say we’ve sent this string

string = 100 * 'A' + 'BBBB' + 'CCCC' 

I have filled the stack with ‘AAAA..’ and overwritten the EIP value and set it to ‘BBBB’ and I got the segmentation fault as expected, what I don’t understand is when debugging the ESP points directly to ‘CCCC’, isn’t the ESP pointing to the top of the stack, and we have already filled the stack with ‘AAAA’, shouldn’t be ESP pointing to these AAAA?

CLRS 22.3-1, How Come Solutions Online State There Can’t Be Edges From WHITE to GRAY nodes “at any point… during search”?

The exercise (from the book Introduction To Algorithms) states

Make a 3-by-3 chart with row and column labels WHITE, GRAY,and BLACK. In each cell (i, j) indicate whether, at any point during a depth-first search of a di- rected graph, there can be an edge from a vertex of color i to a vertex of color j . For each possible edge, indicate what edge types it can be. Make a second such chart for depth-first search of an undirected graph.

The colors WHITE, GRAY, BLACK correspond to Undiscovered, discovered but not finished, and finished. The following solution is what multiple sites & universities have posted(such as: walkccc, Rutgers University):

 |       | WHITE         | GRAY                | BLACK                | |-------|---------------|---------------------|----------------------| | WHITE | All kinds     | Cross, Back         | Cross                | | GRAY  | Tree, Forward | Tree, Forward, Back | Tree, Forward, Cross | | BLACK | -             | Back                | All kinds            | 

I will draw a minimal counter example as it helps understand my conflict:

counter-example

  • Start at node 0: 0 is GRAY
  • PAUSE
  • At this point, 3 is still white and has an edge to 0
  • Resume and keep going, eventually the edge from 3 to 0 will be discovered as a tree edge

This contradicts the solutions saying you can only have Cross/Back edges going form WHITE->GRAY. This example can be easily modified to contradict many of the elements in the table. I think the solutions are doing one of the following:

  • Assuming that the graph is a tree and that we start at its root. (Wrong as DFS doesn’t need a tree graph and any node can be started from).
  • More likely (Just thought of this), interpreting the question of "can there be an edge" as "can there be an edge that we have discovered". In which case, the solutions work, as although the edge from 3->0 was a WHITE->GRAY edge at one point, we hadn’t discovered it yet.

Where do D&D Orcs come from?

I’ve always assumed that with all modern fantasy, D&D included, their racial archetypes for their inhabitants always had their roots from Tolkien’s Lord of the Rings. And in part, I do believe there is enough healthy evidence to indicate that many of D&D’s Orc characteristics are indeed inspired from Tolkien’s Orc, whether it’s their physical prowess, inherent brutality (although this is likely to change very soon), militaristic organisation, etc.

But where do they really come from? Tolkien’s Orc stems from enslaved and corrupted elves who had their humanity literally tortured out of them. Where do D&D orcs come from and what makes them what they are?

How come non creatable/destroyable Roblox instances have :Destroy() :Clone() etc?

Roblox has many types of instances. But services and other NonCreatable Instances (ReplicatedStorage, Workspace, etc.) still have methods for creating or destroying. Why? Why do they have :Destroy() and :Clone() methods if they cannot be destroyed or created? What’s the point of inheriting these from the Instance class?