I need to generate a simple random path in 2D tile map. An input parameter is a number of steps. The condition is that each tile has just two adjacent tiles on the path so there are no rooms and no crossroads.
I was looking for some solution on the net and I didn't find anything like this. Drunkard algorithm makes rooms and everything else is maze generation algorithms. Maybe I am not searching by proper keywords.
The important thing is randomness as I need the path completely different every time.
Edit: adding sample image
sample path:
the main feature is that each tile has just 2 neighbors.
Improved version of this would be using specific target tile as the end of the path and minimum and maximum of steps but that's not so important right now.
Thank you for any idea.
create 2D map
so create 2D array of the size of your map and clear it by for example 0
add N random obstacles
for example filled circles in the map
use A* to find shortest path
you can use mine ... C++ A* example
If you want something more complex then you can create random terrain and use A* to find shortest path (while going up will cost more then going down ...). To create random terrain you can use:
Diamond and Square Island generator
which can be use also used for random map generation...
Break this down into sub parts, the only random decision you have to take is whether to go left/right/up/down at a given point on the path without forming a junction, this can be arbitrarily generated using lets say the time stamp of the machine,for example, to check weather the last digit is even or odd and then go left for even and right for odd, up for a modulo 4 etc, thus giving you a fairly random path every time.
Try and slow down the computation on a relatively fast to span this accross a lot of time,to introduce more randomness.
Alternatively, do a DFS like traversal on the 2D map, and store each unique path in a hash map or set, and add a unique number to this map as key, this is the pre processing part, now randomly pick a unique key from a set of all possible solution, remove it from the set, if you need another random unique path, just pick one more at random from the remaining available paths.
I'm creating a random map generator for a rogue-like dungeon crawler, and my approach for the entrance-to-exit path was this:
1. Randomly select a tile as the dungeon entrance. Add it to the path and set it as currentTile
2. Randomly pick a neighboring tile of currentTile that's not already in the path. Add it to the path and set it as currentTile.
3. Repeat step 2 until your path reaches the desired length. If a deadlock occurs, restart from 1.
In your case, you should alter step 2 a bit: you should check that the neighboring tile itself AND all its neighbors (except currentTile, of course) are not already in the path. This could cause your algorithm to reach a deadlock more times probably, but for paths as small as the one in your picture, a few repetitions would not be a problem.
Related
I'm developing a robot simulation using ROS and C++.
I have created a map, which is a list of free positions in a closed room like this one:
0.1,0;0.2,0;0.3,0;...
They are (x,y) locations separated by ;. All of the locations in that list are the free locations in the map. If there is an obstacle in a location, that location won't be in list.
How can I use that list as a map for A* search algorithm?
I've thought to convert that list into a 2D matrix but I don't know what to put inside matrix's cell.
Indeed, it sounds like you can simply convert the list into a 2D matrix by parsing the text file (set x to the character sequence before comma, skip comma, set y to the character sequence before semicolon, skip semicolon, convert x/y to numbers and update matrix accordingly using x/y as indices, etc.).
As for the matrix itself, consider simply a bird's-eye-view of the room, where a '0' in a cell represents a free space, while a '1' represents an obstacle (or the other way around; the values are arbitrary, as long as you use them consistently). And for the A* algorithm, any cell is essentially "adjacent" to the 4 neighboring cells (or whatever movement scheme you are using).
You will have to convert the data to a graph (as in nodes and edges, not as in function plot). In order to do that, you not only need the positions, which translate to nodes (a.k.a. vertices) but the edges. There is an edge between two nodes when you can move from one node directly to the other. In other words, there is no node in between and also no obstacle preventing the movement. Once you have that part down, you can run the A* algorithm on the resulting graph easily.
Steps:
Read and parse input data.
Store data as list of nodes.
Define the requirements for an edge to exist between two nodes.
Create a list of edges with previously defined condition and the nodes.
Run A* on your graph.
Notes:
I won't do the actual work for you because I guess its just homework. Nobody here will hopefully do that.
You can solve each step on its own or even skip it and replace its results using hard-coded values.
You can also skip generating the edges altogether. You just need to adjust the A* algorithm to generate the edges on demand on every node it visits. This may or may not be simpler.
I have a program that create graphs as shown below
The algorithm starts at the green color node and traverses the graph. Assume that a node (Linked list type node with 4 references Left, Right, Up and Down) has been added to the graph depicted by the red dot in the image. Inorder to integrate the newly created node with it neighbors I need to find the four objects and link it so the graph connectivity will be preserved.
Following is what I need to clarify
Assume that all yellow colored nodes are null and I do not keep a another data structure to map nodes what is the most efficient way to find the existence of the neighbors of the newly created node. I know the basic graph search algorithms like DFS, BFS etc and shortest path algorithms but I do not think any of these are efficient enough because the graph can have about 10000 nodes and doing graph search algorithms (starting from the green node) to find the neighbors when a new node is added seems computationally expensive to me.
If the graph search is not avoidable what is the best alternative structure. I thought of a large multi-dimensional array. However, this has memory wastage and also has the issue of not having negative indexes. Since the graph in the image can grow in any directions. My solution to this is to write a separate class that consists of a array based data structure to portray negative indexes. However, before taking this option I would like to know if I could still solve the problem without resolving to a new structure and save a lot of rework.
Thank you for any feedback and reading this question.
I'm not sure if I understand you correctly. Do you want to
Check that there is a path from (0,0) to (x1,y1)
or
Check if any of the neighbors of (x1,y1) are in the graph? (even if there is no path from (0,0) to any of this neighbors).
I assume that you are looking for a path (otherwise you won't use a linked-list), which implies that you can't store points which have no path to (0,0).
Also, you mentioned that you don't want to use any other data structure beside / instead of your 2D linked-list.
You can't avoid full graph search. BFS and DFS are the classic algorithms. I don't think that you care about the shortest path - any path would do.
Another approaches you may consider is A* (simple explanation here) or one of its variants (look here).
An alternative data structure would be a set of nodes (each node is a pair < x,y > of course). You can easily run 4 checks to see if any of its neighbors are already in the set. It would take O(n) space and O(logn) time for both check and add. If your programming language does not support pairs as nodes of a set, you can use a single integer (x*(Ymax+1) + Y) instead.
Your data structure can be made to work, but probably not efficiently. And it will be a lot of work.
With your current data structure you can use an A* search (see https://en.wikipedia.org/wiki/A*_search_algorithm for a basic description) to find a path to the point, which necessarily finds a neighbor. Then pretend that you've got a little guy at that point, put his right hand on the wall, then have him find his way clockwise around the point. When he gets back, he'll have found the rest.
What do I mean by find his way clockwise? For example suppose that you go Down from the neighbor to get to his point. Then your guy should be faced the first of Right, Up, and Left which he has a neighbor. If he can go Right, he will, then he will try the directions Down, Right, Up, and Left. (Just imagine trying to walk through the maze yourself with your right hand on the wall.)
This way lies insanity.
Here are two alternative data structures that are much easier to work with.
You can use a quadtree. See http://en.wikipedia.org/wiki/Quadtree for a description. With this inserting a node is logarithmic in time. Finding neighbors is also logarithmic. And you're only using space for the data you have, so even if your graph is very spread out this is memory efficient.
Alternately you can create a class for a type of array that takes both positive and negative indices. Then one that builds on that to be 2-d class that takes both positive and negative indices. Under the hood that class would be implemented as a regular array and an offset. So an array that can start at some number, positive or negative. If ever you try to insert a piece of data that is before the offset, you create a new offset that is below that piece by a fixed fraction of the length of the array, create a new array, and copy data from the old to the new. Now insert/finding neighbors are usually O(1) but it can be very wasteful of memory.
You can use a spatial index like a quad tree or a r-tree.
I'm facing a hard problem:
Imagine I have a map of an entire country, represented by a huge matrix of Cells. Each cell represents a 1 square meter of territory. Each Cell is represented as a double value between 0 and 1 that represents the cost of traversing the cell.
The map obviously is not fittable in memory.
I am trying to wrap my mind arround a way to calculate the optimal path for a robot, from a start point to a end position. The first idea I had was to make a TCP-like moving window, with a minimap of the real map arround the moving robot, and executing the A* algorithm inside there, but I'm facing some problems with maps with huge walls, bad pathfinding, etc...
I am searching the literature about A*-like algorithms and I could not visualize an approximation of what would be a good solution for this problem.
I'm wondering if someone has faced a similar problem or can help with a idea of a possible solution!
Thanks in advance :)
Since I do not know exact data, here's some information that could be useful:
A partial path of a shortest path is itself a shortest path. I.e. you might split up your matrix into submatrices and find (all) shortest paths in there. Note that you do not have to store all results: You e.g. can save memory by not saving a complete path but just the information: Path goes from A to B. The intermediate nodes might be computed later again or stored in a file for later. You might even be able to precompute some shortest paths for certain areas.
Another approach is that you might be able to compress your matrix in some way. I.e. if you have large areas consisting only of one and the same number, it might be good to store just that number and the dimensions of that area.
Another approach (in connection to precompute some shortest paths) is to generate different levels of detail of your map. Considering a map of the USA, this might look the following: The coarsest level of detail contains just the cities New York, Los Angeles, Chicago, Dallas, Philadelphia, Houston und Phoenix. The finer the levels get, the more cities they contain, but - on the other hand - the smaller area of your whole map is shown by them.
Does your problem have any special structure, e.g., does the triangle inequality hold/can you guarantee that the shortest path doesn't jog back and forth? Do you want to perform the query many times? (If so you can do pre-processing that will amortize over multiple queries.) Do you need the exact minimum solution, or will something within an epsilon factor be OK?
One thought was that you can coarsen the matrix - form 100 meter by 100 meter squares, and determine the shortest path distances through the 100 \times 100 squares. Now this will fit in memory (about 1 Gigabyte), you can run Dijkstra, and then expand each step through the 100 \times 100 square.
Also, have you tried running a forward-backward version of Dijkstra's algorithm? I.e., expand from the source and search forthe sink at the same time, and stop when there's an intersection.
Incidentally, why do you need such a fine level of granularity?
Here are some ideas that may work
You can model your path as a piecewise linear curve. If you have 31 line segments then your curve is fully described by 60 numbers. Each of the possible curves have a cost, so the cost is a function on the following form
cost(x1, x2, x3 ..... x60)
Now your problem is to find the global optimum of a function of 60 variables. You can use standard methods to do this. One idea is to use genetic algorithms. Another idea is to use a monte carlo method such as parallel tempering
http://en.wikipedia.org/wiki/Parallel_tempering
Whenever you have a promising path then you can use it as a starting point to find a local minimum of the cost function. Maybe you can use some interpolation to make your cost function is differentiable. Then you can use Newtons method (or rather BFGS) to find local mimima of the cost function.
http://en.wikipedia.org/wiki/Local_minimum
http://en.wikipedia.org/wiki/BFGS
Your problem is somewhat similar to the problem of finding reaction paths in chemical systems. Maybe you can find some inspiration in the book "Energy Landscapes" by Davis Wales.
But I also have some questions:
Is it necessary for you to find the optimal path, or are you just looking for an path that is OK?
How much computer power and time do you have at hand?
Can the robot make sharp turns, or do you need extra physics modelling to improve the cost function?
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.
I'm working on a simple multiplayer game in which 2-4 players are placed at separate entrypoints in a maze and need to reach a goal point. Generating a maze in general is very easy, but in this case the goal of the game is to reach the goal before everyone else and I don't want the generation algorithm to drastically favor one player over others.
So I'm looking for a maze generation algorithm where the optimal path for each player from the startpoint to the goal is no more than 10% more steps than the average path. This way the players are on more or less an equal playing field. Can anyone think up such an algorithm?
(I've got one idea as it stands, but it's not well thought out and seems far less than optimal -- I'll post it as an answer.)
An alternative to freespace's answer would be to generate a random maze, then assign each cell a value representing the number of moves to reach the end of the maze (you can do both at once if you decide that you're starting at the 'end'). Then pick a distance (perhaps the highest one with n points at that distance?) and place the players at squares with that value.
What about first selecting the position of the players and goal and an equal length path and afterwards build a maze respecting the defined paths? If the paths do not intersect this should easily work, I presume
I would approach this by setting the goal and each player's entry point, then generating paths of similar length for each of them to the goal. Then I would start adding false branches along these paths, being careful to avoid linking to other player's paths, or having a branch connect back to the path. So essentially every branch is a dead end.
This way, you guarantee the paths are similar in length. However it won't allow players to interact with each other. You can however put this in, by creating links between branches such that branch entry points on either path are at a similar distance away from the goal. And on this branch you can branch off more dead ends for fun and profit :-)
The easiest solution I can come up with is to randomly generate an entire maze like normal, then randomly pick the goal point and player startpoints. Once this is done, calculate the shortest path from each startpoint to the goal. Find the average and start 'smoothing' (remove/move barriers -- don't know how this will work) the paths that are significantly above it, until all of the paths are within the proper margin. In addition, it could be possible to take the ones that are significantly below the average and insert additional barriers.
Pick your exit point somewhere in the middle
Start your N paths from there, adding 1 to each path per loop,
until they are as long as you want them to be.
There are your N start points, and they are all the same length.
Add additional branches off of the lines, until the maze is full.