Forum: Ders Arası RSS
XOX Oyunu!
Basit bir XOX oyunu (tamamlanmadı)
Acemi #1
Üye Nis 2014 tarihinden beri · 7 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: XOX Oyunu!
Merhabalar,
Kendimi geliştirmek için basit bir XOX oyunu yazmaya çalıştım. Build etmek için DUB kullanmanıza gerek yok.
Ali hocamın yardımlarıyla oyunu ve kendimi baya bir geliştirdim! İlk haline göre çok daha güzel oldu bence :D
https://github.com/acemi/xox-game

Yapılacaklar:
  • Yapay zeka (hala düşünüyorum :D)
  • Grafik arayüzü (hala kütüphane arıyorum :()
Bu mesaj 3 defa değişti; son değiştiren: Acemi; zaman: 2014-05-03, 06:40.
acehreli (Moderatör) #2
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Çok güzel olmuş ve zevkle oynanıyor. :)

Notlar:

  • alias tiles benim 2.066 geliştirme sürümünde derlenmedi: "Error: alias tiles cannot alias an expression this.tilesData" alias yerine auto yazdım.

  • Satır ve sütunu girerken önce satırı girdiğimi düşündüm ama sütunmuş. Yani, 1,2 deyince birinci satır, ikinci sütun olsa...

  • enum PLAYER : MARK kullanımı ilginç. Yapılabildiğini biliyorum ama hiç enum'a bağlı enum kullanmak aklıma gelmezdi. :)

  • row <= 0 gibi karşılaştırmalar hiç sıfırdan küçük olamaz çünkü size_t işaretsiz bir türdür. (Burada işe yarıyor ama bazen bunun row < 0 diye yazıldığına da rastlanıyor; o zaman hiç olmazdı. :) )

  • h[3] diye dizi tanımlamışsın ama sonra v[int] ve d[int] diye eşleme tablosuna dönmüşsün. O ikisi de dizi olabilirmiş.

  • checkIfWon() basitleştirilebilir. Kod o kadar da az olmadı ama şöyle döngüler de kurulabilir (d'yi döngüsüz, dizi ilkleyerek yazdım):
        // ALL POSSIBILITIES
        int h[3]; // Horizontal possibilities
        foreach (i; 0 .. h.length) {
            foreach (j; 0 .. tiles[i].length) {
                h[i] += tiles[i][j];
            }
        }
 
        int v[3]; // Vertical possibilities
        foreach (i; 0 .. v.length) {
            foreach (j; 0 .. tiles[i].length) {
                v[i] += tiles[j][i];
            }
        }
 
        // Diagonal possibilities (only 2)
        int d[2] = [ tiles[0][0] + tiles[1][1] + tiles[2][2],
                     tiles[0][2] + tiles[1][1] + tiles[2][0] ];
Kazanma ile ilgili denetimde de her olasılığı listelemek yerine şöyle bir mantık kurulabilir: h, v, ve d dizileri içinde XXX veya OOO bulunuyor mu. Aşağıdaki kod bu aşamada karışık gelebilir ama tam da o soruyu soruyor:
import std.range;
import std.algorithm;
// ...
        if (chain(h[], v[], d[]).canFind([XXX], [OOO]))
Karışıklığın bir nedeni, chain'in parantezinin içinde boş dizi parantezleri kullanılıyor olması. Onların nedeni, sabit uzunluklu dizilerin aralık (range) olarak kullanılamamaları (çünkü popFront() ile eleman kaybetmeleri olanaksızdır). O yüzden boş dizi parantezleri ile önce tam dilimlerini alıyoruz.

Ali
Acemi #3
Üye Nis 2014 tarihinden beri · 7 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yardımınız ve notlarınız için gerçekten çok teşekkürler :) Sanırım chain ve canFind, std.algorithm içerisinde bulunuyor? Ben dizi içerisinde arama işlemini çok araştırmış ama ne yazık ki bulamamıştım.

Kullanıcı hatalı formatta girdiğinde std.conv.ConvException hatası atıp kapanıyor. Kullanıcıyı uyarıp yeniden girmesini sağlamanın bir yolu var mı acaba?
try-catch denedim ama ne yazık ki sonuç alamadım :(
acehreli:
  • alias tiles benim 2.066 geliştirme sürümünde derlenmedi: "Error: alias tiles cannot alias an expression this.tilesData" alias yerine auto yazdım.
Çok garip gerçekten? Ben 2.065 kullanıyorum. Bu hatayı neden veriyor ben pek anlayamadım...
Bu mesaj 2 defa değişti; son değiştiren: Acemi; zaman: 2014-05-02, 08:42.
acehreli (Moderatör) #4
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Acemi:
Sanırım chain ve canFind, std.algorithm içerisinde bulunuyor

chain std.range içinde. Yaptığı, kendisine verilen ayrık aralıkları tek aralık olarak sunmak.

canFind da nerede olduğuna bakmadan bulunup bulunmadığını bildiriyor.

Ben dizi içerisinde arama işlemini çok araştırmış ama ne yazık ki bulamamıştım.

Hatırlatmak için, standart kütüphane belgeleri şurada:

  http://dlang.org/phobos/index.html

Sol taraftaki std.algorithm'e tıklayınca find bulunuyor. Ancak, find da aralıklarla işlediğinden bulduğu elemanı değil, bulduğu eleman ve sonrasını döndürür:
import std.algorithm;
 
void main()
{
    auto a = [ 1, 10, 3, 3, 8 ];
    assert(a.find(3) == [ 3, 3, 8 ]);
}
Dolayısıyla, bulunup bulunmadığını sonucun boş olup olmadığına bakarak anlayabiliyoruz ve ilk bulunana front ile erişiyoruz (dilimlerin aralık olarak kullanılabilmeleri için std.range gerekir):
import std.range;
// ...
    auto sonuç = a.find(3);
 
    if (!sonuç.empty) {
        assert(sonuç.front == 3);
    }
findSplit de çok kullanışlı; öncesini, bulunanı, ve sonrasını döndürür:
    // Arananın da aralık olması gerekiyor; onun için [ 3 ]:
    auto sonuç = a.findSplit([ 3 ]);
 
    assert(sonuç[0] == [ 1, 10 ]);
    assert(sonuç[1] == [ 3 ]);
    assert(sonuç[2] == [ 3, 8 ]);
try-catch denedim ama ne yazık ki sonuç alamadım :(

Kodunu göremediğimiz için neden olmadığını anlayamıyoruz. ;) Şöyle olur herhalde:
import std.stdio;
import std.array;
 
int intOku()
{
    while (true) {
        try {
            int sayı;
            write("Bir sayı giriniz (çıkmak için -1): ");
            readf(" %s", &sayı);
            return sayı;
 
        } catch (Exception) {
            writeln("HATA: Sayıya dönüştüremedim.");
            stdin.clearerr();
            stdin.readln();
        }
    }
}
 
void main()
{
    int sayı;
 
    while (sayı != -1) {
        sayı = intOku();
    }
}
Görüldüğü gibi, giriş akımının hatalı duruma gelmesi belalı bir iş. Onun yerine, her zaman için tam satır okuyup ondan sonra o satırı formattedRead ile kullanmak daha kolay olabilir:
import std.stdio;
import std.array;
import std.string;
import std.format;
 
int intOku()
{
    while (true) {
        try {
            write("Bir sayı giriniz (çıkmak için -1): ");
            string satır = chomp(readln());
 
            int sayı;
            formattedRead(satır, " %s", &sayı);
            return sayı;
 
        } catch (Exception) {
            writeln("HATA: Sayıya dönüştüremedim.");
        }
    }
}
 
void main()
{
    int sayı;
 
    while (sayı != -1) {
        sayı = intOku();
    }
}
hatayı neden veriyor ben pek anlayamadım...
alias'ın artık ifadelerle kullanılamadığı gibi bir şeyler konuşulduğunu hatırlar gibiyim ama emin değilim. (?)

Ali
Acemi #5
Üye Nis 2014 tarihinden beri · 7 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Ali hocam size ne kadar teşekkür etsem azdır. Bu proje bana programlama açısından çok şey öğretti ve hala da öğretiyor. Şu anda oyunu en baştan tekrar yazdım. Bu sefer sınıf, şablon, yapı gibi özellikleri de kullanmaya dikkat ettim.
try - catch konusunda bufferı temizlemeyi unutmuşum. Hata ondan kaynaklanıyormuş :) Hiç aklıma gelmemişti doğrusu!
alias'ın artık ifadelerle kullanılamadığı gibi bir şeyler konuşulduğunu hatırlar gibiyim ama emin değilim. (?)
Hata mesajından o çıkarımı yaptım ben de... Ama anlayamadığım neden böyle bir düzenlemeye gidildiği?
Yeniden çok teşekkürler.
Bu mesaj 2 defa değişti; son değiştiren: Acemi; zaman: 2014-05-03, 10:29.
acehreli (Moderatör) #6
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Belgesinde de açıkça ifadelerle kullanılamadığı yazıyor: "Aliases cannot be used for expressions"

  http://dlang.org/declaration.html#alias

2.065'ten sonra düzeltilen bir hata olarak kabul ediyoruz. :)

Ali
Acemi #7
Üye Nis 2014 tarihinden beri · 7 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
acehreli:
Belgesinde de açıkça ifadelerle kullanılamadığı yazıyor: "Aliases cannot be used for expressions"

  http://dlang.org/declaration.html#alias

2.065'ten sonra düzeltilen bir hata olarak kabul ediyoruz. :)

Ali
Anladım, teşekkürler :)
acehreli (Moderatör) #8
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #1
Acemi on 2014-05-01, 18:00:
  • Grafik arayüzü (hala kütüphane arıyorum :()

Acaba şu mu? :)

  http://ddili.org/forum/post/10759

Ali
agora #9
Üye Tem 2013 tarihinden beri · 221 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Bu bildigimiz Tic-Tac-Toe oyunu mu acaba?

Bunun icin Minimax algoritmasi vardi Alpha Beta Pruning ile birlikte. Bir turlu kavrayamamistim eger mumkunse bu baslik altinda o algoritmayi biliyorsaniz anlatma sansiniz var mi :(

Pruning ne demek bilmedigimden ingilizce yazdim.
Avatar
Salih Dinçer #10
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
agora:
Pruning ne demek bilmedigimden ingilizce yazdim.
Sanırım "budama" demek yani teknik manada eleme oluyor herhalde; gereksiz ve fayda vermeyen ayrıntıları çıkarma.
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
acehreli (Moderatör) #11
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Bazı problemler bir çözüm ağacı değerlendirilerek çözülür. Ağacın her dalı bir sonraki hamleyi temsil eder. Örneğin, tic-tac-toe oyununda ilk hamlede 9 seçenek vardır. İlk oyuncunun seçimine göre bir sonraki hamlede artık 8 dal vardır, vs. Dolayısıyla bütün ağaç belirlenmişse kazanan yolların hangileri oldukları bu ağaçta ilerlenerek belirlenebilir.

Bazı problemlerde ise çözüm ağacı bütün dalları incelenemeyecek kadar büyük olabilir. Örneğin, satrançtaki bütün hamlelerden oluşan ağaç çok büyüktür. (Go oyununda durum çok daha vahim; o yüzden henüz insan oyuncuları yenebilen go programı yok.)

Dolayısıyla, herhangi bir daldan aşağıya dallanıp kaybolup gitmek ve çok uzun zaman harcamak yerine, bazı dalların iyi olmadıklarına karar vermek ve onları elemek gerekiyor. İşte alpha-beta elemesi böyle bir eleme yöntemi: Tek daldan aşağıya gidildiğinde öncekinden daha kötü gibi görünen bir durum varsa hemen o dal (ve bütün alt ağaç) eleniyor.

Bu elemenin her probleme uygun olmadığı açık: Örneğin satrançta taş feda edilerek sonradan kazanç sağlamak mümkün.

Ne olursa olsun, alpha-beta işte o. :)

Ali
agora #12
Üye Tem 2013 tarihinden beri · 221 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Hocam çok teşekkür ederim denemelerini yaptım :) Biraz daha uğraşıyorum olacak :) Sağolun :) Bunları araştırırken de makaleler buldum yine D ile çözüme ulaştırmaya çalışayım
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Forum: Ders Arası RSS
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-11-18, 22:35:47 (UTC -08:00)