Klasik "merdivenler ve yılanlar" oyununun yılan yerine kaydırak kullananı da var: Chutes and Ladders. Evde bu oyunu oynarken yine kaç hamlede bittiğini vs. merak ettim ve bir program yazdım.
Geçen günki sohbette sözü geçince de biraz düzenleyip burada göstermek istedim:
import std.stdio;
import std.range;
import std.algorithm;
import std.random;
import std.format;
import core.thread;
enum konumAdedi = 100;
const(size_t[]) bağlantılar;
shared static this() {
bağlantılar = {
auto sonuç = size_t(konumAdedi + 1).iota.array;
// 0 numaralı konum hiç kullanılmayacak; yasal olmayan bir değerle ilkleyelim
sonuç[0] = 2 * konumAdedi;
const merdivenler = [ 1 : 38, 4 : 14, 9 : 31, 21 : 42, 28 : 84,
36 : 44, 51 : 67, 71 : 91, 80 : 100 ];
const kaydıraklar = [ 16 : 6, 48 : 26, 49 : 11, 56 : 53, 62 : 19,
64 : 60, 87 : 24, 93 : 73, 95 : 75, 98 : 78 ];
chain(merdivenler.byKeyValue,
kaydıraklar.byKeyValue)
.each!(kv => sonuç[kv.key] = kv.value);
return sonuç;
}();
}
struct Oyun {
size_t[] zarlar; // Şimdiye kadar atılan zarlar
size_t konum;
bool bitti_mi() const {
return konum == konumAdedi;
}
void oyna(size_t zar, Flag!"bilgiVer" bilgiVer = No.bilgiVer) {
zarlar ~= zar;
const yeniKonum = konum + zar;
if (yeniKonum > konumAdedi) {
return;
}
const atlanan = bağlantılar[yeniKonum];
konum = atlanan;
if (bilgiVer) {
const hamle = zarlar.length;
writef!"%s: konum: %s zar: %s"(hamle, konum, zar);
string bilgi() {
if (atlanan == yeniKonum) {
return format!"%s"(konum);
}
string atlamaBilgisi(string karakter, size_t uzunluk) {
return format!"%s %s %s"(yeniKonum, karakter.repeat(uzunluk).joiner, atlanan);
}
if (atlanan > yeniKonum) {
return atlamaBilgisi("+", atlanan - yeniKonum);
}
return atlamaBilgisi("-", yeniKonum - atlanan);
}
writefln!" yeni konum: %s"(bilgi);
}
}
}
void deney(ref size_t enKısa, ref size_t enUzun) {
auto o = Oyun();
while (!o.bitti_mi) {
const zar = uniform(1, 7);
o.oyna(zar);
}
const uzunluk = o.zarlar.length;
void göster(string bilgi) {
writefln!"\nEn %s: %s zar atışı"(bilgi, uzunluk);
auto o2 = Oyun();
o.zarlar.each!(zar => o2.oyna(zar, Yes.bilgiVer));
}
if (uzunluk > enUzun) {
göster("uzun");
enUzun = uzunluk;
}
if (uzunluk < enKısa) {
göster("kısa");
enKısa = uzunluk;
}
}
void main() {
auto enUzun = size_t.min;
auto enKısa = size_t.max;
foreach (oyunNumarası; 1 .. 1_000_001) {
if ((oyunNumarası % 100_000) == 0) {
writefln!"Oyun %,s..."(oyunNumarası);
}
deney(enKısa, enUzun);
}
}
İnternette bu oyunun başka analizleri de bulunuyor. Oralarda da görüldüğü gibi, en kısa oyun 7 hamle sürüyor ama en uzun oyunun hamle sınırı yok. 7'de biten birden fazla olasılık var ama yukarıdaki program ilk bulduğu 7'den başkasını göstermiyor.
Ali
--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]