निर्धारक गो एआई का निर्माण करें


11

यहाँ एक दिलचस्प समस्या है जो मैंने दूसरे दिन के बारे में सोचा, जिसमें कोड के अन्य बिट्स के खिलाफ प्रतिस्पर्धा करने वाले कोड शामिल हैं, न केवल एक संपत्ति में जो कोड में है, बल्कि कोड के उन अन्य बिट्स के खिलाफ एक गेम खेलकर।

आपका कार्य एक ऐसे कार्यक्रम का निर्माण करना है जो एक गो बोर्ड की वर्तमान स्थिति लेता है, और यह निर्धारित करता है कि क्या बनाना है या पास करना है।

आपका कार्यक्रम निम्नलिखित को इनपुट के रूप में स्वीकार करेगा:

  • 19 लाइनें, प्रत्येक 19 वर्णों के साथ, वर्तमान में गो बोर्ड पर टुकड़ों का प्रतिनिधित्व करती है। एक वर्ण 0एक खाली वर्ग का प्रतिनिधित्व करता है, 1काला है, और 2सफेद है।

  • प्रत्येक खिलाड़ी के पास कैदी के टुकड़ों की संख्या का प्रतिनिधित्व करने वाले दो नंबर (काले, फिर सफेद) हैं।

  • एक संख्या जिसका प्रतिनिधित्व यह मोड़ (काला या सफेद) ले जाने के लिए है। जैसा कि ऊपर, 1काला है, और 2सफेद है।

और निम्न में से एक आउटपुट:

  • निर्देशांक की एक जोड़ी निर्देशांक का a bप्रतिनिधित्व करती है जिस पर स्थानांतरित करना है। 1 1शीर्ष-बाएँ वर्ग है, और पहली और दूसरी संख्या क्रमशः नीचे और दाईं ओर जाने का प्रतिनिधित्व करती है।

  • स्ट्रिंग pass, जो पास करने के लिए एक चाल का प्रतिनिधित्व करता है।

उदाहरण के लिए, प्रोग्राम को निम्नलिखित इनपुट प्राप्त हो सकते हैं:

0000000000000000000
0000000000000000000
0000000000000000000
0001000000000002000
0000000000000000000
0000000000000000000
0001210000000000000
0000100000000000000
0000000000000000000
0000000000000000000
0000000000000000000
0000000000000000000
0000000000000000000
0000000000000000000
0000000000000000000
0002000000000001000
0000000000000000000
0000000000000000000
0000000000000000000
0 0 1

जो एक खेल का प्रतिनिधित्व करता है जहां केवल कुछ चालें खेली गई हैं।

फिर कार्यक्रम आउटपुट हो सकता है 6 5, जिसका अर्थ है "ऊपर से 6 वें बिंदु पर एक काला पत्थर और बाईं ओर से 5 वां पत्थर"। यह सफेद पत्थर पर कब्जा करेगा 7 5। बोर्ड की स्थिति तब बदल जाएगी:

0000000000000000000
0000000000000000000
0000000000000000000
0001000000000002000
0000000000000000000
0000100000000000000
0001010000000000000
0000100000000000000
0000000000000000000
0000000000000000000
0000000000000000000
0000000000000000000
0000000000000000000
0000000000000000000
0000000000000000000
0002000000000001000
0000000000000000000
0000000000000000000
0000000000000000000
1 0 2

(ध्यान दें कि यद्यपि एक सफेद पत्थर पर कब्जा कर लिया गया था, यह काले रंग के कैदी के रूप में गिना जाता है।)

आपके कोड को अतिरिक्त रूप से निम्नलिखित गुणों को पूरा करना होगा:

  • यदि आपके प्रोग्राम को समान इनपुट स्थिति दी गई है, तो उसे हमेशा उसी आउटपुट का उत्पादन करना चाहिए। यह गो एआई का दृढ़ संकल्प है। यह एक यादृच्छिक घटक नहीं होना चाहिए।

  • आपके कार्यक्रम को निर्धारित करने के लिए लगभग 60 सेकंड से अधिक नहीं लेना चाहिए कि क्या बनाना है। कंप्यूटिंग शक्ति में बदलाव के कारण इस नियम को कड़ाई से लागू नहीं किया जाएगा, लेकिन इसे उचित मात्रा में चलना चाहिए।

  • आपके प्रोग्राम का सोर्स कोड कुल 1 मेगाबाइट (1,048,576 बाइट्स) से अधिक नहीं होना चाहिए।

  • आपके कार्यक्रम को हमेशा कानूनी कदम उठाने चाहिए। आपका कार्यक्रम एक ऐसी जगह नहीं बना सकता जहां एक पत्थर पहले से मौजूद है, और एक टुकड़ा नहीं रख सकता है जिसके परिणामस्वरूप अपने स्वयं के पत्थरों के एक समूह पर कब्जा कर लिया जाएगा। (इस चुनौती के प्रयोजनों के लिए नियमों का एक अपवाद यह है कि एक कार्यक्रम को एक स्थिति बनाने की अनुमति है जो मूल रूप से वहां थी - क्योंकि यह केवल एक बोर्ड की वर्तमान स्थिति दी गई है, यह संग्रहीत करने की अपेक्षा नहीं की जा सकती है इससे पहले।)

आपका सबमिशन तब गो-गेम में, जहाँ बोर्ड की स्थिति खाली होने के बाद शुरू होती है, और अन्य प्रत्येक कार्यक्रम में बोर्ड की स्थिति को देखते हुए और एक कदम रखते हुए, सभी अन्य सबमिशन के खिलाफ एक ऑल-प्ले-ऑल-टूर्नामेंट में खेलेंगे। ।

सबमिशन की प्रत्येक जोड़ी दो राउंड खेलेगी - एक राउंड प्रत्येक खिलाड़ी के काले होने के साथ। क्योंकि इस समस्या में AI पूरी तरह से नियतात्मक हैं, एक ही AI के दो एक साथ खेलने के परिणामस्वरूप हमेशा एक ही गेम खेला जाएगा।

एक जीत के लिए शर्तें इस प्रकार हैं:

  • यदि आपका कार्यक्रम गेम के अंत में खेलता है, तो विजेता को निर्धारित करने के लिए गो के चीनी स्कोरिंग नियमों का उपयोग किया जाएगा। कोई कोमी नहीं लगाया जाएगा।

  • यदि आपका प्रोग्राम इस बिंदु पर खेलता है कि पहले की स्थिति तक पहुँच गया है, तो इस तरह एक अनंत लूप का कारण बनता है, दो कार्यक्रमों को बांधने की घोषणा की जाएगी।

आपका सबमिशन कितने अंकों का होगा, यह अन्य सबमिशन के मुकाबले स्कोर करता है। एक जीत 1 अंक के लायक है, और एक टाई आधा अंक के लायक है। सबसे अधिक अंकों के साथ प्रस्तुत करने वाला समग्र विजेता है।


यह एक पहाड़ी चुनौती है, जिसमें कोई भी किसी भी समय एक नई प्रविष्टि पोस्ट कर सकता है और ऐसा होने पर समय-समय पर स्टैंडों का पुनर्मूल्यांकन किया जाएगा।


7
ठीक है, सभी अन्य सबमिशनों की प्रतीक्षा कर रहा हूं और फिर उन्हें हरा देने के लिए अपना खुद का लिखता हूं - यह संभव होना चाहिए क्योंकि समाधान निर्धारक हैं।
हॉवर्ड

1
ऐसा लगता है कि कोए में ऐसा खेल रहा है कि पिछली स्थिति को दोहराया जाता है, लेकिन तत्काल ड्रॉ की ओर जाता है (क्योंकि यह एक लूप का कारण बनता है)। दिलचस्प ...
फायरफली

2
ऐसा लगता है कि आपकी समस्या बहुत अधिक है और कोई भी इतना कठिन काम नहीं करेगा कि वह एक सार्थक उत्तर दे सके (यह वास्तव में बहुत काम की चीज है)। यह एक अच्छी समस्या है, लेकिन साथ काम करने के लिए रास्ता बहुत कठिन है।
विक्टर स्टैफुसा

1
एक छोटे बोर्ड का उपयोग क्यों नहीं करते? 9x9 शुरुआती खिलाड़ियों के लिए काफी आम है। यह खोज स्थान को नाटकीय रूप से कम कर देता है, लेकिन यह इतना छोटा नहीं है कि यह विश्लेषण द्वारा अभी तक "पीटा" गया है (मुझे लगता है कि सबसे बड़ी जो पूरी तरह से हल हो गई है वह 5x6 है)।
जॉयबिट्स

1
इनपुट कैसे काम करता है? stdin या कमांड लाइन तर्क?
यज्ञपिन

जवाबों:


7

इस चुनौती को जमीन पर उतारने के लिए यहां मेरा प्रवेश है। पायथन कोड:

print "pass"

आपके नियमों के अनुसार हमेशा "पास" खेलना एक वैध (यद्यपि बुरा) रणनीति है।


आपका कोड हमेशा किसी के भी खिलाफ खो जाएगा जो इसके खिलाफ कोई भी नाटक करता है। फिर भी, अच्छा बेस-केस जवाब।
जो जेड।

1
@JoeZ। और इसके लगने से वह इसके साथ जीता: पी
डेविड मूल्डर

4

जावा: कोई स्पॉट, कोई भी स्पॉट चुनें

बस वैधता के लिए परीक्षण करने के लिए बोर्ड पर स्पॉट चुनता है। यह PRNG का उपयोग करता है, लेकिन एक निर्धारित बीज के साथ इसलिए यह निर्धारक है। यह PRNG चक्र के विभिन्न चक्रों का उपयोग करता है, जो इस बात पर निर्भर करता है कि कितने मोड़ आए हैं।

प्रत्येक उम्मीदवार की स्थिति के लिए, यह देखने के लिए जांचता है कि यह एक वैध कदम है (लेकिन ऐसा नहीं है कि यह एक स्मार्ट चाल है)। यदि ऐसा नहीं है, तो यह अगले उम्मीदवार के लिए आगे बढ़ता है। यदि यह 1000 कोशिशों के बाद एक वैध चाल नहीं पा सकता है, तो यह गुजरता है।

import java.util.Random;
import java.util.Scanner;

public class GoNaive {

    int[][] board;
    boolean[] checked;
    int me;

    public static void main(String[] args) {
        new GoNaive().run();
    }

    void run(){
        int turns = init();
        Random rand = new Random(seed);

        for(int i=0;i<turns*tries;i++)
            rand.nextInt(size*size);

        for(int i=0;i<tries;i++){
            int pos = rand.nextInt(size*size);
            for(int c=0;c<size*size;c++)
                checked[c]=false;
            if(board[pos%size][pos/size] == 0)
                if(hasLiberties(pos, me)){
                    System.out.print((pos%size+1) + " " + (pos/size+1));
                    System.exit(0);
                }
        }
        System.out.print("pass");
    }

    boolean hasLiberties(int pos, int color){
        if(checked[pos])
            return false;
        checked[pos] = true;

        int x = pos%size, y=pos/size, n;

        if(x>0){
            n = board[x-1][y];
            if(n==0 || (n==me && hasLiberties(y*size+x-1, color)))
                return true;
        }
        if(size-x>1){
            n = board[x+1][y];
            if(n==0 || (n==me && hasLiberties(y*size+x+1, color)))
                return true;
        }
        if(y>0){
            n = board[x][y-1];
            if(n==0 || (n==me && hasLiberties((y-1)*size+x, color)))
                return true;
        }
        if(size-y>1){
            n = board[x][y+1];
            if(n==0 || (n==me && hasLiberties((y+1)*size+x, color)))
                return true;
        }
        return false;
    }

    int init(){
        int turns = 0;
        board = new int[size][size];
        checked = new boolean[size*size];
        turns = 0;
        Scanner s = new Scanner(System.in);
        String line;
        for(int i=0;i<size;i++){
            line = s.nextLine();
            for(int j=0;j<size;j++){
                board[j][i] = line.charAt(j)-48;
                if(board[j][i] > 0)
                    turns++;
            }
        }
        String[] tokens = s.nextLine().split(" ");
        turns += Integer.valueOf(tokens[0]);
        turns += Integer.valueOf(tokens[1]);
        me = Integer.valueOf(tokens[2]);
        s.close();
        return turns;
    }

    final static int size = 19;
    final static int seed = 0xdeadface;
    final static int tries = 1000;
}

2

कुछ स्काला:

package go;

class Go {
  def main(args : Array[String]) {
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    System.out.printLn("1 1")
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    readLine()
    System.out.printLn("pass")
  }
}

विकिपीडिया पढ़ने से, मुझे लगता है कि यह वर्तमान समाधान को हरा देगा।


वास्तव में, यह दोनों मामलों में 361 अंकों से जीतेगा।
जो जेड।

असल में, मुझे वह वापस लेना होगा, यह कल्पना का पालन नहीं करता है। एआई को स्टेटलेस माना जाता है। यह केवल बोर्ड की स्थिति को देखते हुए एक चीज को प्रिंट करने वाला है , और आपने इसे दो ( 1 1और pass) प्रिंट किया है ।
जो Z.

@JoeZ। ठीक कर दिया। वैसे भी संकलित नहीं किया होता।
yayestechlab

यह हमेशा प्रिंट होता है 1 1, वास्तव में, चूंकि कार्यक्रम हमेशा हर बार बोर्ड में परिवर्तन होने पर नए सिरे से चलाया जाता है।
जो जेड

1

जावा

public class Go {
  public static void main(String[] args) {
    Scanner s = new Scanner(System.in);
    for (int i = 0; i < 361;) {
      char c = s.nextChar();
      if (c != '\n') {
        if (c == '0') {
          System.out.println((i % 19 + 1) + " " + (i / 19 + 1));
          System.exit(0);
        }
        i++;
      }
    }
  }
}

पहला खाली स्थान चुनता है। पोस्टिंग के समय के रूप में किसी भी एआई के खिलाफ जीत।


2
यह एक कानूनी कदम की गारंटी नहीं देता है। यदि पहले उपलब्ध स्थान में कोई स्वतंत्रता नहीं है, तो इसे नहीं खेला जा सकता है। उदाहरण के लिए, यदि यह AI खुद खेलता है: बारी-बारी से टुकड़ों की पहली पंक्ति के बाद, 1 1सफेद (अब खाली) द्वारा कब्जा कर लिया जाएगा और अगले मोड़ पर काले द्वारा नहीं खेला जा सकता है।
जियोबिट्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.