Cum funcționează Provably Fair în Dice

Iată cum se joacă Dice pe Cloudbet și cum poți verifica dacă fiecare aruncare este provably fair.

Cum se joacă Dice

Dice este un joc rapid în care pariezi dacă un număr generat aleatoriu va fi peste sau sub o țintă aleasă de tine. Alege un număr țintă și decide dacă pariezi că rezultatul va fi Roll Over (peste) sau Roll Under (sub) acesta. Cu cât ținta ta este mai aproape de marginea intervalului, cu atât șansele de câștig sunt mai mici — dar câștigul este mai mare dacă reușești. Odată plasat pariul, rezultatul este dezvăluit instant.

Cloudbet Originals Dice

Dice-ul propriu al Cloudbet Originals folosește un interval țintă de la 0,00 la 100,00, un RTP de 99%, un multiplicator maxim de x9.800 și acceptă pariuri de la 0,01 $ la 10.000 $. Auto Bet este disponibil pentru a automatiza un număr de runde.

Această pagină acoperă modul în care Dice transformă un număr aleatoriu verificat în aruncarea ta. Pentru cum este generat și securizat aleatoriul propriu-zis — Server Seed, Client Seed, Nonce, hash — vezi pagina noastră Provably Fair. Joci Dice: Golden Ticket? Acesta eșantionează valoarea zarului în același mod descris aici, apoi adaugă o valoare Golden Ticket și un multiplicator suplimentar.

Transformarea numerelor aleatorii într-un rezultat Dice

Rezultatul la Dice trebuie să fie legat, în mod demonstrabil, de același aleatoriu verificabil ca orice alt joc Cloudbet Original. Odată ce secvența de numere aleatorii a unei runde este generată (prin SHAKE256 — vezi procesul provably fair pentru detalii), Dice o folosește astfel:

Un număr întreg între 0 și 10.000 (inclusiv) este eșantionat din secvență, apoi împărțit la 100 — obținând o valoare între 0 și 100, cu două zecimale. Acesta este rezultatul tău la Dice.

Cum funcționează eșantionarea

Dice are 10.001 rezultate posibile (0,00 până la 100,00, în pași de 0,01), așa că pentru acest joc, P = 10.001.

Pentru a alege corect dintre aceste 10.001 rezultate, Dice folosește aceeași metodă de rejection sampling descrisă în ghidul nostru despre provably fair — se generează un număr aleatoriu de 32 de biți, care este respins și reeșantionat dacă ar denatura rezultatul, până când se găsește unul corect. Acel număr este apoi trecut printr-o operație modulo cu 10.001 pentru a obține o valoare între 0 și 10.000, care este împărțită la 100 pentru rezultatul final.

Diagramă de flux a calculului cu corectitudine demonstrabilă al jocului Dice de la Cloudbet: un număr aleatoriu este supus eșantionării prin respingere și convertit în rezultatul final al zarului.

Desfășurarea jocului

Rezultatul este generat și blocat pe server înainte să plasezi pariul — nu poate fi schimbat sau modificat nedetectat odată ce runda a început. După ce pariezi, pragul ales de tine este comparat cu acest număr generat în prealabil pentru a stabili dacă ai prezis corect.

Cod pentru verificare independentă a corectitudinii Dice

Acest program este fidel implementării Dice de pe Cloudbet. Introdu Server Seed-ul, Client Seed-ul și Nonce-ul pentru a-ți verifica propriile rezultate. Notă: pentru a dezvălui Server Seed-ul unui joc pe Cloudbet, trebuie mai întâi să rotești către un nou Server Seed.

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.
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
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 getDiceResult(rng) {
  const diceMinValue = 0;
  const diceMaxValue = 10000;
  let number = sampleFromRange(diceMinValue, diceMaxValue, rng);
  number = number / 100; // So that the dice's value ranges from 0 to 100
  return number;
}
// Sample a number between 'min' to 'max' (inclusive) using Rejection Sampling
function sampleFromRange(min, max, rng) {
  const P = max - min + 1
  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 + min;
}

// Example usage
(function main() {
  let nonce = 1;
  if (usingCustomData) { nonce = myNonce; }

  const { serverSeed, commitment } = generateServerSeed();
  const clientSeed = getClientSeed();

  const roundSignature = createRoundSignature(serverSeed, clientSeed, nonce);
  const numbersToGenerate = 1 * 2; // We need 1 random number, however due to rejection sampling we may need more
  const rng = createRandomNumberSequence(numbersToGenerate, roundSignature);

  const diceValue = getDiceResult(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('🔁 Round Signature (can be verified after the game):', roundSignature);
  console.log('🎯 Dice landed on:', diceValue);
})();

Mai multe ghiduri Provably Fair pentru jocuri:

  1. Provably Fair la Mines
  2. Provably Fair la Pump
  3. Provably Fair la Plinko
  4. Provably Fair la Dice: Golden Ticket
  5. Provably Fair la Limbo
  6. Provably Fair la Roulette
  7. Provably Fair la Keno