How to implement a "reverse" BFS algorithm? - algorithm

I'm playing a game with the following rules:
There is a map (with walls), some coins (randomly generated in the map) and a Minotaur. The goal is to grab as many coins as possible without the minotaur killing you. I have implemented a BFS to find coins and move towards them, but my character keeps dying to the minotaur, because i don t know how to make an efficient "run away" algorithm.
What would be the best solution to find the path that runs away from the minotaur as fast as possible (without colliding with walls)
The pseudo code would look somewhat like this:
*if(minotaur_is_close) run_away*
*else find_coins*
Edit: Added picture of the starting round of randomly generated map (green tiles are walkable, grey ones are walls, blue is character, red is Minotaur, orange are coins)

Related

Solving the sliding puzzle-like problem with arbitrary number of holes

I've tried searching for a while, but haven't come across a solution, so figured I would ask my own.
Consider an MxM 2D grid of holes, and a set of N balls which are randomly placed in the grid. You are given some final configuration of the N balls in the grid, and your goal is to move the balls in the grid to achieve this final configuration in the shortest time possible.
The only move you are allowed to make is to move any contiguous subsection of the grid (on either a row or column) by one space. That sounds a bit confusing; basically you can select any set of points in a straight line in the grid, and shift all the balls in that subsection by one spot to the left or right if it is a row, or one spot up or down if it is a hole. If that is confusing, it's fine to consider the alternate problem where the only move you can make is to move a single ball to any adjacent spot. The caveat is that two balls can never overlap.
Ultimately this problem basically boils down to a version of the classic sliding tile puzzle, with two key differences: 1) there can be an arbitrary number of holes, and 2) we don't a priori know the numbering of the tiles - we don't care which balls end up in the final holes, we just want to final holes to be filled after it is all said and done.
I'm looking for suggestions about how to go about adapting classic sliding puzzle solutions to these two constraints. The arbitrary number of holes is likely pretty easy to implement efficiently, but the fact that we don't know which balls are destined to go in which holes at the start is throwing me for a loop. Any advice (or implementations of similar problems) would be greatly appreciated.
If I understood well:
all the balls are equal and cannot be distinguished - they can occupy any position on the grid, the starting state is a random configuration of balls and holes on the grid.
there are nxn = balls + holes = number of cells in the grid
your target is to reach a given configuration.
It seems a rather trivial problem, so maybe I missed some constraints. If this is indeed the problem, solving it can be approached like this:
Consider that you move the holes, not the balls.
conduct a search between each hole and each hole position in the target configuration.
Minimize the number of steps to walk the holes to their closest target. (maybe with a BFS if it is needed) - That is to say that you can use this measure as a heuristic to order the moves in a flavor of A* maybe. I think for a 50x50 grid, the search will be very fast, because your heuristic is extremely precise and nearly costless to calculate.
Solving the problem where you can move a hole along multiple positions on a line, or a file is not much more complicated; you can solve it by adding to the possible moves/next steps in your queue.

Shortest Path, but on a physical maze

I'm implementing a robot to be able to solve any maze (where the robot only has front sensors, but I make it scan the surroundings), and I was able to get it to turn the maze into a map where 0 represents walls, and 1 represents roads, with possibly slanted roads. Now, the robot is not fast at turning, but fairly fast at moving down a straight line. Therefore, a normal shortest path algorithm through the somewhat slanted hallway would be slow, although the paths are wide enough for it.
For example, we find
0001111111000
0011111110000
0111111100000
1111111000000
1111110000000
As a possible map. I'd like the robot to recognize that it can walk diagonally, or even just go straight up then right then right again, instead of turning every time in a normal shortest path algorithm.
Any ideas? Also, a complete algorithm change is welcome too - I'm fairly new to this.
I've faced similar problem some time ago.
You can assign weights to surrounding cells and less weight to the front cell, thus making a weight graph that is made during the movement.
I used Dijkstra algorithm with weights of 2 for surrounding cells and weight 1 for the front cell, you must pass direction of robot to Dijkstra and when adding them to the priority queue, and when extracting cells from the queue add the neighbors with respect to the direction saved in the extracted cell.
Then make the move and then recompute the modified Dijkstra for finding the nearest unseen cell.

Generating Random Puzzle Boards for Rush Hour Game

If you're not familiar with it, the game consists of a collection of cars of varying sizes, set either horizontally or vertically, on a NxM grid that has a single exit.
Each car can move forward/backward in the directions it's set in, as long as another car is not blocking it. You can never change the direction of a car.
There is one special car, usually it's the red one. It's set in the same row that the exit is in, and the objective of the game is to find a series of moves (a move - moving a car N steps back or forward) that will allow the red car to drive out of the maze.
I've been trying to think how to generate instances for this problem, generating levels of difficulty based on the minimum number to solve the board.
Any idea of an algorithm or a strategy to do that?
Thanks in advance!
The board given in the question has at most 4*4*4*5*5*3*5 = 24.000 possible configurations, given the placement of cars.
A graph with 24.000 nodes is not very large for todays computers. So a possible approach would be to
construct the graph of all positions (nodes are positions, edges are moves),
find the number of winning moves for all nodes (e.g. using Dijkstra) and
select a node with a large distance from the goal.
One possible approach would be creating it in reverse.
Generate a random board, that has the red car in the winning position.
Build the graph of all reachable positions.
Select a position that has the largest distance from every winning position.
The number of reachable positions is not that big (probably always below 100k), so (2) and (3) are feasible.
How to create harder instances through local search
It's possible that above approach will not yield hard instances, as most random instances don't give rise to a complex interlocking behavior of the cars.
You can do some local search, which requires
a way to generate other boards from an existing one
an evaluation/fitness function
(2) is simple, maybe use the length of the longest solution, see above. Though this is quite costly.
(1) requires some thought. Possible modifications are:
add a car somewhere
remove a car (I assume this will always make the board easier)
Those two are enough to reach all possible boards. But one might to add other ways, because of removing makes the board easier. Here are some ideas:
move a car perpendicularly to its driving direction
swap cars within the same lane (aaa..bb.) -> (bb..aaa.)
Hillclimbing/steepest ascend is probably bad because of the large branching factor. One can try to subsample the set of possible neighbouring boards, i.e., don't look at all but only at a few random ones.
I know this is ancient but I recently had to deal with a similar problem so maybe this could help.
Constructing instances by applying random operators from a terminal state (i.e., reverse) will not work well. This is due to the symmetry in the state space. On average you end up in a state that is too close to the terminal state.
Instead, what worked better was to generate initial states (by placing random cars on the grid) and then to try to solve it with some bounded heuristic search algorithm such as IDA* or branch and bound. If an instance cannot be solved under the bound, discard it.
Try to avoid A*. If you have your definition of what you mean is a "hard" instance (I find 16 moves to be pretty difficult) you can use A* with a pruning rule that prevents expansion of nodes x with g(x)+h(x)>T (T being your threshold (e.g., 16)).
Heuristics function - Since you don't have to be optimal when solving it, you can use any simple inadmissible heuristic such as number of obstacle squares to the goal. Alternatively, if you need a stronger heuristic function, you can implement a manhattan distance function by generating the entire set of winning states for the generated puzzle and then using the minimal distance from a current state to any of the terminal state.

Level solving and pathfinding

I have played a little flash game recently called Just A Trim Please and really liked the whole concept.
The basic objective of the game is to mow the whole lawn by going over each square once. Your lawn mower starts on a tile and from there you can move in all directions (except where there are walls blocking you). If you run on the grass tiles more than once it will deteriorate and you will lose the level. You can only move left, right, up, or down.
However, as you finish the game, more tiles get added:
A tile you can only mow once (grass).
A tile you can run over twice before deteriorating it (taller grass).
A tiie you can go over as much as you want (concrete).
A tile you can't go over (a wall).
If you don't get what I mean, go play the game and you'll understand.
I managed to code a brute-force algorithm that can solve puzzles with only the first kind of tile (which is basically a variation of the Knight's Tour problem). However, this is not optimal and only works for puzzles with tiles that can only be ran on once. I'm completely lost as to how I'd deal with the extra tiles.
Given a starting point and a tile map, is there a way or an algorithm to find the path that will solve the level (if it can be solved)? I don't care about efficiency, this is just a question I had in mind. I'm curious as to how you'd have to go to solve it.
I'm not looking for code, just guidelines or if possible a plain text explanation of the procedure. If you do have pseudocode however, then please do share! :)
(Also, I'm not entirely sure if this has to do with path-finding, but that's my best guess at it.)
The problem is finite so, sure, there is an algorithm.
A non-deterministic algorithm can solve the problem easily by guessing the correct moves and then verifying that they work. This algorithm can be determinized by using for example backtracking search.
If you want to reduce the extra tiles (taller grass and concrete) to standard grass, you can go about it like this:
Every continuous block of concrete is first reduced into a single graph vertex, and then the vertex is removed, because the concrete block areas are actually just a way to move around to reach other tiles.
Every taller grass tile is replaced with two vertices that are connected to the original neighbors, but not to each other.
Example: G = grass, T = tall grass, C = concrete
G G T
G C T
C C G
Consider it as a graph:
Now transform the concrete blocks away. First shrink them to one (as they're all connected):
Then remove the vertex, connecting "through" it:
Then expand the tall grass tiles, connecting the copies to the same nodes as the originals.
Then replace T, T' with G. You have now a graph that is no longer rectangular grid but it only contains grass nodes.
The transformed problem can be solved if and only if the original one can be solved, and you can transform a solution of the transformed problem into a solution of the original one.
There is a DP approach for the travelling salesman.
Perhaps you could modify it (recalculating as more pieces are added).
For a long piece of grass, you could perhaps split it into two nodes since you must visit it twice. Then reconnect the two nodes to the nodes around it.

How can I find islands in a randomly generated hexagonal map?

I'm programming a Risk like game in Codigniter and JQuery. I've come up with a way to create randomly generated maps by making a full layout of tiles then deleting random ones. However, this sometimes produces what I call islands.
In risk, you can only attack one space over. So if one player happens to have an island all to them self, they would never be able to loose.
I'm trying to find a way that I can check the map before the game begins to see if it has islands.
I have already come up with a function to find out how many adjacent spaces there are to each space, but am not sure how to implement it in order to find islands.
Each missing spot is also identified as "water."
I'm not allowed to use image tags:
http://imgur.com/xwWzC.gif
There's a standard name for this problem but off the top of my head the following might work:
Pick any tile at random
Color it
Color its neighbours
Color its neighbours' neighbours
Color its neighbours' neighbours' neighbours, etc.
When you're done (i.e. when all neighbours are colored), loop through the list of all tiles to see whether there are any still/left uncolored (if so, they're an island).
How do you do the random generation? Probably the best way is to solve it at this time. When you're generating the map, if you notice that you just created is impossible to get to, you can resolve it by adding the appropriate element.
Though we'll need to know how you do the generation.
Here's your basic depth-first traversal starting at a random tile, pseudo-coded in python-like language:
visited = set()
queue = Queue()
r = random tile
queue.add(r)
while not queue.empty():
current = queue.pop()
visited.add(current)
for neighbor in current.neighbors():
if neighbor not in visited:
queue.add(neighbor)
if visited == set(all tiles):
print "No islands"
else:
print "Island starting at ", r
This hopefully provides another solution. Instead of "island" I'm using the term "disconnected component" since it only matters whether all tiles are reachable from all others (if there are disconnected components then a player cannot win via conquest if his own territories are all in one component).
Iterate over all 'land' tiles (easy enough to do) and for each tile generate a node in a graph.
For each vertex, join it with an undirected edge to the vertices representing its neighbour tiles (maximum of 6).
Pick any vertex and run depth-first search (or bread-first) from it.
If the set of vertices found by the DFS is equal to the set of all vertices then there are no disconnected components, otherwise a disconnected component (island) exists.
This should (I think) run in time O(n) where n is the number of land tiles.
Run a blurring kernel over your data set.
treating the hex grid as an image ( it is , sort of)
value(x,y) = average of all tiles around this (x,y)
this will erode beaches slightly, and eliminate islands.
It is left as an exercise for the student to run an edge-detection kernel over the resulting dataset to populate the beach tiles.

Resources