JSFiddle - React, Tailwind, and code Playground

Multi-step Random Number Generator Simulates Skip/Jump Ahead

by skibulk

JavaScript

console.clear();

// -----------------------
// https://gist.github.com/blixt/f17b47c62508be59987b

function Random(seed) {
	if(Number.isInteger(seed)){
    this._seed = (Math.abs(seed) % 2147483646) + 1;
  } else {
  	this._seed = 2147483646;
  }
}

// Returns a number between 0 and 9,999,999,999
Random.prototype.next = function() {
	this._seed = this._seed * 48271 % 2147483647;
  return Math.trunc(this._seed / 2147483647 * 1e11);
};

// Returns a number between 0 and 0.99999...
Random.prototype.nextFloat = function(){
	this._seed = this._seed * 48271 % 2147483647;
  return this._seed / 2147483647;
}

// -----------------------

/*
var stack = setupStack(1, 2, 13);
console.log(stack);

function setupStack(seed, base, power){
	var stack = [];
  for(var i = power; i > 0; i--){
    var prng = new Random(seed);
    level = {
      prng: prng,
      output: prng.next(),
      index: 0,
      mod: Math.pow(base, i)
    };
    stack[i] = level;
    seed = level.output;
  }
  return stack;
}
*/

function Generator(seed, steps, base){
  this._seed = seed;
  this._steps = steps;
  this._base = base || 2;
  this._states = {seed: seed};
  this._iterations = 0;
}

Generator.prototype.getDef = function(id) {
	
  var state = this._states;
  
  for(var i = this._steps; i >= 0; i--){
  
    var max = Math.pow(this._base, i) - 1;
    var target = Math.floor(id / max);
    console.log(id, max, target);
    
  	if(state.state == undefined || state.state.index > target) {
    
      var prng = new Random(state.seed);
      
      state = state.state = {
        prng: prng,
        index: -1,
        max: max
      };
    }
    
    // Don't advance the final state
    if(max > 0){
    
    	// Advance the current state
      while (state.index < target) {

        state.output = state.prng.next();
        state.index++;
        this._iterations++;
      }

      id %= state.max;
    }
  }
  
  console.log(this._iterations, this._states);
  return state.prng;
}

//...