चलो मेटा टिक-टैक-टो खेलते हैं!


38

मेटा टिक-टैक-टो का खेल खेलते हैं!

यह मेटा टिक-टैक-टू का एक टूर्नामेंट है। मेटा टिक-टैक-टो के नियम इस प्रकार हैं:

  1. टिक-टैक-टो के सभी नियमित नियम लागू होते हैं।

  2. एक मास्टर बोर्ड बनाने के लिए नौ बोर्ड की व्यवस्था है। इस तरह:

    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 
    

    बोर्ड 0 शीर्ष बाएं बोर्ड को संदर्भित करता है, बोर्ड 1 शीर्ष मध्य बोर्ड को संदर्भित करता है ... इस तरह

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

    यदि मैं बोर्ड 3, टाइल 4 कहता हूं, तो इसका मतलब है कि मध्य बाईं ओर बोर्ड की केंद्र टाइल।

  3. आपको केवल एक छोटे बोर्ड में जाने की अनुमति है।

  4. यदि आप एक छोटे बोर्ड को जीतते हैं, तो वह पूरा बोर्ड आपकी टाइल के रूप में गिना जाता है।

  5. यदि बॉट के जीतने से पहले उनमें से एक बोर्ड भर जाता है, तो इसे नोबॉडी टाइल के रूप में गिना जाता है।

  6. जो भी मास्टर बोर्ड जीतता है वह जीतता है!

हालांकि, एक महत्वपूर्ण मोड़ है। मान लें कि मैं बोर्ड 7, टाइल 2 में जाता हूं। इसका मतलब है कि आपकी बारी है, आप केवल बोर्ड 2 में जा सकते हैं। फिर मान लें कि आप बोर्ड 2, टाइल 5 में चलते हैं। अब अपनी बारी पर, मैं केवल बोर्ड 5 में जा सकता हूं । मान लीजिए कि बोर्ड 1 भरा हुआ है। (अब और धब्बे नहीं बचे हैं, या हम में से एक ने पहले ही बोर्ड 1 जीत लिया है) अब अगर मैं बोर्ड 5, टाइल 1 में जाता हूं, तो आप जो भी बोर्ड चाहते हैं, उसमें जा सकते हैं।

इन नियमों को माना जा सकता है:

  1. आपको पिछले खिलाड़ी द्वारा खेली गई स्थिति के अनुसार बोर्ड में खेलना चाहिए।
    • यदि X बोर्ड 2, टाइल 5 में खेलता है; ओ को बोर्ड 5 में खेलना चाहिए
  2. यदि लक्ष्य बोर्ड भरा हुआ है (एक टाई) या पहले से ही एक विजेता है, तो अगला कदम असंवैधानिक है।
  3. एक विजेता के साथ एक बोर्ड को एक असंवैधानिक कदम पर भी नहीं खेला जा सकता है।

यदि यह थोड़ा भ्रमित करने वाला है, तो आप इसे ऑनलाइन यहाँ आज़मा सकते हैं। ("पहली टाइल जीत" से "एक पंक्ति में 3 टाइलें" पर स्विच करना सुनिश्चित करें)

अब यहाँ चुनौती के नियम हैं।

  1. आपको एक बॉट लिखना होगा जो इस गेम को खेलता है।

  2. बॉट 1 एक्स है, और इसे पहले जाना है। इसे इन कमांड लाइन तर्कों (कोष्ठक में सामान के बिना) के साथ कहा जाएगा:

    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)
    

    पहला चरित्र दर्शाता है कि बॉट कौन है। इस स्थिति में, बॉट 1 एक्स के रूप में खेलता है। अगली 9 लाइनें 9 बोर्डों को संदर्भित करती हैं। 11 वीं पंक्ति मास्टर बोर्ड को संदर्भित करती है। "Xx" अंतिम चाल है। अब, bot1 को 0 और 8. के ​​बीच दो नंबर प्रिंट करने चाहिए। नंबर 1 वह बोर्ड है जिसमें आपका bot चल रहा है और नंबर 2 उक्त बोर्ड में टाइल है। नियंत्रक इस कदम का ट्रैक रखेगा। मान लीजिए कि बॉट 1 प्रिंट 38 है। अब बोर्ड इस तरह दिखेगा:

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

    और bot2 इन तर्कों के साथ बुलाया जाएगा:

    O
    ---------
    --------- 
    --------- 
    --------X 
    --------- 
    --------- 
    --------- 
    --------- 
    --------- 
    ---------
    38
    
  3. अब बॉट 2 को बोर्ड 8 में ले जाना चाहिए (क्योंकि बॉट 1 ने टाइल 3 में एक एक्स रखा है)। मान लें कि bot2 प्रिंट 84 है। अब बोर्ड इस तरह दिखता है।

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

    अब bot1 को इन तर्कों के साथ बुलाया जा रहा है:

    X
    ---------
    --------- 
    --------- 
    --------X 
    --------- 
    --------- 
    --------- 
    --------- 
    ----0---- 
    ---------
    84
    
  4. अब bot1 को बोर्ड 4 में ले जाना चाहिए। हालाँकि, bot1 एक शरारती छोटा बॉट है, और बोर्ड 3 में जाने का फैसला करता है। यह '30' प्रिंट करता है। बोर्ड बिल्कुल नहीं बदलता है। मास्टर बॉट इस पर नज़र रखता है। अब bot2 को इन तर्कों के साथ बुलाया जाएगा:

    O
    ---------
    --------- 
    --------- 
    --------X 
    --------- 
    --------- 
    --------- 
    --------- 
    ----0---- 
    ---------
    xx
    
  5. अब बॉट 2 कहीं भी जा सकता है (38 और 84 को छोड़कर, निश्चित रूप से)। यह तब तक जारी रहता है जब तक कि कोई एक पंक्ति में 3 मास्टर बोर्ड नहीं जीतता। फिर, दूसरा मैचअप होता है, जहां बॉट 2 एक्स होता है और पहले जाना होता है।

  6. यह तब तक दोहराता है जब तक कि हर एक बॉट ने हर दूसरे बॉट को नहीं खेला।

स्कोरिंग

स्कोरिंग इस तरह काम करता है:

प्रत्येक मैच के विजेता को 100 + number of open spotsअंक मिलते हैं। इस तरह, यह अधिक मूल्यवान है अगर आपका बॉट जल्दी से जीतता है। जब भी आपका बॉट अमान्य कदम उठाता है, वह 1 अंक खो देता है। यदि 250 राउंड के बाद, न तो बॉट जीता है, प्रत्येक बॉट 10 अंक खो देता है, और हम अगले दौर में जाते हैं।


सब कुछ एक निर्देशिका में रखा जाएगा

  1. नियंत्रक बॉट। यह एक C ++ प्रोग्राम है जो मैंने लिखा है। आप यहां कंट्रोलर बॉट सोर्स कोड देख सकते हैं। कृपया मुझे बताएं कि क्या आपको ऐसा कुछ दिखाई देता है जो नियंत्रक के साथ सही नहीं है।

  2. इस फ़ाइल नाम की एक टेक्स्ट फ़ाइल instructions.txtकुछ इस तरह दिखाई देगी:

    [Total number of bots that are competing]
    
    [bot1Name] [bot1 command to run]
    [bot2Name] [bot2 command to run]
    ...
    
  3. प्रत्येक बॉट के लिए एक फ़ोल्डर। यह फ़ोल्डर आपके प्रोग्राम (चाहे वह स्क्रिप्ट या बाइनरी हो) और वन टेक्स्ट फ़ाइल को रखेगा, data.txtजिसे आपका बॉट जो चाहे पढ़ और लिख सकता है।

तकनीकी विनिर्देश और नियम स्पष्टीकरण

  • कोई भी बॉट जो उसके अंदर से कहीं से भी कुछ पढ़ने / लिखने का प्रयास करता है, उसे गेम से हटा दिया जाएगा।

  • आपका प्रोग्राम योसमाइट चलाने वाली मैकबुक पर चलने में सक्षम होना चाहिए। वर्तमान में समर्थित भाषाएं पायथन (2.7.9 और 3.4.2), C / C ++, ऑब्जेक्टिव-सी, पर्ल, रूबी, बैश, PHP, जावा, C #, जावास्क्रिप्ट और हास्केल हैं। और भी बहुत कुछ हैं, लेकिन ये वही हैं जो मैं अभी सोच सकता हूं। समय बढ़ने पर मैं और जोड़ूंगा। यदि आप किसी विशिष्ट भाषा में प्रतिस्पर्धा करना चाहते हैं, तो मुझे संदेश या टिप्पणी दें, और यदि संभव हो तो मैं इसे सूची में जोड़ दूंगा।

  • यदि कोई बोर्ड जीता है, लेकिन अभी भी जगह है, तो आप अभी भी खुले स्थानों में से एक में नहीं जा सकते।

  • ध्यान दें कि आपके सबमिशन की कार्यशील निर्देशिका वह निर्देशिका होगी जिसमें कंट्रोलर और अन्य सभी बॉट शामिल होंगे, न कि वह निर्देशिका जिसमें आपका बॉट शामिल है।

  • कृपया अपने नियंत्रक बॉट कोड के साथ पोस्ट करें (यदि लागू हो) संकलन करने और अपने बॉट को चलाने के लिए सही कमांड। इसमें से अधिकांश ओएस एक्स टर्मिनल से किया जाएगा, जो काफी हद तक एक लिनक्स टर्मिनल के समान है।

  • बॉट को एक सेकंड के अंदर पूरा करना होगा। दुर्भाग्य से, मैं नियंत्रक बॉट में टाइमर जोड़ने के लिए पर्याप्त सक्षम नहीं हूं। हालाँकि, मैं मैन्युअल रूप से बॉट्स को समय दूंगा।


परिणाम!

खैर, मैं सही था। मैं मास्टर बोडर भरा हुआ है यह देखने के लिए नियंत्रक बॉट की जांच करना भूल गया। यदि मास्टरबोर्ड भरा हुआ है, तो हर कदम अमान्य है, लेकिन यह बॉट्स को कॉल करना जारी रखता है, जो संभवतः इसलिए कई अमान्य कदम थे। मैंने इसे अब ठीक कर दिया है। यहां सभी बॉट्स के सबसे वर्तमान संस्करण के साथ आधिकारिक परिणाम हैं।

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.

डेप्थ बॉट राज करने वाला चैंपियन है! कम से कम, अभी के लिए।


के रूप में एक अलग रूप में, क्या आपने कभी देखा है आग और बर्फ (एक pbem संस्करण gamerz.net ) - वहाँ यह करने के लिए कुछ टिक टीएसी को पैर की अंगुली तत्व हैं ... हालांकि यह भी मुझे की याद दिला दी मुंशी

9 लाइक और 40 व्यूज। मैं प्रसन्न हूँ!
लोवोजो

5
आप बॉट्स के रिस्पांस टाइम पर एक लिमिट लगाना चाहते हैं, या बॉट्स भविष्य के सभी संभावित मूव्स को सर्च करते हुए प्रति मिनट 3 मिनट ले सकते हैं।
लॉज नाइट

1
मैंने अगले कदम के बारे में कुछ नियम स्पष्टीकरण जोड़े हैं। मुझे डेटा प्रारूप और नियमों में से एक के बारे में चिंता है। पहले खंड से नियम 5: "यदि बोर्ड में से एक भरा हो जाता है, तो इसे नोबॉडी टाइल के रूप में गिना जाता है।" क्या यह एक विजेता के बिना भरा है? यानी यदि कोई पहले टाइल जीतता है, और यह भर जाता है तो क्या यह टाइलों का नामकरण है? इसके अलावा, अगर बॉट स्टेटलेस (वे प्रतीत होते हैं) राज्य में पारित हो जाते हैं, तो एक बोर्ड के विजेता को XXX000---प्रेषित कैसे किया जाता है? या यह है कि 'ओ के जीतने के बावजूद कोई भी इसे प्राप्त नहीं करता है'?

@ मिचेल बोर्ड के विजेता को 11 वीं पंक्ति में पारित किया गया है। मैं इस हिस्से को थोड़ा और स्पष्ट करने के लिए संपादित करूँगा, हालाँकि आपका संपादन गलत है। "यदि कोई बोर्ड जीता है, लेकिन अभी भी जगह है, तो आप अभी भी खुले स्थानों में से एक में नहीं जा सकते।"
DJMcMayhem

जवाबों:


5

पायथन 2.7, गहराई

एक अल्फा-बीटा छंटाई कार्यान्वयन बिना कुछ भी फैंसी। यह अल्फ़ा-बीटा निष्कासन को अधिकतम करने के लिए कम भोले तरीके से चाल को क्रमबद्ध करने की कोशिश करता है। मैं शायद इसे गति देने की कोशिश करूंगा, लेकिन ईमानदारी से मुझे नहीं पता है कि गति के एक सवाल पर नीचे आने पर पायथन कितना प्रतिस्पर्धी हो सकता है।

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)

इसे चलाने के लिए, आप बस कर सकते हैं python Depth.py <input>, हालांकि मैं pypyइसका उपयोग करने का सुझाव दूंगा क्योंकि यह इसे तेजी से बढ़ाता है।

इसके अलावा मुझे नहीं पता कि आपका सिस्टम कितना तेज है, लेकिन आप पहले तर्क को DepthPlayerबहुत अंत में संशोधित कर सकते हैं उच्च होने के लिए अगर यह अभी भी निर्दिष्ट समय में चल सकता है (मेरे सिस्टम पर यह लगभग सभी चीजों को बहुत तेज़ी से गहराई से पूरा करता है 7 या 8, लेकिन कुछ मामले ऐसे थे जो एक सेकंड के पास या उससे ऊपर थे इसलिए मैंने इसे सुरक्षित होने के लिए 6 पर सेट किया)।


अजगर की sys.argvएक अलग पंक्ति स्ट्रिंग वापस नहीं करता है। यह इस प्रारूप में तार की एक सूची देता है: ['Depth.py', 'X', '---------', '---------', ...]मैंने इसे अंतिम दो पंक्तियों को संपादित करके इसे तय किया है command = '\n'.join(sys.argv[1:]) print DepthPlayer(6).run(command)मुझे आशा है कि आपको कोई आपत्ति नहीं है।
DJMcMayhem

@DJMcMayhem ओह धन्यवाद, मैंने उस अंतिम पंक्ति का परीक्षण नहीं किया।
केसाब

2

जावा, नाइव

यदि संभव हो, तो यह जीतता है। अन्यथा, यह एक प्रतिद्वंद्वी को जीतने से रोकता है।

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!");
    }
}

आपको जावा नोब होने के लिए मुझे माफ करना होगा, लेकिन मैं इसे मूल निर्देशिका से कैसे चलाऊं? मैं मुख्य निर्देशिका के अंदर Naive.classनामित एक निर्देशिका में है naiveBot
DJMcMayhem

@DJMcMayhem I के पास मैक तक पहुंच नहीं है, लेकिन विंडोज पर, आप केवल java Naive <args>कमांड चला सकते हैं , यह मानकर कि पर्यावरण चर में सूचक शामिल हैं C:\Program Files\Java\jdk1.8.0\bin। आशा है कि ये आपकी मदद करेगा।
यज्ञपिन

ठीक है, मैं इसका पता लगा लूंगा।
DJMcMayhem

@DJMcMayhem यदि आपने इसे पहले ही समझ नहीं लिया है, तो java -classpath naiveBot Naive;)
कॉमनग्यू

@Ypnypn यदि legalAnywhereयह सच है, तो आपका सबमिशन विफल हो जाता है क्योंकि आप उन बोर्डों का उपयोग करने की कोशिश करते हैं जो पहले से ही एक खिलाड़ी द्वारा जीते जाते हैं।
कॉमनग्यू

2

पायथन 2, मिडिलबोट

मिडिलबॉट को बीच पसंद है। केंद्रीय खेल (4) जीतने से पहले, यह प्रतिद्वंद्वी को बार-बार मध्य खेल में वापस लाने के लिए, अधिक से अधिक गेम के केंद्र वर्ग को हथियाने की कोशिश करेगा।
एक बार जब यह हो जाता है, तो यह किसी भी खेल को जीतने की कोशिश कर सकता है, या बस पहले उपलब्ध स्थान को भर देता है यदि नहीं (इसके देर से खेल पर काम करने की आवश्यकता है, मुझे लगता है)

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)      

इसे चलाने के लिए, python MiddleBot.py <input>यह खुशी से मेरे लिए एक सेकंड के तहत चलता है, इसलिए उम्मीद है कि यह आपके लिए भी होगा


सब कुछ ठीक चलता है, लेकिन FYI करें, यह दुर्घटनाग्रस्त हो जाता है जब अंतिम चाल 'xx' होती है जो शुरुआत में होती है और हर बार एक बोट एक अवैध कदम बनाती है।
DJMcMayhem

ऊप्स! अब तय होना चाहिए। उस पुनरावृत्ति में 'xx' मामले को जांचना भूल गया, क्षमा करें!
लोगियनविथाहैट

एक संपादन भी किया - अगर कोई बोर्ड विजेता के बिना भरा गया होता तो यह दुर्घटनाग्रस्त हो जाता और उसे वहां खेलने के लिए कहा जाता
LogianWithAHat

0

साथ ही मिक्स में मेरे अपने बॉट को फेंक सकते हैं।

अजगर 2, goodRandomBot

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)

यह बॉट परवाह नहीं करता है कि यह कहाँ चलता है, जब तक यह एक वैध चाल है। सभी मान्य चालों से यादृच्छिक पर चिपकती है, और औसतन 0अवैध चाल चलती है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.