Cum funcționează Provably Fair în Roulette
Iată cum se joacă Roulette pe Cloudbet și cum poți verifica dacă fiecare rotire este provably fair.
Cum se joacă Roulette
Roulette este un joc clasic de cazinou în care pariezi pe locul unde va ateriza o bilă rotitoare pe o roată numerotată. Plasezi unul sau mai multe pariuri pe masa de numere, apoi roata se rotește și bila este lansată. Odată ce se așează într-un buzunar numerotat, acela este numărul câștigător — orice pariu care îl acoperă plătește, iar restul pierd.
Plasarea pariurilor
Poți paria pe rezultat în mai multe moduri diferite și ești liber să combini mai multe pariuri în aceeași rundă. Pariurile interioare (pe numere specifice) plătesc mai mult, dar sunt mai greu de nimerit; pariurile exterioare (pe grupuri mai largi) plătesc mai puțin, dar ies mai des:
- Plin / Număr Simplu (35:1): pariezi pe un singur număr exact (0–36, sau 00 la Roulette American).
- Cal (17:1): două numere adiacente.
- Transversală (11:1): trei numere la rând.
- Colț (8:1): patru numere care se întâlnesc într-un colț.
- Primele Patru / Top Line (8:1 European / 6:1 American): acoperă 0 (și 00 la American), 1, 2, 3.
- Linie Șase (5:1): două rânduri adiacente, șase numere.
- Coloană (2:1): una dintre cele trei coloane verticale.
- Duzine (2:1): 1–12, 13–24 sau 25–36.
- Roșu/Negru, Par/Impar, Mare/Mic (1:1 fiecare).
Roulette European vs. American
Cloudbet oferă ambele versiuni. Roulette European are un singur zero (37 de rezultate posibile, RTP 97,30%); Roulette American adaugă un al doilea buzunar „00” (38 de rezultate posibile, RTP 97%), ceea ce mărește ușor avantajul casei. Versiunea la care joci ar trebui afișată clar înainte să plasezi un pariu. Ambele includ un mod Autoplay pentru rotiri continue, cu valori de jeton și numere de rotiri prestabilite.
Odată ce pariurile tale sunt plasate și runda se rezolvă, orice pariu câștigător este plătit automat conform cotelor sale, iar masa se resetează pentru runda următoare.
Această pagină acoperă modul în care Roulette transformă o secvență de numere aleatorii provably fair într-un număr câștigător. Pentru modul în care este generată această secvență aleatorie în primul rând — server seed, client seed, nonce, hash, SHAKE256 — vezi ghidul Cloudbet despre corectitudine demonstrabilă.
Transformarea numerelor aleatorii într-un rezultat la Roulette
Pentru Roulette, sistemul provably fair trebuie să demonstreze că numărul câștigător este ales printr-un aleatoriu verificabil, nu ales ulterior.
Procesul este simplu: la Roulette European, un număr întreg între 0 și 36 este eșantionat din secvența aleatorie — acesta este numărul câștigător. La Roulette American, numărul eșantionat poate varia de la 0 la 37, cu „37” asociat cu dublul zero, „00”; rezultatele de la 0 la 36 sunt luate ca atare.
Cum este selectat numărul câștigător
Octeții aleatorii generați de SHAKE256 (vezi pagina noastră despre corectitudine demonstrabilă) sunt împărțiți în numere întregi fără semn de 4 octeți, variind de la 0 la 2³²−1. Numărul câștigător la Roulette este ales dintre 37 de rezultate posibile (European) sau 38 (American) — așadar, în pașii de mai jos, P este 37 sau 38.
Pentru a alege corect un număr câștigător dintre acele P rezultate, aplicăm rejection sampling (vezi Cum funcționează Provably Fair), apoi luăm numărul rezultat modulo P — restul devine numărul câștigător (pentru Roulette American, „37” este afișat ca „00”).

Odată generat, numărul câștigător este salvat și ascuns pe server — nu poate fi schimbat sau modificat nedetectat după ce runda a început. Odată ce ți-ai plasat pariul, acesta este comparat cu acest număr predeterminat pentru a rezolva runda.
Verifică-ți propriile rezultate la Roulette
Am scris un mic program Node.js fidel implementării Roulette de pe Cloudbet (atât European, cât și American). Introdu Server Seed-ul, Client Seed-ul și Nonce-ul pentru a-ți reproduce rezultatul. (Reamintire: pentru a dezvălui Server Seed-ul unei runde pe Cloudbet, trebuie să fi rotit deja către o nouă pereche de semințe.)
Dependențe:
npm install js-sha3
Codul:
// 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);
})();

