Meta tic tac toe oynayalım!


38

Meta Tic Tac Toe oyunu oynayalım!

Bu, Meta tic-tac-toe turnuvasının bir turnuvasıdır. Meta Tic Tac Toe kuralları şunlardır:

  1. Tic Tac Toe'nun normal kuralları geçerlidir.

  2. Bir ana tahta yapmak için düzenlenmiş dokuz tahta vardır. Bunun gibi:

    0|1|2 || 0|1|2 || 0|1|2 
    ----- || ----- || ----- 
    3|4|5 || 3|4|5 || 3|4|5 
    ----- || ----- || ----- 
    6|7|8 || 6|7|8 || 6|7|8 
    ========================
    0|1|2 || 0|1|2 || 0|1|2 
    ----- || ----- || ----- 
    3|4|5 || 3|4|5 || 3|4|5 
    ----- || ----- || ----- 
    6|7|8 || 6|7|8 || 6|7|8 
    ========================
    0|1|2 || 0|1|2 || 0|1|2 
    ----- || ----- || ----- 
    3|4|5 || 3|4|5 || 3|4|5 
    ----- || ----- || ----- 
    6|7|8 || 6|7|8 || 6|7|8 
    

    tahta 0 üst sol tahtayı gösterir, tahta 1 üst orta tahtayı gösterir ... bunun gibi

    0|1|2
    -----
    3|4|5
    -----
    6|7|8
    

    Tahta 3, kiremit 4 dersem, bu, orta soldaki tahtanın merkez döşemesi anlamına gelir.

  3. Yalnızca küçük panolardan birinde hareket etmenize izin verilir.

  4. Daha küçük tahtalardan birini kazanırsanız, o tahtanın tamamı döşemeniz olarak sayılır.

  5. Eğer herhangi bir bot kazanmadan önce panolardan biri doldurulursa, nobodies fayansı olarak sayılır.

  6. Her kim kazanırsa asıl tahta kazanır!

Ancak, önemli bir bükülme var. Diyelim ben dönüşte araçlarının yapabilirsiniz O gemide 7, karo 2. gitmek demek sadece Sonra dönüşte Şimdi çini 5., ben yapabilirsiniz, en gemide 2'de gitmek diyelim kurulu 2. gitmek sadece tahta 5'de gidin. Diyelim ki tahta 1 dolu. (Artık leke kalmadı ya da birimiz daha önce tahta 1'i kazandı.) Şimdi tahta 5, karo 1'e gidersem, istediğiniz tahtalardan birine girebilirsiniz.

Bu kurallar şöyle kabul edilebilir:

  1. Bir önceki oyuncunun oynadığı pozisyona karşılık gelen tahtada oynamalısınız.
    • Eğer X tahta 2'de oynarsa, fayans 5; O tahta 5 oynamak gerekir
  2. Hedef tahtası doluysa (bir beraberlik) veya zaten bir galibi varsa, bir sonraki hareket kısıtlanamaz.
  3. Bir kazanan bir kurul olabilir değil hatta kısıtsız hareket içine oynanacak.

Bu biraz kafa karıştırıcıysa, çevrimiçi olarak deneyebilirsiniz burada. ("ilk döşeme kazancı" ndan "arka arkaya 3 döşeme" arasında geçiş yaptığınızdan emin olun)

Şimdi burada meydan okuma kuralları.

  1. Bu oyunu oynayan bir bot yazmalısınız.

  2. Bot 1, X'ler ve önce başlıyor. Bu komut satırı argümanları ile çağrılacaktır (parantez içindeki maddeler olmadan):

    X         (whose turn)
    --------- (board 0)
    --------- (board 1)
    --------- (board 2)
    --------- (board 3)
    --------- (board 4)
    --------- (board 5)
    --------- (board 6)
    --------- (board 7)
    --------- (board 8)
    --------- (master board)
    xx        (last move)
    

    İlk karakter botun kim olduğunu gösterir. Bu durumda, bot 1 X olarak oynar. Sonraki 9 satır 9 panoya aittir. 11. satır ana panoya atıfta bulunur. "Xx" son harekettir. Şimdi, bot1, 0 ​​ile 8 arasında iki sayı yazdırmalıdır. Sayı 1, botunuzun hareket ettiği karttır ve 2 numaralı kartta belirtilen karttur. Kontrolör bu hareketi takip edecektir. Diyelim ki bot 1 38 yazdırıyor. Şimdi tahta şöyle görünecek:

     | |  ||  | |  ||  | |  
    ----- || ----- || ----- 
     | |  ||  | |  ||  | |  
    ----- || ----- || ----- 
     | |  ||  | |  ||  | |  
    ==========================
     | |  ||  | |  ||  | |  
    ----- || ----- || ----- 
     | |  ||  | |  ||  | |  
    ----- || ----- || ----- 
     | |X ||  | |  ||  | |  
    ==========================
     | |  ||  | |  ||  | |  
    ----- || ----- || ----- 
     | |  ||  | |  ||  | |  
    ----- || ----- || ----- 
     | |  ||  | |  ||  | |  
    

    ve bot2 bu argümanlarla çağrılacak:

    O
    ---------
    --------- 
    --------- 
    --------X 
    --------- 
    --------- 
    --------- 
    --------- 
    --------- 
    ---------
    38
    
  3. Şimdi bot 2, pano 8'de hareket etmelidir (bot1, kiremit 3'e x yerleştirilir). Diyelim ki bot2 84 yazdırıyor. Şimdi tahta böyle görünüyor.

     | |  ||  | |  ||  | |  
    ----- || ----- || ----- 
     | |  ||  | |  ||  | |  
    ----- || ----- || ----- 
     | |  ||  | |  ||  | |  
    ==========================
     | |  ||  | |  ||  | |  
    ----- || ----- || ----- 
     | |  ||  | |  ||  | |  
    ----- || ----- || ----- 
     | |X ||  | |  ||  | |  
    ==========================
     | |  ||  | |  ||  | |  
    ----- || ----- || ----- 
     | |  ||  | |  ||  |O|  
    ----- || ----- || ----- 
     | |  ||  | |  ||  | |  
    

    şimdi bot1 bu argümanlarla çağrılacak:

    X
    ---------
    --------- 
    --------- 
    --------X 
    --------- 
    --------- 
    --------- 
    --------- 
    ----0---- 
    ---------
    84
    
  4. Şimdi bot1 tahta 4'e taşınmalı. Ancak bot1 yaramaz küçük bir bottur ve tahta 3'e girmeye karar verir. Yönetim Kurulu hiç değişmiyor. Ana bot bunu takip ediyor. Şimdi bot2 bu argümanlarla çağrılacak:

    O
    ---------
    --------- 
    --------- 
    --------X 
    --------- 
    --------- 
    --------- 
    --------- 
    ----0---- 
    ---------
    xx
    
  5. Şimdi bot 2 istediği yere gidebilir (tabii ki 38 ve 84 hariç). Bu, birisi ana kartlardan 3 tanesini kazanana kadar devam eder. Ardından, bot2'nin X olduğu ve ilk başlayacağı ikinci bir eşleşme var.

  6. Bu, her bir bot diğer her botu oynayana kadar tekrar eder.

puanlama

Puanlama böyle çalışır:

Her maçın galibi 100 + number of open spotspuan alır . Böylece botunuz çabuk kazanırsa daha değerli olur. Botunuz geçersiz bir hamle yaptığında, 1 puan kaybeder. 250 turdan sonra, hiçbir bot kazanmazsa, her bot 10 puan kaybederse, bir sonraki tura geçiyoruz.


Her şey içeren bir dizine konur

  1. Kontrolör botu. Bu yazdığım bir C ++ programı. Kontrolör bot kaynak koduna buradan bakabilirsiniz . Kontrol cihazında doğru olmayan bir şey görürseniz lütfen bana bildirin.

  2. instructions.txtBu dosya adlı bir metin dosyası şuna benzer:

    [Total number of bots that are competing]
    
    [bot1Name] [bot1 command to run]
    [bot2Name] [bot2 command to run]
    ...
    
  3. Her bot için bir klasör. Bu klasör programınızı tutar (ister bir komut dosyası ister ikili dosya) ve data.txtbotunuzun istediği şeyi okuyabileceği ve yazabileceği adlı bir TEK metin dosyası .

Teknik özellikler ve kural açıklamaları

  • Klasörünün içinde olmayan herhangi bir yerden okuma / yazma girişiminde bulunan botlar oyundan atılır.

  • Programınız Yosemite çalıştıran bir macbook üzerinde çalışabilmelidir. Şu anda desteklenen diller python (2.7.9 ve 3.4.2), C / C ++, objektif-C, perl, yakut, bash, PHP, Java, C #, javascript ve Haskell. Çok daha fazlası var, ama bunlar şu an düşünebileceklerim. Zaman geçtikçe daha fazlasını ekleyeceğim. Belirli bir dilde rekabet etmek istiyorsanız, bana mesaj gönderin veya yorum yazın; mümkünse listeye eklerim.

  • Bir tahta kazanılırsa, ancak hala boşluk varsa, hala açık noktalardan birine giremezsiniz.

  • Gönderinizin çalışma dizini, denetleyiciyi içeren dizin ve botunuzu içeren dizin DEĞİLDİR.

  • Derlemek (varsa) ve botunuzu çalıştırmak için lütfen doğru komut ile birlikte kontrol cihazınızın bot kodunu gönderin. Bunun çoğu, linux terminaline oldukça benzeyen OS X terminalinden yapılacak.

  • Botlar bir saniyenin altında tamamlanmalıdır. Ne yazık ki, kontrolör botuna bir zamanlayıcı eklemek için yeterince yetkin değilim. Ancak botları manuel olarak zamanlayacağım.


Sonuçlar!

Ben haklıydım. MasterBoard'ın dolu olup olmadığını kontrol etmek için bot botunu kontrol etmeyi unuttum. MasterBoard doluysa, HER hamle geçersizdir, ancak botları çağırmaya devam eder, bu yüzden muhtemelen bu kadar çok geçersiz hamle olmuştu. Şimdi tamir ettim. İşte tüm botların en güncel versiyonunun resmi sonuçları.

Bot 1, goodRandBot, has 1 wins and made 0 illegal moves, for a total of 133 points.
Bot 2, naiveBot, has 3 wins and made 48 illegal moves, for a total of 361 points.
Bot 3, depthBot, has 5 wins and made 0 illegal moves, for a total of 664 points.
Bot 4, middleBot, has 1 wins and made 20 illegal moves, for a total of 114 points.

With 4 bots, This program took 477.471 seconds to finish.

Derinlik Bot saltanatı şampiyonu! En azından şimdilik.


Bir kenara, hiç baktı olması itibariyle Fire and Ice (bir PBEM sürümü gamerz.net ) - bu olsa ona bazı tic-tac-toe elemanları ... orada da hatırlattı çizici .

9 beğenme ve 40 görüntüleme. Etkilendim!
Loovjo

5
Botların yanıt süresine bir sınır koymak isteyebilirsiniz veya gelecekteki tüm olası hareketleri ararken botlar hamle başına 3 dakika sürebilir.
Mantık Şövalye

1
Bir sonraki hamle ile ilgili bazı kural açıklamaları ekledim. Veri formatı ve kurallardan biri hakkında endişelerim var. İlk bölümden Kural 5: "Eğer kurullardan biri doldurulursa, nobodies döşemesi olarak sayılır." Bu kazanan olmadan dolu mu? yani eğer birileri kiremit daha önce kazanırsa ve dolarsa kiremit olmaz mı? Dahası, eğer devletler geçtikten sonra botlar vatansızsa (göründüğü gibi), iletilen bir kurulun kazananı nasıl XXX000---? ya da 'O'nu kazanmasına rağmen O hiç kimse anlamadı' mı?

Yönetim Kurulu galibi @MichaelT 11. sıraya geçti. Bu kısmı biraz daha net hale getirmek için düzenleyeceğim, ancak düzenlemeniz yanlış. “Bir tahta kazanılırsa, ancak hala boşluk varsa, hala açık noktalardan birine giremezsiniz.”
DJMcMayhem

Yanıtlar:


5

Python 2.7, Derinlik

Fantezi bir şey olmadan bir alfa beta budama uygulaması. Alfa-beta elemelerini en üst düzeye çıkarmak için daha az naif bir şekilde hamle sipariş etmeye çalışır. Muhtemelen hızlandırmaya çalışacağım, ama dürüst olmak gerekirse, bir hız meselesi söz konusu olduğunda Python'un ne kadar rekabetçi olabileceğini bilmiyorum.

class DepthPlayer:
    def __init__(self,depth):
        self.depth = depth

    def score(self,master,subs,last_move):
        total = 0
        for x in range(3):
            for y in range(3):
                c = master[3*y+x]
                if c == 0:
                    total += sum(subs[3*y+x])
                else:
                    total += c*10
                    for (dx,dy) in [(1,-1),(1,0),(0,1),(1,1)]:
                        if x+dx<=2 and 0<=y+dy<=2 and master[3*(y+dy)+(x+dx)] == c:
                            total += c*10
        if last_move is None or master[last_move[1]] != 0 or 0 not in subs[last_move[1]]:
            total += 5
        return total

    def winner(self,board):
        for y in range(3):
            row = board[3*y:3*y+3]
            if 0!=row[0]==row[1]==row[2]:
                return row[0]
        for x in range(3):
            col = board[x:9:3]
            if 0!=col[0]==col[1]==col[2]:
                return col[0]
        if 0!=board[0]==board[4]==board[8]:
            return board[0]
        if 0!=board[2]==board[4]==board[6]:
            return board[2]

        return 0

    def parse(self,input):
        lines = input.split('\n')
        team = lines[0]
        subs_str = lines[1:10]
        master_str = lines[10]
        last_move_str = lines[11]

        master = [1 if c==team else 0 if c=='-' else -1 for c in master_str]
        subs = [[1 if c==team else 0 if c=='-' else -1 for c in sub_str] for sub_str in subs_str]
        if last_move_str == 'xx':
            last_move = None

        else:
            last_move = [int(c) for c in last_move_str]
        return master,subs,last_move

    def alphabeta(self, master,subs,last_move, depth, alpha, beta, player):
        if depth == 0:
            return self.score(master,subs,last_move),None
        w = self.winner(master)
        if w != 0:
            return w*1000,None

        if player:
            v = -10000
            best = None
            for n_master,n_subs,n_last_move in self.all_moves(master,subs,last_move,1):
                nv,_ = self.alphabeta(n_master,n_subs,n_last_move, depth-1, alpha, beta, False)
                if nv>v:
                    v = nv
                    best = n_last_move
                alpha = max(alpha, v)
                if beta <= alpha:
                    break
            return v,best
        else:
            v = 10000
            best = None
            for n_master,n_subs,n_last_move in self.all_moves(master,subs,last_move,-1):
                nv,nb = self.alphabeta(n_master,n_subs,n_last_move, depth-1, alpha, beta, True)
                if nv<v:
                    v = nv
                    best = n_last_move
                beta = min(beta, v)
                if beta <= alpha:
                    break
            return v,best

    def make_move(self,master,subs,move,player):
        n_subs = [sub[:] for sub in subs]
        n_master = master[:]
        n_subs[move[0]][move[1]] = player
        if n_master[move[0]] == 0:
            n_master[move[0]] = self.winner(n_subs[move[0]])
        return n_master,n_subs,move

    def sub_moves(self,board):
        first = []
        second = []
        third = []
        for i in range(9):
            if board[i] != 0:
                continue
            y,x = divmod(i,3)
            c=-2
            if   x==0 and 0!=board[i+1]==board[i+2]>c: c=board[i+1]
            elif x==1 and 0!=board[i-1]==board[i+1]>c: c=board[i-1]
            elif x==2 and 0!=board[i-2]==board[i-1]>c: c=board[i-2]
            if   y==0 and 0!=board[i+3]==board[i+6]>c: c=board[i+3]
            elif y==1 and 0!=board[i-3]==board[i+3]>c: c=board[i-3]
            elif y==2 and 0!=board[i-6]==board[i-3]>c: c=board[i-6]
            if i in [0,4,8] and 0!=board[(i+4)%12]==board[(i+4)%12]>c: c=board[i-6]
            if i in [2,4,6] and 0!=board[6 if i==2 else i-2]==board[2 if i==6 else i+2]>c: c=board[i-6]

            if c==-2:   third.append(i)
            elif c==-1: second.append(i)
            else:       third.append(i)
        return first+second+third

    def all_moves(self,master,subs,last_move,player):
        if last_move is not None and master[last_move[1]]==0 and 0 in subs[last_move[1]]:
            for i in self.sub_moves(subs[last_move[1]]):
                yield self.make_move(master,subs,[last_move[1],i],player)

        else:
            for j in range(9):
                if master[j]==0 and 0 in subs[j]:
                    for i in self.sub_moves(subs[j]):
                        yield self.make_move(master,subs,[j,i],player)

    def move(self,master,subs,last_move):
        return self.alphabeta(master,subs,last_move, self.depth, -10000, 10000, True)[1]

    def run(self,input):
        result = self.move(*self.parse(input))
        if result:
            return str(result[0])+str(result[1])

def print_board(subs,player):
    string = ""
    for row in range(9):
        for sub in subs[row/3*3:row/3*3+3]:
            for c in sub[row%3*3:row%3*3+3]:
                string += "-XO"[c*(1 if player=='X' else -1)]
            string += ' '
        if row%3 == 2:
            string += '\n'
        string += '\n'
    print string

def to_string(master,subs,last_move,player):
    string = player+'\n'
    for sub in subs:
        for c in sub:
            string += "-XO"[c*(1 if player=='O' else -1)]
        string += '\n'
    for c in master:
        string += "-XO"[c*(1 if player=='O' else -1)]
    string += '\n'+str(last_move[0])+str(last_move[1])
    return string


import sys
command = '\n'.join(sys.argv[1:])
print DepthPlayer(8).run(command)

Çalıştırmak için, basitçe yapabilirsiniz python Depth.py <input>, ancak pypygöze çarpan bir şekilde hızlandırarak kullanmanızı öneririm .

Ayrıca sisteminizin ne kadar hızlı olduğunu bilmiyorum ama ilk argümanı DepthPlayeren sonunda, belirtilen sürede hala çalışabiliyorsa daha yüksek olacak şekilde değiştirebilirsiniz (benim sistemimde hemen hemen her şeyi çok hızlı bir şekilde tamamladı. 7 ya da 8, ancak bir saniyeye yakın ya da üstünde olan birkaç durum vardı, bu yüzden güvenli olmasını 6'ya ayarladım).


python's sys.argvyeni satır ayrılmış bir dize döndürmez. Bu formatta dizelerin bir listesini verir: ['Depth.py', 'X', '---------', '---------', ...]Bunu son iki satırı düzenleyerek düzelttim command = '\n'.join(sys.argv[1:]) print DepthPlayer(6).run(command)umarım sakıncası yoktur.
DJMcMayhem

@DJMcMayhem Oh teşekkürler, bu son satırı test etmedim.
KSab

2

Java, Naive

Mümkünse, kazanır. Aksi takdirde, rakibin kazanmasını önler.

import java.util.Arrays;

public class Naive {

    public static void main(String[] args) {

        char[][] board = new char[9][9];
        for (int i = 0; i < 9; i++) {
            board[i] = args[i + 1].toCharArray();
        }
        char[] metaBox = args[10].toCharArray();

        char a = args[0].charAt(0),
                b = (char) ('X' + 'O' - a);

        int legalBox = args[11].charAt(1) - '0';
        boolean legalAnywhere = legalBox == 'x' - '0';
        if (!legalAnywhere) {
            if (wins(board[legalBox], 'X') || wins(board[legalBox], 'O')) {
                legalAnywhere = true;
            }
        }
        a:
        if (!legalAnywhere) {
            for (int i = 0; i < 9; i++) {
                if (board[legalBox][i] == '-') {
                    break a;
                }
            }
            legalAnywhere = true;
        }

        if (legalAnywhere) {
            chooseMove(board, metaBox, a, b);
        } else {
            chooseMove(board, metaBox, a, b, legalBox);
        }
    }

    static boolean canWinWith(char[] box, char c) {
        for (int i = 0; i < 9; i++) {
            if (wins(box, i, c)) {
                return true;
            }
        }
        return false;
    }

    static boolean wins(char[] box, int move, char c) {
        char[] copy = Arrays.copyOf(box, 9);
        copy[move] = c;
        return wins(copy, c);
    }

    static boolean wins(char[] box, char c) {
        return (box[0] == c && box[1] == c && box[2] == c)
               || (box[3] == c && box[4] == c && box[5] == c)
               || (box[6] == c && box[7] == c && box[8] == c)
               || (box[0] == c && box[3] == c && box[6] == c)
               || (box[1] == c && box[4] == c && box[7] == c)
               || (box[2] == c && box[5] == c && box[8] == c)
               || (box[0] == c && box[4] == c && box[8] == c)
               || (box[2] == c && box[4] == c && box[6] == c);
    }

    static void endWith(int box, int i) {
        System.out.println("" + box + i);
        System.exit(0);
    }

    private static void chooseMove(char[][] board, char[] metaBox, char a, char b, int legalBox) {
        for (int i = 0; i < 9; i++) {
            if (wins(board[legalBox], i, a) && board[legalBox][i] == '-') {
                endWith(legalBox, i);
            }
        }
        for (int i = 0; i < 9; i++) {
            if (wins(board[legalBox], i, b) && board[legalBox][i] == '-') {
                endWith(legalBox, i);
            }
        }
        for (int i = 0; i < 9; i++) {
            if (board[legalBox][i] == '-') {
                if (!canWinWith(board[i], b)) {
                    endWith(legalBox, i);
                }
            }
        }
        for (int i = 0; i < 9; i++) {
            if (board[legalBox][i] == '-') {
                endWith(legalBox, i);
            }
        }
        throw new RuntimeException("No move chosen!");
    }

    private static void chooseMove(char[][] board, char[] metaBox, char a, char b) {
        for (int box = 0; box < 9; box++) {
            for (int i = 0; i < 9; i++) {
                if (wins(board[box], i, a) && board[box][i] == '-') {
                    endWith(box, i);
                }
            }
        }
        for (int box = 0; box < 9; box++) {
            for (int i = 0; i < 9; i++) {
                if (wins(board[box], i, b) && board[box][i] == '-') {
                    endWith(box, i);
                }
            }
        }
        for (int box = 0; box < 9; box++) {
            for (int i = 0; i < 9; i++) {
                if (board[box][i] == '-') {
                    if (!canWinWith(board[i], b)) {
                        endWith(box, i);
                    }
                }
            }
        }
        for (int box = 0; box < 9; box++) {
            for (int i = 0; i < 9; i++) {
                if (board[box][i] == '-') {
                    endWith(box, i);
                }
            }
        }
        throw new RuntimeException("No move chosen!");
    }
}

Java noob olduğum için beni affetmeniz gerekecek, ancak bunu ana dizinden nasıl çalıştırabilirim? Ana dizinde Naive.classisimlendirilmiş bir dizinde var naiveBot.
DJMcMayhem

@DJMcMayhem Mac'e erişimim yok, ancak Windows'ta, java Naive <args>ortam değişkenlerinin işaretçiyi içerdiğini varsayarak Windows komutunu çalıştırabilirsiniz C:\Program Files\Java\jdk1.8.0\bin. Umarım bu yardımcı olur.
Ypnypn

Tamam, çözeceğim.
DJMcMayhem

@DJMcMayhem Zaten java -classpath naiveBot Naive
çözemediyseniz

@Ypnypn Doğruysa legalAnywhere, gönderiminiz başarısız olur, çünkü zaten bir oyuncu tarafından kazanılan panoları kullanmayı denersiniz.
CommonGuy

2

Python 2, MiddleBot

MiddleBot ortayı seviyor. Merkezi oyun (4) kazanılmadan önce, rakibini tekrar tekrar orta oyuna zorlayarak, oyunun orta karesini mümkün olduğunca kapmaya çalışacaktır.
Bu yapıldıktan sonra, kazanabileceği herhangi bir oyunu kazanmaya çalışır ya da olmasa da ilk boş alanı doldurur (geç oyun üzerinde çalışması gerekir, sanırım)

from random import randint
import sys
command_in = '\n'.join(sys.argv[1:])
class MiddleBot:

    def scan_in(self,the_game):

        lines = the_game.split('\n')
        self.us = lines[0]
        if self.us == 'X':
            self.them = 'O'
        else:
            self.them = 'X'
        self.games = lines[1:10]
        self.metagame = lines[10]
        self.last_move = lines[11]

        try:
            self.sub_board = int(self.last_move[1])
        except ValueError:
            self.sub_board = self.last_move[1]

    def empty(self,game,target):
        if self.games[int(game)][int(target)] == '-':
            self.emptycell = 1
        else: self.emptycell = 0

    def empty_fill(self,game):
        #checks for next empty space, fills it
        for k in xrange(0,8):
            self.empty(game,k)
            if self.emptycell == 1:
                self.first_empty_space = k
                break
            if self.emptycell == 0:
                game = randint(0,8)
                self.first_empty_space = 4


    def aim_for_target(self,game,target):
        if self.games[int(game)][int(target)] == '-':
            self.move = `game` + `target`
        else:
            self.empty_fill(game)
            self.move = `game` + `self.first_empty_space`


    #define all win conditions        
    win = [0]*8            
    win[0] = [0,1,2]
    win[1] = [3,4,5]
    win[2] = [6,7,8]
    win[3] = [0,3,6]
    win[4] = [1,4,7]
    win[5] = [2,5,8]
    win[6] = [0,4,8]
    win[7] = [2,4,6]

    #check if current board state is one move away from 'us' winning
    def aim_for_win(self,game):
            for k in xrange(0,len(self.win)):
                if self.games[self.sub_board][self.win[k][0]] == self.games[self.sub_board][self.win[k][1]] == self.us:
                    self.empty(self.sub_board,self.win[k][2])
                    if self.emptycell == 1:
                        self.move = `self.sub_board`+`self.win[k][2]`
                    else:
                        self.empty_fill(self.sub_board)
                        self.move = `self.sub_board`,`self.first_empty_space`
                elif self.games[self.sub_board][self.win[k][0]] == self.games[self.sub_board][self.win[k][2]] == self.us:
                    self.empty(self.sub_board,self.win[k][1])
                    if self.emptycell == 1:
                        self.move = `self.sub_board`+`self.win[k][1]`
                    else:
                        self.empty_fill(self.sub_board)
                        self.move = `self.sub_board`+`self.first_empty_space`
                elif self.games[self.sub_board][self.win[k][1]] == self.games[self.sub_board][self.win[k][2]] == self.us:
                    self.empty(self.sub_board,self.win[k][0])
                    if self.emptycell == 1:
                        self.move = `self.sub_board`+`self.win[k][0]`
                    else:
                        self.empty_fill(self.sub_board)
                        self.move = `self.sub_board`+`self.first_empty_space`
                else:
                    self.empty_fill(self.sub_board)
                    self.move = `self.sub_board`+`self.first_empty_space`


    def play(self):
        #If the middle board is not won, aim for the middle square of each board
        if self.metagame[4] == '-':
            if self.sub_board == 4 or self.sub_board == 'x':
                self.aim_for_target(4,4)
            else:
                self.aim_for_target(self.sub_board,4)
        else:
            #once the middle board is won, pretty much plays randomly, aiming to win if it can, otherwise just filling the first empty space in each subgame
            played = 0
            if self.sub_board == 'x':
                self.sub_board = randint(0,8)
            while played == 0:
                if self.metagame[int(self.sub_board)] == '-':
                    self.aim_for_win(self.sub_board)
                    played = 1
                else:
                    self.sub_board = randint(0,8)
        return self.move

    def run(self,game_board):
        self.scan_in(game_board)
        self.play()
        return self.move

print MiddleBot().run(command_in)      

Koşmak için, python MiddleBot.py <input>benim için mutlu bir şekilde bir saniyenin altında koşuyor gibi görünüyor, bu yüzden umarım sizin için de olur


Her şey yolunda gidiyor, fakat FYI, en son hareket 'xx' olduğunda çarpıyor ve bir bot her seferinde geçersiz bir hareket yapıyor.
DJMcMayhem

Hata! Şimdi düzeltilmeli. Bu yinelemede 'xx' durumunu test etmeyi unuttum, özür dilerim!
LogicianWithAHat

Ayrıca bir düzenleme yaptı - eğer bir kurul kazanan olmadan doldurulmuş olsaydı ve orada oynaması
istenirse çarpışacaktı

0

Belki de kendi botumu karışımın içine atabilirim.

python 2, iyiRandomBot

import sys
from random import choice

args = sys.argv
if len(args) < 13:
    print ("I can't work with this!\n")
    sys.exit()

whoAmI = args[1];
masterBoard = list(args[11])
board = []
for i in range(2, 11):
    board.append(list(args[i]))

oppMove = args[12]

def findAllValidMoves(board, masterBoard):
    validMoves = []
    for row in range(9):
        if masterBoard[row] != '-':
            continue
        for col in range(len(board[row])):
            if board[row][col] == '-':
                validMoves.append(str(row) + str(col))
    return validMoves

validMoves = []
if oppMove == "xx" or masterBoard[int(oppMove[1])] != "-":
    validMoves = findAllValidMoves(board, masterBoard)    

else:
    row = int(oppMove[1])
    for col in range(len(board[row])):
        if board[row][col] == '-' and masterBoard[row] == "-":
            validMoves.append(str(row) + str(col))

if (validMoves == []):
    validMoves = findAllValidMoves(board, masterBoard)

print choice(validMoves)

Bu bot geçerli bir hamle olduğu sürece nereye taşındığı umrunda değil. Geçerli tüm hareketlerden rastgele seçer ve ortalama 0geçersiz hamle yapar .

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.