Nasıl Bir Algoritma İzlenmeli?

oyuncuya karşı bilgisayar bazlı tic tac toe oyunu yapmaya çalışıyorum. Bir konuda fikrinize ihtiyacım var.
Kodları buradan inceleyebilirsiniz —> https://dpaste.com/4EXGYGNCQ.

#                           DEVELOPING AND FINISHING PHASE

artificial intelligence adlı fonksiyonun altında yukarıdaki gibi bir kısımla karşılaşacaksınız. Burada oyunun gelişim ve bitiş aşamasını ifade eden durumlar yer alıyor.
Ben burayı bu şekilde doldurdum . Üstten başlamak üzere ilk satırda X-O-X pozisyonu yakalandıktan sonra oyunu ilerletmeye çalıştım buradaki kodlarda
Ancak bir yerden sonra iyice karmaşıklaşmaya başladı. Bu durumları ifade eden kodları nasıl daha okunaklı ve daha kısa yazabilirim ? Bir fikriniz var mı ?
Durumlardan kasıt şu oluyor :

X-O-X
O-X-O
*-X-*

durumdan kasıt mesela yukarıdaki gibi.
Şu durumda bilgisayar, sağ alta mı oynasın ? Sol alta mı ? gibi.
Bu durumları daha kısa bir şekilde tanımlamaya ihtiyacım var
Kodlara baktığınızda daha iyi anlaşılacağını düşünüyorum.

Kodları doğrudan buraya atamıyorum üzgünüm. Karakter limiti aşılıyor çünkü.

1 Beğeni

En kısa yolunu geçen bir başka konunuzda yazmıştım. Onun dışında minimax algoritmasını uygulamadığınız sürece kodlarınız hep uzun olacaktır. Minmax konusunda da örnek olması için bir kod paylaşmıştım. İncelemenizi tavsiye ederim.

Bu sadece yazdığım if bloklarını kısaltmaya yaradı. If blokları yine var. Toplasak 500 tane durum var. 500 tane If bloğu yazmak imkansız.

Hangisidir acaba ?

Burada yazdığım GameAlpha sınıfını şöyle kullanabilirsiniz.

>>> game = GameAlpha() # Oyunu oluşturuyoruz
>>> print(game.board)
[['-', '-', '-'], ['-', '-', '-'], ['-', '-', '-']]
>>> game.play(1,1,game.player) # Burada biz oynuyoruz
True
>>> print(game.board)
[['-', '-', '-'], ['-', 'o', '-'], ['-', '-', '-']]
>>> game.play_computer() # Burada bilgisayarın karar vermesi için metodu çağırıyoruz
[2, 2]
>>> print(game.board)
[['-', '-', '-'], ['-', 'o', '-'], ['-', '-', 'x']]
1 Beğeni

Anlamaya çalışıp bir şeyler deneyeceğim, teşekkürler.

1 Beğeni

easyAI

adında bir modül buldum. Bu işimi görür mü sizce ? Nasıl çalıştığını anlayamadım. Fazla kullanım örneğine de rastlamadım.

Kullanabilirseniz neden isinize yaramasin? Muhtemelen dokumani vardir

“EasyAL module python” şeklinde aratmama rağmen sonuçlar çok dar. Pypi yazana kadar hiçbir sonuç çıkmıyor. PyPI’dekinden de bir şey anlayamadım.

Tam dokümanların linki :

1 Beğeni

yada şu adımları kullanacak bir kodda yazabilirsiniz
1-Oyunu kazandıracak hamle var mı diye bak var mı diye bak varsa oyna yoksa 2. adıma geç
2-Rakibin kazanmasını engelleyecek bir hamle varsa oyna yoksa 3.adıma geç
3-Rastgele oyna

AI. I harfi, L degil.

Kodu okumadim. Su:

Ne demek? * bosluk mu oluyor?

Tahtayi "XOXOXO*X*" seklinde ifade edebilirsin. Sadece tahtanin butun pozisyonlarini kontrol ettigin icin (sadece tahtanin butun pozisyonlarini mi kontrol ediyorsun?) tahta == "XOXOXO*X*" gibi bir kontrol yapabilirsin.

Pardon. Artificial Intelligence (AI) diye yazmalıydım.

Evet boşluk oluyor.

Bunu zaten yapıyorum. Amacım bundan kurtulmak. Çünkü çok fazla If bloğu oluşuyor.
Mesela bakınız,

# Position = "X-O-X"            
#      -----------------------------------------------------------
        # table of blocks
        self.blocks = [
            [self.left_top_block, self.top_middle_block, self.top_right_block],          # row 1
            [self.middle_left_block, self.middle_middle_block, self.middle_right_block], # row 2
            [self.bot_left_block, self.bot_middle_block, self.bot_right_block]           # row 3
        ]

        self.coordinates = {
            "1" : self.blocks[0][0],
            "2" : self.blocks[0][1],
            "3" : self.blocks[0][2],
            "4" : self.blocks[1][0],
            "5" : self.blocks[1][1],
            "6" : self.blocks[1][2],
            "7" : self.blocks[2][0],
            "8" : self.blocks[2][1], 
            "9" : self.blocks[2][2]
        }
         . . . .
        . . . . .

        # Durumlar :
        elif ( 
            self.blocks[0][0].text() == "X" and self.blocks[0][1].text() == "O" and self.blocks[0][2].text() == "X" and 
            self.blocks[1][0].text() == "X" and self.blocks[1][1].text() == "O" and self.blocks[1][2].text() == "" and 
            self.blocks[2][0].text() == ""  and self.blocks[2][1].text() == ""  and self.blocks[2][2].text() == ""
        ):
            random_assignments = ["8"]
            random_assignment = random.choice(random_assignments)
            self.timer.singleShot(300, lambda: self.coordinates[random_assignment].setText("O"))
        elif ( 
            self.blocks[0][0].text() == "X" and self.blocks[0][1].text() == "O" and self.blocks[0][2].text() == "X" and 
            self.blocks[1][0].text() == ""  and self.blocks[1][1].text() == "O" and self.blocks[1][2].text() == "X"and 
            self.blocks[2][0].text() == ""  and self.blocks[2][1].text() == ""  and self.blocks[2][2].text() == ""
        ):
            random_assignments = ["8"]
            random_assignment = random.choice(random_assignments)
            self.timer.singleShot(300, lambda: self.coordinates[random_assignment].setText("O"))

Toplasanız kaç tane böyle durum var. Hepsini bu şekilde hata yapmadan yazmak çok zor. Tam olarak bu durumdan kurtulmaya ihtiyacım var.
Bir konsol uygulaması yapılıyor olsaydı daha kolay olurdu. Bir sürü örneği de var ancak pyqt5 ile yapılan hiçbir örnek yok.
Eğer bu if bloklarından kurtulmanın bir yolu yoksa, öyle bir fonksiyon olmalı ki, şu yaptıklarımı tek bir satırda yapabilmeli.

Hani? Kacinci satir?

Nasil bir alternatif arayisindasin?

Nasil daha kolay olurdu? O zaman niye oyle baslamadin?

“board soyleyse su cevabi ver” seklinde kodlamak istiyorsan board’un alabilecegi her durumu eklemek zorundasin. Ama bunlarin hepsi buyuk bloklar olmak zorunda degil, bu mesajin ilk satirinda alternatifini yazdim.

1 Beğeni
elif (
            self.blocks[0][0].text() == "X" and self.blocks[0][1].text() == "O" and self.blocks[0][2].text() == "" and 
            self.blocks[1][0].text() == "X" and self.blocks[1][1].text() == ""  and self.blocks[1][2].text() == "" and 
            self.blocks[2][0].text() == ""  and self.blocks[2][1].text() == ""  and self.blocks[2][2].text() == ""
        ):
            random_assignments = ["7"]
            random_assignment = random.choice(random_assignments)
            self.timer.singleShot(300, lambda: self.coordinates[random_assignment].setText("O"))

Kodları incelediyseniz, bütün durumları bu şekilde kontrol etmeye çalıştığımı göreceksiniz.
Eğer ben sizi yanlış anlamadıysam

Bu dediğinizle aynı şeyi yapıyorum.

Bütün durumları

elif (
            self.blocks[0][0].text() == "X" and self.blocks[0][1].text() == "O" and self.blocks[0][2].text() == "" and 
            self.blocks[1][0].text() == "X" and self.blocks[1][1].text() == ""  and self.blocks[1][2].text() == "" and 
            self.blocks[2][0].text() == ""  and self.blocks[2][1].text() == ""  and self.blocks[2][2].text() == ""
        ):
            random_assignments = ["7"]
            random_assignment = random.choice(random_assignments)
            self.timer.singleShot(300, lambda: self.coordinates[random_assignment].setText("O"))

buradaki mantıkla kontrol edebileceğimi sandım. Ancak bir yerden sonra işler fazlasıyla karmaşık olmaya başladı. Bu yaptığımdan daha basit bir yöntem arayışındayım. Aslında kendi yaptığım bu yöntemle oyunun yenilmez modunu yapabilirim. Çünkü hamleler çok dar. Google sayesinde fark ettim.
En basitinden örnek verecek olursam, ortadaki blok dışında nereye “X” koyarsam koyayım yapay zeka daima en ortadaki bloğa “O” koyarak başlıyor.
Fakat yapacağım kolay ve normal moddaki bilgisayar için bir sürü alternatif olacağı için bu şekilde yürümeyecek. Zor modu bu yöntemle yapsam bile daha basit bir yönteme diğer modlar için ihtiacım var.

Amacım PyQt5 ile arayüzlü güzel bir oyun yapmak olduğu için konsoldan yapmayı tercih etmedim.

Bu sefer daha net olabilmişimdir umarım.

Teknik olarak evet. Pratikte bir bakista gozuken 20 karakter yerine uzun ve hataya daha acik buyuk bir blok var. Konumuz uzun kodu kisaltmak oldugu icin soyledim. Algoritmik olarak hic bir farklari yok.

“Burada ne oldugu onemli degil” karakteriyle baslayabilirsiniz:

if tahta.match("XX*......"): # ilk satira oyna
if tahta.match("X..X..*.."): # sol alt koseye oyna

Ama asil gereken algoritmik optimizasyon. 4x4’luk tahtaya gecince yazilacak kod miktarini 2 kat arttirmayan bir algoritma lazim.

Evet, tesekkurler. Netsizligin bir sebebi de bu:

Arayuzu algoritmadan ayirmak boyle bir oyunu tasarlamanin temeli. Bir tarafta yaptigini diger tarafta yapiyormus gibi ve geri cevirmek cok basit bir donusum. Yapmak istedigini arayuzsuz yapamazken arayuzun yukunu koduna tasiyorsun (text()).

1 Beğeni