Fast algorithm for line of sight calculation in an RTS game - algorithm

I'm making a simple RTS game. I want it to run very fast because it should work with thousands of units and 8 players.
Everything seems to work flawlessly but it seems the line of sight calculation is a bottleneck. It's simple: if an enemy unit is closer than any of my unit's LOS range it will be visible.
Currently I use a quite naive algorithm: for every enemy units I check whether any of my units is see him. It's O(n^2)
So If there are 8 players and they have 3000 units each that would mean 3000*21000=63000000 tests per player at the worst case. Which is quite slow.
More details: it's a stupid simple 2D space RTS: no grid, units are moving along a straight lines everywhere and there is no collision so they can move through each other. So even hundreds of units can be at the same spot.
I want to speed up this LOS algorithm somehow. Any ideas?
EDIT:
So additional details:
I meant one player can have even 3000 units.
my units have radars so they towards all directions equally.

Use a spatial data structure to efficiently look up units by location.
Additionally, if you only care whether a unit is visible, but not which unit spotted it, you can do
for each unit
mark the regions this unit sees in your spatial data structure
and have:
isVisible(unit) = isVisible(region(unit))
A very simple spatial data structure is the grid: You overlay a coarse grid over the playing field. The regions are this grid's cells. You allocate an array of regions, and for each region keep of list of units presently in this region.
You may also find Muki Haklay's demonstration of spatial indexes useful.

One of the most fundamental rules in gamedev is to optimize the bejeebers out of your algorithms by exploiting all possible constraints your gameplay defines - this is the main reason that you don't see wildly different games built on top of any given companies game engine, they've exploited their constraints so efficiently that they can't deal with anything that isn't within these constraints.
That said, you said that units move in straight lines - and you say that players can 3000 units - even if I assume that's 3000 units for eight players, that's 375 units per player, so I think I'm safe in assuming that on each step of game play (and I am assuming that each step involves the calculation you describe above) that more units will not change their direction than units that will change direction.
So, if this is true, then you want to divide all your pieces into two groups - those that did change direction in the last step, and those that did not.
For those that did, you need to do a bit of calulating - for units of any two opposing forces, you want to ask 'when will unit A see unit B given that neither unit A nor unit B change direction or speed ?(you can deal with accelleration/decelleration, but then it gets more complicated) - to calculate this you need first to determine if the vectors that unit A and unit B are travelling on will intersect (simple 2D line intersection calculation, combined with a calculation that tells you when each unit hits this intersection) - if they don't, and they can't see each other now, then they never will see each other unless at least one of them changes direction. If they do intersect, then you need to calculate the time differential between when the first and second unit pass through the point of intersection - if this distance is greater than the LOS range, then these units will never see each other unless one changes direction - if this differential is less than the LOS range then a few more (wave hands vigorously) calculations will tell you when this blessed event will take place.
Now, what you have is a collection of information bifurcated into elements that never will see each other and elements that will see each other at some time t in the future - each step, you simply deal with the units that have changed direction and compute their interactions with the rest of the units. (Oh, and deal with those units that previous calculations told you would come into view of each other - remember to keep these in an insertable ordered structure) What you've effectively done is exploited the linear behavior of the system to change your question from 'Does unit A see unit B' to 'When will unit A see unit B'
Now, all of that said, this isn't to discount the spatial data structure answer - it's a good answer - however, it is also capable of dealing with units in random motion, so you want to consider how to optimize this process further - you also need to be careful about dealing with cross region visibility, i.e. units at the borders of two different regions may be able to see each other - if you have pieces that tend to clump up, using a spatial data structure with variable dimensions might be the answer, where pieces that are not in the same region are guaranteed not to be able to see each other.

I'd do this with a grid. I think that's how commercial RTS games solve the problem.
Discretize the game world for the visibility tracker. (Square grid is easiest. Experiment with the coarseness to see what value works best.)
Record the present units in each area. (Update whenever a unit moves.)
Record the areas each player sees. (This has to be updated as units move. The unit could just poll to determine its visible tiles. Or you could analyze the map before the game starts..)
Make a list (or whatever structure is fitting) for the enemy units seen by each player.
Now whenever a unit goes from one area of visibility to another, perform a check:
Went from an unseen to a seen area - add the unit to the player's visibility tracker.
Went from a seen to an unseen area - remove the unit from the player's visibility tracker.
In the other two cases no visibility change occurred.
This is fast but takes some memory. However, with BitArrays and Lists of pointers, the memory usage shouldn't be that bad.
There was an article about this in one of the Game Programming Gems books (one of the first three, I think.)

Related

Collision Management in a Simulation with Discrete Motion

I am building a simulation in which items (like chess pieces) move on a discrete set of positions that do not follow a sequence (like positions on a chessboard) according to a schedule.
Each position can hold only one item at any given time. The schedule could ask multiple items to move at the same time. If the destination position is occupied, the scheduled movement is cancelled.
Here is the question: if item A and item B, originally situated at position 1 and position 2 respectively, are scheduled to move simultaneously to their next positions position 2 and position 3, how do I make sure that item A gets to position 2, hopefully in an efficient design?
The reason to ask this question is that naively I would check whether position 2 is being occupied for item 1 to move into. If the check happens before item B is moved out of the way, item 1 would not move while in fact it should. Because the positions do not follow a sequence, it is not obvious which one to check first. You could imagine things gets messy if many items want to move at the same time. In the extreme case, a full chessboard of items should be allowed to move/rearrange themselves but the naive check may not be able to facilitate that.
Is there a common practice to handle such "nonexistent collision"? Ideas and references are all welcomed.
Two researchers, Ahmed Al Rowaei and Arnold Buss, published a paper in 2010 investigating the impact that using discrete time steps has on model accuracy/fidelity when the real-world system is event-based. There was also some follow-on work in 2011 with their colleague Stephen Lieberman. A major finding was that if you use time stepped models, order of execution matters and can cause the models to deviate from real-world behaviors in significant ways. Time-stepped models generally require you to introduce tie-breaking logic which doesn't exist in the real system. Logic that is needed for the model but doesn't exist in reality is called a "modeling artifact," and can lead to increased model complexity and inaccuracies. Systematic collision resolution schemes can lead to systematic biases.
Their recommendation was to build models based on continuous time. Events are scheduled using the actual (continuous) event times, which determine the order of event execution as in the real-world system. This occasionally (but rarely) requires priority tie breaking based on event type, so that (for example) departure events occur before arrival events if both were to occur at the exact same time.
If you insist on sticking with time-stepped models, a different strategy is to use two or more passes at each time step. The first pass lays out the desired state transitions and identifies potential conflicts, the last pass applies the actual transitions after conflicts have been resolved. The resolution process might be do-able in the initial setup pass, or may require additional passes if it's sufficiently complex.

Need some suggestions on what algorithm to use [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
Its a simple game in c++ .
There are 5 random towers generated in coordinate range (0.0f,0.0f) to (10.0f,10.0f).
They have random hp,range and damage capped within a certain limit. They can't move.
Now , 10 units are added on the map with fixed movement speed, hp and damage.
No of units and towers will be fixed through simulations . Only their initial position will be randomized.
1000 simulations are to be run.
Goal is to achieve a win rate of 90% approx for units.
A game is won when units destroy all of the towers . Units can move at a predefined speed towards tower. Each simulation takes multiple rounds to complete. In each round unit move towards best selected target and attack if within a certain range. Similarly towers pick any one unit within its attack range and keeps attacking it until it dies or moves out of range.
I need some pointers on what algorithms shall i invest my time in to achieve the same.
Currently , I am able to achieve 84.2% win rate using some weighted average of distance from unit, hp ,range and damage of towers and selecting the tower which scores least on these criteria. Moving towards tower with least distance from unit without considering other attributes achieves a win rate of approx 72 % .
From comment of deleted answer:
There is one more restriction . I can just select a target each time. The units will make sure to move towards that target . I am not supposed to modify the part where units move towards target . So , there has to be a target tower each round of a simulation towards which unit targeting it will move. So , there is no way i can move my units away from tower to a safe area and assemble them at a point and then plan my attack.
I've had a better idea for a formula to select what tower to attack.
For each of the warriors use it to get a "score" for each tower. Then select the tower with the highest score
a1*todalDmgFromOtherWarriorsAimedAtThatTower - a2*towerRange - a3*towerDamage - a4*towerHP - a5*distance/speed
a1-a5 should be modified again and again until you get the optimal result making some parameters more important than others
If there is no time limit or advantage for time, I would try to go for a grouped approach - let all units attack the same tower together, and have all units enter the tower's attack range at the exact same time. This may actually end up not taking that much longer, since you'll fire faster while taking less damage and thus not have to account for preventing units from dying as much, also producing a much higher (if not perfect) win rate.
You can possibly have a specific unit (one with the highest HP?) enter the range slightly before the other units so it draws fire and can move out of range when it's close to death. If the strongest unit has moved out of range, you can either move the next attacked unit out of range too (and so on) or simply continue attacking until the tower is destroyed.
You'll have to play around with which tower to attack first. Probably the weakest (lowest HP + damage), but you may not want to send in your strongest unit to draw fire, because you probably want to keep this for the last, strongest tower.
Moving a unit such to avoid the attack range of all the towers to get to the desired tower may be difficult. Some options:
Leave the unit where it is.
Pick towers strategically to 'untrap' the strongest units.
Attack multiple towers.
If all of this sounds like a near-impossible task, requiring some really advanced AI, note that it may be a lot simpler than you think. Just ignore most of the constraints to start and add them in one at a time, as in start simple and build it up from there. But yes, it's a lot more difficult than your individual approach; the main difficulty lies in the geometry calculations and playing around a bit to find the best order of attack for the towers and order of damage-takers.
How I would probably approach this: (test the efficiency at every step and stop when you're happy)
Write a heuristic to determine the best tower. Move all your units there to attack it (ignoring all other towers). Repeat until the game ends. This should be really simple.
Modify to wait until most units are there before entering the tower range. Shouldn't be too difficult.
You can stop here if you want, before any difficult stuff starts happening (maybe hack at it a little to improve), thus it shouldn't have taken you too long, and simply compare this to your current approach.
Write some simple code to have units move around other towers (if possible).
Modify your picking-tower code to redetermine a tower if some units can't get there.
Incrementally make everything more complicated.
Side note - Since the towers are static, you can determine the time it will take to get to a tower ahead of time, so you can just wait at a safe spot (rather than just outside range of the tower, which may be inside range of multiple other towers) if other units will take longer to get there.
Additional note - If units can be ranged too, if any unit has a longer attack range than any tower, it would be most efficient to have that unit solo that tower until it is destroyed (FREE KILL!).

Dividing the world in a thousand or so locations

Background: I want to create a weather service, and since most available APIs limit the number of daily calls, I want to divide the planet in a thousand or so areas.
Obviously, internet users are not uniformly distributed, so the sampling should be finer around densely populated regions.
How should I go about implementing this?
Where can I find data regarding geographical internet user density?
The algorithm will probably be something similar to k-means. However, implementing it on a sphere with oceans may be a bit tricky. Any insight?
Finally, maybe there is a way I can avoid doing all of this?
Very similar to k-mean is the centroidal Voronoi diagram (it is the continuous version of k-means). However, this would produce a uniform tesselation of your sphere that does not account for user density as you wish.
So a similar solution is the same technique but used with a Power Diagram : a Power Diagram is a Voronoi Diagram that accounts for a density (by assigning a weight to each Voronoi seed). Such diagram can be computed using an embedding in a 3D space (instead of 2D) that consists of the first two (x,y) coordinates plus a third one which is the square root of [any large positive constant minus the weight for the given point].
Using that, you can obtain a tesselation of your domain accounting for a user density.
You don't care about internet user density in general. You care about the density of users using your service - and you don't care where those users are, you care where they ask about. So once your site has been going for more than a day you can use the locations people ask about the previous day to work out what the areas should be for the next day.
Dynamic programming on a tree is easy. What I would do for an algorithm is to build a tree of successively more finely divided cells. More cells mean a smaller error, because people get predictions for points closer to them, and you can work out the error, or at least the relative error between more cells and fewer cells. Starting from the bottom up work out the smallest possible total error contributed by each subtree, allowing it to be divided in up to 1,2,3,..N. ways. You can work out the best possible division and smallest possible error for each k=1..N for a node by looking at the smallest possible error you have already calculated for each of its descendants, and working out how best to share out the available k divisions between them.
I would try to avoid doing this by thinking of a different idea. Depending on the way you look at life, there are at least two disadvantages of this:
1) You don't seem to be adding anything to the party. It looks like you are interposing yourself between organizations that actually make weather forecasts and their clients. Organizations lose direct contact with their clients, which might for instance lose them advertising revenue. Customers get a poorer weather forecast.
2) Most sites have legal terms of service, which must clients can ignore without worrying. My guess is that you would be breaking those terms of service, and if your service gets popular enough to be noticed they will be enforced against you.

Techniques to evaluate the "twistiness" of a road in Google Maps?

As per the title. I want to, given a Google maps URL, generate a twistiness rating based on how windy the roads are. Are there any techniques available I can look into?
What do I mean by twistiness? Well I'm not sure exactly. I suppose it's characterized by a high turn -to-distance ratio, as well as high angle-change-per-turn number. I'd also say that elevation change of a road comes in to it as well.
I think that once you know exactly what you want to measure, the implementation is quite straightforward.
I can think of several measurements:
the ratio of the road length to the distance between start and end (this would make a long single curve "twisty", so it is most likely not the complete answer)
the number of inflection points per unit length (this would make an almost straight road with a lot of little swaying "twisty", so it is most likely not the complete answer)
These two could be combined by multiplication, so that you would have:
road-length * inflection-points
--------------------------------------
start-end-distance * road-length
You can see that this can be shortened to "inflection-points per start-end-distance", which does seem like a good indicator for "twistiness" to me.
As for taking elevation into account, I think that making the whole calculation in three dimensions is enough for a first attempt.
You might want to handle left-right inflections separately from up-down inflections, though, in order to make it possible to scale the elevation inflections by some factor.
Try http://www.hardingconsultants.co.nz/transportationconference2007/images/Presentations/Technical%20Conference/L1%20Megan%20Fowler%20Canterbury%20University.pdf as a starting point.
I'd assume that you'd have to somehow capture the road centreline from Google Maps as a vectorised dataset & analyse using GIS software to do what you describe. Maybe do a screen grab then a raster-to-vector conversion to start with.
Cumulative turn angle per Km is a commonly-used measure in road assessment. Vertex density is also useful. Note that these measures depend upon an assumption that vertices have been placed at some form of equal density along the line length whilst they were captured, rather than being manually placed. Running a GIS tool such as a "bendsimplify" algorithm on the line should solve this. I have written scripts in Python for ArcGIS 10 to define these measures if anyone wants them.
Sinuosity is sometimes used for measuring bends in rivers - see the help pages for Hawths Tools for ArcGIS for a good description. It could be misleading for roads that have major
changes in course along their length though.

Finding patterns in Puzzle games

I was wondering, which are the most commonly used algorithms applied to finding patterns in puzzle games conformed by grids of cells.
I know that depends of many factors, like the kind of patterns You want to detect, or the rules of the game...but I wanted to know which are the most commonly used algorithms in that kind of problems...
For example, games like columns, bejeweled, even tetris.
I also want to know if detecting patterns by "brute force" ( like , scanning all the grid trying to find three adyacent cells of the same color ) is significantly worst that using particular algorithms in very small grids, like 4 X 4 for example ( and again, I know that depends of the kind of game and rules ...)
Which structures are commonly used in this kind of games ?
It's always domain-dependent. But there's also two situations where you'd do these kinds of searches. Ones situation is after a move (a change to the game field made by the player), and the other would be if/when the whole board has changed.
In Tetris, you wouldn't need to scan the whole board after a piece is dropped. You'd just have to search the rows the piece is touching.
In a match-3 games like Bejeweled, where you're swapping two adjacent pieces at a time, you'd first run a localized search in each direction around each square that changed, to see if any pieces have triggered. Then, if they have, the game will dump some new, random pieces onto the board. Now, you could run the same localized search around each square that's changed, but that might involve a lot of if statements and might actually be slower to just scanning the whole board from top left to bottom right. It depends on your implementation and would require profiling.
As Adrian says, a simple 2D array suffices. Often, though, you may add a "border" of pixels around this array, to simplify the searching-for-patterns aspect. Without a border, you'd have to have if statements along the edge squares that says "well, if you're in the top row, don't search up (and walk off the array)". With a border around it, you can safely just search through everything: saving yourself if statements, saving yourself branching, saving yourself pipeline issues, searching faster.
To Jon: these kinds of things really do matter in high-performance settings, even on modern machines, if you're making a search algorithm to play/solve the game. If you are, you want your underlying simulation to run as quickly as possible in order to search as deep as possible in the fewest cycles.
Regarding algorithms: It certainly depends on the game. For example for tetris, you'd only have to scan each row if it has the same color. I can't even think of something that would not equal the brute force approach in this case. But for most casual games brute force should be perfectly fine. Pattern recognition should be negligible in comparison to graphics and sound processing.
Regarding structures: A simple 2D-Array should suffice for representing the board.
Given the average computer speed these days, if it's real-time as the user is playing the game, it probably won't matter (EDIT: for very small game boards only). Certainly, it would depend on the complexity of the game logic, but also how fast the code is going to run on the target machine (i.e., is this a JavaScript web page game, or a Windows app written in C++).
If this is for something like simulating gameplay strategies, then use an algorithm that's more efficient.
A more efficient strategy could involve keeping track of incremental changes to the game board, instead of re-scanning the whole board every time.

Resources