Dördüncü girdi
Sağlanabilir adil oyunun her açıklaması, bizimki dahil, üç girdiden bahseder: kasanın önceden taahhüt ettiği bir sunucu tohumu (server seed), kendinizin belirleyebildiği bir istemci tohumu (client seed) ve her bahiste bir artan bir nonce. Bunları anahtarlı bir hash'e beslersiniz ve turun rastgeleliği ortaya çıkar. Bu açıklama yazı tura için eksiksizdir. Neredeyse her şey için eksiktir, çünkü bir hash tek bir sayı üretir ve çoğu oyun birden fazlasına ihtiyaç duyar.
Dördüncü girdi imleçtir (cursor). Bu sitede hash'lenen mesaj "client seed-nonce" değil, "client seed-nonce-cursor"dur ve imleç, tur içindeki bir sayaçtır: oyunun ihtiyaç duyduğu ilk rastgele sayı için 0, ikincisi için 1, ve böyle devam eder. Her imleç değeri, komşularıyla hiçbir şekilde istismar edilemeyecek şekilde ilişkisiz, taze bir 256 bit özet (digest) verir ve motor her özetin ilk sekiz baytını 0 ile 1 arasında bir sayı olarak okur.
MOTOR TARAFINDAN DOĞRULANMIŞ_shared/demoLocal.ts: uAt(pair, cursor), u64(HMAC-SHA256(serverSeed, `${clientSeed}-${nonce}-${cursor}`)) döndürür, bu da sunucunun RandomUtils.generateHash("clientSeed-nonce-cursor") ile eşleştiği belirtilir. _shared/rng.ts: u64, özetin ilk sekiz baytını hi/2^32 + lo/2^64 olarak okur, sunucunun ULong→Double dönüşümüyle "aynı tek yuvarlamalı yapı". Nonce, tüm oyunlarda tohum çifti başına tek bir akıştır: her bahis mevcut nonce'u tüketir ve nonce + 1'i saklar.
Yani bir tur tek bir rastgele sayı değil, oyunun ihtiyacı kadar uzun, numaralandırılmış bir sayı listesidir ve listedeki her giriş, tohum çifti ve nonce belirlendiği anda sabitlenmiştir. Oyun ilerledikçe çekmez. Zaten var olan bir listeyi okur.
Her oyun ne okur
İlginç olan kısım, listenin her oyun için farklı olması ve her türetme modülünün düzenini kendi başlığında belirtmesidir. İşte tohum çiftinden çeken her orijinal oyunun imleç akışı, motor kaynağından alınmıştır.
| OYUN | OKUNAN İMLEÇLER | NEYE DÖNÜŞÜYORLAR |
|---|---|---|
| Limbo | 0 | 0.99 ÷ (1 − u) eğrisinden geçen tek bir sayı |
| Rulet | 0 | Cep: floor(u × 37) |
| Fukubukuro | 0 | Eşya, çantanın ağırlık tablosuna göre |
| Sic Bo | 0, 1, 2 | Üç zar |
| Chinchiro | taraf × 9 + deneme × 3 + zar | 18'e kadar: önce kasa sonra oyuncu, her biri üçer zarla en fazla üç atış; bir el oluşturan atış tarafı sonlandırır |
| Koban Flip | her çevirme için bir | Çevirme i, imleç i'yi okur; ilk para satın alındığında turun her yüzü sabitlenir |
| Omikuji | 0, ardından 1–3, ardından 4'ten itibaren | Şans katmanı; kazançta kazanan üç hücre; geri kalanı için dolgu semboller |
| Pagoda | her kat için bir | Her kattaki tuzak karo: floor(u × karo) |
| Video Poker | 5, artı değiştirilen her kart için bir | 52 kart üzerinde iadesiz bir sıra; her şeyi tut ve başka imleç okunmaz |
| Casino Hold'em | 9'a kadar | oyuncu 1, oyuncu 2, kurpiyer 1, kurpiyer 2, flop 1–3, turn, river; turn ve river yalnızca CALL durumunda okunur |
| Blackjack | kart başına bir | Sonsuz kart destesi, kart = floor(u × 52), dağıtım sırasına göre: oyuncu, kurpiyer açık kart, oyuncu, kurpiyer kapalı kart, ardından her ek çekiliş |
| Andar Bahar | 0–4, ardından yarışan her kart için bir | İki güçlendirilmiş kova, bunların büyüklükleri, joker, ardından rütbe tekrarlanana kadar yarış |
| Hanabi | spin başına 15 | Hücre = makara × 3 + satır; free spin j, 15 + 15j'den itibaren okunur |
| Bingo | 0–24, ardından 25–62 | Kart, sütun başına beş çekiliş; ardından 38 top |
Keno ve Crash istisnadır: demo turları, aşağıda açıklanan seed-pair nonce yerine bilet başına bir hash zinciri kullanır. Mines ve Plinko, house servisi tarafından sonuçlandırılır; mines API'si tüm düzenin tek bir nonce'tan geldiğini belirtir.
MOTOR TARAFINDAN DOĞRULANMIŞTIRbingo/derive.ts içindeki başlık yorumları (“Cursor stream: 0..24 — the card … 25..62 — the 38 balls”), hanabi/engine.ts (“base spin = cells 0..14 … free spin j = cells 15+15j .. 29+15j”), blackjack/derive.ts (“card i = floor(u × 52) at cursor i … Deal order (cursor): player1, dealer-up, player2, dealer-hole”), vpoker/derive.ts (“the first five are the deal, replacements continue the same sequence … Hold everything and no further cursor is read”), holdem/derive.ts (“player1, player2, dealer1, dealer2, flop1, flop2, flop3, turn, river. The turn/river cursors are only consumed on CALL”), andar/derive.ts (cursors 0–4 then “5.. one cursor per raced card”), koban/derive.ts (“flip i reads cursor i”), sicbo/derive.ts (“cursors 0/1/2 are the three dice”), roulette/derive.ts (“cursor 0 alone decides the pocket: floor(u × 37)”), fuku/derive.ts (“cursor 0 alone draws the item”), omikuji/derive.ts (cursor 0 tier, 1..3 winning cells, 4.. fillers); demoLocal.ts rollSide (chinchiro cursor = side*9 + attempt*3 + d), trapAt (pagoda: the floor number is the cursor), demoLimboBet (uAt(p, 0)); mines/minesApi.ts (“the whole mine layout comes off this one nonce”).
Bu tabloda üç şey dikkat çekiyor. Birincisi, kart dağıtan oyunlar her kart için sabit bir sırayla bir cursor okur, bu yüzden bir blackjack elini işlem listesinden yeniden oynatmak mümkündür: hit kararınız yeni bir kart yaratmaz, dağıtımdan önce zaten tamamlanmış olan bir listedeki bir sonraki kartı çevirir. İkincisi, birçok oyun okumayı erken durdurur. Beş kartın tümünü tuttuğunuz bir video poker eli asla cursor 5'e dokunmaz; bir Hold'em fold'u asla turn veya river'ı okumaz. Sayılar oradaydı; oyunun onlara ihtiyacı olmadı. Üçüncüsü, Andar Bahar'daki iki güçlendirilmiş kova ve Omikuji'deki şans seviyesi, kartlardan ve hücrelerden önce, akışın başında çekilir, böylece turun özel özellikleri sıradan özellikleriyle aynı taahhütle sabitlenir.
İadesiz çekiliş
0 ile 1 arasındaki tekdüze bir sayıyı bir rulet cebine dönüştürmek kolaydır: 37 ile çarpın ve aşağı yuvarlayın. Bir deste daha zordur, çünkü ikinci kart tekrar birinci kart olmamalıdır. Motor bunu, kendi yorumlarının pool hop dediği yöntemle halleder: havuzda hâlâ kalan kartların bir listesini tutun, bir konum seçmek için cursor'ın sayısını kullanın ve seçilen kartı listenin sonuna takas edin, böylece bir sonraki çekiliş bir eksik kalandan seçim yapar. Video Poker, Casino Hold'em, Andar Bahar ve Bingo kartı bu şekilde çekilir, böylece bir tur içinde hiçbir kart veya sayı tekrarlanmaz.
Blackjack, bilinçli bir istisnadır. Kart destesi sonsuzdur: her kart kendi cursor'ından floor(u × 52) ile hesaplanır ve aynı kart bir elde iki kez görünebilir. Bu, blackjack ödeme makalesinde tartışılan yayımlanmış bir maliyeti olan bilinçli bir tasarım tercihidir ve tam olarak cursor düzeninin size söylediği, bir pazarlama sayfasının söylemeyeceği türden bir şeydir.
MOTOR TARAFINDAN DOĞRULANMIŞTIRvpoker/derive.ts: “Cards come from ONE without-replacement sequence over the 52-card deck (pool-hop, cursor per draw)”. holdem/derive.ts: “ONE without-replacement pool-hop sequence (cursor per draw)”. bingo/derive.ts: “five pool-hop draws per column” and “the 38 balls, pool-hops over 1..75”. blackjack/derive.ts: “Infinite shoe: card i = floor(u × 52) at cursor i”.
İki istisna
Keno ve Crash, demo motorunda seed-pair nonce'unu hiç okumaz. Keno, bilet başına bir şema kullanır: bilet kendi rastgele hash'ini ve bir salt alır, ve on topun her biri bir önceki hash'i tekrar hashleyerek, öndeki bitleri bir sayı olarak alıp kırktan oluşan küçülen havuzdan seçim yaparak çekilir. Fairness paneli, bir keno biletini seed çiftinden değil, bu iki string'den doğrular. Crash, bustabit geleneğini takip eder; her turun crash noktasının kendi zincir bağlantısından tam sayı aritmetiğiyle hesaplandığı bir hash zinciridir.
MOTOR TARAFINDAN DOĞRULANDIdemoLocal.ts kenoDraws: “bahis başına randomHash zinciri + salt (fairness modalı üzerinden bilet başına doğrulanabilir) … seed-pair nonce'una dokunmaz”; döngü HMAC-SHA256(salt, önceki hash) işlemini on kez uygular, öndeki 52 biti okur ve 40 sayılık havuzdan index floor(norm × kalan) seçer, sona bir takasla. rng.ts h52 ve crash yorumu: “yüzde birlik cinsinden bustabit crash noktası: floor((n·e − h)/(e − h)), e = 2^52, n = 100 … Sunucuyla eşleşmek için tam BigInt matematiği”.
Her iki istisna da cursor şemasından daha zayıf değildir; ikisi de daha eski ve daha iyi bilinir. Bir oyuncu için önemli olan tek şey, panelin bir turun hangi şemayı kullandığını göstermesi ve her birinin gösterdiği string'lerden yeniden hesaplanabilmesidir.
Masada ne anlama gelir
- Tur, sen hareket etmeden önce zaten var. Bir turun her kartı, topu ve makara sembolü, seed çiftinin, nonce'un ve cursor konumunun bir fonksiyonudur. Vurmak, çağırmak veya beklemek, hangi girişlerin okunacağını seçer, içeriklerini değil.
- Seçimlerin listeyi değiştiremez, kasa da değiştiremez. Sunucu seed'i taahhüt edilip nonce sabitlendiğinde, hiçbir taraf 7 numaralı girişi, sana gösterilen parmak izini bozmadan değiştiremez.
- Bir doğrulayıcı, aynı listeyi aynı şekilde okumak zorundadır. Bir bingo turunu yeniden hesaplamak, yayınlanan sırada 63 cursor'un tümünü türetmek demektir; bir Hold'em fold'unu yeniden hesaplamak 7 tanesini türetmek demektir. Seed paneli bunu tarayıcında yapar, ve yukarıdaki tablodaki düzenler onun izlediği şeydir.
- Bir seri bir listedir, bir ruh hali değil. İki tur, seed çiftinden başka hiçbir şey paylaşmaz; nonce'ları farklıdır, dolayısıyla her digest de farklıdır. Bu, hot hand makalesinin diğer taraftan yaptığı aynı noktadır.
Üç girdi turu belirler. Dördüncüsü turun ne kadar süreceğini belirler.tek satırda cursor
Yukarıdaki cursor düzenleri, tarayıcı doğrulayıcısı ve demo motorunun paylaştığı istemci tarafı türetme modüllerinden okunmuştur. Kasa hizmeti ödeme yapan yetkilidir; kaynak kodundaki bir yorum bir modülün sunucuyu yansıttığını söylediğinde, bu yazıldığı gibi alıntılanır, bizim tarafımızdan onaylanmış değildir.
SSS
Provably fair bir turda cursor nedir?
Tur içindeki bir sayaç. Sunucu seed'iyle hashlenmiş mesaj “client seed-nonce-cursor”dur; cursor 0, oyunun ihtiyaç duyduğu ilk rastgele sayıyı verir, cursor 1 ikincisini, ve böyle devam eder. Bir sayıya ihtiyaç duyan bir oyun sadece cursor 0'ı okur.
Cursor, nonce'tan nasıl farklıdır?
Nonce turları sayar ve her orijinaldeki her bahiste bir artar. Cursor, bir tur içindeki çekilişleri sayar ve her turda 0'dan yeniden başlar. Seed çiftiyle birlikte, sitenin ürettiği her rastgele sayıyı tanımlarlar.
Bir bingo turu kaç rastgele sayı kullanır?
Altmış üç: cursor 0'dan 24'e kartın 25 hücresini yerleştirir ve cursor 25'ten 62'ye 38 topu çeker, tümü kendi havuzları içinde iadesiz olarak.
Blackjack'te vurmak bir sonraki kartı değiştirir mi?
Hayır. Her kart, dağıtım sırasına göre kendi cursor'undan türetilir, ve seed çifti ile nonce sabitlendiğinde tüm liste zaten mevcuttur. Vurmak bir sonraki girişi okur; durmak onu okunmadan bırakır.
Tüm oyunlar imleç şemasını mı kullanıyor?
Keno ve Crash bunun yerine hash zincirlerini kullanır: keno, bilet başına rastgele bir hash ve salt değerini on kez hashler, crash ise bustabit zincirini tam sayı aritmetiğiyle takip eder. Adalet paneli, gösterdiği string'lerden her birini doğrular.
KAYNAKLAR VE REFERANSLAR
- Betkyo motor kaynağı: _shared/demoLocal.ts (uAt, rollSide, trapAt, kenoDraws), _shared/rng.ts (u64, h52, crash point) ve bingo, hanabi, blackjack, vpoker, holdem, andar, koban, sicbo, roulette, fuku ve omikuji için türetme modülleri
- RFC 2104 — HMAC: Mesaj Doğrulama için Anahtarlı Hashleme
- Bustabit provably fair şeması (motorun yansıttığı crash-point yapısı)
BU MAKALEDEKİ OYUNLAR
Blackjack — kurallar ve ücretsiz oyun →Bingo — kurallar ve ücretsiz oyun →Sic Bo — kurallar ve ücretsiz oyun →