رياضي

ألعاب

عام

ألعاب مخصصة - Provably Fair

كيف يتم استخدامها في الألعاب المخصصة

تبدأ كل رهان في لعبة YEET Original من بذرة جولة. بذرة الجولة هي HMAC-SHA256 لبذرة العميل الخاصة بك وnonce الرهان، مشفرة ببذرة خادم تختارها YEET. تستمد اللعبة بعد ذلك كل قيمة عشوائية تحتاجها لهذا الرهان من بذرة الجولة. يتم عرض بذرة الخادم لك بشكل مجزأ (hashed) قبل اللعب، ويتم الكشف عنها عند تدوير زوج البذور الخاص بك، حتى تتمكن من إعادة حساب بذرة الجولة لأي رهان سابق والتحقق من أن نتيجته لم تتغير بعد أن قمت بالمراهنة.

قد لا تتطابق أدوات التحقق الأخرى

مواقع التحقق المخصصة للكازينوهات الأخرى قد تولد أرقاماً عشوائية بطريقة مختلفة، لذا فإن التحقق من رهان YEET هناك قد يعطي نتيجة مختلفة. تحقق من رهانات YEET في علامة تبويب التحقق (Verify) ضمن نافذة النزاهة (Fairness) للعبة، أو باستخدام الكود الموجود في هذه الصفحة.

التحويلات

يقوم التحويل بتحويل إنتروبيا مفتاح الجولة إلى نتيجة لعبة. حجر الأساس هو نفسه في كل لعبة أصلية: تختار unbiasedUint موضعاً واحداً من n مواضع متساوية الاحتمالية، وتتحقق اللعبة مما إذا كان هذا الموضع فائزاً. الخطوة التي تحتوي على s مواضع فائزة من أصل n لديها فرصة بنسبة s / n.

هذه الصفحة لا تدرج تحويلاً لكل لعبة. يوضح المثال أدناه النمط المتبع مع إحدى الألعاب.

مثال: لامب تشوب (Lamb Chop)

تحتوي لعبة لامب تشوب على 16 قفزة، وكل قفزة هي سحب واحد من نفس بذرة الجولة. في القفزة h، يحتوي المسار على totalStart − h من المراكز، منها safeStart − h آمنة. الرمية التي تكون أقل من عدد المراكز الآمنة تنجو. أول رمية لا تحقق ذلك تنهي الجولة، ويتم تحديد المضاعف من جدول الرواتب بناءً على عدد القفزات التي تم تجاوزها.

const LAMB_CHOP_TOTAL_HOPS = 16;

const LAMB_CHOP_LANES = {
  easy: [19, 21],
  medium: [19, 23],
  hard: [19, 25],
  very_hard: [19, 27],
  death_wish: [20, 32],
};

const LAMB_CHOP_PAYTABLE = {
  easy: [
    1.0721, 1.1912, 1.3313, 1.4977, 1.6975, 1.94, 2.2384, 2.6115,
    3.0863, 3.7036, 4.5266, 5.6583, 7.275, 9.7, 13.58, 20.37,
  ],
  medium: [
    1.1742, 1.4351, 1.7728, 2.216, 2.8069, 3.6089, 4.7194, 6.2925,
    8.5807, 12.013, 17.3522, 26.0283, 40.9016, 68.1694, 122.705, 245.41,
  ],
  hard: [
    1.2763, 1.7017, 2.3023, 3.1657, 4.432, 6.3315, 9.2537, 13.8806,
    21.4519, 34.323, 57.2051, 100.1089, 185.9166, 371.8333, 818.0333, 2045.0833,
  ],
  very_hard: [
    1.3784, 1.991, 2.928, 4.392, 6.7344, 10.5826, 17.0951, 28.4918,
    49.2132, 88.5838, 167.325, 334.65, 717.1071, 1673.25, 4350.45, 13051.35,
  ],
  death_wish: [
    1.552, 2.5322, 4.2203, 7.1994, 12.5989, 22.6781, 42.1166, 80.9934,
    161.9869, 338.7, 745.1401, 1738.6604, 4346.651, 11798.0529, 35394.1588, 120340.14,
  ],
};

async function verifyLambChopBet(serverSeed, clientSeed, nonce, volatility) {
  const seed = await deriveGameSeed(serverSeed, clientSeed, nonce);
  const result = await verifyLambChopFromSeed(seed, volatility);
  return { serverSeed, clientSeed, nonce, ...result };
}

async function verifyLambChopFromSeed(seed, volatility) {
  const lane = LAMB_CHOP_LANES[volatility];
  if (!lane) throw new Error(`No lamb-chop lane geometry for risk profile '${volatility}'.`);

  const [safeStart, totalStart] = lane;
  const entropy = new GameEntropy(hexToBytes(seed));
  const hops = [];
  let bustIndex = LAMB_CHOP_TOTAL_HOPS;

  for (let hop = 0; hop < LAMB_CHOP_TOTAL_HOPS; hop++) {
    const safePositions = safeStart - hop;
    const totalPositions = totalStart - hop;
    const roll = await unbiasedUint(entropy, totalPositions);
    const survived = roll < safePositions;

    hops.push({
      hop,
      safePositions,
      totalPositions,
      chance: safePositions / totalPositions,
      roll,
      survived,
    });

    if (!survived) {
      bustIndex = hop;
      break;
    }
  }

  return {
    seed,
    entropyCursor: entropy.cursor,
    volatility,
    hops,
    bustIndex,
    clearedAllHops: bustIndex >= LAMB_CHOP_TOTAL_HOPS,
    maxReachableMultiplier: lambChopMultiplierFor(volatility, bustIndex),
    paytable: LAMB_CHOP_PAYTABLE[volatility],
  };
}

function lambChopMultiplierFor(volatility, hopCount) {
  if (hopCount < 1) return 0;

  const row = LAMB_CHOP_PAYTABLE[volatility];
  if (!row) throw new Error(`No lamb-chop paytable for risk profile '${volatility}'.`);

  const multiplier = row[hopCount - 1];
  if (multiplier === undefined) {
    throw new Error(`No lamb-chop paytable row for ${volatility} at ${hopCount} hop(s).`);
  }

  return multiplier;
}

// Use the revealed server seed (64 hex characters) and the client seed and nonce shown on the bet.
console.log(await verifyLambChopBet(
  'REVEALED_SERVER_SEED',
  'yeetdemo-7f3a91',
  '1842',
  'easy'
));