#pragma once // ----------------------------------------------------------------------------- // Чистые хеш-функции без состояния. Значение зависит ТОЛЬКО от аргументов. // // Это не генератор случайных чисел: общего состояния нет, «посеять» нечего, // последовательность вызовов ни на что не влияет. Поэтому такой хеш можно // звать и из симуляции, не ломая детерминизм: --headless по-прежнему выдаёт // один и тот же прогон, а разброс выстрела воспроизводится по номеру выстрела // и индексу стрелка (см. sim/loadout.h и docs/08-decisions.md). // // Рендер использует те же функции через render/noise.h. // ----------------------------------------------------------------------------- #include inline uint32_t HashU32(uint32_t x) { x ^= x >> 16; x *= 0x7FEB352Du; x ^= x >> 15; x *= 0x846CA68Bu; x ^= x >> 16; return x; } inline uint32_t Hash2(uint32_t x, uint32_t y) { return HashU32(x * 0x27D4EB2Du ^ (y + 0x165667B1u)); } inline uint32_t Hash3(uint32_t x, uint32_t y, uint32_t z) { return HashU32(Hash2(x, y) ^ (z * 0x9E3779B9u)); } // [0, 1) inline float Hash01(uint32_t h) { return float(h & 0x00FFFFFFu) * (1.0f / 16777216.0f); } // [-1, 1) inline float HashSigned(uint32_t h) { return Hash01(h) * 2.0f - 1.0f; }