Bir satranç motoru yazmak için en iyi yaklaşım? [kapalı]


15

Ben satranç meraklısıyım ve programcıyım. Geçenlerde satranç ve programlama bilgimi kullanarak bir satranç motoru yapmaya karar verdim. İşte sorum:

Bir satranç motoru yazarken hangi dili (Java, C ++ ve Python'u tanıyorum) ve metodolojiyi uyarlamalıyım?

Biraz rehberlik çok takdir edilecektir.

Düzenle:

Bu yüzden JavaScript ile yapmaya karar verdim. Ben indirmek bu github gelen satranç UI ve şimdi Hazırım! İlk adımım bunun için yasal hamleler yazmak olacaktır. Öyleyse kimse beni doğru yönde gösterebilir mi? (Ben jQuery yeniyim ama programlama deneyimi bir sürü var).

Not: Çok verimli bir motor yapmaya çalışmıyorum (çok zor olduğunu biliyorum), sadece sürece aşina olmak ve yol boyunca yeni teknikler öğrenmek istiyorum.


5
Herhangi bir ana dil ve metodoloji yapardı, bir satranç motoru hakkında özel bir şey (bu bağlamda).
yannis

3
Hedefler konusunda daha spesifik olurdum. Sadece bir dizi rote kuralına kadar kaynatmak istiyorsanız, bu büyük bir görevdir, ancak herhangi bir programcı bu kaba kuvvet yolunu sıralayabilir. Eğer örüntü tanıma veya riskin tartısı ile ödülün karşılaştırılması gibi şeylere girmek istiyorsanız, cevaplar bu kadar çabuk olabilir.
Erik Reppen

Chess Engine wiki altındaki Pedagojik bölümü kontrol ettiniz mi? Bunlar özellikle Satranç Programlamayı öğretmek içindir ve hepsi Açık Kaynaktır. : Eğer gerçek belgeler genellikle gelişme arkasında ne açıklayacağız kaynak kodu kullanabilirsiniz bile en.wikipedia.org/wiki/Chess_engine#Categorizations
user60812

1
Gerçekten zor olan kısım, belirli bir pozisyonun nasıl değerlendirileceğidir, çünkü seçim için A pozisyonunun B pozisyonundan daha iyi olup olmadığını görmeniz gerekir.

1
Ne bilmek istediğiniz hiç belli değil. Bir pozisyonun temsiline karar verdiniz mi? Eğer öyleyse, bir sonraki adım bir hareket jeneratörü yazmak ve test etmektir. JQuery'nin bununla ne ilgisi olduğunu düşündüğünüzden emin değilim.
kevin cline

Yanıtlar:


19

2072 puanlı satranç oyuncusu burada. Bu web sitesini bir hafta sonu saf JavaScript ile yaptım . Bu bir satranç motoru değil (sapkın bir Chess960 motoru gibi eğlenceli açılış pozisyonları yaratmak için tasarladım), ama bir başlangıç ​​noktası. Kaynak kodu burada .

İşlevsel bir tahta yapmanın bir çok komplikasyonu vardır. Bunlar:

  • İlk olarak, temel yasal hareketlerin nasıl temsil edileceğini bulmak. Başlangıç ​​ve bitiş koordinatlarıyla matematik yapmak zorundasınız. Örneğin, kale hareketleriyle, koordinatlardan birinin önce ve sonra aynı olması gerekir. Şövalye hamlelerinde, koordinat değişikliklerinin mutlak değerinin toplamı 3 olmalı ve her iki koordinat da değişmelidir. Piskopos hamlelerinde, ya koordinatların toplamı aynı kalır ya da her ikisi de aynı miktarda artar. Piyonlar en zor olanıdır, çünkü sadece iki kareyi veya birini hareket ettirip değiştiremediklerini bulmak zorunda değilsiniz (kaç hamle yaptıkları saklamak yerine satırı ve rengi kontrol edin), aynı zamanda tüm yakalama ile çapraz olarak uğraşmak zorundasınız, hareket edin ileri bir şey.
  • Yakalama, piyonlar ve kontrol nedeniyle bir meydan okumadır. Bir parça başka bir parçanın karesine hareket ederse, o zaman bir yakalama olduğunu söyleyemezsiniz. Sonuçta, piyonlar yakalamak için başka bir parçanın karesine geçemezler - kendi özel yakalama yollarına sahiptirler.
  • Düşman parçalarının yasal olup olmadığına karar vermek için bir taş hareketine engel olup olmadığını görmek için etkili bir yol bulmalısınız.
  • Çek ile başa çıkmak zor. Her hareketten sonra, düşman parçalarının gidebileceği tüm kareleri kontrol etmeli ve bunlardan birinin kralınızı içerip içermediğini görmelisiniz ve eğer öyleyse, bu yasadışı bir harekettir.
  • Castling, en passant, promosyon, çıkmaza, zorla berabere, tekrar - sorun ölçeği göz önüne alındığında bunların hiçbiri önemsiz değildir.

Tüm satranç motorları, bir pozisyondaki yasal hamlelerin tümüne (muhtemelen sezgisel olarak belirlenmiş bir alt kümeye) bakarak ve bu hamleleri yaparak ve sonuçta ortaya çıkan pozisyonlar için aynı şeyi tekrar tekrar yaparak sayıları göreceli değerlerini temsil etmek için değerlendirerek çalışır. Buradaki ikiz problemleriniz

  • Bu veriler verimli bir şekilde nasıl saklanır?
  • Bu özyinelemeli aramaya nasıl devam edilir - sonuçta, sonsuza kadar devam etmesine izin veremezsiniz, bu nedenle bir sınır koymanız ve daha sonra bu sınır dahilinde en uygun ve kapsamlı aramayı yapmak için algoritmanızı nasıl tasarlayacağınızı bulmanız gerekir. Örneğin, en azından her olası başlangıç ​​hareketi için bir değerlendirme ile geldiğinden emin olmak istersiniz, ancak her hamleye eşit miktarda zaman vermek yerine daha ümit verici hamleleri değerlendirmek için daha fazla zaman harcamak isteyebilirsiniz.

Bu, ilk önce algoritma tasarlamanın üstünde, üzerinde bol miktarda bilgi bulunan.

Hangi dile gideceğinize gelince (sanırım JavaScript'e zaten karar vermiş olsanız da), hedefinize başka her şeyden daha fazla bağlı olduğunu düşünüyorum. Benimkini çevrimiçi yapmak (ve JavaScript'te daha iyi olmak) istedim, bu yüzden JavaScript benim seçimimdi. Nesne yönelimli herhangi bir programlama dili buna rağmen yapar.

Yaptığınız şeyden memnun olduğunuzda, aşağıdaki kaynaklar muhtemelen gerçekten yararlı olacaktır:

İyi şanslar!


Çok teşekkürler, kesinlikle başlamak için bana çok yardımcı oldu. Öğrenilecek ve uygulanacak çok şey olmasına rağmen, satranç motorlarının yazılması asla kolay değildir. Ama bence sevdiğin bir şeyle çalışmak güzel!
Adnan Zahid

Katılıyorum. Gerçekten çok çeşitli projelere devam etmek istedim, ama dürüst olmak gerekirse satranç eşyalarını geliştirmekten daha çok keyif alıyorum.
Andrew Latham

Lathamcity.com alan adı şu anda satılıktır. Kod şimdi farklı bir web sitesinde mevcut mu?
IkWeetHetOokNiet

14

Bir kavram olarak "satranç programı" ile ilgili sorun, çok fazla zaman emebilecek ve şu anda ilginizi çekmeyecek birçok parça olmasıdır. Yılları sadece grafikler üzerinde çalışarak veya bir alfa-beta aramasında veya arama motoru için geliştirmeye yardımcı olacak bir görselleştirmede geçirebilirsiniz veya ... pek çok parça var.

Açık kaynak kodlu bir satranç programı bulmanızı (çok olması gerekir) ve bunun sizi en çok ilgilendiren kısımlarını geliştirmeye karar verdim. Sonunda tüm programı, bir seferde bir işlevi değiştirebilir veya yeterince öğrenebilir ve onu atmak ve kendi programınızı sıfırdan tasarlamak için motive olabilirsiniz. Her durumda, anahtar "hafif" başlatmak ve bir programın tamamını mimarisini oluşturmaya çalışmadan önce ipleri öğrenmektir.


Kurulan arayüz protokollerinden birine uyarak, motorunuzla mevcut tüm ön uçları kullanabilirsiniz.

Umarım alfa beta yazmak yıllar
Kevin

1
Yazmak için yıl değil, grok için yıl :)
ddyer

9

Satranç kurallarına aşina iseniz, temel teknikler hakkında iyi bir başlangıç ​​noktası http://www.frayn.net/beowulf/theory.html Burada bulabileceğiniz kapsamlı bir Materyaller ve bağlantılar koleksiyonu: http: // chessprogramming .wikispaces.com / Ve üçüncüsü: Başkalarının kodundan öğrenin. Crafty'nin kaynaklarına bir göz atın . Önde gelen açık kaynaklı bir motor. Test senaryoları hakkında düşünmek, iyileştirmeler yapıp yapmadığınızı görmek çok önemlidir: Örneğin 3 veya 4 rakamlı bazı basit basit oyun sonu pozisyonları ile başlayın.


3

Daha önce de belirtildiği gibi, bir satranç motoru yapmak konusunda çok zor bir şey yoktur. Belki de, muhtemelen dil seçiminizi belirleyeceğinden, bu uygulamayı nasıl kullanacağınıza ve (potansiyel olarak) dağıttığınıza odaklanmalısınız.

Bu sadece eğlenceli bir alıştırma ise, Javascript'te kodlamak ve bir web sayfası olarak dağıtmak isteyebilirsiniz. Asla uzman bir satranç oyununa girmek istemezseniz, en azından diğerleri onunla ve kaynak koduyla oynayabilecektir.

Belirli bir teknolojiyi aynı anda öğrenmek istiyorsanız, WPF deyin, o zaman bu, iki kuşu bir taşla öldürmenin iyi bir yolu olabilir. MVVM bu uygulama için aşırıya kaçabilir, ancak en azından öğrenirsiniz.

Android cihazları hedeflemek istiyorsanız, Java iyi bir seçim olacaktır. Benzer şekilde, iOS cihazlar için Objective-C.

Uzun ve kısa, bir boşlukta dil seçimi yoktur.


3

Min-Max, ağaçlar ve budama, sezgisel ve diğer temel kavramlar hakkında zaten bildiğinizi varsayalım ve burada yazdıklarım, azımsanmış olabilecek bazı ayrıntılar.

Bir arkadaşımla birlikte bazen önce kendi satranç motorumuzu yazdım. Sahip olduğumuz bazı sorunları ve fikirleri paylaşıyorum ve umarım bunları faydalı bulursunuz.

İkimiz de java programcısı olduğumuz için dilimiz java oldu ve nesne yönelimli bir yaklaşımla başladık. Parçalar nesne, tahta nesne, dosyalar ve rütbeler (satranç literatüründeki satırlar ve sütunlar) nesnelerdi. Ve bu yanlıştı. Tepegöz büyüktü ve program arama ağacında 2 hamleden (4 kat) daha ileri gitmek için uğraşıyordu.

Bazı aramalarda parlak bir fikirle sonuçlandık (bizimki değil!): Parçaları ve tahtayı Uzun tamsayılar (64bit) olarak temsil ediyoruz. Bir satranç tahtasının 64 karesi olduğu için bu mantıklıdır. Gerisi biraz akıllıca işlemler (cpu = çok hızlı çalışan çok hızlı) oldu. Örneğin, parçaların tahtada saldırabileceği kareleri sundukları bir ikili 64 bit tamsayı düşünün. Şimdi böyle iki sayı arasında mantıklı bir "VE" yürütürseniz, sıfır olmayan bir sonuç saldırganlarla dolu bir kareniz olduğunu belirtir. Satranç tahtasını ve taşlarını sunmanın birkaç yolu vardır, Yani:

1 - Kurul Sununuza karar verin

Sonra gerek ve açılış veritabanı. Satranç açılışı bir şekilde çözüldü ve kitap açmanız şiddetle tavsiye edilir. Bu durumda, yıldırım oyunlarında çok fazla zamanınız olur.

2 - Kendinize bir açılış kitabı bulun.

Bunları yaptık, ama yine de iyi olmaktan uzaktık:

3 - İyi bir satranç motoru ileriye 6 hamle (12 kat) görebilmelidir.

O zaman yaptığımız ölü zamanı kullanmaktı (eğer bir insan vs bilgisayar motoru ise).

4 - Rakibin ağacınızın bazı seviyelerini yaratmayı düşündüğü zamanı kullanın.

Ve hala 12 kattan çok uzaktaydık. Daha fazla çalışma ile, bazı hileler keşfediyoruz! Örneğin, ağacın bir katını atlayıp bir sonraki kattan başlamak önerildi (rakip yok gibi). Fikir şu ki, eğer bir hamle son derece aptalca ise, o zaman neden zaman kaybetmek ve rakiplerin bu hamleye verdikleri yanıtları görmek. Bununla birlikte, iyi bir motor, idiotik hareket ile dahi kraliçe kurbanını ayırt edebilmelidir.

5 - Bu özel problem için programlama hilelerini öğrenin (satranç).

Ben ve arkadaşım, bu durumda hala kötüydük: / Yapabileceğimiz - ve kısmen yaptığımız - hesaplanan pozisyonları kurtarmaktı. Bir pozisyon hesaplarsanız, gelecek için saklayın! Aynı şey arama ağacındaki döngüler için de geçerlidir. Mesele, verimli bir şekilde kaydetmek / almaktı:

6 - Oluşturduğunuz verileri kaydedin ... Verimli!

ve sonunda:

7 - Maksimum optimizasyonlu kod.

Bu sorun hem CPU zamanı hem de bellek açısından son derece pahalıdır. Kodunuzu çok verimli bir şekilde yazmak çok önemlidir. 35'in dal faktörü hakkında konuştuğumuzu unutmayın. Bu, sezgiselinizde bir 3.3792205e+18yerde, arama ağacınızın derinliklerinde bir yerde "işe yaramazsa" işe yaramazsa "anlamına gelir .

Satranç programlama çok ilginç bir mücadeledir ve programlama yeteneklerinizi ciddi bir teste tabi tutabileceğiniz zamandır. Önerebileceğim birkaç nokta daha var ama eminim ki bunları kendiniz keşfedeceksiniz. Bilmediğim daha birçok nokta var ama bunları internette bulabilirsiniz!

İyi şanslar ve iyi eğlenceler!

ps Ben çok iyi javascript bilmiyorum ama bir şey bana sorunun zorluk temel söylüyor, belki, tüm C ++ sunabilir göz önüne alındığında, javascript bırakmak ve C ++ yapmak daha iyi olurdu.


2

Düzenlemenize göre, 'yasal' hamleleri tanımlama aşamasına hazırsınız.

Satrançtaki hareketleri tanımlamanın iki yolu vardır. Betimleyici gösterim ve Cebirsel gösterim. Muhtemelen istediğiniz şey, parçayı, başlangıç ​​konumunu ve bitiş konumunu parametre olarak alan bir işlevdir. Örneğin. QN1'den QB2'ye kadar olan şövalye geçersiz, ancak QN1'den Q2'ye kadar olan şövalye geçerli. Bunu düşünerek, 'göreli' konumlandırmayı kolayca hesaplama yeteneği nedeniyle Cebirsel gösterim daha basit olabilir.

Gerekli minimum kod miktarını yazdığınızdan emin olmak için, önce bu işlev için testler yazmaya başladım . Cebirsel notasyon kullanıyorsanız, muhtemelen parça / başlangıç ​​/ bitiş başına bir teste ihtiyacınız yoktur. Her testin çalışmasını sağlayın ve bir sonraki 'hamleye' geçmeden önce tekrarlamayı yeniden düzenleyin. Kodunuz daha temiz olacaktır.

Her parça için yasal ve yasadışı hamleleri yeterince ele aldıktan sonra, diğer değişkenleri (bir Kralı 'çek' ve 'eş' koşullara taşımak gibi) kontroller eklemeye başlarım.

JavaScript'teki birim testler için qunit ve davranış testleri için jasmine öneririm .


1

Aslında bir satranç motoru yazdım. Kendinizi hem tedavi hem de kabus için hazırlayın. Arkadaşlarım ve ben bunu yaptığımızda, zamanlanmış bir programlama yarışmasına katıldık ve gitmeye karar verdiğimiz dil Java'ydı. Java veya C'nin en iyi seçim olduğunu hissediyorum, ancak Javascript ile gitmeye karar verdiğini görüyorum. Gerçekten çalamıyorum çünkü aşina değilim.

Buradaki asıl sorun, hesaba katmanız gereken her parça ile çok fazla hamle / kazan senaryosu olması olacaktır, bu yüzden kodlamaya başlamadan önce her parça için tüm bu olası durumları yazmanızı tavsiye ederim. Sadece plan yapmadan atlamak bu eğlenceli projeyi tekrarlayan bir angarya haline getirecektir. Ama asıl önemli olan bu. Öncelikle kodun dışında plan yapın ve her senaryoyu birer birer aldığınızdan emin olun.

İyi şanslar


1

Oyunun bilgisayar-oyuncu-kararları bölümü için, "Yapay Zeka: Modern Bir Yaklaşım" kitabını yeterince öneremem (kitap web sitesi http://aima.cs.berkeley.edu/ ). Matematikteki arka planınıza bağlı olarak (grafik teorisi yardımcı olur) biraz yüksek düzeyde olabilir, ancak bu akademik şeyler olabileceği gibi yazılmıştır ve tekniklere çok güncel bir genel bakış (ve biraz derinlik) içerir. programların karar vermesini sağlamak.

Size bir hedef belirleme (örneğin şah mat veya boş), belirli bir durumun (tahta düzeni) bu hedefe ne kadar yakın olduğunu, mevcut olandan başlayarak farklı olası aşağıdaki durumları nasıl oluşturacağınızı değerlendirmek ve muazzam bir problem alanı nedir?

Bir AI algoritması tasarlamaya yardımcı olabilecek bir şey, kazanılan bir oyuna çok yakın bir durumdan başlayarak, dünyadaki her zaman sanki hangi hamlenin oynayacağına nasıl karar verileceğini bulmaktır. Makul bir sürede (saat) bir çözüm bulması için optimize edersiniz, daha sonra henüz tüm sonuçları keşfetmemiş olsanız bile, kazanan bir yol seçmenin yollarını bulursunuz, böylece gerçekten "düşünmeyi" bir dönüşe değer.

Ancak o zaman, önerildiği gibi uzun tamsayılar kullanmak gibi bireysel hesaplamaları daha hızlı yapmak için temsilini optimize etmeye bakarım. Ne kadar hızlı olursa olsun, tek bir karşılaştırma yapabilirsiniz, eğer sorunlu alanı geçme şeklinizin iyi bir buluşsal yöntemi yoksa, bunu yapmak zaman alacaktır.


0

Gerçekten istediğiniz şekilde gidebilirsiniz, ancak bunlar konu hakkındaki düşüncelerim:

Java'yı çok yüksek düzeyde olmanıza ve doğrudan kullanıcı emrinizde kullanıcı arabirimi kitaplıklarına (AWT, Swing) sahip olmanızı sağlar. Satranç tahtasını ve taşlarını modellemek için nesne yönelimli bir yaklaşım kullanabilirsiniz. Diğer nesneler hareket geçmişi ve puanlama için ayakta kalabilir. Oyuncular bile nesne olabilir ve daha sonra Playeryapay zeki bir bilgisayar oynatıcı sağlamak için sınıfınızı genişletebilirsiniz .

Sen bir göz atmak isteyebilirsiniz Model-View-Controller (MVC) o kullanıcı arayüzü (görünüm) için model nesneleri (alan modeli) kravat ve kullanıcı işlemek için izin vermek için bu durumda çok güzel bir yaklaşımdır olarak modeli (kontrolör aracılığıyla).

Test odaklı geliştirmeyi de uygulamak isteyebilirsiniz , tüm yöntemlerin beklediğiniz şekilde davranmasını sağlamakla kalmayıp sizi test edilebilir, modüler kod yazmaya zorlayan .


4
Bir satranç motorunun UI ile hiçbir ilgisi yoktur, sadece en iyi hareketi hesaplayan “zihin”.
CSE

@CSE - Motor tanımınıza bağlıdır .
Daniel AA Pelsmaeker

@CSE - As Adnan'ın düzenleme gösterileri, o oldu aslında aynı zamanda bir UI arıyorum. Bu yüzden cevabım alakalı.
Daniel AA Pelsmaeker

-8

Satranç kuralları oldukça basittir. Sadece tahta için bir matris (2 boyutlu dizi) oluşturabilmeniz ve parçaların kavramlarını, her parça için hareket kurallarını, bir hareketin yasal olduğunu doğrulayan ve sinyal veren koşulları kodlamanın bir yolunu bulmanız gerekir. Oyunun sonu. Bunlardan herhangi biri hakkında özellikle zor bir şey yok. En iyi bildiğiniz dili kullanmanız gerekir.

Şimdi, oyunculardan birinin rolünü üstlenecek satranç oynayan bir yapay zeka yapmak istiyorsanız, işlerin zor olduğu yer burası. Ama yine, dil seçimi burada en büyük sorun değil; ilgili AI ilkelerini anlamak. Bu çok daha önemli bir faktör olacak.

(Bunu söyledikten sonra, bu tür bir karar verme işlemi son derece hesaplama açısından yoğun olabilir ve muhtemelen bir komut dosyası dili yerine yerel koda derleyen bir şey kullanmak isteyeceksiniz. C ++ çok kötü bir seçim, çünkü iyi değil Bu soruna uygun, ancak genel olarak çok kötü bir dil olduğu ve içindeki karmaşık şeyleri uygulamaya çalıştığınız için, kendiniz için her türlü baş ağrısını kodlamanın iyi bir yoludur.)


15
Bence kutsal savaştan kaçınmak için neden C ++ 'ın bu özel göreve uygun olmadığı konusunda biraz daha spesifik olmalısınız.
Erik Reppen

9
Kutsal savaş başlatma girişimi için -1.
Doc Brown

1
Neden C ++ 'ın genel olarak çok kötü bir dil olduğunu düşünüyorsunuz?
Anthony

Bence onu kesinlikle yanlış anladın. Ben onun görüşünü paylaşmak için, C ++ başlamak için iyi bir dildir ama karmaşık şeyler ile uğraşırken bir acı olur!
Adnan Zahid
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.