Replay: deterministic record & playback (#4)
Add deterministic record/playback for a run. Recording captures `(seed, config hash, ordered tick-tagged commands)` and re-simulates on playback — no state snapshots. `DotaFactory.exe --replay <file>` re-plays a recorded run view-only with manual speed/pause. Reviewed-on: #4 Co-authored-by: Malte Langkabel <malte.langkabel@gmail.com> Co-committed-by: Malte Langkabel <malte.langkabel@gmail.com>
This commit was merged in pull request #4.
This commit is contained in:
61
src/lib/sim/StateChecksum.cpp
Normal file
61
src/lib/sim/StateChecksum.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#include "StateChecksum.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
void Hasher::appendBytes(const void* data, std::size_t byteCount)
|
||||
{
|
||||
const unsigned char* bytes = static_cast<const unsigned char*>(data);
|
||||
for (std::size_t i = 0; i < byteCount; ++i)
|
||||
{
|
||||
m_state ^= bytes[i];
|
||||
m_state *= 1099511628211ull; // FNV-1a 64-bit prime
|
||||
}
|
||||
}
|
||||
|
||||
void Hasher::append(float value)
|
||||
{
|
||||
// Normalize -0.0f to +0.0f so the two equal values share a fingerprint.
|
||||
if (value == 0.0f) { value = 0.0f; }
|
||||
appendBytes(&value, sizeof(value));
|
||||
}
|
||||
|
||||
void Hasher::append(double value)
|
||||
{
|
||||
if (value == 0.0) { value = 0.0; }
|
||||
appendBytes(&value, sizeof(value));
|
||||
}
|
||||
|
||||
void Hasher::append(const QPoint& point)
|
||||
{
|
||||
const int coords[2] = { point.x(), point.y() };
|
||||
appendBytes(coords, sizeof(coords));
|
||||
}
|
||||
|
||||
void Hasher::append(const QPointF& point)
|
||||
{
|
||||
append(point.x());
|
||||
append(point.y());
|
||||
}
|
||||
|
||||
void Hasher::append(const QVector2D& vector)
|
||||
{
|
||||
append(vector.x());
|
||||
append(vector.y());
|
||||
}
|
||||
|
||||
void Hasher::append(const std::string& text)
|
||||
{
|
||||
appendBytes(text.data(), text.size());
|
||||
// Length terminator so "ab"+"c" and "a"+"bc" do not collide.
|
||||
const std::size_t length = text.size();
|
||||
appendBytes(&length, sizeof(length));
|
||||
}
|
||||
|
||||
std::uint64_t fingerprintRng(const std::mt19937& rng)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << rng; // full internal state as space-separated integers
|
||||
Hasher hasher;
|
||||
hasher.append(stream.str());
|
||||
return hasher.value();
|
||||
}
|
||||
Reference in New Issue
Block a user