สร้าง Go AI ที่กำหนดขึ้น


11

นี่เป็นปัญหาที่น่าสนใจที่ฉันนึกถึงเมื่อวันก่อนซึ่งเกี่ยวข้องกับบิตของโค้ดที่แข่งขันกับบิตของโค้ดอื่น ๆ ไม่ใช่แค่ในคุณสมบัติที่โค้ดมี แต่โดยการเล่นเกมกับบิตของโค้ดอื่น ๆ

งานของคุณคือการสร้างโปรแกรมที่ใช้สถานะปัจจุบันของกระดาน Go และกำหนดสิ่งที่จะทำหรือผ่าน

โปรแกรมของคุณจะยอมรับสิ่งต่อไปนี้เป็นอินพุต:

  • 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

(โปรดทราบว่าแม้ว่าจะมีก้อนหินสีขาวถูกจับ แต่ก็นับว่าเป็นนักโทษสำหรับคนผิวดำ)

รหัสของคุณจะต้องเป็นไปตามคุณสมบัติต่อไปนี้เพิ่มเติม:

  • หากโปรแกรมของคุณได้รับสถานะอินพุตเดียวกันมันจะต้องสร้างเอาต์พุตเดียวกันเสมอ นี่คือระดับของ Go AI มันจะต้องไม่มีองค์ประกอบแบบสุ่ม

  • โปรแกรมของคุณต้องไม่ใช้เวลานานกว่าประมาณ 60 วินาทีเพื่อพิจารณาว่าจะย้ายไปทางไหน กฎนี้จะไม่ถูกนำมาใช้อย่างเคร่งครัดเนื่องจากความแปรปรวนของกำลังการคำนวณ แต่จะต้องดำเนินการในเวลาที่เหมาะสม

  • ซอร์สโค้ดของโปรแกรมของคุณต้องไม่เกิน 1 เมกะไบต์ (1,048,576 ไบต์)

  • โปรแกรมของคุณจะต้องดำเนินการทางกฎหมายเสมอ โปรแกรมของคุณไม่สามารถเคลื่อนย้ายหินที่มีอยู่แล้วและไม่สามารถวางชิ้นส่วนที่จะส่งผลให้กลุ่มของหินถูกจับ (ข้อยกเว้นสำหรับกฎสำหรับวัตถุประสงค์ของการท้าทายนี้คือโปรแกรมอนุญาตให้สร้างตำแหน่งที่มีอยู่เดิม - เนื่องจากได้รับตำแหน่งปัจจุบันของบอร์ดเท่านั้นจึงไม่สามารถคาดหวังได้ว่าจะเก็บสิ่งที่เคลื่อนไหว ก่อน.)

การส่งของคุณจะเล่นในทัวร์นาเมนท์ที่เล่นได้ทั้งหมดกับการส่งอื่น ๆ ทั้งหมดในเกมโกที่สถานะของกระดานเริ่มว่างเปล่าและแต่ละโปรแกรมจะเปลี่ยนเป็นฟีดตำแหน่งของกระดานและเคลื่อนไหว .

การส่งแต่ละคู่จะเล่นสองรอบ - หนึ่งรอบโดยผู้เล่นแต่ละคนจะเป็นสีดำ เนื่องจาก AIs ในปัญหานี้ถูกกำหนดไว้อย่างสมบูรณ์ดังนั้นการเล่น AIs เดียวกันสองรายการด้วยกันจะส่งผลให้เกิดการเล่นเกมเดียวกันทุกครั้ง

เงื่อนไขสำหรับการชนะเป็นเช่นนี้:

  • หากโปรแกรมของคุณเล่นจนจบเกมกฎการให้คะแนนของจีนจะใช้เพื่อตัดสินผู้ชนะ จะไม่มีการใช้โคมิ

  • หากโปรแกรมของคุณเล่นจนถึงจุดที่ถึงสถานะก่อนหน้านี้ซึ่งก่อให้เกิดการวนซ้ำไม่สิ้นสุดโปรแกรมสองโปรแกรมจะถูกประกาศให้เชื่อมโยงกัน

การส่งของคุณจะได้รับคะแนนโดยคะแนนกี่คะแนนเทียบกับการส่งอื่น ๆ การชนะมีค่า 1 คะแนนและการเสมอมีค่าครึ่งคะแนน การส่งที่มีคะแนนมากที่สุดคือผู้ชนะโดยรวม


นี่เป็นความท้าทายที่ยอดเยี่ยมซึ่งทุกคนสามารถโพสต์รายการใหม่ได้ตลอดเวลาและอันดับจะได้รับการประเมินซ้ำเป็นระยะเมื่อเกิดเหตุการณ์นี้


7
ตกลงรอการส่งอื่น ๆ ทั้งหมดแล้วเขียนของฉันเองเพื่อเอาชนะพวกเขา - ควรเป็นไปได้เนื่องจากคำตอบนั้นถูกกำหนดไว้แล้ว
Howard

1
ดูเหมือนว่าจะเล่นในเกาะที่อนุญาตให้ทำซ้ำตำแหน่งก่อนหน้า แต่นำไปสู่การเสมอในทันที (เนื่องจากทำให้เกิดการวนซ้ำ) ที่น่าสนใจ ...
FireFly

2
ดูเหมือนว่าปัญหาของคุณจะดุเดือดเกินไปและไม่มีใครทำงานหนักพอที่จะสร้างคำตอบที่มีค่า มันเป็นปัญหาที่ดี แต่การทำงานหนักเกินไป
Victor Stafusa

1
ทำไมไม่ใช้บอร์ดขนาดเล็ก? 9x9 เป็นเรื่องธรรมดามากพอสำหรับผู้เล่นระดับเริ่มต้น มันลดพื้นที่การค้นหาลงอย่างมาก แต่ก็ไม่เล็กจนมันถูก "ถูก" โดยการวิเคราะห์ (ฉันคิดว่าใหญ่ที่สุดที่ได้รับการแก้ไขอย่างเต็มที่คือ 5x6)
Geobits

1
อินพุตทำงานอย่างไร อาร์กิวเมนต์ stdin หรือบรรทัดคำสั่ง?
Ypnypn

คำตอบ:


7

นี่คือรายการของฉันที่จะได้รับความท้าทายนี้จากพื้นดิน รหัสหลาม:

print "pass"

ตามกฎของคุณที่เล่น "ผ่าน" เป็นกลยุทธ์ที่ถูกต้อง (แม้ว่าจะไม่ดี)


รหัสของคุณจะแพ้กับใครก็ตามที่เล่นกับมัน ยังคงคำตอบกรณีฐานที่ดี
Joe Z.

1
@JoeZ และจากรูปลักษณ์ของมันเขาชนะด้วย: P
David Mulder

4

Java: เลือกจุดใดก็ได้

เพียงเลือกจุดบนกระดานเพื่อทดสอบความถูกต้อง มันใช้ PRNG แต่มีการตั้งค่าเมล็ดเพื่อที่จะกำหนดไว้ มันใช้ชิ้นส่วนที่แตกต่างกันของวงจร PRNG ขึ้นอยู่กับจำนวนรอบที่ผ่านไป

สำหรับตำแหน่งผู้สมัครแต่ละตำแหน่งจะตรวจสอบเพื่อดูว่าเป็นการย้ายที่ถูกต้อง (แต่ไม่ใช่ว่าเป็นการย้ายที่ชาญฉลาด ) ถ้าไม่ใช่มันจะย้ายไปยังตัวเลือกถัดไป หากไม่พบการย้ายที่ถูกต้องหลังจากลอง 1,000 ครั้งจะผ่าน

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

จากการอ่าน Wikipedia ฉันคิดว่าสิ่งนี้จะเอาชนะทางออกปัจจุบันได้


ในความเป็นจริงมันจะชนะ 361 คะแนนในทั้งสองกรณี
Joe Z.

ที่จริงแล้วฉันจะต้องเอามันกลับไปมันไม่ทำตามสเป็ค AI ควรจะไร้สัญชาติ จริง ๆ แล้วมันควรจะพิมพ์สิ่งเดียวที่กำหนดสถานะของกระดานและคุณได้พิมพ์สอง ( 1 1และpass)
Joe Z.

@JoeZ ซ่อมมัน. จะไม่ได้รวบรวมเลย
yayestechlab

ที่จะพิมพ์เสมอ1 1อันที่จริงเนื่องจากโปรแกรมทำงานอยู่เสมอทุกครั้งที่มีการเปลี่ยนแปลงบอร์ด
Joe Z.

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++;
      }
    }
  }
}

เลือกพื้นที่ว่างแรก ชนะต่อ AIS ใด ๆ เมื่อถึงเวลาโพสต์


2
สิ่งนี้ไม่รับประกันว่าจะมีการเคลื่อนไหวทางกฎหมาย หากพื้นที่ว่างที่ว่างแรกไม่มีเสรีภาพจะไม่สามารถเล่นได้ ตัวอย่างเช่นหาก AI นี้เล่นเอง: หลังจากแถวแรกของชิ้นส่วนสลับ1 1จะถูกจับด้วยสีขาว (ตอนนี้ว่างเปล่า) และไม่สามารถเล่นเป็นสีดำในเทิร์นถัดไป
Geobits
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.