I am making a strategy game AI. Specifically, I'm using BWMirror java library to make Starcraft: BroodWar zerg AI.
I came accross a problem with unit management. Player has some units in his disposition, let's say it's List<Unit> with such contents:
Offset Name Position
0. Drone [Worker]
1. Drone [Worker]
2. Zergling [Fighter]
3. Hatchery [Building]
4. Drone [Worker]
5. Larva [Passive]
Some functions obviously only work with unit subsets. I have implemented a method that selects subset from the main list and returns it as new list. For workers, I'd get:
Offset Name Position
0. Drone [Worker]
1. Drone [Worker]
2. Drone [Worker]
Now if one of these workers is removed from the original list (eg. because it dies), it will persist in this sub-list. There are 2 possible solutions and I don't like either:
Generate the selection list every time when needed.
Assign some event callbacks to remove items in all lists they are present in.
My questions is: Is there any kind of data storage that would let me make sub-selections but allow me to keep the data synchronized?
This means I'd have two Iterable objects and one would contain all units, other would contain workers. And removing worker from all units would also make it disappear from workers, without any callback.
I think you only have the 2 options you listed, and of the two, I think your first option makes the most sense.
Lazily generating the list only when you needed it would save a lot of cycles. One stim packed up Marine (such as yourself) , might kill a huge number of zerglings, you really don't want to be sending messages for every zergling that dies. It would be much better to just see what you have left when you need them.
Related
I am trying to solve a vrp which consists of pickups and deliveries. I have 73 vehicles and I want to use all the available vehicles to reduce overall time of process. I observed that the result is 24 vehicles never been used while other got multiple jobs. The issue is some of assigned vehicle actually come back to the next job at location that is nearer to unassigned vehicle while further to it last location. So looks like the engine still trying to use least vehicle. How could I change the parameters like:
“FixedCost”,
“DistanceCost”,
“TravelTimeCost”,
“WaitingTimeCost”
to maximize the number of vehicles used? I have tried to change some ways (put some values to FixedCost or make it equal to zero), add values to DistanceCost, TravelTimeCost, but still not working. I still seeing vehicles taking multiple jobs while many vehicle nearer to some of that jobs will never been used on it's available time.
I believe maximizing number of vehicles is not your genuine demand but maybe you want to minimize the longest route in terms of time.
So that is the same problem as AbeProblemMinMax.
However, this is implemented in jsprit v1.3 which is a quite old version. See here for a re-implementation in v1.7.3.
So I am working on a project that requires a collection of clients to be iterated through for updating, with each client requiring an update packet for every other client within proximity. I want to be able to do this in a fast way since updates will happen for a large amount of clients, at an often-occurring interval.
My original plan of attack was to create regions based on client locations, updating each client only with the other clients in their region. This would entail a LinkedList<Region>, with the Region having its own list of clients which would update among each other. One problem with this method was that some regions could have 1 client, while others could have 1000. Another level of difficulty arose from the fact that clients will constantly be moving (thus changing location and Region). These problems could be avoided if there was a way to modify the list while iterating through it, possibly splitting elements when a region gets too large.
Next I thought of creating one large List<Client> that held all players, which was constantly sorted based on location. Then to update client at index n of the list with the closest 20 clients, I would only iterate n-10 and n+10 from their current index. I don't really like this method as much since if there was a 21st client in a closeby area, they could be ignored even though they had equal distance to the client at n as the one at n+10. It also seemed slow to have to resort all the clients every tick.
In terms of speed, which of these methods provides better performance? Additionally, are there any other Java collections I should consider? Thanks!
I strongly prefer the first method. Sorting the entire list every tick is going to end up being a very bad idea time-wise, which rules out the second method.
To solve the concurrency issues, you should make a copy of the LinkedList<Reigon> before updating it in a thread. That way you will allow Clients to change their Reigon at the same time as updates are being pushed out to each Reigon.
Another note is that if you plan on retrieving an arbitrary Reigon from the LinkedList<Reigon> (for example, when you move a Client from one Reigon to another) you should look into some kind of a hash set. It will increase performance greatly when retrieving an arbitrary element from the middle of the list, especially if the list is large.
I am currently working on a 2D grid based sandbox type game. Technically its 3D as the map is a 3 dimensional array with grid tiles being able to be placed behind each other. It is however rendered in 2D. All scripts in the game will need to be quite efficient as I am looking to release it for android.
The game will have a major wiring mechanic that allows players to connect machines up to electrical sources using wire. I need an efficient way to calculate all entities connected by the wire for every circuit.
The only failsafe way I can think of is using a flood fill algorithm to spread out from one point and record all connected objects, but I feel this would be too inefficient for an android app.
Here is some information on the structure of the game and the wire.
The game is being written in java.
All objects are currently static.
Every object is held in an array
that reflects the objects position. Adjacent objects and their
variables can be accessed simply be referencing the x/y values in the
array.This means adjacent blocks can be updated as needed.
Wire can be placed an removed at will by the player, and may follow any
pattern.
Wire can connect on all x/y/z axis' to other wire and
machinery.
Certain objects will output power and others will use
power.
Im currently thinking along the lines of having wireGroup
objects that contain all connected objects for a group of wires
including the wires themselves. Each wire object would contain the
wireGroup ID allowing new wires(and machines) to be easily added to the wireGroup.
All I really need is a way to detect connected objects when a piece of wire is removed.
Detecting connected objects when it is being placed is simple: Just add any machinery next to the new wire to the list in the adjacent wire's wireGroup.
The problem comes about when removing wire. Since their may be 7 or 8 unique wire paths connecting two objects together, it is difficult to find the effect of removing one wire.
For example:
Here you can see that no changes will take place to the connected objects.
And here the wireGroup will be split into two wireGroups, one containing the blue and bottom white, and one containing the two whites.
Even if someone can come up with a 2D only algorithm, that would still be fantastic.
I'm sorry If I've missed anything important, please do tell me so I can remedy it.
Think of all your 'connectable' points (whether empty, a power source, or a machine) as nodes in a (disconnected) graph. A wire can connect two nodes. Say that each node keeps track of the wires connected to it, and thinks about each wire as being one of two types: "powered" and "unpowered", where "powered" wires are those that are transmitting power to this node. Each node tracks these in a pair of sets. A node is "powered" if it has any wires in the "powered" set, or if it itself is a power source.
So the interesting question is, how to handle adding or removing a wire:
When a wire is placed between two nodes, for each of the two nodes place it in either the powered or unpowered set, depending on the "power" status of the other node. If as a result, this node goes from unpowered to powered, walk the graph changing the states of nodes and wires appropriately by moving wires from "unpowered" to "powered".
If a wire is removed, remove it from the sets of connected wires it exists in. If either of the endpoint nodes now have an empty "powered" set of connections, walk the graph from that node turning everyone off.
This should handle multiple powered inputs very efficiently, only having to visit multiple nodes if their state changes. And if a state changes for any node in a subgraph, then it is changing for all the nodes in the subgraph.
Imagine that each node either supplies or receives power. Each wire carries with it one or more directions in which power travels (from power source to element). Two connected power sources would have one wire represented by two internal connections.
So you have a directed graph of power. Upon removing a wire, all associated internal connections are removed. Check all nodes which the removal of the wire affected to see if they have any incoming connections. If there are none and the node was previously powered, then you must walk the graph from that point and depower every node.
Adding a wire is also simple, you check the power state of both nodes. Each node that is powered builds an internal connection in the direction of the other node. Then the graph must be walked from the other node building outward connections at every node. If neither are powered build a directionless connection which may be changed on the event of power. This allows for multiple power sources quite efficiently.
I have written following game server and want to provide a groups feature. Groups will allow to group players together who are "nearby" on screen. In fast action games, this group would be changing fast since players will be moving in and out of their zones constantly.
Since each player would need to listen to events from other players in the group, players will subscribe to the group.
This brings me to my question. What is the appropriate datastructure or java collection class which can be used in this scenario to hold the changing set of event listeners on a group? The number of listeners to a group would rarely exceed 20 in my opinion, and should be lesser than that in most scenarios. It is a multi-threaded environment.
The one I am planning to use is a CopyOnWriteArrayList. But since there will be reasonable amount of updates(due to changing subscriptions) is this class appropriate? What other class would be good to use? If you have any custom implementation using array's etc please share.
Unless you have millions of changes per second (which seems unlikely in your scenario) a CopyOnWriteArrayList should be good enough for what you need. If I were you, I would use that.
IF you notice a performance issue AND you have profiled your application AND you have identified that the CopyOnWriteArrayList is the bottleneck, then you can find a better structure. But I doubt it will be the case.
Do players have integer IDs? If so then I have an lightweight, immutable array-based set class that might make sense for you:
http://code.google.com/p/mikeralib/source/browse/trunk/Mikera/src/main/java/mikera/persistent/IntSet.java
This was written for similar kinds of situations in game engines.
However I also have an alternative approach to consider: If you are updating the groups automatically based on vicinity, then you might want to consider not tracking groups at all. Instead, consider using a spatial data structure that allows you to quickly search for nearby players whenever an event occurs, and directly send the event to nearby players.
Typically you could use a 2D or 3D grid or octree with the smallest division size set to be equal to the max range for your groups. Then a vicinity search will only need to check 9 (2D case) or 27 (3D case) locations in order to find all nearby players. I think doing this search whenever needed will be faster and simpler than the overhead of maintaining lists of groups and listeners all the time....
From what I've gathered, you have choice between CopyOnWriteArrayList and ConcurrentHashMap:
CopyOnWriteArrayList:
Add/remove operation computational cost is linear to the size of the list. May happen multiple times during a single iteration (group notification).
Simpler data structure with constant read time.
ConcurrentHashMap:
Add/remove operation is a constant time operation. Additions or Removal of subscribers do not affect iteration already in progress and blocking is minimized.
Larger data structure that requires slightly longer read time.
Creating a custom solution is possible when it comes to efficiency but probably not as safe when it comes to thread safety. I'm leaning towards ConcurrentHashMap but the winner will probably depend heavily on how your game turns out.
I'm making a bitmap editor where a document consists of several layers where each layer represents a bitmap. Each layer must have a unique ID compared to all other layers that currently exist in the document. I also need to take into account that I need to save and load documents along with the layer IDs.
I'm using the command pattern to store actions that are performed on the document and the unique IDs are used to keep track of which layer an action should be performed on.
At the moment, I just keep a counter called X, when a new layer is created its ID is set to X then X is incremented. When loading, I need to make sure X is set to an appropriate number so that new layers are given unique IDs i.e. I could save the value of X and restore that, or set X based on the biggest layer ID loaded.
Given X is a 32-bit number, the user will need to create 4,294,967,296 layers working on the same file before IDs start to be reused which will cause weird behaviour. Should I implement a better unique ID system or is this generally good enough?
I'm in Java so I could use the UUID library which creates 128 bit unique IDs according to a standard algorithm. This seems overkill though.
Is there some general approach to this kind of problem?
This is perfectly good enough. At a rate of ten new layers per second 24/365, which is silly, it'll run fine for roughly three years.
If you think you might manipulate layers programmatically, and thus have some possibility of having 2^32 layers in the lifetime of the image, then throw all the layer IDs into a HashSet when you read the file, and update that set when you add/remove layers. (You don't need to explicitly store the set; the ID associated with each mask is enough.) Then instead of taking "the next number", take "the next number not in the set". Having a counter is still useful, but whether you set it to 0 or (max+1) when you read a file is immaterial; it won't take a significant amount of time to find an empty space unless you envision bafflingly large numbers of layers present simultaneously.
But since you're using Java, you could just use a long instead of an int, and then you wouldn't ever (practically speaking) be able to overflow the number even if all you did was create a one-pixel mask and destroy it over and over again.