Bangun simulator slot Anda sendiri dalam 40 baris Python — dan buktikan angkanya
Cara terbaik memahami mesin slot adalah membangunnya. Tutorial langkah demi langkah membuat simulator gulungan berbobot yang mereproduksi near-miss, RTP, dan varians — dengan kode yang bisa Anda jalankan.
Semua artikel di situs ini bersandar pada satu kebiasaan: alih-alih mempercayai klaim tentang mesin slot, kita membangun mesinnya dan mengukur sendiri. Bagian yang menyenangkan, membangun simulator slot yang cukup realistis tidak butuh lebih dari sekitar empat puluh baris Python. Tutorial ini menuntun Anda membuatnya dari nol — mesin yang mereproduksi gulungan berbobot, “hampir menang”, RTP, dan varians — sehingga Anda bisa memverifikasi tiap angka yang pernah saya terbitkan, dan menguji dugaan Anda sendiri.
Gagasan inti: gulungan berbobot
Kunci realisme sebuah mesin slot adalah bahwa simbol tidak muncul dengan peluang sama. Kita meniru ini dengan memberi tiap simbol sebuah bobot: makin besar bobotnya, makin sering ia terpilih. Simbol jackpot diberi bobot kecil (jarang), simbol kosong bobot besar (sering). Inilah cara kita mengendalikan hit rate dan mereproduksi near-miss tanpa mengubah berapa simbol yang terlihat.
Mulai dengan mendefinisikan gulungan dan cara memutar satu gulungan:
import random
# Bobot tiap simbol pada satu gulungan. Jackpot (SEV) langka.
WEIGHTS = {'SEV': 1, 'BAR': 3, 'BELL': 6, 'CH': 9, 'LEM': 13}
def putar_satu_gulungan(rng, weights):
total = sum(weights.values())
r = rng.random() * total
akumulasi = 0
for simbol, bobot in weights.items():
akumulasi += bobot
if r < akumulasi:
return simbol
Fungsi ini memilih simbol sebanding bobotnya: SEV dengan bobot 1 dari total 32 hanya muncul sekitar 3 persen waktu, sementara LEM dengan bobot 13 muncul sekitar 41 persen. Itulah gulungan virtual dalam bentuk paling sederhana.
Menambahkan tabel bayaran
Sekarang definisikan cara sebuah putaran tiga-gulungan dibayar. Kita bayar tiga simbol sama, plus kasus khusus dua ceri:
PAYTABLE = {'SEV': 594, 'BAR': 89, 'BELL': 30, 'CH': 11, 'LEM': 4.5}
def bayaran(hasil):
a, b, c = hasil
if a == b == c:
return PAYTABLE[a] # tiga simbol sama
if a == 'CH' and b == 'CH':
return 2.2 # dua ceri di dua gulungan pertama
return 0.0
def satu_putaran(rng):
hasil = [putar_satu_gulungan(rng, WEIGHTS) for _ in range(3)]
return hasil, bayaran(hasil)
Angka pada PAYTABLE bukan sembarang; mereka dipilih agar RTP mesin mendekati 96 persen. Bagaimana kita tahu? Kita ukur.
Mengukur RTP dan hit rate
Inilah inti metode Monte Carlo: jalankan mesin berkali-kali dan rata-ratakan. Perhatikan penggunaan benih tetap (seed) — inilah yang membuat hasil Anda bisa direproduksi persis oleh siapa pun:
def ukur(nspin, seed=7):
rng = random.Random(seed) # benih tetap: hasil dapat diulang
total_bayar = 0.0
hit = 0
for _ in range(nspin):
_, bayar = satu_putaran(rng)
total_bayar += bayar
if bayar > 0:
hit += 1
print(f"RTP = {total_bayar / nspin:.4f}")
print(f"Hit rate = {hit / nspin:.4f}")
ukur(3_000_000)
# RTP = 0.9602
# Hit rate = 0.1537
Jalankan, dan Anda akan melihat RTP sekitar 0,96 dan hit rate sekitar 0,15 — artinya 85 persen putaran mengembalikan nol. Ubah PAYTABLE atau WEIGHTS, dan angka ini bergerak: Anda bisa menyetel mesin ke RTP mana pun. Coba naikkan bobot SEV dan RTP ikut naik karena jackpot lebih sering. Ini persis tuas yang dipakai perancang mesin sungguhan.
Mereproduksi “hampir menang”
Untuk melihat near-miss lahir dari kode, kita memodifikasi gulungan ketiga agar simbol di dekat jackpot dibobot lebih berat — meniru cara mesin nyata menempatkan “nyaris” tepat di sebelah garis bayar. Prinsipnya: beri gulungan ketiga bobot berbeda yang memperbanyak simbol tepat sebelum dan sesudah SEV. Ketika Anda menghitung berapa sering “dua SEV di garis bayar lalu SEV meleset tipis di gulungan ketiga”, frekuensinya keluar berkali-kali lipat lebih tinggi daripada jackpot itu sendiri — bukan karena nasib, melainkan karena bobot yang Anda pasang. Near-miss adalah keluaran langsung dari tabel bobot, dan simulator ini menunjukkannya di depan mata Anda.
Dari putaran ke sesi
Setelah mesin jadi, pertanyaan menarik bergeser dari “berapa RTP” ke “apa yang terjadi pada seorang pemain”. Bungkus mesin dalam simulasi sesi:
def sesi(rng, modal, taruhan, nspin):
saldo = modal
for _ in range(nspin):
if saldo < taruhan:
break # bangkrut
saldo -= taruhan
_, bayar = satu_putaran(rng)
saldo += bayar
return saldo
def banyak_sesi(npemain, modal=100, taruhan=1, nspin=500, seed=11):
rng = random.Random(seed)
hasil = [sesi(rng, modal, taruhan, nspin) for _ in range(npemain)]
untung = sum(1 for h in hasil if h > modal)
bangkrut = sum(1 for h in hasil if h < taruhan)
print(f"Untung : {100*untung/npemain:.1f}%")
print(f"Bangkrut : {100*bangkrut/npemain:.1f}%")
banyak_sesi(10_000)
# Untung : 33.7%
# Bangkrut : 34.5%
Dengan potongan ini Anda mereproduksi salah satu temuan terpenting: di mesin RTP 96 persen, sepertiga pemain pulang untung sementara sepertiga bangkrut total — sebaran yang sangat jauh dari “semua orang dapat 96 persen”.
Latihan: ukur varians dan rentetan kekeringan sendiri
Dua pengukuran lanjutan mengubah simulator dari mainan menjadi alat analisis. Pertama, varians — seberapa liar bayaran melompat. Kumpulkan bayaran tiap putaran, lalu hitung simpangan bakunya:
def ukur_varians(rng, nspin):
data = [satu_putaran(rng)[1] for _ in range(nspin)]
rata = sum(data) / nspin
varians = sum((b - rata) ** 2 for b in data) / nspin
print(f"Simpangan baku per putaran = {varians ** 0.5:.2f}")
Ubah PAYTABLE agar hadiah puncak jauh lebih besar dan lebih langka, dan simpangan baku melonjak — itulah volatilitas tinggi lahir dari kode. Kedua, rentetan kekeringan: berapa putaran beruntun tanpa bayaran. Lacak penghitung yang direset tiap kali menang, dan simpan nilai terpanjangnya. Anda akan menemukan bahwa rentetan puluhan putaran nihil sepenuhnya normal di mesin ber-hit-rate 15 persen — bukti terukur bahwa “mesin dingin” hanyalah bagian biasa dari distribusi, bukan pertanda apa pun.
Kenapa membangunnya mengubah cara Anda melihat
Nilai sejati latihan ini bukan kodenya, melainkan pergeseran sikap yang ia paksa. Begitu Anda bisa menyetel RTP dengan mengubah satu angka, “RTP 96 persen” berhenti menjadi jimat dan menjadi apa adanya: sebuah parameter desain. Begitu Anda melihat near-miss lahir dari tabel bobot, ia berhenti terasa seperti nasib dan menjadi keputusan teknik. Dan begitu Anda menjalankan sepuluh ribu pemain lalu melihat sepertiga bangkrut, “menang semalam” tak lagi bisa Anda anggap sebagai bukti apa pun tentang mesin.
Salin seluruh potongan di atas ke satu berkas, jalankan pada Python 3 tanpa pustaka tambahan, dan Anda punya laboratorium slot sendiri. Ubah bobotnya, ubah tabel bayarannya, uji dugaan Anda. Setiap angka yang saya terbitkan berasal dari mesin seperti ini — dan sekarang Anda bisa memeriksanya, bukan sekadar mempercayainya.