9#include "jaffarCommon/deserializers/contiguous.hpp"
10#include "jaffarCommon/hash.hpp"
11#include "jaffarCommon/serializers/contiguous.hpp"
15#include <unordered_map>
81 void initialize(
const std::vector<std::string>& inputSequence)
84 for (
size_t i = 0; i <= inputSequence.size(); i++)
90 bool isEndOfSequence = i == inputSequence.size();
93 step.
inputString = isEndOfSequence ==
false ? inputSequence[i] :
"<End Of Sequence>";
99 if (isEndOfSequence ==
true) step.
inputIndex = 0;
105 if (isRegisteredInput ==
true)
108 step.
isInputAllowed = std::find(allowedInputs.begin(), allowedInputs.end(), step.
inputIndex) != allowedInputs.end();
121 sameHashSteps.push_back(i);
153 if (i < inputSequence.size())
176 free(step.gameStateData);
177 free(step.rendererStateData);
213 const auto& step =
getStep(currentStep);
236 jaffarCommon::logger::log(
"[J+] Runner Information: \n");
238 jaffarCommon::logger::log(
"[J+] Game Information: \n");
240 jaffarCommon::logger::log(
"[J+] Emulator Information: \n");
253 if (stepId >=
_sequence.size()) JAFFAR_THROW_RUNTIME(
"Requested step %lu which exceeds sequence size %lu", stepId,
_sequence.size());
268 size_t operator()(
const jaffarCommon::hash::hash_t& h)
const noexcept {
return h.first ^ (h.second + 0x9E3779B97F4A7C15ULL + (h.first << 6) + (h.first >> 2)); }
virtual size_t getRendererStateSize() const =0
Returns the size of the renderer state.
virtual void printInfo() const =0
Prints core-specific debug information.
virtual void deserializeRendererState(jaffarCommon::deserializer::Base &deserializer)=0
Loads the renderer state for a given state/frame from the deserializer.
virtual void showRender()=0
Shows the contents of the emulator's renderer in the window.
virtual void serializeRendererState(jaffarCommon::serializer::Base &serializer) const =0
Gathers the data needed to render a given state/frame into the serializer.
virtual void updateRendererState(const size_t stepIdx, const std::string input)=0
Updates the internal state of the renderer with the current game state.
Emulator * getEmulator() const
Returns a pointer to the internal emulator.
void updateReward()
Recomputes the current state's reward from the satisfied rules.
void evaluateRules()
Evaluates the rule set against the current state.
void printInfo() const
Prints the current game state to the logger.
void updateGameStateType()
Recomputes the state type and checkpoint level from the satisfied rules.
stateType_t getStateType() const
Returns the current state type (normal, win or fail).
@ fail
A fail rule is currently satisfied.
@ win
A win rule is currently satisfied.
Replays a solution's input sequence and caches per-step state for navigation.
ssize_t getFirstWinStep() const
Returns the first step (number of inputs applied) at which the solution reaches a win state,...
Playback(Runner &runner)
Constructs the playback over a runner and caches state sizes.
std::vector< step_t > _sequence
The recorded sequence of playback steps.
step_t getStep(const size_t stepId) const
Returns the cached step with the given id.
void printInfo() const
Prints runner, game, and emulator information.
void initialize(const std::vector< std::string > &inputSequence)
Replays the input sequence, recording one cached step per input (plus a trailing end-of-sequence step...
~Playback()
Frees the game and renderer state memory allocated during initialization.
bool isInputAllowed(const size_t currentStep) const
Returns whether the input of the given step is allowed by the current move set.
ssize_t getFirstFailStep() const
Returns the first step (number of inputs applied) at which the solution reaches a fail state,...
size_t _gameStateSize
Size, in bytes, of a serialized game state.
size_t _rendererStateSize
Size, in bytes, of a serialized renderer state.
jaffarPlus::InputSet::inputIndex_t getStateInputIndex(const size_t currentStep) const
Returns the input index of the given step.
Runner * _runner
Pointer to the runner used for playback.
std::string getStateInputString(const size_t currentStep) const
Returns the input string of the given step.
std::unordered_map< jaffarCommon::hash::hash_t, std::vector< size_t >, hashHasher_t > _hashOccurrences
Maps each state hash to the steps (ascending) at which it occurred, used to detect the repeated state...
jaffarCommon::hash::hash_t getStateHash(const size_t currentStep) const
Returns the state hash of the given step.
ssize_t _firstFailStep
First step (inputs applied) reaching a fail state; -1 until/unless one is seen.
void * getStateData(const size_t currentStep) const
Returns the serialized game state data of the given step.
const std::vector< size_t > getStateRepeatedHashSteps(const size_t currentStep) const
Returns the earlier steps (ascending) sharing the given step's hash.
void loadStepData(const size_t stepId)
Loads the cached game state of the given step back into the runner.
ssize_t _firstWinStep
First step (inputs applied) reaching a win state; -1 until/unless one is seen.
void renderFrame(const size_t currentStep)
Renders the cached frame for the given step into the emulator window.
Owns a Game instance and advances it according to configured inputs.
InputSet::inputIndex_t registerInput(const std::string &input)
Registers an input string and returns its numeric index.
const auto getAllowedInputs() const
Returns the inputs currently allowed for the game's state.
size_t getStateSize() const
Computes the size in bytes of the serialized runner state.
void printInfo() const
Logs runner state information.
jaffarPlus::InputSet::inputIndex_t getInputIndex(const std::string &input) const
Looks up the index registered for an input string.
void advanceState(const InputSet::inputIndex_t inputIdx)
Advances the game by one input, then by the configured number of frameskip frames.
jaffarCommon::hash::hash_t computeHash() const
Computes a hash of the current runner state.
Game * getGame() const
Returns a pointer to the owned game instance.
void serializeState(jaffarCommon::serializer::Base &serializer) const
Serializes the runner state: the game state, the input history, and the input counter.
bool isInputRegistered(const std::string &inputString)
Reports whether an input string has been registered.
void deserializeState(jaffarCommon::deserializer::Base &deserializer)
Restores the runner state: the game state, the input history, and the input counter.
Drives a Game forward one input at a time, managing the allowed/candidate input sets,...
Hash functor for 128-bit state hashes (std::pair<uint64_t, uint64_t>).
size_t operator()(const jaffarCommon::hash::hash_t &h) const noexcept
Combines the two 64-bit halves of a state hash into a size_t.
A single recorded playback step.
void * rendererStateData
The step's serialized renderer state data.
bool isInputAllowed
Whether the move is allowed by the current move set.
jaffarCommon::hash::hash_t stateHash
The step's state hash.
void * gameStateData
The step's serialized game state data.
jaffarPlus::InputSet::inputIndex_t inputIndex
The step's input index.
std::vector< size_t > _repeatedHashSteps
Earlier steps (ascending) that shared this step's hash.
std::string inputString
The step's input string.