How to properly check the available path on a maze [duplicate] - c#

What are the possible ways to solve a maze?
Ive got two ideas, but I think they are not very elegant.
Base situation: We have a matrix, and the elements in this matrix are ordered in a way that it represents a maze, with one way in, and one out.
My first idea was to send a robot through the maze, following one side, until it's out of the maze. I think this is a very slow solution.
The second one passes through every successive item marked with 1, checks where it can go (up, right, down, left) chooses one way and it continues its path there. This is even slower than the first one.
Of course it's a bit faster if I make the two bots multi-threaded at every junction, but thats also not the best way.
There needs to be better solutions to send a bot through a maze.
EDIT
First: Thanks for the nice answers!
The second part of my question is: What to do in the case if we have a multi-dimensional graph? Are there special practices for that, or is the answer of Justin L. usable for that too?
I think it's not the best way for this case.
The third question:
Which of these maze solver algorithms is/are the fastest? (Purely hypothetically)

You can think of your maze as a tree.
A
/ \
/ \
B C
/ \ / \
D E F G
/ \ \
H I J
/ \
L M
/ \
** O
(which could possibly represent)
START
+ +---+---+
| A C G |
+---+ + + +
| D B | F | J |
+---+---+ +---+---+
| L H E I |
+---+ +---+---+
| M O |
+ +---+
FINISH
(ignoring left-right ordering on the tree)
Where each node is a junction of paths. D, I, J, L and O are dead ends, and ** is the goal.
Of course, in your actual tree, each node has a possibility of having as many as three children.
Your goal is now simply finding what nodes to traverse to to find the finish. Any ol' tree search algorithm will do.
Looking at the tree, it's pretty easy to see your correct solution by simply "tracing up" from the ** at the deepest part of the tree:
A B E H M **
Note that this approach becomes only slightly more complicated when you have "loops" in your maze (i.e., when it is possible, without backtracing, you re-enter a passage you've already traversed through). Check the comments for one nice solution.
Now, let's look at your first solution you mentioned, applied to this tree.
Your first solution is basically a Depth-First Search, which really isn't that bad. It's actually a pretty good recursive search. Basically, it says, "Always take the rightmost approach first. If nothing is there, backtrack until the first place you can go straight or left, and then repeat.
A depth-first search will search the above tree in this order:
A B D (backtrack) E H L (backtrack) M ** (backtrack) O (backtrack thrice) I
(backtrack thrice) C F (backtrack) G J
Note that you can stop as soon as you find the **.
However, when you actually code a depth-first search, using recursive programming makes makes everything much easier. Even iterative methods work too, and you never have to explicitly program how to backtrack. Check out the linked article for implementations.
Another way of searching a tree is the Breadth-First solution, which searches through trees by depth. It'd search through the above tree in this order:
A (next level) B C (next level) D E F G (next level)
H I J (next level) L M (next level) ** O
Note that, due to the nature of a maze, breadth-first has a much higher average amount of nodes it checks. Breadth-first is easily implementing by having a queue of paths to search, and each iteration popping a path out of a queue, "exploding it" by getting all of the paths that it can turn into after one step, and putting those new paths at the end of the queue. There are no explicit "next level" commands to code, and those were just there to aid in understanding.
In fact, there is a whole expansive list of ways to search a tree. I've just mentioned the two simplest, most straightforward way.
If your maze is very, very long and deep, and has loops and crazies, and is complicated, I suggest the A* algorithm, which is the industry standard pathfinding algorithm which combines a Breadth-First search with heuristics...sort of like an "intelligent breadth-first search".
It basically works like this:
Put one path in a queue (the path where you only walk one step straight into the maze). A path has a "weight" given by its current length + its straight-line distance from the end (which can be calculated mathematically)
Pop the path with the lowest weight from the queue.
"Explode" the path into every path that it could be after one step. (i.e., if your path is Right Left Left Right, then your exploded paths are R L L R R and R L L R L, not including illegal ones that go through walls)
If one of these paths has the goal, then Victory! Otherwise:
Calculate the weights of the exploded paths, and put all of them back into the queue (not including the original path)
Sort the queue by weight, lowest first. Then repeat from Step #2
And that's A*, which I present specially highlighted because it is more or less the industry standard pathfinding algorithm for all applications of pathfinding, including moving from one edge of the map to another while avoiding off-road paths or mountains, etc. It works so well because it uses a shortest possible distance heuristic, which gives it its "intelligence". A* is so versatile because, given any problem, if you have a shortest possible distance heuristic available (ours is easy -- the straight line), you can apply it.
BUT it is of great value to note that A* is not your only option.
In fact, the wikipedia category of tree traversal algorithms lists 97 alone! (the best will still be on this page linked earlier)
Sorry for the length =P (I tend to ramble)

Lots of maze-solving algorithms exist:
http://en.wikipedia.org/wiki/Maze_solving_algorithm
http://www.astrolog.org/labyrnth/algrithm.htm#solve
For a robot, Tremaux's algorithm looks promising.

An interesting approach, at least I found it interesting, is to use cellular automata. In short a "space" cell surrounded by 3 "wall" cells turns into a "wall" cell. At the end the only space cells left are the ones on route to the exit.
If you look at the tree Justin put in his answer then you can see that leaf nodes have 3 walls. Prune the tree until you have a path.

This is one of my favorite algorithms ever....
1) Move forward
2) Are you at a wall?
2a) If yes, turn left
3) Are you at the finish?
3a) If no, go to 1
3b) If yes, solved

How about building a graph out of your Matrix and using Breadth First Search, Depth First Search or Dijkstras Algorithm?

I had a similar problem in one of my University Comp. Sci. courses. The solution we came up with was to follow the left hand wall (right hand wall will work just as well). Here is some pseudocode
While Not At End
If Square To Left is open,
Rotate Left
Go Forward
Else
Rotate Right
End If
Wend
That's basically it. The complex part is keeping track of which direction your facing, and figuring out which grid position is on your left based on this direction. It worked for any test case I put up against it. Interesting enough the Professors solution was something along the lines of:
While Not At End
If Can Go North
Go North
ElseIf Can Go East
Go East
ElseIf Can Go South
Go South
ElseIf Can Go West
Go West
EndIf
Wend
Which will work well for most simple mazes, but fails on the a maze that looks like the following:
SXXXXXXXXXXXXX
X X
X X
X X
XXX X
X X X
X XXXXXXXXXXX XXXE
X X
XXXXXXXXXXXXXXXXXXX
With S and E being the start and end.
With anything that doesn't follow the wall, you end up having to keep a list of the places you have been, so that you can backtrack if necessary, when you fall into a dead end, and so that you don't get caught in a loop. If you follow the wall, there's no need to keep track of where you've been. Although you won't find the most optimal path through the maze, you will always get through it.

This is a very simple representation to simulate maze in C++ :)
#ifndef vAlgorithms_Interview_graph_maze_better_h
#define vAlgorithms_Interview_graph_maze_better_h
static const int kMaxRows = 100;
static const int kMaxColumns = 100;
class MazeSolver
{
private:
char m_matrix[kMaxRows][kMaxColumns]; //matrix representation of graph
int rows, cols; //actual rows and columns
bool m_exit_found;
int m_exit_row, m_exit_col;
int m_entrance_row, m_entrance_col;
struct square //abstraction for data stored in every verex
{
pair<int, int> m_coord; //x and y co-ordinates of the matrix
square* m_parent; //to trace the path backwards
square() : m_parent(0) {}
};
queue<square*> Q;
public:
MazeSolver(const char* filename)
: m_exit_found(false)
, m_exit_row(0)
, m_exit_col(0)
, m_entrance_row(0)
, m_entrance_col(0)
{
ifstream file;
file.open(filename);
if(!file)
{
cout << "could not open the file" << endl << flush;
// in real world, put this in second phase constructor
}
init_matrix(file);
}
~MazeSolver()
{
}
void solve_maze()
{
//we will basically use BFS: keep pushing squares on q, visit all 4 neighbors and see
//which way can we proceed depending on obstacle(wall)
square* s = new square();
s->m_coord = make_pair(m_entrance_row, m_entrance_col);
Q.push(s);
while(!m_exit_found && !Q.empty())
{
s = Q.front();
Q.pop();
int x = s->m_coord.first;
int y = s->m_coord.second;
//check if this square is an exit cell
if(x == m_exit_row && y == m_exit_col)
{
m_matrix[x][y] = '>'; // end of the path
m_exit_found = true;
//todo: try breaking? no= queue wont empty
}
else
{
//try walking all 4 neighbors and select best path
//NOTE: Since we check all 4 neighbors simultaneously,
// the path will be the shortest path
walk_path(x-1, y, s);
walk_path(x+1, y, s);
walk_path(x, y-1, s);
walk_path(x, y+1, s);
}
} /* end while */
clear_maze(); //unset all previously marked visited shit
//put the traversed path in maze for printing
while(s->m_parent)
{
m_matrix[s->m_coord.first][s->m_coord.second] = '-';
s = s->m_parent;
} /* end while */
}
void print()
{
for(int i=0; i<rows; i++)
{
for(int j=0; j<cols; j++)
cout << m_matrix[i][j];
cout << endl << flush;
}
}
private:
void init_matrix(ifstream& file)
{
//read the contents line-wise
string line;
int row=0;
while(!file.eof())
{
std::getline(file, line);
for(int i=0; i<line.size(); i++)
{
m_matrix[row][i] = line[i];
}
row++;
if(line.size() > 0)
{
cols = line.size();
}
} /* end while */
rows = row - 1;
find_exit_and_entry();
m_exit_found = false;
}
//find and mark ramp and exit points
void find_exit_and_entry()
{
for(int i=0; i<rows; i++)
{
if(m_matrix[i][cols-1] == ' ')
{
m_exit_row = i;
m_exit_col = cols - 1;
}
if(m_matrix[i][0] == ' ')
{
m_entrance_row = i;
m_entrance_col = 0;
}
} /* end for */
//mark entry and exit for testing
m_matrix[m_entrance_row][m_entrance_col] = 's';
m_matrix[m_exit_row][m_exit_col] = 'e';
}
void clear_maze()
{
for(int x=0; x<rows; x++)
for(int y=0; y<cols; y++)
if(m_matrix[x][y] == '-')
m_matrix[x][y] = ' ';
}
// Take a square, see if it's the exit. If not,
// push it onto the queue so its (possible) pathways
// are checked.
void walk_path(int x, int y, square* parent)
{
if(m_exit_found) return;
if(x==m_exit_row && y==m_exit_col)
{
m_matrix[x][y] = '>';
m_exit_found = true;
}
else
{
if(can_walk_at(x, y))
{
//tag this cell as visited
m_matrix[x][y] = '-';
cout << "can walk = " << x << ", " << y << endl << flush;
//add to queue
square* s = new square();
s->m_parent = parent;
s->m_coord = make_pair(x, y);
Q.push(s);
}
}
}
bool can_walk_at(int x, int y)
{
bool oob = is_out_of_bounds(x, y);
bool visited = m_matrix[x][y] == '-';
bool walled = m_matrix[x][y] == '#';
return ( !oob && !visited && !walled);
}
bool is_out_of_bounds(int x, int y)
{
if(x<0 || x > rows || y<0 || y>cols)
return true;
return false;
}
};
void run_test_graph_maze_better()
{
MazeSolver m("/Users/vshakya/Dropbox/private/graph/maze.txt");
m.print();
m.solve_maze();
m.print();
}
#endif

Just an idea. Why not throw some bots in there in the monte carlo fashion.
Let's call the first generation of bots gen0.
We only keep the bots from gen0 that have some continuous roads in this way:
-from the start to some point
or -from some point to the end
We run a new gen1 of bots in new random dots, then we try to connect the roads of the bots of gen1 with those of gen0 and see if we get a continous road from start to finish.
So for genn we try to connect with the bots form gen0, gen1, ..., genn-1.
Of course a generation lasts only a feasibil finit amount of time.
I don't know if the complexion of the algorithm will prove to be practical for small data sets.
Also the algorithm assumes we know start and finish points.
some good sites for ideas:
http://citeseerx.ist.psu.edu/
http://arxiv.org/

If the robot can keep track of its location, so it knows if it has been to a location before, then depth-first search is the obvious algorithm. You can show by an adversarial argument that it is not possible to get better worst-case performance than depth-first search.
If you have available to you techniques that cannot be implemented by robots, then breadth-first search may perform better for many mazes, as may Dijkstra's algorithm for finding the shortest path in a graph.

Same answer as all questions on stack-overflow ;)
Use vi!
http://www.texteditors.org/cgi-bin/wiki.pl?Vi-Maze
It's truly fascinating to see a text editor solve an ascii-maze, I'm sure the emacs guys have an equivalent ..

there are many algorithms, and many different settings that specify which algorithm is best.
this is just one idea about an interesting setting:
let's assume you have the following properties...
you move a robot and you want to minimize its movement, not its CPU usage.
that robot can either inspect only its neighbouring cells or look along corridors either seeing or not seeing cross-ways.
it has GPS.
it knows the coordinates of its destination.
then you can design an A.I. which...
draws a map – every time it receives new information about the maze.
calculates the minimal known path lengths between all unobserved positions (and itself and the destination).
can prioritize unobserved positions for inspection based upon surrounding structures. (if it is impossible to reach the destination from there anyway...)
can prioritize unobserved positions for inspection based upon direction and distance to destination.
can prioritize unobserved positions for inspection based upon experience about collecting information. (how far can it see on average and how far does it have to walk?)
can prioritize unobserved positions to find possible shortcuts. (experience: are there many loops?)

This azkaban algorithm might also help you,
http://journals.analysisofalgorithms.com/2011/08/efficient-maze-solving-approach-with.html

The best way to solve a maze is to use a connectivity algorithm such as union-find which is a quasi-linear time algorithm assuming path compression is done.
Union-Find is a data structure that tells you whether two elements in a set are transitively connected.
To use a union-find data structure to solve a maze, first the neighbor connectivity data is used to build the union-find data structure. Then the union find is compressed. To determine whether the maze is solvable the entrance and exit values are compared. If they have the same value, then they are connected and the maze is solvable. Finally, to find a solution, you start with the entrance and examine the root associated with each of its neighbors. As soon as you find a previously unvisited neighbor with the same root as the current cell, you visit that cell and repeat the process.
The main disadvantage of this approach is that it will not tell you the shortest route through the maze, if there is more than one path.

Not specifically for your case, but I've come across several programming contest questions where I found the Lee's algorithm quite handy to code up quickly. Its not the most efficient for all cases, but is easy to crank out. Here's one I hacked up for a contest.

Related

Maze Recursion and shortest path

I know this isn't perfect, and I know that it isn't near done. The board is a 19 by 19 array, where 1's represent empty squares. Right now, it will go straight down, then go west. If there is a wall to the left of it, then it will have a stack overflow. The reason why is when it trys to 'climb' up the wall, it ends up going back down over and over and crashes. Even if I fix this, though, it wont find the shortest path. The solutions I've found draw paths, not count how many squares it is away.
private static int turnsforshortestmove(Vector2 location, int[,] board, int endrow)
{
if (location.Y == endrow)
{
return 0;
}
if (board[(int)location.X, (int)location.Y - 1] == 1)
{
return 1 + turnsforshortestmove(new Vector2(location.X, location.Y - 2), board, endrow);
}
else if (board[(int)location.X - 1, (int)location.Y] == 1)
{
return 1 + turnsforshortestmove(new Vector2(location.X - 2, location.Y), board, endrow);
}
else if (board[(int)location.X, (int)location.Y + 1] == 1)
{
return 1 + turnsforshortestmove(new Vector2(location.X, location.Y + 2), board, endrow);
}
else if (board[(int)location.X + 1, (int)location.Y ] == 1)
{
return 1 + turnsforshortestmove(new Vector2(location.X + 2, location.Y), board, endrow);
}
return 0;
}
This is a path-finding problem. As SJuan76 has already suggested, Dijkstra's algorithm is the best starting point for this sort of problem.
Given a grid-style map of open/blocked squares where only orthogonal moves (up, down, left and right) are allowed and each move costs the same amount, finding a path from one grid cell to another involves a fairly simple but time-consuming iteration over possible moves.
The basic principle is to create a list of possible moves and process each one looking for the shortest path. In each step you check the possible moves from the current position, check if the target location has been moved to previously, and add the ones that haven't been checked already - or that can be moved to more quickly than the previous check - to the list to be processed. Keep processing the list until you find the location you're aiming for.
How you do this is the fun part.
There are a few things you need to get started on this:
A method for finding possible moves from an arbitrary point in the grid.
A way to track locations you've already visited, and what location they were visited from.
A fast way to figure out the best location to check next.
Given that you're working from a simple square grid, that you're only doing orthogonal moves (up, down, left, right) and that all moves will cost the same, you can gloss over some of the concepts that are not useful in your scenario. So...
Create two collections: one to store the list of locations to process, and one to store the list of visited locations.
Add your starting point to the process list.
While the process list is not empty
Get the next location from the process list
If current location is the target, return the list of previous locations that form the path.
Find available moves from that location, excluding any moves in the visited list
Push all un-visited possible moves into the process list
Eventually, one of two things will happen: either you'll run out of possible moves that haven't already been checked, or you will find your target point.
Here's a structure similar to what I used last time I did path-finding like this:
public struct SearchNode
{
public Vector2 position;
public SearchNode prior;
public int TotalCost;
}
The visited list can be done with a Dictionary:
var visited = new Dictionary<Vector2, SearchNode>();
The process list can be done with a bunch of collection types. The simplest form would be:
var process = new Queue<Vector2>();
Hopefully I've given you something to start with.

Fill poker pots

Essentially there is a table and player A raises to 100$, player B calls (accepts), player C only has 50$ so the pots are created as 100$ (between player A and B) and 150$ (between all three players because everyone chips in at 50$).
How would I implement such a function and handle all the pots properly?
This is what I have so far:
static public void FillPots(Room r, decimal Val, int Player)
{
decimal NewRaise = Val;
if (NewRaise > 0)
{
foreach (Program.Player pz in r.Seated)
{
if (pz == null) { continue; }
if (pz.BuyIn < NewRaise)
{
Pot _pot = new Pot { PotSize = r.MaxPlayers, PotBuy = (NewRaise - pz.BuyIn), PotVal = new decimal[r.MaxPlayers] };
Array.Clear(_pot.PotVal, 0, r.MaxPlayers);
r.Pots.Add(_pot);
NewRaise -= (NewRaise - pz.BuyIn);
}
}
}
for (int i = 0; i < r.Pots.Count; i++)
{
if (r.Pots[i].PotVal[Player] == 0m && NewRaise >= r.Pots[i].PotBuy)
{
r.Pots[i].PotVal[Player] += r.Pots[i].PotBuy;
NewRaise -= r.Pots[i].PotBuy;
}
}
if (NewRaise > 0)
{
Pot _pot = new Pot { PotSize = r.MaxPlayers, PotBuy = (NewRaise), PotVal = new decimal[r.MaxPlayers] };
Array.Clear(_pot.PotVal, 0, r.MaxPlayers);
_pot.PotVal[Player] += NewRaise;
r.Pots.Add(_pot);
NewRaise = 0;
}
}
It's all pretty confusing. It is critical to keep the position of every individual player relative to the player number (int Player) within the array.
I can't speak to C#, but since you have no answers here I'll tell you in general how to handle poker pots. There are two methods: pot-centric and player-centric. I generally prefer the latter since there is less data to manage.
You need one variable for the "combined pot" (let's call it POT), one variable for the "current total bet amount" (CBET), one for last raise amount (LRAISE), and three variables for each player: stake (PSTAKE[N]), "current bet" (PBET[N]), "contribution to pot" (PCONTRIB[N]).
When the hand is dealt, set POT and each player's PCONTRIB[] to 0. If there were antes, add them to POT and to each player's PCONTRIB[], removing them from PSTAKE[].
At the start of each betting round, set CBET, LRAISE and all PBET[] to 0. If this is the first round, and there are blinds, set those players' PBET[] to the blind amounts, removing them from PSTAKE[].
Each player in turn has three choices: (1) fold (you might want to disallow this if CBET is 0), (2) call, in which case he must make his PBET[] equal to CBET (if CBET is 0, this is called a "check", otherwise the call amount is CBET-PBET[], which must be moved from PSTAKE[] to PBET[]). (3) raise, in which the player must increase the CBET amount by at least LRAISE (and obeying any other limits, this amount becoming the new LRAISE), moving the needed amount from his stake. Note: you also need to keep track of who the last raiser was, so that he is not allowed to raise himself.
If the player's stake is insufficient to call or raise, he can go "all in" (if otherwise allowed) moving his entire stake to his PBET[]. When all players have called CBET or gone all in, the betting round is over. If one player raised, all the others folded, and none is all in, then just award the pot to the raiser. Otherwise for each player, add his PBET[] to his PCONTRIB[] and to the POT.
If hand continues to showdown, award the pot like this: Start with the best hand: his winnable amount (W) is his PCONTRIB[]. Go to each player (including him), subtract from POT the lesser of W and that player's PCONTRIB[], and award it to winner. Remove winner from player list, remove any players whose PCONTRIB[] is now 0, and continue with next best hand. Remove that winner, etc., and continue until POT is 0.
The pot-centric method I think is more complex. Instead of keeping each player's contribution, you keep a list of central pot and side pots, and for each pot a list of players involved in that pot (there might be as many pots as players). Then the pots are awarded outside-in, instead of inside-out as above. This is more like how dealers are taught to do it in real games.
Update:
I just realized I was "skipping ahead" and not actually answering what OP was asking. But I'll leave my answer here because this question still shows up in searches related to programmatic poker pot resolution. I had already developed all the action logic prior to resolving where the chips all go.
Previous Answer:
Is it ever too late to answer an unanswered question? I was also looking for the answer to this. The answers I found were a bit confusing, so I finally wrote my own code on dotnetfiddle:
https://dotnetfiddle.net/P0wgR5
Seeing as how I didn't do it exactly as Lee Daniel Crocker mentioned, I wonder if there are bugs with what I've done. I'd be happy to fix them and update code here.
I'm not sure if it's good practice to paste 140 lines of code into StackOverflow, but that's how many lines I ended up with. The console shows what's being done, and you can experiment with hand creation in the Main function.
I tested this thoroughly, and compared the results to this pot calculator:
https://www.pokerlistings.com/rules-for-poker-all-in-situations-poker-side-pot-calculator
The results appeared to line up.

Local Thresholding or Binarization of Text in an image

Im developing an application to exctract text in C# in different light condition.
My problem is that sometimes there are different brightness levels in the image, like this:
So i cant utilize a pre-calculated threshold for the whole image, or i will loose some letters.
Im searching an algorithm/snippet/function or else, that can apply the right Threshold/Binarization to the image.
I founded thhis BradleyLocalThresholding in AForge, is better than other non adaptive methods, but it loose some details. ( for example the G in the image become an O )
Anyone can suggest to me a better way?
yes, use niblack (opencv has it as a function) - basically it uses the local average to construct a variable theshold. it works best for OCR. depending on the image resolution you might also want to bicubically upsample by a factor of 2x or 3x BEFORE thresholding.
Its quite difficult since the quality of your images are so low, but you could try an iterative global thresholding approach as follows:
Randomly select an initial estimate threshold T (usually as the mean).
Segment the signal using T, which will yield two groups, G1 consisting of all points with values<=T and G2 consisting of points with value>T.
Compute the average distance between points of G1 and T, and points of G2 and T.
Compute a new threshold value T=(M1+M2)/2
Repeat steps 2 through 4 until the change of T is smaller enough.
The trick is not to apply it to the whole image, but to break up the image into blocks of (for example) 5x5 and apply it to the blocks individually which would give you:
Below is an implementation in R which I'm sure you could reproduce
getT = function(y){
t = mean(y)
mu1 = mean(y[y>=t])
mu2 = mean(y[y 1){
cmu1 = mean(y[y>=t])
cmu2 = mean(y[y 1 & cmu1 == mu1 & cmu2 == mu2){
print(paste('done t=', t))
return(t)
break;
}else{
mu1 = cmu1
mu2 = cmu2
t = (mu1 + mu2)/2
print(paste('new t=', t))
}
i = i+1
}
}
r = seq(1, nrow(image), by=5)
c = seq(1, ncol(image), by=5)
r[length(r)] = nrow(image)
c[length(c)] = ncol(image)
y = image
for(i in 2:length(r) ){
for(j in 2:length(c) ){
block = image[r[i-1]:r[i], c[j-1]:c[j]]
t = getT(block)
y[r[i-1]:r[i], c[j-1]:c[j]] = (block>t)+0
}
}
display(y)
The other option besides a local threshold would be to adjust for the varying illumination. There are methods that attempt to correct the illumination and make it uniform across the image. You could then use a constant threshold, or continue to use a local threshold, with perhaps better success. If the images are like the one you show, then you could use the brighter squares around the letters as the key to adjusting the illumination.

2d tile based map - How to repeat map on edges?

I'm making a platformer, with tile based map (like a lot of people). I begin in video games's developing so it's a little hard. I wan't to learn by myself but on this problem I'm stuck .
My maps are made with a list like this :
mapList[x][y] = tile
With this list, I can loop on all the Tiles and draw them.
What I want to do is to "Loop" (repeat) the map. I mean, when the character reach the right limit (or left), the map repeats. I don't understand how to do this, I search all the forums and all the question, but I found nothing :(
For instance
I don't know if I'm making myself clear but English is not my best language and i'm sorry for this :p.
Thanks in advance for trying to help me or just for reading my issue.
When you have a grid that is WxH cells, the valid ranges for X are 0..W-1
So as a first approach :
int nextX = (X+1) % W; // wraps around to 0
but you'll also need something for prevX (X-1) and maybe for X+d where d can be positive or negative.
You don't want to mess with the modulo of negative numbers, so
int MoveX(int d) { return (X+W+d) % W; }

Getting the distance between geographically placed objects

I have an application (cad like editor) in which the user may place a lot of positional nodes (defined by their latitude and longitude). The application needs to tell the user if these nodes are very close together - a common design error is to overlap them. What the app is doing is something rather like ReSharper or CodeRush does in the IDE - parses the project and reports problems. A project may have several thousand of these nodes so testing for overlap becomes exponetially more time consuming as the numbers go. At the moment I am using two for loops to get through the list.
for (int i = 0; i < count - 1; i++) {
for (int j = i + 1; j < count; j++) {
// check the distance between the i and j elements and if less than
// a predetermined value report it
}
}
I would like to get the process of identifying these into 'real time' so that the user is told at once in the event that an overlap occurs. The looping is expensive as is the testing of the distance between nodes. Most of the comparisons are wasted of course.
I just wonder if there is another way. I have thought about sorting the list by lat and lon and comparing adjacent elements but I suspect that will not work nor necessarily be faster.
My other thought is to move the activity to another thread (I really have no experience of using multiple threads) so that the values are being updated - for example storing a reference to nearby nodes in each object. However I can imagine needing to clone the object tree for the background thread so that there is no conflict with the foreground.
You could look into Tessealtion.
Executing this on another Thread is a completely separate issue, you could do that with your nested loops as well as with a more efficient algorithm.
Since the user is placing these locations, the ideal solution would be to assume all previously placed points are not nearby, and with each new point or moved point, check against the rest -- this becomes a single for loop, which should be reasonable.
Another, more ideal solution however:
Let position of A be lat, lng.
Convert both lat and lng to a fixed-length representation
(truncating the degree of precision to a value below which
you are sure they will overlap)
Let xa = lat . lng (concatenate both)
Let ya = lng . lat
Given some position B, find xb, yb.
B is 'close' to A iff | xa - xb | < delta, | ya - yb | < delta.
So what you can do is sort the values of xi, yi for all your input points. When you want to check for points that are too close, you need to traverse through the list of xi's to find points that are too close together (linear time, since they will be adjacent) and then check if the same points in the list of yi's are too close.
Thanks to the insights given here I think I have found a reasonable way to deal with this.
*First to sort all the points in latitude order.
*Then loop through the sorted list.
*For each entry in the list compare the latitude offset (distance in meters) to the entries below it.
*If the latitude offset is less than the test distance then check the actual distance from point to point and if it is inside the test radius report the issue.
*When the latitude offset exceeds the test distance move on to the next point in the list and repeat the tests.
I have not written the code yet but it seems to me that if there are no overlaps then I will make a single pass. Since overlaps are rare in practice then the total number of tests is likely to be quite small. For 1000 points the current method makes 500,000 tests. The new method is unlikely to make more than a few thousand.

Categories

Resources