스포츠

게임

일반

사용자 지정 게임 - 공정성 입증

커스텀 게임에서 사용되는 방법

YEET Original의 모든 베팅은 라운드 시드에서 시작됩니다. 라운드 시드는 클라이언트 시드와 베팅의 nonce를 HMAC-SHA256으로 해싱한 값이며, YEET이 선택한 서버 시드가 키로 사용됩니다. 게임은 해당 베팅에 필요한 모든 무작위 값을 이 라운드 시드에서 추출합니다. 서버 시드는 플레이하기 전에 해싱된 상태로 표시되며, 시드 페어를 교체할 때 공개되므로 과거 베팅의 라운드 시드를 다시 계산하여 결과가 조작되지 않았는지 확인할 수 있습니다.

다른 검증 결과와 일치하지 않을 수 있음

다른 카지노용으로 제작된 검증 사이트는 무작위 숫자 생성 방식이 다를 수 있으므로, 해당 사이트에서 YEET 베팅을 확인하면 결과가 다르게 나올 수 있습니다. YEET 베팅은 게임의 공정성 창에 있는 검증 탭이나 이 페이지의 코드를 사용하여 확인하세요.

전환

변환은 라운드 시드의 엔트로피를 게임 결과로 바꿉니다. 모든 Original 게임의 기본 구성 요소는 동일합니다. unbiasedUint가 동일한 확률의 n개 위치 중 하나를 선택하면, 게임은 해당 위치가 당첨인지 확인합니다. n개 중 s개의 당첨 위치를 가진 단계의 확률은 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'
));