//
//  SequenceRandomGenerator.hpp
//  eagle0
//
//  Created by Dan Crosby on 3/10/18.
//  Copyright © 2018 none. All rights reserved.
//

#ifndef SequenceRandomGenerator_h
#define SequenceRandomGenerator_h

#include <memory>
#include <vector>

#include "src/main/cpp/net/eagle0/common/RandomGenerator.hpp"

// A deterministic random generator that returns values from a fixed sequence.
// Used for testing and MCTS simulation where we want specific, predictable outcomes.
//
// Values in the sequence are treated as [0, 1] probabilities that are returned
// by DoubleZeroToOne(). The normal percentile methods (including open-ended
// variants) work as usual, so callers must provide appropriate sequences.
// For example, to get an open-ended low result of -50, provide [0.02, 0.52]
// which produces: initial=2 (triggers open-ended), accumulated=52, final=2-52=-50
class SequenceRandomGenerator : public ::RandomGenerator {
private:
    const std::vector<double> sequence;
    size_t position = 0;

    auto DoubleZeroToOne() -> double override {
        const double nextVal = sequence[position];
        position++;
        if (position >= sequence.size()) { position = 0; }
        return nextVal;
    }

public:
    explicit SequenceRandomGenerator(std::vector<double> s) : sequence(std::move(s)), position(0) {}
    static auto WithSequence(const std::vector<double>& s)
            -> std::shared_ptr<SequenceRandomGenerator> {
        return std::make_shared<SequenceRandomGenerator>(s);
    }
};

#endif /* SequenceRandomGenerator_h */
