I'm having a problem with the random number generator that I wrote for the game. I need a fast pseudo-random field generator. It does not have to be cryptographically secure, it just needs to take a vector and a seed and give a hash value that is arbitrary enough to fool a person's cursory control.
However, this code does not produce a “pseudo-random” output when I give a 2d vector and change the result to 2. It basically produces a checkerboard pattern.
I don’t know why, and frankly, it would be great to know, but I will not sweat if I never understand this. Basically, I just thought that this way of generating random numbers was too terrible, so I wanted to know about an alternative way to approach this problem. Those. I was really looking for resources or pointers to what would be a good alternative way to generate random numbers this way, rather than asking "what am I doing wrong?"
Basically, I am trying to create an “infinite” 2D noise field (I think white noise) that I can return if I put in the same inputs.
The code I wrote (it should be an fnv hash, please excuse the template material. I kind of just pulled this out of the code, I cleaned it up a bit later).
template<typename T, typename... TL>
uint32_t static_random_u32(T const& d, TL const&... rest) {
return fnv_hash32(d, rest..., 2938728349u);
}
template<typename T, typename... TL>
uint32_t fnv_hash32(T const& v, TL const&... rest) {
uint32_t hash;
fnv_hash32_init(hash);
fnv_hash32_types(hash, v, rest...);
return hash;
}
inline void fnv_hash32_init(uint32_t& hash) {
hash = 2166136279u;
}
template<typename T, typename... TL>
void fnv_hash32_types(uint32_t& hash, T const& v, TL const&... rest) {
#if LITTLE_ENDIAN
fnv_hash32_bytes(hash, (char*)&v, sizeof(v), true);
#else
fnv_hash32_bytes(hash, (char*)&v, sizeof(v), false);
#endif
fnv_hash32_types(hash, rest...);
}
inline void fnv_hash32_types(uint32_t& hash) {}
inline void fnv_hash32_bytes(uint32_t& hash, char const* bytes, size_t len, bool swapOrder = false) {
if (swapOrder) {
for (size_t i = len; i > 0; --i)
fnv_hash32_next(hash, bytes[i - 1]);
} else {
for (size_t i = 0; i < len; ++i)
fnv_hash32_next(hash, bytes[i]);
}
}
inline void fnv_hash32_next(uint32_t& hash, char byte) {
hash ^= byte;
hash *= 16777619u;
}