Bytes to Floats
The output of the Random Number Generator (byteGenerator) function is a hexadecimal 32-byte hash. As explained under the cursor implementation, we use 4 bytes of data to generate a single game result. Each set of 4 bytes is used to generate floats between 0 and 1 (4 bytes are used instead of one to ensure a higher level of precision when generating the float.) It is with these generated floats that we derive the formal output of the provable fair algorithm before it is translated into game events.
// Convert the hash output from the rng byteGenerator to floats
function generateFloats ({ serverSeed, clientSeed, nonce, cursor, count }) {
// Random number generator function
const rng = byteGenerator({ serverSeed, clientSeed, nonce, cursor });
// Declare bytes as empty array
const bytes = [];
// Populate bytes array with sets of 4 from RNG output
while (bytes.length < count * 4) {
bytes.push(rng.next().value);
}
// Return bytes as floats using lodash reduce function
return _.chunk(bytes, 4).map(bytesChunk =>
bytesChunk.reduce((result, value, i) => {
const divider = 256 ** (i + 1);
const partialResult = value / divider;
return result + partialResult;
}, 0)
);
};
Floats to Game Events
Where the process of generating random outputs is universal for all our games, it's at this point in the game outcome generation where a unique procedure is implemented to determine the translation from floats to game events.
The randomly generated float is multiplied by the number of possible remaining outcomes in the specific game being played. For example, in a game that uses a 52-card deck, this is done simply by multiplying the float by 52. The result of this calculation is then converted into the corresponding game event. For games that require multiple game events, this process continues through each corresponding 4-byte segment in the result chain that was generated using the described byteGenerator function.
Shuffle of Game Events
For games such as Keno, Mines, Pump, Chicken and Video Poker, where outcomes cannot be duplicated, we then utilise the Fisher-Yates shuffle algorithm. This procedure influences the conversion process from floats to game events because each time a game event is translated, the amount of possible remaining game event possibilities has been reduced for any remaining steps in the result chain.
As an example, in video poker, there are initially 52 cards available in the full deck, so the first game event is determined by multiplying the random float by 52. After this card has been dealt, only 51 cards remain in the deck, so the second card is determined by multiplying the next random float by 51. This process continues in the same way until all required game events have been generated.
With regards to Mines, Pump, Chicken and Keno, this is simply a matter of implementing the same process as explained with video poker but changing that to tiles or locations on the board or grid, ensuring that each game event generated hasn’t already occurred earlier in the chain of results.
