In a game, we use a technique called \'colour picking\' to select units.
This means that every visible unit is given a unique colour.
Here is an example of a
My try:
Pick a "medium range" primitive root (43062 43067 is a good candidate).
class Sequence
{
public:
uint32_t get() const {return state;}
void advance() { state = (state * k)%p;}
void reset() { state = k; }
private:
uint32_t state = 43067;
const uint32_t k = 43067;
const uint32_t p = 64007;
};
This cycles all the numbers in range [1, 64007) exactly once, in a pseudo-random fashion.
I don't really see the problem. As I wrote in the comments, you need only 128K to store a permutation of [0..64K), and you don't need any allocations inside the main loop. Here's a stateful color store in C++11 (in older C++, use a vector
or new[]
):
class ColorPicker {
std::array<uint16_t, 65536> colors;
uint16_t idx;
public:
ColorPicker() : idx(0)
{
std::iota(colors.begin(), colors.end(), 0);
std::random_shuffle(colors.begin(), colors.end());
}
uint16_t next_color()
{
return colors[idx++];
}
};
You only need one of these structures. Now, whenever you create a new unit, call next_color
on the ColorPicker
and store it on the unit as an attribute.
This solution will cycle though the colors. If that's not desired, do a random_shuffle
each time the index wraps around to zero.
It seems to me that what's important is that the contrast between units which are close to each other is high enough, i.e. I would try to come up with some way to take the proximity of units into account.
For instance, you could take the X/Y coordinates of the units into account such that coordinates which are close to each other get colors with a high contrast, low contrast is only used for units which are sufficiently far away.
A first shot might be to have a simple array a
of 256 colors such that there's a large contrast between a[n]
and a[n+1]
. You can then pick the color of units by using their X and/or Y coordinate modulo 256 as the index into the array. That way, you will get colors reused for units which are at least 256 pixels (or whatever metric you may use) apart, but different colors for units which are very close to each other.
First, use binary to store color states(1-used, 0-unused). 2^16=65536(states). If we use 1 bit for one color, 65536/8=8192 bytes are needed.
Next question is how to manage these bytes. I suggest a tree structue: upon these 8192 bytes, another (8192/8=)1024 bytes are needed, every bit in these upper bytes representes one byte in 8192 bytes, if one of lower bytes are ALL 1, its upper bit is 1.
This rule can expand upper and upper: 8192 -> 1024 -> 128 ... at last, to 1 byte(not fully used though).
To use this structure, you can generate a random number in 0..7 for many times, from the root byte, if its bit is 1, try again; if its 0, down to the lower byte, repeat these action until the lowest byte is reached.
Additionally, you can build this tree in one array: just like the heap in heapsort. (with some empty units).
APPEND: A int16 is need for one color, once down to a lower byte, you get a three-bit binary number, append them from left to right to the color number: int16. (The root byte represent only 2 states, and only generate 1-bit binary number, its form is 111111??.
Can you simply take step_size to be the total available colors divided by the total units, and then use (unit_index * step_size) as the color for each unit?