I'm programming my first game and I have one last problem to solve. I need an algorithm to check if I can move a chosen ball to a chosen place.
Look at this picture:
The rule is, if I picked up the blue ball on the white background (in the very middle) I can move it to all the green spaces and I can't move it to the purple ones, cause they are sort of fenced by other balls. I naturally can't move it to the places taken by other balls. The ball can only move up, down, left and right.
Now I am aware that there is two already existing algorithms: A* and Dijkstra's algorithm that might be helpful, but they seem too complex for what I need (both using vectors or stuff that I weren't taught yet, I'm quite new to programming and this is my semester project). I don't need to find the shortest way, I just need to know whether the chosen destination place is fenced by other balls or not.
My board in the game is 9x9 array simply filled with '/' if it's an empty place or one of the 7 letters if it's taken.
Is there a way I can code the algorithm in a simple way?
[I went for the flood fill and it works just fine, thank you for all your help and if someone has a similar problem - I recommend using flood fill, it's really simple and quick]
I suggest using Flood fill algorithm:
Flood fill, also called seed fill, is an algorithm that determines the
area connected to a given node in a multi-dimensional array. It is
used in the "bucket" fill tool of paint programs to fill connected,
similarly-colored areas with a different color, and in games such as
Go and Minesweeper for determining which pieces are cleared. When
applied on an image to fill a particular bounded area with color, it
is also known as boundary fill.
In terms of complexity time, this algorithm will be equals the recursive one: O(N×M), where N and M are the dimensions of the input matrix. The key idea is that in both algorithms each node is processed at most once.
In this link you can find a guide to the implementation of the algorithm.
More specifically, as Martin Bonner suggested, there are some key concepts for the implementation:
Mark all empty cells as unknown (all full cells are unreachable)
Add the source cell to a set of routable cells
While the set is not empty:
pop an element from the set;
mark all adjacent unknown cells as "reachable" and add them to the set
All remaining unknown cells are unreachable.
PS: You may want to read Flood fill vs DFS.
You can do this very simply using the BFS(Breadth First Search) algorithm.
For this you need to study the Graph data structure. Its pretty simple to implement, once you understand it.
Key Idea
Your cells will act as vertices, whereas the edges will tell whether or not you will be able to move from one cell to another.
Once you have implemented you graph using an adjacency list or adjacency matrix representation, you are good to go and use the BFS algorithm to do what you are trying to do.
Related
How graph algorithms can be used in line follower maze solving robot. I have solved grid using DFS search but do not know how to implement it actual line follower robot. my shortest path finding implements on a 20 by 20 grid . where s= start and g = destination and numbers denotes the position of each point inside the grid (row by row basis).
-If you are a beginner to microcontroller, then i would recommend you to first achieve in making your robot follow the line .
-If robot performs well in line following then you should try it in making your robot pass the strips(junctions in the grid) and make your robot transverse complete grid(all co-ordinates of the grid), simultaneously you can make a count of number of strips the robot passed(you can use two dimensional array to store there co-ordinates).
-If you can achieve the above two tasks then you are good to go for applying your logic in solving the maze inside the grid.
I once implemented shortest path algorithm on AVR board.
Here are the steps that you should follow.
Step 1: Do a dry run of arena and save all coordinate in an 2-D array. As you have described, there seems to be two type of junction. Make sure to blink a different LED on board every time you pass a junction. This way you can make sure that you are reading the board correctly.
Step 2: Now you have all the coordinates in a 2D array. You are applying DFS. I would not recommend that. since you have a grid not a tree to solve. Use Dijkstra's algorithm.
Implementation of this should not be hard. As compiler of AVR is very much similar to C.
Step 3: Now follow the result. lets day you have a 8*8 array. define a numbering from 1 to 64. your output should be in form of
1 9 10 18.... so on
Now calculate difference between two adjacent number
8, 1, 8 and so on
and fix a move for every number like for 8 go on left , for 1 go north. Just keep your current direction in mind to make move to other direction. Like going north from west would be different from going north from east.
Again I would recommend you to display your final result on LED first. Sometime your algorithm works fine and hardware stops working.
Shortest path algorithm for line follower robot, which do not involve loops in the line are relatively easy to implement.
It can be made by exhaustively traversing through all possible routs, making a default left/right turn at every decision making point. This way if there are no loops in the track, the robot will eventually get to the destination. The robot should keep track of all the turns that were made until the destination is reached.
After that it is a matter of reduction to eliminate the unnecessary turn the robot had made. I have discussed this shorted path algorithm in detail at my blog here.
The title is a little vague, but I'll explain better here.
The Setup
I'm trying to program a little water level simulator, much like the water levels in the game, LIMBO. When an opening is made, allowing water to flow between two bodies of water, the levels equalize. The setup I have now is two containers, with blue blocks inside representing water levels. My mouse removes chunks of terrain away, and so, when an opening is made between the bodies, they should adjust and their Y values should move to match.
Image examples:
Semi-filled tanks:
Equalized tanks:
Now, I know some maths could be done to figure out how much to adjust the levels and the ratios between different sized tanks. That part I think is pretty straight forward. But I can't figure out a good method of determining if and when the two bodies of water are connected.
Any algorithm, pseudo-code, or references would be much appreciated!
If you need more clarification, please, don't hesitate to ask. I look forward to all feedback and will edit my post for specific clarification.
Thanks!
~ natebot13
BTW: I'm using C++, SFML, and Box2D (Box2D is for some other physics related things I need, not necessarily needed for this example).
You need to check whether the edge of the container1 is connected to container2 at any point of time if so then adjust the water level. I guess you are working on a image so you can use the connected components algorithm to check if any of the edge pixels of container1 is connected to any of edge pixels of container2 and also get their positions.
Algorithm :-
puts edges of container1 in one set which is connected to a dummy parent1.
puts edges of container2 in another set which is connected to another dummy parent2.
say after every one second add the new added pixels to sets using connected components
check at end of every union whether dummy parent1 and parent2 are connected.
You can use DFS to check the exacts points of connection by starting from one edge set1 and reaching the other. The last pixel and
the previous first pixel in edge set1 are connection end points.
Note:-
There is a implementation of disjoint set in c++ boost lib which might be useful in implementation of connected components.
I think you can start from left to right for example:
the right side of the left tank position is known.
search the column to its right for a blue square.
once found, search its surrounding squares - up, down and to the right.
keep searching until you get to the known left side of the right tank.
I have a wireless mesh network of nodes, each of which is capable of reporting its 'distance' to its neighbors, measured in (simplified) signal strength to them. The nodes are geographically in 3d space but because of radio interference, the distance between nodes need not be trigonometrically (trigonomically?) consistent. I.e., given nodes A, B and C, the distance between A and B might be 10, between A and C also 10, yet between B and C 100.
What I want to do is visualize the logical network layout in terms of connectness of nodes, i.e. include the logical distance between nodes in the visual.
So far my research has shown the multidimensional scaling (MDS) is designed for exactly this sort of thing. Given that my data can be directly expressed as a 2d distance matrix, it's even a simpler form of the more general MDS.
Now, there seem to be many MDS algorithms, see e.g. http://homepage.tudelft.nl/19j49/Matlab_Toolbox_for_Dimensionality_Reduction.html and http://tapkee.lisitsyn.me/ . I need to do this in C++ and I'm hoping I can use a ready-made component, i.e. not have to re-implement an algo from a paper. So, I thought this: https://sites.google.com/site/simpmatrix/ would be the ticket. And it works, but:
The layout is not stable, i.e. every time the algorithm is re-run, the position of the nodes changes (see differences between image 1 and 2 below - this is from having been run twice, without any further changes). This is due to the initialization matrix (which contains the initial location of each node, which the algorithm then iteratively corrects) that is passed to this algorithm - I pass an empty one and then the implementation derives a random one. In general, the layout does approach the layout I expected from the given input data. Furthermore, between different runs, the direction of nodes (clockwise or counterclockwise) can change. See image 3 below.
The 'solution' I thought was obvious, was to pass a stable default initialization matrix. But when I put all nodes initially in the same place, they're not moved at all; when I put them on one axis (node 0 at 0,0 ; node 1 at 1,0 ; node 2 at 2,0 etc.), they are moved along that axis only. (see image 4 below). The relative distances between them are OK, though.
So it seems like this algorithm only changes distance between nodes, but doesn't change their location.
Thanks for reading this far - my questions are (I'd be happy to get just one or a few of them answered as each of them might give me a clue as to what direction to continue in):
Where can I find more information on the properties of each of the many MDS algorithms?
Is there an algorithm that derives the complete location of each node in a network, without having to pass an initial position for each node?
Is there a solid way to estimate the location of each point so that the algorithm can then correctly scale the distance between them? I have no geographic location of each of these nodes, that is the whole point of this exercise.
Are there any algorithms to keep the 'angle' at which the network is derived constant between runs?
If all else fails, my next option is going to be to use the algorithm I mentioned above, increase the number of iterations to keep the variability between runs at around a few pixels (I'd have to experiment with how many iterations that would take), then 'rotate' each node around node 0 to, for example, align nodes 0 and 1 on a horizontal line from left to right; that way, I would 'correct' the location of the points after their relative distances have been determined by the MDS algorithm. I would have to correct for the order of connected nodes (clockwise or counterclockwise) around each node as well. This might become hairy quite quickly.
Obviously I'd prefer a stable algorithmic solution - increasing iterations to smooth out the randomness is not very reliable.
Thanks.
EDIT: I was referred to cs.stackexchange.com and some comments have been made there; for algorithmic suggestions, please see https://cs.stackexchange.com/questions/18439/stable-multi-dimensional-scaling-algorithm .
Image 1 - with random initialization matrix:
Image 2 - after running with same input data, rotated when compared to 1:
Image 3 - same as previous 2, but nodes 1-3 are in another direction:
Image 4 - with the initial layout of the nodes on one line, their position on the y axis isn't changed:
Most scaling algorithms effectively set "springs" between nodes, where the resting length of the spring is the desired length of the edge. They then attempt to minimize the energy of the system of springs. When you initialize all the nodes on top of each other though, the amount of energy released when any one node is moved is the same in every direction. So the gradient of energy with respect to each node's position is zero, so the algorithm leaves the node where it is. Similarly if you start them all in a straight line, the gradient is always along that line, so the nodes are only ever moved along it.
(That's a flawed explanation in many respects, but it works for an intuition)
Try initializing the nodes to lie on the unit circle, on a grid or in any other fashion such that they aren't all co-linear. Assuming the library algorithm's update scheme is deterministic, that should give you reproducible visualizations and avoid degeneracy conditions.
If the library is non-deterministic, either find another library which is deterministic, or open up the source code and replace the randomness generator with a PRNG initialized with a fixed seed. I'd recommend the former option though, as other, more advanced libraries should allow you to set edges you want to "ignore" too.
I have read the codes of the "SimpleMatrix" MDS library and found that it use a random permutation matrix to decide the order of points. After fix the permutation order (just use srand(12345) instead of srand(time(0))), the result of the same data is unchanged.
Obviously there's no exact solution in general to this problem; with just 4 nodes ABCD and distances AB=BC=AC=AD=BD=1 CD=10 you cannot clearly draw a suitable 2D diagram (and not even a 3D one).
What those algorithms do is just placing springs between the nodes and then simulate a repulsion/attraction (depending on if the spring is shorter or longer than prescribed distance) probably also adding spatial friction to avoid resonance and explosion.
To keep a "stable" diagram just build a solution and then only update the distances, re-using the current position from previous solution as starting point. Picking two fixed nodes and aligning them seems a good idea to prevent a slow drift but I'd say that spring forces never end up creating a rotational momentum and thus I'd expect that just scaling and centering the solution should be enough anyway.
I have an image, holding results of segmentation, like this one.
I need to build a graph of neighborhood of patches, colored in different colors.
As a result I'd like a structure, representing the following
Here numbers represent separate patches, and lines represent patches' neighborhood.
Currently I cannot figure out where to start, which keywords to google.
Could anyone suggest anything useful?
Image is stored in OpenCV's cv::Mat class, as for graph, I plan to use Boost.Graph library.
So, please, give me some links to code samples and algorithms, or keywords.
Thanks.
Update.
After a coffee-break and some discussions, the following has come to my mind.
Build a large lattice graph, where each node corresponds to each image pixel, and links connect 8 or 4 neighbors.
Label each graph node with a corresponding pixel value.
Try to merge somehow nodes with the same label.
My another problem is that I'm not familiar with the BGL (but the book is on the way :)).
So, what do you think about this solution?
Update2
Probably, this link can help.
However, the solution is still not found.
You could solve it like that:
Define regions (your numbers in the graph)
make a 2D array which stores the region number
start at (0/0) and set it to 1 (region number)
set the whole region as 1 using floodfill algorithm or something.
during floodfill you probably encounter coordinates which have different color. store those inside a queue. start filling from those coordinates and increment region number if your previous fill is done.
.
Make links between regions
iterate through your 2D array.
if you have neighbouring numbers, store the number pair (probably in a sorted manner, you also have to check whether the pair already exists or not). You only have to check the element below, right and the one diagonal to the right, if you advance from left to right.
Though I have to admit I don't know a thing about this topic.. just my simple idea..
You could use BFS to mark regions.
To expose cv::Mat to BGL you should write a lot of code. I think writeing your own bfs is much more simplier.
Than you for every two negbours write their marks to std::set<std::pair<mark_t, mark_t>>.
And than build graph from that.
I think that if your color patches are that random, you will probably need a brute force algorithm to do what you want. An idea could be:
Do a first brute force pass. This has to identify all the patches. For example, make a matrix A of the same size as the image, and initialize it to 0. For each pixel which is still zero, start from it and mark it as a new patch, and try a brute force approach to find the whole extent of the patch. Each matrix cell will then have a value equal to the number of the patch it is in it.
The patch numbers have to be 2^N, for example 1, 2, 4, 8, ...
Make another matrix B of the size of the image, but each cell holds two values. This will represent the connection between pixels. For each cell of matrix B, the first value will be the absolute difference between the patch number in the pixel and the patch number of an adjacent pixel. First value is difference with the pixel below, second with the pixel to the left.
Pick all unique values in matrix B, you have all the connections possible.
This works because each difference between patches number is unique. For example, if in B you end up with numbers 3, 6, 7 it will mean that there are contacts between patches (4,1), (8,2) and (8,1). Value 0 of course means that there are two pixels in the same patch next to each other, so you just ignore them.
I want to find path in 2d platform game, teeworlds. The player there can move left/right, jump, and use hook, that lets you move upward the wall or move under ceiling. Well, its hard becouse normal pathfinds like a* or bfs cant exist here, cuz you cant just move up. I need to find path btw 2 players so 1 can go to the second one. There are 3 types of tiles, collide, nohook (you cant hook it) and nothing (air). I have the map in format int map[w][h] where 0=air, 1=collide, 2=nohook. map isnt modified for whole game time.
I have completly no idea how to do that. If you can help me, I'd be pleased.
PS. The question is general about platform games, teeworlds is only one of them...
From the pathfinding algorithm's standpoint you could treat the climbable walls as if they were normal walkways, so the algorithm does not stop there.
I don't think I completely understand the possibilities in your game. But this is how it works in general:
Path finding algorithms work on graphs (directed, undirected, with costs or equal costs for all edges doesn't matter). All you have to do is model your graph according to your game's rules. I.e. if there is only a normal way between field i and j than cost(i,j) = normal, if there is an additional way to use a hook, it could would be that cost(i,j) = min(hook, normal) . and so on. Once you have a graph (i assume it has to be directed for your game) all the normal Pathfinding algorithms will work.
if there are requirements like "you can only use hook n-times", a multi-label dijsktra can work.
pathfinding algorithms work on graphs in general
movement from one cell to another means that there is a connection between two cells (for instance in four directions). But you can also link to some other cell (the ceiling).
A* as a general search algorithm can still be applicable here, you just need to find a way to represent your platform game path-finding problem as a general search problem. So while you might have been introduced to A* as an algorithm to find a path through a grid-like maze, that is just a specific case of such a general search problem.
The more general case being graphs, where edges represent moves or actions and nodes represent positions or states.
One way to use A* for the game you mention is by taking an example from this Infinite Mario AI. This implementation of A* works locally and is rerun every tick to get the most optimal actions at that exact moment which is great for a fast-paced game like Mario or the game you mention, but be mindful that this is different from A* when it's used to solve a maze, in which case the path is found only once and it is like a global plan to be followed until its end.
Use simple BFS method, preprocessing the pairs to nodes.