ग्रिड रूटिंग लड़ाई


22

नोट: यह चुनौती वर्तमान में मृत है, क्योंकि मैं एक मैच चलाने के लिए आवश्यक भाषाओं को स्थापित करने में असमर्थ हूं। यदि किसी और के पास इसे करने का समय और रुचि है, तो मैं विरोध नहीं करता।

लीडरबोर्ड के लिए पोस्ट के नीचे देखें।

यह एक अर्ध-सहकारी राजा-की-पहाड़ी चुनौती है, जहां बॉट द्वि-आयामी ग्रिड ग्राफ के माध्यम से पथ का निर्माण करते हैं। सबसे अधिक ट्रैफ़िक वाले नोड्स को नियंत्रित करने वाला बॉट विजेता है। हालांकि, यह वास्तव में एक संपर्क पथ का निर्माण करने के लिए एक से अधिक बॉट के संसाधन लेता है, इसलिए बॉट्स को एक साथ - कुछ हद तक काम करना होगा।

गेमप्ले

निम्नलिखित में, N > 0खेलने में बॉट की संख्या होने दें ।

ग्रिड

खेल आकार के दो-आयामी पूर्णांक ग्रिड पर खेला जाता है , जिसका निचला बाईं ओर समन्वय होता है । प्रत्येक समन्वय के साथ तीन निर्देशांक के लिए बाहर जाने वाले किनारों है , और यह ऊपर है, जहां -coordinates सापेक्ष लिया जाता है । इसका मतलब है कि ग्रिड पूर्व और पश्चिम किनारों पर घूमता है। हर निचला समन्वय एक स्रोत है , और प्रत्येक शीर्ष समन्वय एक सिंक है⌊4/3N2⌋ × ⌊4/3N2(0,0)(x,y)0 ≤ y < ⌊4/3N2⌋-1(x-1,y+1)(x,y+1)(x+1,y+1)x⌊4/3N2(x,0)(x,⌊4/3N2⌋-1)

निम्न चित्र एक 8 × 8ग्रिड दिखाता है।

एक 8x8 ग्रिड।

ग्राफ़ का प्रत्येक शीर्ष या तो निष्क्रिय है , सक्रिय है , या टूटा हुआ है । सभी कोने निष्क्रिय शुरू होते हैं, और बॉट्स द्वारा सक्रिय किया जा सकता है, जो तब उनके मालिक होंगे। इसके अलावा, बॉट्स कोने को तोड़ सकते हैं, और उनकी मरम्मत नहीं की जा सकती है।

आदेश चालू करें

एक मोड़ में विनाश चरण और सक्रियण चरण होता है । विनाश चरण में, प्रत्येक बॉट एक निष्क्रिय शीर्ष को तोड़ सकता है। तब से यह शीर्ष टूट गया है, और किसी के द्वारा सक्रिय नहीं किया जा सकता है। सक्रियण चरण में, प्रत्येक बॉट एक निष्क्रिय शीर्ष को सक्रिय कर सकता है। तब से, वे उस शीर्ष के मालिक हैं, और इसे किसी और द्वारा पुन: सक्रिय नहीं किया जा सकता है। कई बॉट्स एक ही शीर्ष के मालिक हो सकते हैं, अगर वे सभी एक ही मोड़ पर इसे सक्रिय करते हैं। प्रत्येक चरण में, शीर्ष चयन एक साथ किया जाता है।

स्कोरिंग

एक दौर बिल्कुल मोड़ के लिए रहता है। इसके बाद, इस प्रकार गोल किया जाता है। प्रत्येक सक्रिय स्रोत शीर्ष से, हम प्रदर्शन करते हैंN2N कई बार सक्रिय लंबवत के साथ एक यादृच्छिक गहराई-पहली खोज करते हैं (जिसका अर्थ है कि प्रत्येक शीर्ष के बच्चे यादृच्छिक क्रम में जाते हैं)। यदि कोई स्रोत स्रोत से किसी सिंक तक पाया जाता है, तो उस पथ के सभी कोने के लिए, शीर्ष के प्रत्येक मालिक को एक बिंदु मिलता है।

पूरा खेल 100 राउंड तक चलता है, और कुल मिलाकर सबसे अधिक अंकों के साथ बॉट विजेता है। यदि स्कोर बहुत अधिक है, तो मैं इस संख्या को बढ़ा सकता हूं।

अतिरिक्त नियम

  • नियंत्रक या अन्य प्रस्तुतियाँ के साथ कोई खिलवाड़ नहीं।
  • प्रति प्रतियोगी अधिकतम एक जमा पर।
  • कोई बाहरी संसाधन, एक निजी पाठ फ़ाइल को छोड़कर, खेल की शुरुआत में साफ मिटा दिया।
  • विशिष्ट विरोधियों को हरा या समर्थन करने के लिए अपने बॉट को डिज़ाइन न करें।
  • अपने बॉट को संकलित करने और चलाने के लिए आदेश प्रदान करें। डेबियन लिनक्स के लिए स्वतंत्र रूप से उपलब्ध कोई भी कंपाइलर / दुभाषिया स्वीकार्य है।

नियंत्रक

नियंत्रक पायथन 3 में लिखा गया है, और गिटहब में पाया जा सकता है । विस्तृत निर्देशों के लिए README फाइल देखें। आपको आरंभ करने के लिए यहां एक एपीआई है:

  • बॉट्स प्रत्येक दौर की शुरुआत में शुरू होते हैं, और राउंड के अंत तक बने रहते हैं। नियंत्रक के साथ संवाद STDIN और STDOUT के माध्यम से, newline- समाप्त संदेशों का उपयोग।
  • BEGIN [num-of-bots] [num-of-turns] [side-length] शुरुआत में इनपुट है।
  • DESTROY [turn]प्रत्येक विनाश चरण की शुरुआत में इनपुट है। आपका बॉट VERTEX x,yएक शीर्ष चुनने के लिए या तो जवाब देगा , या NONE
  • BROKEN [turn] [your-choice] [other-choices]प्रत्येक विनाश चरण के अंत में इनपुट है। अन्य बॉट्स का क्रम प्रत्येक गेम की शुरुआत में यादृच्छिक होता है, लेकिन इसके दौरान स्थिर रहता है। विकल्प के रूप में प्रस्तुत कर रहे हैं x,yयाN
  • ACTIVATE [turn]और OWNED [turn] [your-choice] [other-choices]सक्रियण चरण के लिए ऊपर के समकक्ष हैं, और एक ही शब्दार्थ है।
  • SCORE [your-score] [other-scores] खेल के अंत में इनपुट है।
  • किसी चरण के परिणामों का विश्लेषण करने और अगला शीर्ष चुनने के लिए आपके बॉट में 1 सेकंड है, और स्कोर दिए जाने के बाद छोड़ने के लिए 1 सेकंड । मैं अपने अपेक्षाकृत पुराने लैपटॉप पर सबमिशन का परीक्षण करूंगा, इसलिए यहां कुछ मार्जिन छोड़ना बेहतर है।

कृपया अपने आउटपुट बफर को फ्लश करना याद रखें।ऐसा न करने से कुछ वातावरण में नियंत्रक लटका रह सकता है।

लीडरबोर्ड

अपडेट किया गया 3/13/2015

पीसमेकर ऊपर और चल रहा है, और फ़नलवेब को एक अपडेट भी मिला। स्कोर एक परिमाण के क्रम से उछल गया। कनेक्टर दो गेम में समय सीमा को पार कर गया।

Funnelweb: 30911
Connector: 18431
Watermelon: 3488
Annoyance: 1552
Explorer: 735
Checkpoint: 720
Random Builder: 535
FaucetBot: 236
Peacemaker: 80

ASCII कला ग्राफिक्स के साथ पूर्ण लॉग कंट्रोलर के भंडार में, पाया जा सकता है graphical_log.txt

कुछ अवलोकन:

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

1
@ एलेक्स मैंने चुनौती को डिजाइन करने की कोशिश की ताकि आत्मघाती बॉट्स सब कुछ गड़बड़ न करें। तीन अच्छी तरह से डिज़ाइन किए गए बॉट हमेशा एक वैध पथ का निर्माण करने में सक्षम होने चाहिए, अगर वे एक साथ काम करते हैं।
ज़गारब

2
@Zgarb आत्महत्या इसे गड़बड़ नहीं करना चाहिए, लेकिन एक जोड़ी ट्रोल-बॉट्स एक साथ काम कर सकते हैं, जो शायद खेल को बर्बाद करते हुए सभी रास्तों को अवरुद्ध कर सकते हैं।
जियोबिट्स

2
@CarpetPython सक्रिय नोड्स को नष्ट नहीं किया जा सकता है।
जर्ग्बेल

1
ऐसा लगता है कि हम मौजूदा खिलाड़ियों और नियमों के साथ कोई दिलचस्प खेल देखने की संभावना नहीं है। मेरा सुझाव है कि आप दिलचस्प खेलों के अवसर बनाने के लिए नियमों को थोड़ा बदल दें। ग्रिड आकार को 1.5 * N ^ 2 के बजाय 2 * N ^ 2 में बदलना अच्छा होना चाहिए और मौजूदा रोबोट को बहुत अधिक भ्रमित न करें।
लॉजिक नाइट

1
@ अन्याय सच है। लॉग में खेल वास्तव में कम ग्रिड आकार के साथ खेले गए थे 4/3*N^2, और यहां तक ​​कि बॉट्स को वैध रास्ते बनाने में समस्या थी। हालांकि, कनेक्टर को एक त्रुटि के कारण अस्थायी रूप से अयोग्य घोषित कर दिया गया था, और अब जबकि यह तय हो गया है, मुझे उम्मीद है कि खेल अधिक दिलचस्प होंगे। मैं आज रात एक और बैच चलाऊंगा।
ज़र्गब

जवाबों:


7

कनेक्टर (जावा)

एक यादृच्छिक स्थिति में एक रास्ता बनाने की कोशिश करता है। क्योंकि यह अपने आप कोई रास्ता नहीं बना सकता है, यह सक्रिय कोशिकाओं को खोजता है और उनका उपयोग करता है। क्रेडिट जियोबिट्स को जाता है, जिनसे मैंने कुछ कोड चुराए हैं। इसके अलावा, यह सबमिशन अभी तक खत्म नहीं हुआ है, क्योंकि यह रास्ता बनाते ही कुछ भी करना बंद कर देता है।

संपादित करें: यदि कोई पथ बनाया गया है, तो कनेक्टर मौजूदा के साथ कई पथ बनाने का प्रयास करता है।

import java.awt.Point;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Connector {
    private static final int INACTIVE = 0;
    private static final int ACTIVE   = 1;
    private static final int BROKEN   = 2;
    private static final int MINE     = 3;

    private int size = 0;
    private int[][] grid = new int[size][size];
    private Point previousCell = null;
    private final List<Point> path = new ArrayList<>();

    public static void main(String[] args) {
        new Connector().start();
    }

    private void start() {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        while(true) {
            try {
                String input = reader.readLine();
                act(input);
            } catch (Exception e) {
                e.printStackTrace();
                System.exit(0);
            }
        }
    }

    private void act(String input) throws Exception {
        String[] msg = input.split(" ");
        String output = "";
        int turn;
        switch(msg[0]){
        case "BEGIN":
            size = Integer.parseInt(msg[3]);
            grid = new int[size][size];
            break;
        case "DESTROY":
            output = "NONE";
            break;
        case "BROKEN":
            update(msg, true);
            break;
        case "ACTIVATE":
            turn = Integer.parseInt(msg[1]);
            output = activate(turn);
            break;
        case "OWNED":
            update(msg, false);
            break;
        case "SCORE":
            System.exit(0);
            break;
        }
        if (output.length() > 0) {
            System.out.println(output);
        }
    }

    private String activate(int turn) {
        if (turn == 0) {
            Random r = new Random();
            previousCell = new Point(r.nextInt(size), 0);
            return "VERTEX " + previousCell.x + "," + 0;
        }
        Point lastCell = findLastPathCell(previousCell.x, previousCell.y);
        if (lastCell.y == size-1) {
            //path is done
            Point extendingPathPoint = findExtendingPathPoint();
            if (extendingPathPoint == null) {
                return "NONE";
            }
            return "VERTEX " + extendingPathPoint.x + "," + extendingPathPoint.y;
        } else {
            int x = findBestX(lastCell.x, lastCell.y);
            return "VERTEX " + x + "," + (lastCell.y + 1);
        }
    }

    private int findBestX(int x, int y) {
        int bestScore = Integer.MIN_VALUE;
        int bestX = 0;
        for (int i = -1; i <= 1; i++) {
            int newY = y + 1;
            int newX = (x + i + size) % size;
            int score = calcCellScore(newX, newY, 10);
            if (score > bestScore) {
                bestScore = score;
                bestX = newX;
            } else if (score == bestScore && Math.random() < 0.3) {
                bestX = newX;
            }
        }
        return bestX;
    }

    private int calcCellScore(int x, int y, int depth) {
        int newY = y + 1;
        if (depth < 0) {
            return 1;
        }
        if (newY >= size)
            return 100;
        int cellScore = 0;
        for (int i = -1; i <= 1; i++) {
            int newX = (x + i + size) % size;
            if (grid[newX][newY] == ACTIVE || grid[newX][newY] == MINE) {
                cellScore += 5;
            } else if (grid[newX][newY] == INACTIVE) {
                cellScore += 1;             
            } else {
                cellScore -= 2;
            }
            cellScore += calcCellScore(newX, newY, depth -1);
        }
        return cellScore;
    }

    private Point findLastPathCell(int x, int y) {
        Point thisCell = new Point(x,y);
        int newY = y + 1;
        if (newY >= size) {
            return thisCell;
        }
        List<Point> endCells = new ArrayList<>();
        endCells.add(thisCell);
        path.add(thisCell);
        for (int i = -1; i <= 1; i++) {
            int newX = (x + i + size) % size;
            if (grid[newX][newY] == ACTIVE || grid[newX][newY] == MINE) {
                endCells.add(findLastPathCell(newX, newY));
            }
        }
        int bestY = -1;
        Point bestPoint = null;
        for (Point p : endCells) {
            if (p.y > bestY) {
                bestY = p.y;
                bestPoint = p;
            }
        }
        return bestPoint;
    }

    private Point findExtendingPathPoint() {
        if (path.size() == 0)
            return null;
        Random rand = new Random();
        for (int i = 0; i < size; i++) {
            Point cell = path.get(rand.nextInt(path.size()));
            for (int j = -1; j <= 1; j += 2) {
                Point newCellX = new Point((cell.x + j + size) % size, cell.y);
                if (grid[newCellX.x][newCellX.y] == INACTIVE)
                    return newCellX;

                Point newCellY = new Point(cell.x, cell.y + j);
                if (cell.y < 0 || cell.y >= size)
                    continue;
                if (grid[newCellY.x][newCellY.y] == INACTIVE)
                    return newCellY;
            }
        }
        return null;
    }

    private void update(String[] args, boolean destroyPhase) {
        for(int i = 2; i < args.length; i++) {
            String[] tokens = args[i].split(",");
            if(tokens.length > 1){
                int x = Integer.parseInt(tokens[0]);
                int y = Integer.parseInt(tokens[1]);
                if (grid[x][y] == INACTIVE) {
                    if (destroyPhase) {
                        grid[x][y] = BROKEN;
                    } else if (i == 2) {
                        grid[x][y] = MINE;
                        path.add(new Point(x,y));
                        previousCell = new Point(x,y);
                    } else {
                        grid[x][y] = ACTIVE;
                    }
                }
            }
        }
    }
}

@Zgarb क्षमा करें, मैंने दूसरे को ठीक करते हुए एक बग बनाया है। अब यह काम करता है
कॉमनग्यू

@ मनु, यह अच्छा है कि तुम खेल में वापस आओ। बहुत सारे शोषक हैं और पर्याप्त बिल्डर नहीं हैं। कनेक्टर चलने के साथ, खेल और अधिक दिलचस्प बन सकते हैं (अधिक से अधिक 1 स्कोर में 100 खेल)।
लॉजिक नाइट

नवीनतम खेलों में से एक में जवाब देने के लिए कनेक्टर ने 28 सेकंड का समय लिया (लॉग देखें)। ऐसा लगता है कि यह तरबूज में भाग गया और एक कठिन समय तय कर रहा था कि आगे कहां जाना है।
ज़र्गब

मैंने कुछ गेमों को फिर से सुधारित पीसमेकर के साथ चलाया, और कनेक्टर ने एक त्रुटि फेंक दी java.lang.ArrayIndexOutOfBoundsException: -1 at Connector.findExtendingPathPoint(Connector.java:166):।
झगरब

7

फ़नलवेब, पायथन 2

संस्करण 1.2 - बेहतर ज्वाइनिंग कोड, नया एनीमेशन जोड़ा

जिसका नाम ऑस्ट्रेलिया के कम अनुकूल मकड़ियों में से एक के नाम पर रखा गया है। यह बॉट पहले शीर्ष पंक्तियों में एक फ़नल के आकार का घोंसला बनाता है, फिर अन्य बॉट्स को घोंसले के लिए ट्रैफ़िक के निर्माण के मार्ग में ले जाता है।

यहाँ 4 / 3N ^ 2 बोर्ड पर 6 बॉट गेम का एक नया एनीमेशन है जिसमें फ़नलवेब और कुछ सरल बॉट दिखाए गए हैं:

bots6.gif

फ़नलवेब का पायथन कोड:

from random import *
import sys
ME = 0
def pt(x,y): return '%u,%u' % (x % side_len, y)

while True:
    msg = raw_input().split()

    if msg[0] == 'BEGIN':
        turn = 0
        numbots, turns, side_len = map(int, msg[1:])
        R = range(side_len)
        top = side_len - 1
        grid = dict((pt(x, y), []) for x in R for y in R)
        mynodes = set()
        deadnodes = set()
        freenodes = set(grid.keys())
        mycol = choice(R)
        extra = sample([pt(x,top) for x in R], side_len)
        path = [(mycol, y) for y in range(top, top - side_len/6, -1)]
        moves = []
        fence = []
        for x,y in path:
            moves.append( [pt(x,y), pt(x+1,y), pt(x-1,y)] )
            fence.extend( [pt(x+1,y), pt(x-1,y)] )
        for dx in range(2, side_len):
            fence.extend( [pt(x+dx,y), pt(x-dx,y)] )
        for x,y in [(mycol, y) for y in 
                range(top - side_len/6, top - 3*side_len/4, -1)]:
            moves.append( [pt(x,y), pt(x+1,y), pt(x-1,y)] )

    elif msg[0] == 'DESTROY':
        target = 'NONE'
        while fence:
            loc = fence.pop(0)
            if loc in freenodes:
                target = 'VERTEX ' + loc
                break
        print target
        sys.stdout.flush()

    elif msg[0] == 'BROKEN':
        for rid, loc in enumerate(msg[2:]):
            if loc != 'N':
                grid[loc] = None
                deadnodes.add(loc)
                freenodes.discard(loc)
                if loc in extra: extra.remove(loc)

    elif msg[0] == 'ACTIVATE':
        target = 'NONE'
        while moves:
            loclist = moves.pop(0)
            goodlocs = [loc for loc in loclist if loc in freenodes]
            if goodlocs:
                target = 'VERTEX ' + goodlocs[0]
                break
        if target == 'NONE':
            if extra:
                target = 'VERTEX ' + extra.pop(0)
            else:
                target = 'VERTEX ' + pt(choice(R), choice(R))
        print target
        sys.stdout.flush()

    elif msg[0] == 'OWNED':
        for rid, loc in enumerate(msg[2:]):
            if loc != 'N':
                grid[loc].append(rid)
                if rid == ME:
                    mynodes.add(loc)
                freenodes.discard(loc)
                if loc in extra: extra.remove(loc)
        turn += 1

    elif msg[0] == 'SCORE':
        break

मकड़ी के साथ चलाया जाता है python funnelweb.py


एल्गोरिथ्म को बदल दिया और इसका परीक्षण किया। इसे अब चलना चाहिए।
लॉज नाइट

अब बहुत अच्छा काम करता है!
जर्गबेल

6

चौकी, जावा

यह बॉट चौकियों को बनाने की कोशिश करता है ताकि कोई भी वैध रास्ता मेरे एक कोने से होकर गुजरे। चूँकि N 2 मोड़ हैं और बोर्ड 2N 2 के पार है, मैं हर नोड को एक क्षैतिज रेखा पर सक्रिय कर सकता / तोड़ सकता हूँ (यह मानते हुए कि मैं पहले वहाँ हूँ)। एक वैकल्पिक पैटर्न में ऐसा करें ( xटूट गया है, oमेरा है):

xoxoxoxoxoxox...

यदि आप एक रास्ता बनाना चाहते हैं, तो आपको मेरी चौकियों से गुजरना होगा :)

अब, ऐसे कई मुद्दे हैं जिनका सामना करना पड़ सकता है। सबसे पहले, यह बहुत अच्छा नहीं करने जा रहा है जब तक कि कई रास्ते नहीं हैं। चूंकि वह खुद कोई उत्पादक रास्ता नहीं बनाता है , वह वास्तव में कुछ प्रतियोगियों होने के कारण पूरी तरह से निर्भर है। यहां तक ​​कि एक एकल पथ बनाने के लिए संयोजन करने वाले युगल प्रतियोगियों को बहुत मदद नहीं मिलेगी, क्योंकि वह केवल प्रत्येक पथ के लिए एक स्थान प्राप्त करता है। उसे चमकने के लिए जो कुछ चाहिए वह शायद कुछ बॉट्स हैं जो कुछ अलग रास्ते बनाते हैं। फिर भी, यह बहुत अधिक स्कोर नहीं कर सकता है , लेकिन यह एक विचार था जो मैंने चैट में किया था, इसलिए ...

यदि लाइन में से कोई एक स्थान पहले से ही अवरुद्ध / दावा किया गया है, तो मैं बस पास के स्थान की तलाश करता हूं जिसका उपयोग कर सकता हूं (अधिमानतः एक ही xलाइन पर, केवल लंबवत स्थानांतरित किया गया)।


import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Checkpoint {
    public static void main(String[] args) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        while(true)
            try {
                String input = reader.readLine();
                act(input);
            } catch (Exception e) {
                e.printStackTrace();
                System.exit(0);
            }
    }

    static void act(String input) throws Exception{
        String[] msg = input.split(" ");
        String output = "";
        int turn;
        boolean found = false;
        switch(msg[0]){
        case "BEGIN":
            size = Integer.parseInt(msg[3]);
            grid = new int[size][size];
            target = size/2;
            break;
        case "DESTROY":
            turn = Integer.parseInt(msg[1]);
            for(int x=0;x<size;x+=2)
                for(int y=0;y<size&&!found;y++)
                    if(grid[(x+turn*2)%size][(y+target)%size]==INACTIVE){
                        output = "VERTEX " + ((x+turn*2)%size) + "," + ((y+target)%size);
                        found = true;
                    }
            if(output.length() < 1)
                output = "NONE";
            break;
        case "BROKEN":
            for(int i=2;i<msg.length;i++){
                String[] tokens = msg[i].split(",");
                if(tokens.length>1){
                    int x = Integer.parseInt(tokens[0]);
                    int y = Integer.parseInt(tokens[1]);                    
                    if(grid[x][y]==INACTIVE)
                        grid[x][y] = BROKEN;
                }
            }
            break;
        case "ACTIVATE":
            turn = Integer.parseInt(msg[1]);
            for(int x=1;x<size;x+=2)
                for(int y=0;y<size&&!found;y++)
                    if(grid[(x+turn*2)%size][(y+target)%size]==INACTIVE){
                        output = "VERTEX " + ((x+turn*2)%size) + "," + ((y+target)%size);
                        found = true;
                    }
            if(output.length() < 1)
                output = "NONE";
            break;
        case "OWNED":
            for(int i=2;i<msg.length;i++){
                String[] tokens = msg[i].split(",");
                if(tokens.length>1){
                    int x = Integer.parseInt(tokens[0]);
                    int y = Integer.parseInt(tokens[1]);
                    if(i==2){
                        if(grid[x][y]==INACTIVE)
                            grid[x][y] = MINE;
                    }else{
                        if(grid[x][y]==INACTIVE)
                            grid[x][y]=ACTIVE;
                    }
                }
            }
            break;
        case "SCORE":
            System.exit(0);
            break;
        }
        if(output.length()>0)
            System.out.println(output);
    }

    static int size = 2;
    static int target = size/2;
    static int[][] grid = new int[size][size];

    static final int INACTIVE = 0;
    static final int ACTIVE   = 1;
    static final int BROKEN   = 2;
    static final int MINE     = 3;
}

संकलन करने के लिए, यह है javac Checkpoint.java। चलाने के लिए, java Checkpoint। आप जहाँ कहीं भी हैं, उसे प्रतिबिंबित करने के लिए पथ जोड़ना / बदलना चाहते हैं।


5

तरबूज, जावा

ग्रिड पर तरबूज खींचने का प्रयास।

import java.awt.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class Watermelon {

    private static int numberOfBots;
    private static int numberOfTurns;
    private static int sideLength;

    private static int turn = 0;

    private static int[][] theGrid;

    private static final int INACTIVE = -2;
    private static final int BROKEN   = -1;
    private static final int MINE     =  0;
    private static final int ACTIVE   =  1;

    private static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    private static PrintStream out = System.out;

    public static void main(String[] args) throws IOException {
        while (true){
            String[] input = in.readLine().trim().split(" ");
            String instruction = input[0];
            switch (instruction){
                case "BEGIN":
                    begin(input);
                    break;
                case "DESTROY":
                    destroy(input);
                    break;
                case "BROKEN":
                    broken(input);
                    break;
                case "ACTIVATE":
                    activate(input);
                    break;
                case "OWNED":
                    owned(input);
                    break;
                default:
                    return;
            }
            out.flush();
        }
    }

    private static void begin(String[] input) {
        numberOfBots = Integer.parseInt(input[1]);
        numberOfTurns = Integer.parseInt(input[2]);
        sideLength = Integer.parseInt(input[3]);
        theGrid = new int[sideLength][sideLength];
        for (int x = 0; x < sideLength; x++){
            for (int y = 0; y < sideLength; y++){
                theGrid[x][y] = INACTIVE;
            }
        }
    }

    private static void owned(String[] input) {
        turn = Integer.parseInt(input[1]);
        for (int i = input.length - 1; i >= 2; i--){
            if (input[i].equals("N")){
                continue;
            }
            String[] coordinates = input[i].split(",");
            int x = Integer.parseInt(coordinates[0]);
            int y = Integer.parseInt(coordinates[1]);
            int player = i - 2;
            if (player == 0){
                theGrid[x][y] = MINE;
            } else {
                theGrid[x][y] = ACTIVE;
            }
        }
    }

    private static void activate(String[] input) {
        turn = Integer.parseInt(input[1]);
        double[][] values = new double[sideLength][sideLength];
        List<Point> pointList = new ArrayList<>();
        for (int x = 0; x < sideLength; x++){
            for (int y = 0; y < sideLength; y++){
                if (theGrid[x][y] == MINE || theGrid[x][y] == ACTIVE){
                    for (int x1 = 0; x1 < sideLength; x1++){
                        for (int y1 = 0; y1 < sideLength; y1++){
                            double distance = Math.pow(x - x1, 2) + Math.pow(y - y1, 2);
                            values[x1][y1] += 1 / (distance + 1);
                        }
                    }
                }
                pointList.add(new Point(x, y));
            }
        }
        pointList.sort(Comparator.comparingDouble((Point a) -> values[a.x][a.y]).reversed());
        for (Point point : pointList){
            if (theGrid[point.x][point.y] == INACTIVE){
                out.println("VERTEX " + point.x + "," + point.y);
                return;
            }
        }
        out.println("NONE");
    }

    private static void broken(String[] input) {
        turn = Integer.parseInt(input[1]);
        for (int i = 2; i < input.length; i++){
            if (input[i].equals("N")){
                continue;
            }
            String[] coordinates = input[i].split(",");
            int x = Integer.parseInt(coordinates[0]);
            int y = Integer.parseInt(coordinates[1]);
            theGrid[x][y] = BROKEN;
        }
    }

    private static void destroy(String[] input) {
        turn = Integer.parseInt(input[1]);
        double[][] values = new double[sideLength][sideLength];
        List<Point> pointList = new ArrayList<>();
        for (int x = 0; x < sideLength; x++){
            for (int y = 0; y < sideLength; y++){
                if (theGrid[x][y] == MINE){
                    for (int x1 = 0; x1 < sideLength; x1++){
                        for (int y1 = 0; y1 < sideLength; y1++){
                            double distance = Math.pow(x - x1, 2) + Math.pow(y - y1, 2);
                            values[x1][y1] -= 1 / (distance + 1);
                        }
                    }
                }
                if (theGrid[x][y] == ACTIVE){
                    for (int x1 = 0; x1 < sideLength; x1++){
                        for (int y1 = 0; y1 < sideLength; y1++){
                            double distance = Math.pow(x - x1, 2) + Math.pow(y - y1, 2);
                            values[x1][y1] += 1 / (distance + 1) / (numberOfBots - 1);
                        }
                    }
                }
                pointList.add(new Point(x, y));
            }
        }
        pointList.sort(Comparator.comparingDouble((Point a) -> values[a.x][a.y]).reversed());
        for (Point point : pointList){
            if (theGrid[point.x][point.y] == INACTIVE){
                out.println("VERTEX " + point.x + "," + point.y);
                return;
            }
        }
        out.println("NONE");
    }
}

5

नल (आर में)

दूसरी पंक्ति पर एक अड़चन बनाता है, और इसके पीछे के मार्ग पर नोड्स को सक्रिय करता है।

infile <- file("stdin")
open(infile)
repeat{
    input <- readLines(infile,1)
    args <- strsplit(input," ")[[1]]
    if(args[1]=="BEGIN"){
        L <- as.integer(args[4])
        M <- N <- matrix(0,nrow=L,ncol=L)
        x0 <- sample(2:(L-1),1)
        }
    if(args[1]=="DESTROY"){
        if(args[2]==0){
            X <- x0
            Y <- 2
            }else{
                free <- which(M[,2] == 0)
                mine <- which(N[,2] == 1)
                X <- free[which.min(abs(free-mine))]
                Y <- 2
                }
        if(length(X)){cat(sprintf("VERTEX %s,%s\n",X-1,Y-1))}else{cat("NONE\n")}
        flush(stdout())
        }
    if(args[1]=="BROKEN"){
        b <- strsplit(args[args!="N"][-(1:2)],",")
        o <- strsplit(args[3],",")[[1]]
        b <- lapply(b,as.integer)
        if(o[1]!="N") N[as.integer(o[1])+1,as.integer(o[2])+1] <- -1
        for(i in seq_along(b)){M[b[[i]][1]+1,b[[i]][2]+1] <- -1}
        }
    if(args[1]=="ACTIVATE"){
        if(args[2]==0){
            broken <- which(M[,2] == -1)
            free <- which(M[,2] == 0)
            X <- free[which.min(abs(broken-free))]
            Y <- 2
            }else{
                y <- 3
                X <- NULL
                while(length(X)<1){
                    lastrow <- which(N[,y-1]==1)
                    newrow <- unlist(sapply(lastrow,function(x)which(M[,y]==0 & abs((1:L)-x)<2)))
                    if(length(newrow)){
                        X <- sample(newrow,1)
                        Y <- y
                        }
                    y <- y+1
                    if(y>L){X <- x0; Y <- 1}
                    }
                }
        cat(sprintf("VERTEX %s,%s\n",X-1,Y-1))
        flush(stdout())
        }
    if(args[1]=="OWNED"){
        b <- strsplit(args[args!="N"][-(1:2)],",")
        o <- strsplit(args[3],",")[[1]]
        b <- lapply(b,as.integer)
        if(o[1]!="N") N[as.integer(o[1])+1,as.integer(o[2])+1] <- 1
        for(i in seq_along(b)){M[b[[i]][1]+1,b[[i]][2]+1] <- 1}
        }
    if(args[1]=="SCORE") q(save="no")
    }

अगर मैं खराब नहीं हुआ, तो अंतिम कॉन्फ़िगरेशन कुछ इस तरह होना चाहिए:

........    .a..aa..
..aaa...    ..aaa...
.xxaxx..    xxxaxxx.    etc.
........    ........

आज्ञा है Rscript FaucetBot.R


5

शांतिदूत, जावा

मनु के कोड के आधार पर।

पीसमेकर खोज संघर्ष क्षेत्र (यानी सबसे अधिक या सक्रिय शीर्ष एकाग्रता) और पास में एक यादृच्छिक शीर्ष सक्रिय करता है।

import java.awt.Point;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.stream.IntStream;

public class Peacemaker {
    private static final int INACTIVE = 0;
    private static final int ACTIVE   = 1;
    private static final int BROKEN   = 2;
    private static final int MINE     = 3;

    private int size = 0;
    private int[][] grid = new int[size][size];
    private int startingPoint = 0;

    public static void main(String[] args) {
        new Peacemaker().start();
    }

    private void start() {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        while(true) {
            try {
                String input = reader.readLine();
                act(input);
            } catch (Exception e) {
                e.printStackTrace();
                System.exit(0);
            }
        }
    }

    private void act(String input) throws Exception {
        String[] msg = input.split(" ");
        String output = "";
        int turn;
        switch(msg[0]){
        case "BEGIN":
            size = Integer.parseInt(msg[3]);
            grid = new int[size][size];
            break;
        case "DESTROY":
            output = "NONE";
            break;
        case "BROKEN":
            update(msg, true);
            break;
        case "ACTIVATE":
            turn = Integer.parseInt(msg[1]);
            output = activate(turn);
            break;
        case "OWNED":
            update(msg, false);
            break;
        case "SCORE":
            System.exit(0);
            break;
        }
        if (output.length() > 0) {
            System.out.println(output);
        }
    }

    private String activate(int turn) {
        Random r = new Random();
        if (turn == 0) {
            startingPoint = r.nextInt(size);
            return "VERTEX " + startingPoint + "," + 0;
        } else {

            Point point = searchConflicts();

            int posX = point.x;
            int posY = point.y;

            while (grid[posX][posY] != INACTIVE) {
                 int previousX = (posX - 1 < 0 ? size - 1 : posX - 1);
                 int nextX = (posX + 1 > size - 1 ? 0 : posX + 1);
                 int previousY = (posY - 1 < 0 ? size - 1 : posY - 1);
                 int nextY = (posY + 1 > size - 1 ? 0 : posY + 1);

                 int choice = r.nextInt(4);
                 switch (choice) {
                     case 0: posX = previousX; break;
                     case 1: posX = nextX; break;
                     case 2: posY = previousY; break;
                     case 3: posY = nextY; break;
                 }
            }

            return "VERTEX " + posX + "," + posY;
        }
    }

    private Point searchConflicts() {

        int previousCellScore = 0;
        int cellX = 0;
        int cellY = 0;
        for (int i = 0; i < size; i++) {
            for (int j = 0; j < size; j ++) {
                if (previousCellScore < adjacentCellsScore(i, j)) {
                    cellX = i; cellY = j;
                    previousCellScore = adjacentCellsScore(i, j);
                }
            }
        }
        return new Point(cellX, cellY);
    }

    /*  Format of adjacent cells :
     * 
     *   0 1 2
     *   3 . 4
     *   5 6 7
     */
    private int adjacentCellsScore(int x, int y) {

        int[] scores = new int[8];

        int previousX = (x - 1 < 0 ? size - 1 : x - 1);
        int nextX = (x + 1 > size - 1 ? 0 : x + 1);
        int previousY = (y - 1 < 0 ? size - 1 : y - 1);
        int nextY = (y + 1 > size - 1 ? 0 : y + 1);

        scores[0] = calcScore(previousX, nextY);
        scores[1] = calcScore(x, nextY);
        scores[2] = calcScore(nextX, nextY);
        scores[3] = calcScore(previousX, y);
        scores[4] = calcScore(nextX, y);
        scores[5] = calcScore(previousX, previousY);
        scores[6] = calcScore(x, previousY);
        scores[7] = calcScore(nextX, previousY);

        return IntStream.of(scores).reduce(0, (a, b) -> a + b);
    }

    private int calcScore(int x, int y) {
        int activeScore = 2;
        int mineScore = 1;
        int inactiveScore = 0;
        int brokenScore = 3;

        if (grid[x][y] == ACTIVE) 
            return activeScore;
        else if (grid[x][y] == MINE)
            return mineScore;
        else if (grid[x][y] == INACTIVE) 
            return inactiveScore;
        else if (grid[x][y] == BROKEN) 
            return brokenScore;
        else
            return 0;
    }


    private void update(String[] args, boolean destroyPhase) {
        for(int i = 2; i < args.length; i++) {
            String[] tokens = args[i].split(",");
            if(tokens.length > 1){
                int x = Integer.parseInt(tokens[0]);
                int y = Integer.parseInt(tokens[1]);
                if (grid[x][y] == INACTIVE) {
                    if (destroyPhase) {
                        grid[x][y] = BROKEN;
                    } else if (i == 2) {
                        grid[x][y] = MINE;
                    } else {
                        grid[x][y] = ACTIVE;
                    }
                }
            }
        }
    }       
}

@Zgarb धन्यवाद, मुझे अब इस मुद्दे को हल करना चाहिए था।
थ्रक्स

पीसमेकर अब काम करता है, और लीडरबोर्ड में शामिल है। हालाँकि, यह बहुत कुछ नहीं करता है, इसलिए अभी भी कुछ कीड़े बाकी हैं।
जरगब

दरअसल, आपके कोड को देखते हुए, मुझे लगता है कि समस्या विधि के whileपाश में है activate। एक बार जब आप कोई ऐसा शीर्ष खोज पाते हैं, जो आपकी नहीं है और टूटी नहीं है - तो आप खोज को रोक देते हैं, लेकिन यह किसी और के स्वामित्व में हो सकती है, इसलिए आप इसे सक्रिय नहीं कर सकते।
ज़र्गब

@Zgarb मैंने ऐनक को गलत बताया और सोचा कि कई खिलाड़ी एक ही शीर्ष को कभी भी सक्रिय कर सकते हैं। मुझे लगता है कि मुझे केवल अपनी खोज को बदलना होगा और केवल निष्क्रिय शीर्ष की तलाश करनी होगी।
थ्रक्स

2

रैंडम बिल्डर, पायथन 3

यह एक मूर्खतापूर्ण उदाहरण बॉट है जो कभी भी कुछ भी नष्ट नहीं करता है, और हर मोड़ पर एक यादृच्छिक शीर्ष को सक्रिय करने की कोशिश करता है। ध्यान दें कि यह जाँचने की आवश्यकता नहीं है कि क्या शीर्ष निष्क्रिय है; नियंत्रक इसका ख्याल रखता है।

import random as r

while True:
    msg = input().split()
    if msg[0] == "BEGIN":
        side_len = int(msg[3])
    elif msg[0] == "DESTROY":
        print("NONE")
    elif msg[0] == "ACTIVATE":
        print("VERTEX %d,%d"%(r.randrange(side_len), r.randrange(side_len)), flush=True)
    elif msg[0] == "SCORE":
        break

कमान के साथ भागो

python3 random_builder.py

आप बदलना पड़ सकता है python3द्वारा pythonअपने अजगर स्थापना पर निर्भर करता है। ऐसा करने के लिए, बस bots.txtफ़ाइल को संपादित करें । मैंने नियंत्रक को अपडेट किया, और अब फ़ाइल पथों के साथ गड़बड़ करने की कोई आवश्यकता नहीं है।


अपने अजगर 3 का उपयोग करने के बाद से, sys.stdout.flush()आप के बजाय सिर्फ flush=Trueएक तर्क के रूप में कर सकते हैं print
मैटजॉयज

@matsjoyce धन्यवाद, मुझे नहीं पता था कि। मैं बाद में रिपॉजिटरी संस्करण को संपादित करूँगा।
जरगब

2

एक्सप्लोरर, पायथन 3

सक्रियण रणनीति:

प्रत्येक नोड (सक्रिय / निष्क्रिय / टूटी हुई) की स्थिति के आधार पर एक हीटमैप बनाता है और उस नोड को चुनता है जो प्रति व्यक्ति सबसे बड़ी अपेक्षित हीटमैप-मूल्य होगा यदि यह उस एक को चुनता है।

विनाश की रणनीति:

कभी भी कुछ भी नष्ट नहीं करता क्योंकि इससे बॉट को ज्यादा मदद नहीं मिलती है।

import sys

class bd:

    def __init__(s, l):

        s.l=l
        s.b=[]
        s.v=[]
        s.m=[]
        s.bm=[]
        s.utd=False #up_to_date
        s.bmc=1

        for i in range(s.l):
            s.b+=[[]]
            s.v+=[[]]
            s.m+=[[]]
            s.bm+=[[]]
            for k in range(s.l):
                s.b[i]+=[0]
                s.v[i]+=[0]
                s.m[i]+=[0]
                s.bm[i]+=[s.bmc]

    def update(s):
        s.utd=True

        vu=[]
        vd=[]
        for i in range(s.l):
            vu+=[[]]
            vd+=[[]]
            for k in range(s.l):
                vu[i]+=[1]
                vd[i]+=[1]

        #spread up
        for i in range(s.l):
            vu[i][0]*=s.bm[i][0]

        for k in range(1,s.l):
            for i in range(s.l):
                sumv=vu[(i-1)%s.l][k-1]+vu[(i)%s.l][k-1]+vu[(i+1)%s.l][k-1]  
                vu[i][k]*=sumv*s.bm[i][k]/3

        #spread down
        t=s.l-1
        for i in range(s.l):
            vd[i][t]*=s.bm[i][t]

        for k in range(s.l-2,-1,-1):
            for i in range(s.l):
                sumv=vd[(i-1)%s.l][k+1]+vd[(i)%s.l][k+1]+vd[(i+1)%s.l][k+1]  
                vd[i][k]*=sumv*s.bm[i][k]/3

        #mult
        for i in range(s.l):
            for k in range(s.l):
                if s.b[i][k]==-1 or s.m[i][k]==1:
                    s.v[i][k]=float(-1)
                else:
                    s.v[i][k]=vu[i][k]*vd[i][k]/(s.b[i][k]+1)

    def add_act(s,al):
        s.utd=False

        for ind, ap in enumerate(al):
            i,k=ap
            s.b[i][k]+=1            
            s.bm[i][k]=2*s.bmc            
            #doesn't work alone WHY???
            if ind==0: s.m[i][k]=1

    def add_ina(s,il):
        s.utd=False

        for ind, ip in enumerate(il):
            i,k=ip
            s.b[i][k]=-1
            s.bm[i][k]=0                    

    def get_newact(s):
        s.update()
        vm=-28
        pm=None
        for i in range(s.l):
            for k in range(s.l):
                if s.v[i][k]>vm:
                    vm=s.v[i][k]
                    pm=(i,k)
        #doesn't work alone WHY???
        s.m[pm[0]][pm[1]]=1
        return pm


b=None

while True:
    inp=input()
    msg = inp.split()
    if msg[0] == "BEGIN":        
        b = bd(int(msg[3]))
    elif msg[0] == "DESTROY":
        print("NONE")
    elif msg[0] == "BROKEN":
        pl=[]
        for m in msg[2:]:
            if m!='N':
                pl+=[tuple(map(int,m.split(',')))]
        b.add_ina(pl)
    elif msg[0] == "ACTIVATE":
        at=b.get_newact()
        print("VERTEX %d,%d"%(at[0], at[1]))
    elif msg[0] == "OWNED":
        pl=[]
        for m in msg[2:]:
            if m!='N':
                pl+=[tuple(map(int,m.split(',')))]        
        b.add_act(pl)
    elif msg[0] == "SCORE":
        break       

    sys.stdout.flush()

1

वार्षिकी, बैश

#!/bin/bash

declare -A avail
broken=
owned=

while read c p
    case "$c" in
        ACTIVATE|BROKEN) v=broken;;
        *) v=owned
    esac
    case "$c" in
        BEGIN)
            read b t n <<<"$p"
            list=$(
                eval "echo {0..$((n-1))},{0..$((n-1))}\$'\\n'" |
                shuf
            )
            for i in $list; do
                avail[$i]=1
            done;;
        DESTROY|ACTIVATE)
            for t in $(
                for i in ${!v}; do
                    [ "$i" != N ] &&
                    if [ "$c" = ACTIVATE ]; then
                        echo $(((${i%,*}+2)%n)),${i#*,}
                        echo $(((${i%,*}-2+n)%n)),${i#*,}
                    else
                        echo ${i%,*},$(((${i#*,}+1)%n))
                        echo ${i%,*},$(((${i#*,}-1+n)%n))
                    fi
                done |
                shuf
            ) $list; do
                [ "${avail[$t]}" ] && echo VERTEX $t && break
            done ||
            echo NONE;;
        BROKEN|OWNED)
            read x m $v <<<"$p";
            for i in $m ${!v}; do
                unset avail[$i]
            done;;
        SCORE)! :
    esac
do :;done

परिणाम को और अधिक रोचक बनाने की कोशिश की।

साथ चलाना bash annoyance.sh


1
आपका बॉट STDERR को अपने सभी इनपुट प्रिंट करता है। यह निषिद्ध या कुछ भी नहीं है, बस एक झुंझलाहट (सजा का इरादा)।
जर्ग्बेल

@Zgarb क्षमा करें, मैंने गलत संस्करण चिपकाया है। फिक्स्ड।
jimmy23013

1

मिडिल मैन

मैंने देखा कि कुछ बॉट्स ऊपर से बने हैं, और कुछ नीचे से। यह बीच में शुरू करने और ऊपर और नीचे काम करने वाला पहला (मुझे लगता है) है।

(यह नियंत्रक के साथ परीक्षण नहीं किया गया है, इसलिए यदि यह खुराक काम नहीं करती है, तो मुझे बताएं।)

class Node

  def self.set_size s
    @@grid = Array.new(s,Array.new(s,0))
  end

  def initialize x,y
    @x=x
    @y=y
  end

  def offset dx,dy
    return Node.new @x+dx,@y+dy
  end

  def state
    return -1 if @x<0 || @y<0 || @x>=@@grid.length || @y>=@@grid.length
    @@grid[@x][@y]
  end

  def state= n
    return -1 if @x<0 || @y<0 || @x>=@@grid.length || @y>=@@grid.length
     @@grid[@x][@y]=n
  end

  def active?
    state > 0
  end

  def open?
    state == 0
  end
  attr_reader :x,:y

  def to_s
    "VERTEX #{@x},#{@y}"
  end


  def scan_down
    ans = nil
    [0,-1,1].each do|offset|
      n = Node.new @x+offset,@y-1
      ans = (ans||n) if n.open?
      ans = (n.scan_down||ans) if n.active?
    end
    return ans
  end

  def scan_up
    ans = nil
    [0,-1,1].each do|offset|
      n = Node.new @x+offset,@y+1
      ans = (ans||n) if n.open?
      ans = (n.scan_up||ans) if n.active?
    end
    return ans
  end

end

input = gets.split
input.shift

BotCount = input.shift.to_i
Turns = input.shift.to_i
GridSize = input.shift.to_i

Node.set_size GridSize

midRow = GridSize/2

toDestroy = (0...GridSize).map{|i|Node.new i,midRow}
toDestroy.reject!{|n| n.x==midRow}

chain = []
Turns.times do
  gets;
  toDestroy.each{|x|
    if x.active?
      toDestroy.push x.offset 0,1
      toDestroy.push x.offset 1,1
      toDestroy.push x.offset -1,1
    end
  }
  toDestroy.reject!{|x|!x.open?}
  puts toDestroy.sample
  input = gets.split
  input.shift;input.shift
  input.each{|str|
    a,b = str.split ','
    (Node.new a.to_i,b.to_i).state=1
  }
  gets;

  if chain.length == 0
    n = Node.new midRow,midRow
    until n.open?
      n = Node.new n.x+1,midRow
    end
    puts chain[0]=n
  elsif rand>0.5
    n=nil
    loop do
      h=chain[0]
      n = h.scan_down
     break if !n
      chain.shift
    end
    h.unshift n
    puts n
  else
    loop do
      h=chain[-1]
      n = h.scan_up
      h.pop if !n
      brake if n
    end
    chain.push n
    puts n
  end

  input = gets.split
  input.shift;input.shift
  input.each{|str|
    a,b = str.split ','
    (Node.new a,b).state=-1
  }

end
gets
exit

प्रस्तुत करने के लिए धन्यवाद! दुर्भाग्य से, यह चुनौती लगभग आधे साल से निष्क्रिय है, और मैं वर्तमान में अधिकांश बॉट्स चलाने में असमर्थ हूं, क्योंकि मेरे पास एक कंप्यूटर तक पहुंच नहीं है जहां मैं भाषाओं को स्थापित कर सकता हूं।
जर्गब

1
@Zbb मैं समझता हूँ। शायद किसी दिन मैं उचित समय सीमा में एक चुनौती का जवाब दूंगा ...
मेगाटॉम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.