Come funziona il provably fair in Roulette
Ecco come giocare a Roulette su Cloudbet, e come verificare che ogni giro sia provably fair.
Come giocare a Roulette
Roulette è un classico gioco da casinò in cui scommetti su dove atterrerà una pallina in movimento su una ruota numerata. Piazzi una o più scommesse sul tavolo dei numeri, poi la ruota gira e la pallina viene lanciata. Una volta che si ferma in una casella numerata, quello è il numero vincente — tutte le scommesse che lo coprono pagano, tutte le altre perdono.
Piazzare le scommesse
Puoi scommettere sul risultato in diversi modi, e sei libero di combinare più scommesse nello stesso round. Le scommesse interne (su numeri specifici) pagano di più ma sono più difficili da centrare; le scommesse esterne (su gruppi più ampi) pagano meno ma vincono più spesso:
- Pieno / Numero singolo (35:1): scommetti su un numero esatto (0–36, oppure 00 nella Roulette americana).
- Cavallo (17:1): due numeri adiacenti.
- Trasversale (11:1): tre numeri in fila.
- Angolo (8:1): quattro numeri che si incontrano in un angolo.
- Prime Quattro / Linea Superiore (8:1 europea / 6:1 americana): copre lo 0 (e il 00 nella versione americana), 1, 2, 3.
- Sestina (5:1): due righe adiacenti, sei numeri.
- Colonna (2:1): una delle tre colonne verticali.
- Dozzina (2:1): 1–12, 13–24 o 25–36.
- Rosso/Nero, Pari/Dispari, Alto/Basso (1:1 ciascuna).
Roulette europea vs. americana
Cloudbet offre entrambe le versioni. La Roulette europea ha un solo zero (37 esiti possibili, RTP del 97,30%); la Roulette americana aggiunge una seconda casella "00" (38 esiti possibili, RTP del 97%), il che aumenta leggermente il vantaggio del banco. La versione a cui stai giocando dovrebbe essere indicata chiaramente prima di piazzare una scommessa. Entrambe includono una modalità Autoplay per giri continui con valori delle fiches e numero di giri preimpostati.
Una volta piazzate le scommesse e concluso il round, tutte le scommesse vincenti vengono pagate automaticamente in base alle rispettive quote, e il tavolo si azzera per il round successivo.
Questa pagina spiega come Roulette trasforma una sequenza di numeri casuali provably fair in un numero vincente. Per sapere come viene generata quella sequenza casuale — server seed, client seed, nonce, hashing, SHAKE256 — consulta la spiegazione del provably fair di Cloudbet.
Trasformare i numeri casuali in un risultato di Roulette
Per Roulette, il sistema provably fair deve dimostrare che il numero vincente è scelto tramite casualità verificabile, non selezionato a posteriori.
Il processo è semplice: nella Roulette europea, un numero intero compreso tra 0 e 36 viene campionato dalla sequenza di numeri casuali — quello è il numero vincente. Nella Roulette americana, il numero campionato può variare da 0 a 37, con "37" mappato sul doppio zero, "00"; i risultati da 0 a 36 vengono presi così come sono.
Come viene selezionato il numero vincente
I byte casuali generati da SHAKE256 (vedi la nostra pagina sul provably fair) vengono suddivisi in numeri interi senza segno di 4 byte, compresi tra 0 e 2³²−1. Il numero vincente di Roulette viene scelto tra 37 esiti possibili (europea) o 38 (americana) — quindi nei passaggi seguenti, P è 37 o 38.
Per scegliere un numero vincente in modo equo tra questi P esiti, applichiamo il rejection sampling (vedi Come funziona il provably fair), quindi prendiamo il numero risultante modulo P — il resto diventa il numero vincente (per la Roulette americana, "37" viene mostrato come "00").

Una volta generato, il numero vincente viene salvato e nascosto lato server — non può essere cambiato o alterato senza essere rilevato dopo l'inizio del round. Una volta piazzata la tua scommessa, viene confrontata con questo numero predeterminato per definire l'esito del round.
Verifica i tuoi risultati a Roulette
Abbiamo scritto un piccolo programma Node.js fedele all'implementazione di Roulette su Cloudbet (sia europea che americana). Inserisci il tuo Server Seed, Client Seed e Nonce per riprodurre il tuo risultato. (Promemoria: per rivelare il Server Seed di un round su Cloudbet, devi aver già ruotato verso una nuova coppia di seed.)
Dipendenze:
npm install js-sha3
Il codice:
// If you are running this yourself, then you can input your own data here
// You can then compare:
// 1) Cloudbet's provided Commitment to the Commitment outputted here. This proves that the Server Seed was not altered during gameplay.
// 2) Cloudbet's provided game outcome to the game outcome outputted here. This proves that your game's outcome was determined solely by the pre-game seeds and was not altered afterwards.
const Version = Object.freeze({ AMERICAN: "american", EUROPEAN: "european" }); // Here the possible versions are listed
let myServerSeed = 'your_server_seed'; // ✍️YOUR_INPUT✍️: Enter your (unhashed) Server Seed here
let myClientSeed = 'your_client_seed'; // ✍️YOUR_INPUT✍️: Enter your Client Seed here
let myNonce = 1; // ✍️YOUR_INPUT✍️: Enter your Nonce here
let myRouletteVersion = Version.AMERICAN; // ✍️YOUR_INPUT✍️: Enter your roulette version (either Version.AMERICAN or Version.EUROPEAN)
const usingCustomData = false; // Change this to true if you are using your own data
// Load libraries
const crypto = require('crypto');
const { sha3_256, shake256 } = require('js-sha3');
// Step 1: Generate a Server Seed and Commitment
// And generate a Client Seed - either by player input or by the player's browser
function generateServerSeed() {
let seed = crypto.randomBytes(32).toString('hex');
if (usingCustomData) { seed = myServerSeed; }
const commitment = sha3_256(seed);
return { 'serverSeed': seed, 'commitment': commitment };
}
function getClientSeed() {
let seed = crypto.randomBytes(32).toString('hex');
if (usingCustomData) { seed = myClientSeed; }
return seed;
}
// Step 2: Create a Round Signature with SHA3 using a Server Seed, Client Seed and Nonce
function createRoundSignature(serverSeed, clientSeed, nonce) {
return sha3_256(`${serverSeed}:${clientSeed}:${nonce}`);
}
// Step 3: Create a SHAKE256 stream generator from a Round Signature.
// To simplify this example program, this function doesn't create a stream, but instead a sequence of custom length.
function* createRandomNumberSequence(numbersToGenerate, roundSignature) {
const numOfBytes = 4 * numbersToGenerate; // 4 bytes (32 bits) per random number we generate
const byteStream = shake256.create(8 * numOfBytes); // shake takes bits as input
byteStream.update(roundSignature); // Use the Round Signature to seed the generator
const buf = Buffer.from(byteStream.digest()); // The Buffer class lets us package every 4 bytes into one 32-bit integer
for (let i = 0; i < numbersToGenerate; i++) {
yield buf.readUInt32BE(i * 4); // Read buf in 4-byte steps
}
throw new Error("No more numbers in the random number sequence! Fix: make 'numbersToGenerate' larger.");
}
// Step 4: Draw from the random number sequence to calculate the game result
function getGameResult(rouletteVersion, rng) {
let numOfOutcomes = 0;
if (rouletteVersion === Version.EUROPEAN) {
numOfOutcomes = 37;
} else if (rouletteVersion === Version.AMERICAN) {
numOfOutcomes = 38;
}
let result = String(sample(numOfOutcomes, rng))
// Convert the result '37' to '00'
if (result === '37') {
result = '00';
}
return result;
}
// Sample a number from P number of outcomes using Rejection Sampling
function sample(P, rng) {
const maxAcceptable = Math.floor(0x100000000 / P) * P;
// Rejection sampling
let rand;
do {
rand = rng.next().value;
} while (rand >= maxAcceptable);
// Modulo operation
const sampled_number = rand % P;
return sampled_number;
}
// Example usage
(function main() {
let nonce = 1;
let rouletteVersion = Version.AMERICAN;
if (usingCustomData) { nonce = myNonce; rouletteVersion = myRouletteVersion; }
const { serverSeed, commitment } = generateServerSeed();
const clientSeed = getClientSeed();
const roundSignature = createRoundSignature(serverSeed, clientSeed, nonce);
const numbersToGenerate = 1 * 2; // We need 1 random number, but there is an improbable case we'll need two
const rng = createRandomNumberSequence(numbersToGenerate, roundSignature);
const value = getGameResult(rouletteVersion, rng);
console.log('📝 Commitment (shown before the game):', commitment);
console.log('🔒 Server Seed (revealed after the game):', serverSeed);
console.log('🎲 Client Seed:', clientSeed);
console.log('🔢 Nonce:', nonce);
console.log(`🎯 Winning Number (in the ${rouletteVersion} version):`, value);
})();

