I am new to game programming I currently am using unity's 2D power to remake an 2D game for sake of practice. So I am just little confuse about one thing, so far every enemy in my game was dumb(they move on predefined paths) but this enemy, alien-copter, flies and follow the player wherever the player goes. My question is should I implement any pathfinding algorithm? I had studied A* but I trying to figure out if A* is gonna be helpful in my envoirnment because player will be moving and the enemy have to keep on looking for shortest path. I tried to write code for this AI my code was working perfect when there were no obstacles but my game has obstacles so I want something efficient so what do you people think should I implement A* or any other algorithm or not?
As regards AI, if you have obstacles in your game, you will need to implement pathfinding of some sort. Note, that just taking the shortest block (node) is not an option because such algorithm is not complete, i.e. the path may not be found even if there is one. Imagine a going after b:
(wall)(wall)(wall)
(free)(free)a (wall) b
(wall)(wall)(wall)
The shortest (best) path is to the left since up, down and right are blocked. On the next move however, the best move is to go right because it's closer. That's how a will get trapped in a loop. So yes you are right, you do need to get the path from a to b. It will typically be in the form of a list of nodes. Then you just select head (aka element at index 0) of the list.
A* is the perfect option in your case. It is complete, efficient and it will even give you the shortest path. Path recomputation shouldn't be an issue for a small game. Furthermore, if obstacles in your game grid are static for the duration of the game you can precompute paths and cache them. For instance, path from (x,y) to (x1,y1) is [(a,b), (c,d) ...]. So you can store it in some sort of map data structure where key is the two points - start, target and value - the path. This will of course depend on whether you want to classify an enemy as an obstacle for other enemies and other gameplay factors
Related
I'm making a game engine for a board game called Blockade and right now I'm trying to generate all legal moves in a position. The rules aren't exactly the same as the actual game and they don't really matter. The gist is: the board is a matrix and you move a pawn and place a wall every move.
In short, I have to find whether or not a valid path exists from every pawn to every goal after every potential legal move (imagine a pawn doesn't move and a wall is just placed), to rule out illegal moves. Or rather, if I simplify it to a subproblem, whether or not the removal of a few edges (placing a wall) removes all paths to a node.
Brute-forcing it would take O(k*n*m), where n and m are the board dimensions and k is the number of potential legal moves. Searching for a path (worst case; traversing most of the board) is very expensive, but I'm thinking with dynamic programming or some other idea/algorithm it can be done faster since the position is the same the wall placement just changes, or rather, in graph terms, the graph is the same which edges are removed is just changed. Any sort of optimization is welcome.
Edit:
To elaborate on the wall (blockade). A wall is two squares wide/tall (depending on whether it's horizontal or vertical) therefore it will usually remove at least four edges, eg:
p | r
q | t
In this 2x2 matrix, placing a wall in the middle (as shown) will remove jumping from and to:
p and t, q and r, p and r, and q and t
I apologize ahead of time if I don't fully understand your question as it is asked; there seems to be some tacit contextual knowledge you are hinting at in your question with respect to knowledge about how the blockade game works (which I am completely unfamiliar with.)
However, based on a quick scan on wikipedia about the rules of the game, and from what I gather from your question, my understanding is that you are effectively asking how to ensure that a move is legal. Based on what I understand, an illegal move is a wall/blockade placement that would make it impossible for any pawn to reach its goal state.
In this case, I believe a workable solution that would be fairly efficient would be as follows.
Define a path tree of a pawn to be a (possibly but not necessarily shortest) path tree from the pawn to each reachable position. The idea is, you want to maintain a path tree for every pawn so that it can be updated efficiently with every blockade placement. What is described in the previous sentence can be accomplished by observing and implementing the following:
when a blockade is placed it removes 2 edges from the graph, which can sever up to (at most) two edges in all your existing path trees
each pawn's path tree can be efficiently recomputed after edges are severed using the "adoption" algorithm of the Boykov-Komolgrov maxflow algorithm.
once every pawns path tree is recomputed efficiently, simply check that each pawn can still access its goal state, if not mark the move as illegal
repeat for each possible move (reseting graphs as needed during the search)
Here are resources on the adoption algorithm that is critical to doing what is described efficiently:
open-source implementation as part of the BK-maxflow: https://www.boost.org/doc/libs/1_66_0/libs/graph/doc/boykov_kolmogorov_max_flow.html
implementation by authors as part of BK-maxflow: https://pub.ist.ac.at/~vnk/software.html
detailed description of adoption (stage) algorithm of BK maxflow algorithm: section 3.2.3 of https://www.csd.uwo.ca/~yboykov/Papers/pami04.pdf
Note reading the description of the adopton algorithm included in the last
bullet point above would be most critical to understanding how to adopt
orphaned portions of your path-tree efficiently.
In terms of efficiency of this approach, I believe on average you should expect on average O(1) operations for each adopted edge, meaning this approach should take about O(k) time to compute where k is the number of board states which you wish to compute for.
Note, the pawn path tree should actually be a reverse directed tree rooted at the goal nodes, which will allow the computation to be done for all legal pawn placements given a blockade configuration.
A few suggestions:
To check if there's a path from A to B after ever
Every move removes a node from the graph/grid. So what we want to know is if there are critical nodes on the path from A to B (single points that could be blocked to break the path. This is a classic flow problem. For this application you want to set the vertex capacity to 1 and push 2 units of flow (basically just to verify that there are at least 2 paths). If there are 2 paths, no one block can disconnect you from the destination. You can optimize it a bit by using an implicit graph, but if you're new to this maybe create the graph to visualize it better. This should be O(N*M), the size of your grid.
Optimizations
Since this is a game, you know that the setup doesn't change dramatically from one step to another. So, you can keep track of the two paths. If the blocade is not placed on any of the paths, you can ignore it. You already have 2 paths to destination.
If the block does land on one of the paths, cancel only that path and then look for another (reusing the one you already have).
You can also speed up the pawn movement. This can be a bit trick, but what you want is to move the source. I'm assuming the pawn moves only a few cells at a time, maybe instead of finding completely new paths, you can simply adjust them to connect to the new position, speeding up the update.
I have a game where you have to move around a map collecting gold and then move to the exit. I am currently trying to write an AI that will play this game but I want to know what algorithm I should use the find the closest instance of an object. For instance, the closest piece of gold or the closest unknown map square. The issue is that there are walls that the player cannot move through, so rather than just finding the closest object I need to find the one to which there is the shortest route. Is there an algorithm that can do this?
The algorithm you're looking for is called A* Search Algorithm. It is a best-first search algorithm that works by beginning at the starting point and building up a series of possible paths (excluding going through obstacles since those aren't possible paths), then scoring those paths to find the least cost one. In your case you'd need to customize the scoring by decreasing the cost based upon the objects along the path and increasing the cost by distance.
There's some information that will help you with it here:
There's a nifty interactive demo here (code also on github): http://qiao.github.io/PathFinding.js/visual/
Other resources:
https://harablog.wordpress.com/2011/09/01/rectangular-symmetry-reduction/
https://en.wikipedia.org/wiki/A*_search_algorithm
What is a good 2D grid-based path-finding algorithm?
I found several algorithms to solve mazes. Those which are simple enough are suitable only in cases when exit is in outer boundary (Wall-follower, pledge...).
Is there some more sophisticated algorithms for cases when shapes of boundaries are random, costs of zones inequal and exit may be somewhere inside the maze? (btw, all elements are quadratic)
Update: Also, we don't know apriori how maze looks like and are able to see only certain area.
If you mean "normal" 2-dimensinal mazes like those one can find on paper, you can solve them using image analysis. However, if you are somehow located in the (2D/3D) maze itself and should find a way out, you should probably deploy some Machine learning techniques. This works if you don't have any idea what you maze exactly looks like, a.k.a. you only "see" part of it.
Update: Apart from the shortest path finder algorithm family, I can also relate to the so-called Trémaux's algorithm designed to be able to be used by a human inside of the maze. It's similar to a simple recursive backtracker and will find a solution for all mazes.
Description:
As you walk down a passage, draw a line behind you to mark your path. When you hit a dead end turn around and go back the way you came. When you encounter a junction you haven't visited before, pick a new passage at random. If you're walking down a new passage and encounter a junction you have visited before, treat it like a dead end and go back the way you came so that you won't go around in circles or missing passages. If walking down a passage you have visited before (i.e. marked once) and you encounter a junction, take any new passage if one is available, otherwise take an "old" one. Every passage will be either empty (if not visited yet), marked once, or marked twice (if you were forced to backtrack). When you reach the solution, the paths which were marked exactly once will indicate the direct way back to the start. If the maze has no solution, you'll find yourself back at the start with all passages marked twice.
Shortest path algorithms are finding shortest path to the exit, no matter where the exit is.
If the cost is equal - BFS will do - otherwise, you need something like dijkstra's algorithm or A* algorithm [which is basically an informed dijkstra] to find the shortest path.
To use these algorithms, you need to model your maze as a graph: G=(V,E) where V = { all moveable squares in the maze } and E = {(u,v) | you can move from u to v in a sinlgle step }
If the squares have cost let it be cost(v) per each square, you will need a weighting function: w:E->R: define it as w(u,v) = cost(v)
The Pledge Algorithm is useful for the kind of mazes you are talking of. It consists of:
Picking a direction, if you know the general direction to goal good, but a random direction will do. Let say you pick North.
Go that direction until you hit an obstacle.
Follow the obstacle, keeping track of how much you turn. For instance, going North you run into an East-West wall. You turn East (90d), and follow the wall as it turns South (180d), West (270d), and North again (360d). You do not stop following the wall until the amount you have turned becomes 0. So you keep following as it turns West (270d it turned in the opposite direction), South (180d), East (90d), and finally North (0d). Now you can stop following.
Do that any time you hit an obstacle. You will get to the Northern most part of the maze eventually. If you still havent found the goal, because you picked the wrong direction, try again with East or South or whatever direction is closest to the goal.
I have an idea of creating yet another maze game. However, there is a key difference: maze changes on-the-fly during the game. When I think of the problem the following restrictions come into my mind:
there is main route in the maze which never changes
the main route is the only route which leads to the finish
maze mutation should not block paths back to the main route
It also would be nice to control (affect game difficulty):
how much of the maze gets changed during a single mutation
optionally disable restriction #3 (i.e. player can get blocked in the maze for a while)
EDIT:
The question is: can you suggest an algorithm (or give your ideas) for described maze generation/mutation, which will not violate given restrictions?
You could:
Block a path at random (or using some sneaky criteria).
Scan the maze to see if it has been partitioned into 2 regions that are no longer connected.
If disconnected, you can knock down a wall at random so long as it neighbors both regions.
If your maze has only one path between any two points, step 2 will always split the maze and so #3 will always be needed.
Make a graph connecting all the cells of the maze and the walkable connections between them. To modify the maze, first pick a random wall to knock down, which generates a new edge in the graph. Then find a cycle in the graph that contains that edge, and delete a random, non-main-path edge in that cycle, which will erect an edge somewhere else.
This algorithm ensures that if all cells were reachable at the start, they will remain so. You probably want that feature so you can't ever get trapped.
This is probably quite straightforward. Generate the maze using the standard depth-first-search algorithm. Store the list of cells that form the (only) path from start to exit in a list. When you decide you want to mutate the maze, do the following:
Reset the entire maze to the default state (all walls in place), with the exception of any cell along the critical path, and optionally, a few cells within line-of-sight of the player's current location.
Re-execute the breadth-first search algorithm from the start, with one modification: when choosing which unvisited neighbour to explore, prefer edges that already have the wall removed.
The modification in the second step will ensure that the algorithm first explores the existing paths, then adds on side-passages and so forth from there. It's not even strictly necessary to preserve the critical path if you don't want to - you can regenerate the entire maze except where the user's standing, and it'll remain valid.
I think this ought to always produce a valid tree in the same way the original algorithm would, but I'm not 100% sure about the implications of preserving the cells around the user, which may not be on the critical path. I'm positive the reconfigured maze will always be solvable from where the user is standing, though.
This is a pretty neat idea, too. I love the idea of the maze rearranging itself substantially wherever the user isn't looking. If you're doing this in first-person, you could even use the camera view to change the walls behind the user when they're not looking!
I'm having trouble finding the right pathfinding algorithm for some AI I'm working on.
I have players on a pitch, moving around freely (not stuck to a grid), but they are confined to moving in 8 directions (N NE E etc.)
I was working on using A*, and a graph for this. But I realised, every node on the graph is equally far apart, and all the edges have the same weight - since the pitch is rectangular. And the number of nodes is enormous (being a large pitch, with them able to move between 1 pixel and another)
I figured there must be another algorithm, optimised for this sort of thing?
I would break the pitch down into 10x10 pixel grid. Your routing does not have to be as finely grained as the rest of your system and it makes the algorithm take up far less memory.
As Chris suggests above, choosing the right heuristic is the key to getting the algorithm working right for you.
If players move in straight lines between points on your grid, you really don't need to use A*. Bresenham's line algorithm will provide a straight line path very quickly.
You could weight a direction based on another heuristic. So as opposed to weighting the paths based on actual distance you could weight or scale that based on another factor such as "closeness to another player" meaning players will favour routes that will not collide with other players.
The A* algorithm should work well like this.
I think you should try Jump Point Search. It is a very fast algorithm for path finding on 8-dire.
Here is a blog describing Jump Point Search shortly.
And, this is its academic paper <Online Graph Pruning for Pathfinding on Grid Maps>
Besides, there are some interesting videos on Youtube.
I hope this helps.