Oh bu oyunları seviyorum!
İlk önce, bir bilgisayarın oyun oynaması için ilk önce yapması gerekenler:
- çalışmak için bir yapı
- oynamak için kurallar
- çalışmak için bir kazanma koşulu
Bir seferde bu tek parça ele alalım.
yapı
Tahta 8x8'lik bir ızgara olduğundan (ancak kolayca ölçeklenebildiğinden) ve her ızgara alanı beş durumdan yalnızca birinde bulunabilir, bu durumları tanımlayalım:
[EMPTY, WHITE_PIECE, BLACK_PIECE, WHITE_PIECE_PROMOTED, BLACK_PIECE_PROMOTED]
Sırasıyla ENUM’e göre:
[0, 1, 2, 3, 4]
Artık her bir mekanın ne olabileceğini bildiğimize göre, tüm alanları temsil etmek için bir yol, ya da eğer istersen tahtaya ihtiyacımız var. Hemen hemen her güçlü dil çok boyutlu bir diziyi (her öğenin bir dizi tutan veri olduğu bir dizi) destekleyecektir. Dizimizi tanımlamak için aşağıdaki boş kodları alın:
BOARD_ARRAY = array(8, 8)
Bu bize tamsayıları saklayabileceğimiz 8 x 8 bir dizi verecektir (daha önceki enumlarımız):
(
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
)
Şimdi bunun bir tahta gibi görünmeye başladığını zaten görebilirsiniz! Youtube videosunda bahsi geçen varyantı hiç oynamamıştım ancak alttan bir sıra 2 sıra beyaz parça ve üstten bir sıra 2 sıra siyah parça ile başlıyor gibi görünüyor. Bu, bir oyuna başladığımızda dizimizin şöyle görünmesi gerektiği anlamına gelir:
(
[0, 0, 0, 0, 0, 0, 0, 0],
[2, 2, 2, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 2, 2, 2, 2],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[0, 0, 0, 0, 0, 0, 0, 0],
)
(Unutmayın, 2 'BLACK_PIECE' ve 1 'WHITE_PIECE' anlamına gelir)
Şimdi bilgisayarın çalışacak bir yapısı var. 1. adım tamamlandı!
kurallar
Bir usta oyuncuya karşı oynayarak, önünüzde kurulmuş bir tahtanın olduğunu hayal edelim. Parçalarından birini taşımaya kalkarsan, elini tokatlarsın. Bir parçayı yapamayacağınız bir şekilde hareket ettirmeye çalıştıysanız, elinizi tokatlarsınız. İyi dolandırıcılık yapmaya çalıştıysan, anladın. Ancak sorun şu ki, bilgisayarlar yok. Bu yüzden bizim içinde oynamak için katı kurallar koymak bizim işimiz .
Herhangi bir hareketin “yasal” olup olmadığını kontrol etmek için bir yol yaratmamız gerekiyor. Bu, öncelikle bir 'hareketi' temsil etmek için bir yola ihtiyacımız olduğu anlamına gelir. Bir yol dizi pozisyonları kullanmak olacaktır; Örneğin bir parçayı [0, 0] 'dan [0, 1]' e taşımak için, o hamle verilen tahtayı güncelleyecek bir fonksiyon yaratabiliriz. Bu yüzden geri dönelim:
MY_MOVE = array( [0, 0], [0, 1] )
Yukarıdaki, tahtanın üst köşesinden bir boşluk aşağı hareket eden bir parçayı temsil eder (0, 0'ın sol üst köşe olduğu varsayılmaktadır). Ayrıca, hareket için çok boyutlu bir dizi kullanmayı seçtiğimi fark edebilirsiniz. Bunun nedeni, parçaların bir turda teorik olarak birçok kez hareket edebilmesidir (diğer parçaları 'atlamak için). Öyleyse, 0'da 1 gibi davranalım, muhalif bir parça vardı, yani 0'da 2'de ineceğimiz anlamına gelir:
MY_MOVE = array( [0, 0], [0, 2] )
Oldukça basit, ha. Program, bir alanı atlarsak başka bir parça atladığımızı anlamalıdır (ya da bunun yasadışı bir hareket olduğunu ve bir hata yapması gerektiğini). Şimdi iki parça atlayalım:
MY_MOVE = array ( [0, 0], [0, 2], [0, 4] )
Bu bize tahtadaki herhangi bir hareketi tarif etmenin bir yolunu sunar. Yuppi! Şimdi, söz konusu oyunun kurallarını tam olarak anlamadığım için (günümde biraz Kanadalı dama oynamış olmama rağmen), tam hareketlilik yasallığının sizin tarafınızdan tanımlanması gerekecektir. Bu noktaya kadar iyi bir akış şuna benzer:
FUNCTION_FIND_ALL_LEGAL_MOVES( MY_BOARD ) Returns: array ALL_LEGAL_MOVES
FUNCTION_FIND_BEST_MOVE( MY_BOARD, ALL_LEGAL_MOVES ) Returns: array MY_MOVE
FUNCTION_DO_MOVE( MY_BOARD, MY_MOVE ) Throws: error ILLEGAL_MOVE Updates: MY_BOARD
repeat from start for each turn
Yukarıdakiler, tüm yasal hareketlerini bulmak için her bir parça arasında geçiş yapabileceğinizi varsayar, daha sonra tüm yasal hareketlerden oluşan bir koleksiyon verildiğinde bir şekilde en iyisini seçer (burada strateji). Hareket tahtaya uygulanır veya bir hata atar. Sonra sıradaki oyuncu sırasını alır. Bu yüzden nasıl oynanacağını bilen bir AI'mız var! Sevinç! Hareketli.
Kazanan
Basit oyunlar harika, çünkü kazanma çok basit bir durumla tanımlanıyor. Tahtada beyaz parça yok mu? Galiba kazandın! Bu, bizi kazanma koşullarına yaklaştırmak için en iyi hareketi seçtiğimizde 2. adımda uygulanır.
Çok zekice yapay zeka yapmak için mümkün olan her tahtayı bir durum olarak saklayan, mümkün olan her durumdan her hamleyle zincirleri kazanmak için bir veritabanı olarak saklayabilirsiniz.
Şunlar gibi stratejiler de oluşturabilirsiniz: atlanacak bir parça varsa, o parçayı saklayın ya da bir parça birden fazla zıplayabiliyorsa bu zıplamayı yapın.
Size iyi bir başlangıç noktası vermelidir, bu kelimenin tam anlamıyla sınırsız olasılıklardan sadece bir tanesidir. Teorik olarak boya kalemleriyle çizim yapmak için dev bir robot inşa edebilir, daha sonra hareketleri seçmek için çizim üzerinde spektral analiz yapabilirsin ... ama çok iyi veya hızlı bir şekilde işe yaramazdı. Bu şekilde geçmişte çalıştı ve iyi çalıştı (: Yardımcı olur umarım!
Uygulama Üzerine Birkaç Söz
Damalar, 'çözülmüş' bir oyun olarak adlandırılan şeydir, çünkü bilinmeyen her hareketi hesaplayabiliriz. Ama bu tamamen bir hamle! Yani hepsini manuel olarak yapmanın bir yolu yok ... eğer sadece birileri olsaydı ... ah doğru biz programcılar. ilk pompa
SQL, bu görünüşte sonsuz hareketleri depolamak için harika bir araçtır. SQL ile deneyimi olmayanlar için, mySQL ücretsiz (kullanımı oldukça kolaydır) ve açık kaynaklı bir SQL sunucusudur. SQL veritabanlarını yönetmek için kullanılır, steroid bir elektronik tablo gibi sorta. Ayrıca ciddi miktarda veri tutabilir ve çok hızlı bir şekilde çalışabilir.
Peki bunu nasıl kullanabiliriz? Tahtanın tam bir durumda olması durumunda (her bir parça belirli bir pozisyonda) bildiğimiz için mevcut tüm hareketleri hesaplayabilir ve bunları kaydedebiliriz. Örneğin:
+Board State+ +All Possible Moves+ +Best Move+
([0,0,1,2,3],[3..) ([0,1],[0,2]), ([7,6],[7,7],[5..) ([7,6],[7,7])
([0,0,2,2,3],[3..) ([0,1],[0,2]), ([7,6],[7,7],[5..) ([5,5],[5,4])
([0,0,1,3,3],[3..) ([0,1],[0,2]), ([7,6],[7,7],[5..) ([4,4],[4,3])
etc...
Böylece, bilgisayarın bir hareket yapması gerektiğinde, veritabanındaki pano durumunu (birincil anahtar olarak depolanır) arar ve daha kolay bir ortam sağlamak için en iyi hamleyi (yenilmez olmalıdır) veya diğer hamlelerden birini seçebilir AI.
Harika, şimdi bu veritabanını oluşturalım. Öncelikle her tahta durumunu hesaplamamız gerekiyor. Birisi biraz zaman geçirmek ve çalışmak isterse, bu harika olurdu, büyük, büyük, kötü bir döngü ile yapılabilir. Diziye büyük bir sayı olarak bakın, ardından taban 5 (0, 1, 2, 3, 4) hariç her bir oyuncunun yalnızca 16 taş olması koşuluyla, yukarı doğru sayın.
Bu noktada, her tahta durumunu depolamalı ve olası tüm hareketleri hesaplayarak geçmeliyiz.
Tüm olası hareketler hesaplandıktan sonra, mümkün olan en iyi hareketleri bulma yolunun eğlenceli kısmı gelir. Bu benim bilgimin yetersiz kalmaya başladığı yer ve Minimax veya A * gibi şeyler devreye girmeye başladı. Üzgünüm, bu konuda daha fazla yardım edemem: /