Game
Les événements de jeu sont la traduction des floats générés aléatoirement en un résultat lié qui est spécifique au jeu. Cela inclut tout, du résultat d'un lancer de dés à l'ordre des cartes dans un paquet, voire la localisation de chaque bombe dans un jeu de mines.
Ci-dessous se trouve une explication détaillée sur la façon dont nous traduisons les floats en événements pour chaque jeu particulier de notre plateforme.
Hilo
Dans un jeu de cartes standard, il existe 52 résultats uniques possibles. Lorsqu'il s'agit de jouer au blackjack, au hilo et au baccarat sur notre plateforme, nous utilisons un nombre illimité de jeux de cartes lors de la génération de l'événement de jeu, et donc chaque tirage de carte a toujours la même probabilité. Pour calculer cela, nous multiplions chaque float généré aléatoirement par 52, puis traduisons ce résultat en une carte particulière, sur la base de l'index suivant :
// Index of 0 to 51 : ♦2 to ♣A
const CARDS = [
♦2, ♥2, ♠2, ♣2, ♦3, ♥3, ♠3, ♣3, ♦4, ♥4,
♠4, ♣4, ♦5, ♥5, ♠5, ♣5, ♦6, ♥6, ♠6, ♣6,
♦7, ♥7, ♠7, ♣7, ♦8, ♥8, ♠8, ♣8, ♦9, ♥9,
♠9, ♣9, ♦10, ♥10, ♠10, ♣10, ♦J, ♥J, ♠J,
♣J, ♦Q, ♥Q, ♠Q, ♣Q, ♦K, ♥K, ♠K, ♣K, ♦A,
♥A, ♠A, ♣A
];
// Game event translation
const card = CARDS[Math.floor(float * 52)];
Le seul facteur différenciateur impliqué dans ces jeux est qu'avec Hilo et Blackjack, il y a un curseur de 13 pour générer 52 événements de jeu possibles dans les cas où un grand nombre de cartes doivent être distribuées au joueur, alors que dans le cas de la baccarat, nous n'avons besoin de générer que 6 événements de jeu pour couvrir le plus grand nombre de cartes jouables possible.
Diamants
Lors de la partie de Diamonds, il y a 7 résultats possibles sous forme de gemmes. Pour ce faire, nous multiplions chaque float généré par 7 avant de le traduire en une gemme correspondante à l'aide de l'index suivant :
// Index of 0 to 51 : ♦2 to ♣A
const CARDS = [
♦2, ♥2, ♠2, ♣2, ♦3, ♥3, ♠3, ♣3, ♦4, ♥4,
♠4, ♣4, ♦5, ♥5, ♠5, ♣5, ♦6, ♥6, ♠6, ♣6,
♦7, ♥7, ♠7, ♣7, ♦8, ♥8, ♠8, ♣8, ♦9, ♥9,
♠9, ♣9, ♦10, ♥10, ♠10, ♣10, ♦J, ♥J, ♠J,
♣J, ♦Q, ♥Q, ♠Q, ♣Q, ♦K, ♥K, ♠K, ♣K, ♦A,
♥A, ♠A, ♣A
];
// Game event translation
const card = CARDS[Math.floor(float * 52)];
Dés
Dans notre version des dés, nous couvrons une plage de lancés possible de 00.00 à 100.00, qui présente une gamme de 10 001 résultats possibles. La traduction de l'événement de jeu est effectuée en multipliant le float par le nombre de résultats possibles, puis en divisant par 100 afin que le nombre résultant s'inscrive dans les contraintes de notre plage de dés déclarée.
// Game event translation
const roll = (float * 10001) / 100;
Lancer de Pièce
Lors de la partie de Coinflip, il y a 2 résultats possibles sous forme de pièces. Pour ce faire, nous multiplions chaque float généré par 2 avant de le traduire en une gemme correspondante à l'aide de l'index suivant :
// Index of 0 & 1 : batman & joker
const COINS = [ 0, 1 ];
// Game event translation
const coin = COINS[Math.floor(float * 2)];
Limbo
En ce qui concerne Limbo, nous utilisons un processus en deux étapes. Tout d'abord, nous prenons le float et le multiplions par le multiplicateur maximum possible et l'avantage de la maison. Ensuite, pour générer un événement de jeu qui ait Distribution de Probabilité Nous divisons le multiplicateur maximum possible par le résultat de la première étape pour créer l'événement de jeu sous la forme d'un point de crash.
// Game event translation with houseEdge of 0.99 (1%)
const floatPoint = 1e8 / (float * 1e8) * houseEdge;
// Crash point rounded down to required denominator
const crashPoint = Math.floor(floatPoint * 100) / 100;
// Consolidate all crash points below 1
const result = Math.max(crashPoint, 1);
Plinko
Dans n'importe quel jeu de Plinko, le résultat généré est basé sur le chemin de la balle tombante. L'événement de jeu détermine la direction de la balle tombante pour chaque niveau du processus de chute. Les joueurs peuvent choisir entre 8 et 16 épingles de jeu, ce qui détermine le nombre d'événements de jeu nécessaires pour générer un chemin complet de haut en bas. Comme il n'y a que deux directions possibles (gauche ou droite), la traduction se fait en multipliant chaque float par 2, ce qui se mappe à l'index suivant :
// Index of 0 to 1 : left to right
const DIRECTIONS = [ left, right ];
// Game event translation
const direction = CARDS[Math.floor(float * 2)];
Keno
Les jeux de Keno traditionnels nécessitent la sélection de 10 événements de jeu possibles sous forme de frappes sur un tableau.
// Index of 0 to 39 : 1 to 40
const SQUARES = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40
];
const hit = SQUARES[Math.floor(float * 40)];
L'implémentation du mélange Fisher-Yates est utilisée pour éviter la génération de résultats possibles en double.
Mines
Un jeu de mines est généré avec 24 événements de jeu séparés, sous forme de mines sur le plateau. Chaque flottant est multiplié par le nombre de tuiles uniques possibles restantes sur le plateau. Cela se fait en soustrayant le nombre de tuiles restantes par 1 pour chaque itération du résultat de l'événement de jeu généré à l'aide du flottant correspondant fourni. L'emplacement de la mine est tracé à l'aide d'une position de grille de gauche à droite, de haut en bas.
L'implémentation du mélange Fisher-Yates est utilisée pour éviter la génération de résultats possibles en double. Entre 1 et 24 résultats d'événements de jeu sont utilisés, en fonction des paramètres choisis.
Roue
Le numéro de l'événement de jeu est calculé en multipliant le float par les résultats possibles dans le segment. Il est ensuite utilisé pour déterminer le résultat de l'événement de jeu en tant que multiplicateur, en utilisant l'index suivant :
// Index per payout configuration
const PAYOUTS = {
'10': {
low: [ 1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0 ],
medium: [ 0, 1.9, 0, 1.5, 0, 2, 0, 1.5, 0, 3 ],
high: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 9.9 ]
},
'20': {
low: [
1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0,
1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0
],
medium: [
1.5, 0, 2, 0, 2, 0, 2, 0, 1.5, 0,
3, 0, 1.8, 0, 2, 0, 2, 0, 2, 0
],
high: [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 19.8
]
},
'30': {
low: [
1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0,
1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0,
1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0
],
medium: [
1.5, 0, 1.5, 0, 2, 0, 1.5, 0, 2, 0,
2, 0, 1.5, 0, 3, 0, 1.5, 0, 2, 0,
2, 0, 1.7, 0, 4, 0, 1.5, 0, 2, 0
],
high: [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 29.7
]
},
'40': {
low: [
1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0,
1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0,
1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0,
1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0
],
medium: [
2, 0, 3, 0, 2, 0, 1.5, 0, 3, 0,
1.5, 0, 1.5, 0, 2, 0, 1.5, 0, 3, 0,
1.5, 0, 2, 0, 2, 0, 1.6, 0, 2, 0,
1.5, 0, 3, 0, 1.5, 0, 2, 0, 1.5, 0
],
high: [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 39.6
]
},
'50': {
low: [
1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0,
1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0,
1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0,
1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0,
1.5, 1.2, 1.2, 1.2, 0, 1.2, 1.2, 1.2, 1.2, 0
],
medium: [
2, 0, 1.5, 0, 2, 0, 1.5, 0, 3, 0,
1.5, 0, 1.5, 0, 2, 0, 1.5, 0, 3, 0,
1.5, 0, 2, 0, 1.5, 0, 2, 0, 2, 0,
1.5, 0, 3, 0, 1.5, 0, 2, 0, 1.5, 0,
1.5, 0, 5, 0, 1.5, 0, 2, 0, 1.5, 0
],
high: [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 49.5
]
}
};
// Game event translation
const spin = PAYOUTS[segments][risk][float * segments];
Crash
Pour prouver notre impartialité, nous avons généré une chaîne de 10 000 000 de hachages SHA256, où chaque hachage est le hachage de la représentation hexadécimale du hachage précédent. Le dernier hachage de la chaîne est : 78a9757d3be42b74a3f70239078ad9317125fe9ee630d5bdada46de963e56752
La formule pour générer le résultat du jeu :
const gameHash = hashChain.pop()
const hmac = createHmac('sha256', gameHash);
// blockHash is the hash of bitcoin block 584,500
hmac.update(blockHash);
const hex = hmac.digest('hex').substr(0, 8);
const int = parseInt(hex, 16);
// 0.01 will result in 1% house edge with a lowest crashpoint of 1
const crashpoint = Math.max(1, (2 ** 32 / (int + 1)) * (1 - 0.01))
Double
Notre Double est dérivé de la version européenne du jeu où la roue se compose de 15 poches différentes possibles, allant de 0 à 14. L'événement de jeu est calculé en multipliant le float par 15, puis traduit dans une poche correspondante à l'aide de l'index suivant :
// Index of 0 to 14
const POCKETS = [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14
];
// Game event translation
const pocket = POCKETS[Math.floor(float * 15)];
Tour
Un jeu de Tour est généré avec 9 événements de jeu distincts, sous la forme des niveaux de la tour. Nous générons un certain nombre d'œufs en fonction de la difficulté de chaque niveau et avons une gamme de tuiles sur lesquelles l'œuf peut également être représenté par un entier.
Chaque float généré est converti en entiers pour déterminer l'emplacement des œufs dans chaque rangée. Par exemple : Un niveau de difficulté facile serait représenté ainsi : [0, 1, 3] - les œufs seraient présents sur les tuiles 1, 2 et 4.
// count represents the number of eggs
// size represents the number of possible squares
const LEVEL_MAP = {
easy: { count: 3, size: 4 },
medium: { count: 2, size: 3 },
hard: { count: 1, size: 2 },
expert: { count1, size: 3 },
master: { count: 1, size: 4 },}
L'implémentation du mélange de Fisher-Yates est utilisée pour éviter les œufs dupliqués sur une rangée.