Game
Los eventos de juego son la traducción de los flotantes generados aleatoriamente en un resultado relacionado que es específico del juego. Esto incluye cualquier cosa, desde el resultado de una tirada de dados hasta el orden de las cartas en un mazo, o incluso la ubicación de cada bomba en un juego de minas.
A continuación se presenta una explicación detallada sobre cómo traducimos los flotantes en eventos para cada juego específico en nuestra plataforma.
Hilo
En un mazo estándar de cartas, hay 52 resultados únicos posibles. Cuando se trata de jugar al blackjack, hilo y baccarat en nuestra plataforma, utilizamos una cantidad ilimitada de mazos al generar el evento del juego, y, por lo tanto, cada turno de una carta siempre tiene la misma probabilidad. Para calcular esto, multiplicamos cada flotante generado aleatoriamente por 52 y luego traducimos ese resultado en una carta particular, basado en el siguiente índice:
// 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)];
El único factor diferenciador en estos juegos es que en Hilo y Blackjack hay un cursor de 13 para generar 52 posibles eventos de juego para los casos en que se requiere repartir una gran cantidad de cartas al jugador, mientras que en Baccarat solo necesitamos generar 6 eventos de juego para cubrir la mayor cantidad de cartas jugables posible.
Diamantes
Al jugar Diamonds, hay 7 resultados posibles en forma de gemas. Para lograr esto, multiplicamos cada flotador generado por 7 antes de traducirlo en una gema correspondiente utilizando el siguiente índice:
// 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)];
Dados
En nuestra versión de dados, cubrimos un rango de lanzamiento posible de 00.00 a 100.00, que tiene un rango de 10,001 resultados posibles. La traducción del evento de juego se realiza multiplicando el flotador por el número de resultados posibles y luego dividiendo por 100 para que el número resultante se ajuste a las restricciones de nuestro rango de dados declarado.
// Game event translation
const roll = (float * 10001) / 100;
Lanzamiento de Moneda
Al jugar Coinflip, hay 2 resultados posibles en forma de monedas. Para lograr esto, multiplicamos cada flotador generado por 2 antes de traducirlo en una gema correspondiente utilizando el siguiente índice:
// Index of 0 & 1 : batman & joker
const COINS = [ 0, 1 ];
// Game event translation
const coin = COINS[Math.floor(float * 2)];
Limbo
Cuando se trata de Limbo, utilizamos un proceso de dos pasos. Primero, tomamos el flotador y lo multiplicamos tanto por el multiplicador máximo posible como por la ventaja de la casa. Luego, para generar un evento de juego que tenga Distribución de Probabilidad Dividimos el multiplicador máximo posible por el resultado del primer paso para crear el evento del juego en forma de un punto de colapso.
// 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);
プリンコ
Para cualquier juego de Plinko, el resultado generado se basa en la trayectoria de la bola que cae. El evento del juego determina la dirección de la bola que cae para cada nivel en el proceso de caída. Los jugadores pueden elegir entre 8 y 16 pines de juego, lo que determina el número de eventos de juego necesarios para generar un camino completo de arriba hacia abajo. Dado que solo hay dos direcciones posibles (izquierda o derecha), la traducción se realiza multiplicando cada flotador por 2, que se asigna al siguiente índice:
// Index of 0 to 1 : left to right
const DIRECTIONS = [ left, right ];
// Game event translation
const direction = CARDS[Math.floor(float * 2)];
كينو
تتطلب ألعاب كينو التقليدية اختيار 10 أحداث لعبة محتملة على شكل ضربات على اللوح.
// 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)];
La implementación del embarajado de Fisher-Yates se utiliza para evitar que se generen golpes duplicados.
Minas
Un juego de minas se genera con 24 eventos de juego separados, en forma de minas en el tablero. Cada float se multiplica por el número de azulejos únicos posibles que aún quedan en el tablero. Esto se hace restando el número de azulejos restantes por 1 en cada iteración del resultado del evento del juego generado usando el float correspondiente proporcionado. La ubicación de la mina se representa utilizando una posición de cuadrícula de izquierda a derecha, de arriba hacia abajo.
La implementación del embarajado de Fisher-Yates se utiliza para evitar que se generen golpes duplicados. Se utilizan entre 1 y 24 resultados de eventos de juego, según la configuración elegida.
عجلة
El número del evento del juego se calcula multiplicando el float por los posibles resultados en el segmento. Luego se usa para determinar el resultado del evento del juego como un multiplicador, utilizando el siguiente índice:
// 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];
Caída
Para probar nuestra imparcialidad, hemos generado una cadena de 10,000,000 hashes SHA256, donde cada hash es el hash de la representación hexadecimal del hash anterior. El último hash en la cadena es: 78a9757d3be42b74a3f70239078ad9317125fe9ee630d5bdada46de963e56752
La fórmula para generar el resultado del juego:
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))
Doble
Nuestro Doble se deriva de la versión europea del juego, donde la rueda consta de 15 bolsillos diferentes posibles, que van del 0 al 14. El evento del juego se calcula multiplicando el float por 15 y luego se traduce en un bolsillo correspondiente utilizando el siguiente índice:
// 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)];
برج
Un juego de torre se genera con 9 eventos de juego separados, en forma de los niveles de la torre. Generamos una cierta cantidad de huevos según la dificultad de cada nivel y tenemos un rango de azulejos en los que el huevo también puede estar representado por un entero.
Cada float generado se convierte en enteros para determinar la ubicación de los huevos en cada fila. Por ejemplo: Un nivel de dificultad fácil se representaría así: [0, 1, 3] - los huevos estarían presentes en las losas 1, 2 y 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 },}
La implementación del shuffle de Fisher-Yates se utiliza para evitar huevos duplicados en una fila.