গ্রিড-রাউটিং যুদ্ধ


22

দ্রষ্টব্য: এই চ্যালেঞ্জটি বর্তমানে মারা গেছে, কারণ আমি কোনও ম্যাচ চালানোর জন্য প্রয়োজনীয় ভাষাগুলি ইনস্টল করতে অক্ষম। যদি অন্য কারও কাছে এটি করার সময় এবং আগ্রহ থাকে তবে আমি বিরোধী নই।

লিডারবোর্ডের জন্য পোস্টের নীচে দেখুন।

এটি হিল চ্যালেঞ্জের একটি আধা-সমবায় রাজা, যেখানে বটগুলি দ্বিমাত্রিক গ্রিড গ্রাফের মাধ্যমে পথ তৈরি করে। যে বটটি সর্বাধিক ট্র্যাফিকের সাথে নোডগুলি নিয়ন্ত্রণ করে সে বিজয়ী। তবে এটি সংযোগের পথটি তৈরি করতে একাধিক বটের সংস্থান গ্রহণ করে, সুতরাং বটগুলি একসাথে কাজ করতে হবে - কিছুটা হলেও।

গেমপ্লের

নীচে, N > 0খেলতে বট সংখ্যা হওয়া যাক ।

গ্রিড

খেলা আকারের একটি দ্বি-মাত্রিক পূর্ণসংখ্যা গ্রিড উপর গাওয়া হয় , যার নীচে বাঁদিকের তুল্য হয় । প্রতিটি তুল্য সঙ্গে তিন স্থানাঙ্ক থেকে বহির্গামী প্রান্ত হয়েছে , এবং উপরে, যেখানে -coordinates মডিউল নেয়া হয় । এর অর্থ গ্রিডটি পূর্ব এবং পশ্চিম প্রান্তে প্রায় আবৃত থাকে ps প্রতিটি নীচের স্থানাঙ্ক হ'ল উত্স , এবং প্রতিটি শীর্ষ স্থানাঙ্ক একটি সিঙ্ক⌊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 গ্রিড।

গ্রাফের প্রতিটি প্রান্তটি হয় নিষ্ক্রিয় , সক্রিয় বা ভাঙ্গা । সমস্ত উল্লম্ব নিষ্ক্রিয় শুরু হয়, এবং বট দ্বারা সক্রিয় করা যেতে পারে, যা পরে তাদের মালিক হবে be এছাড়াও, বটগুলি উল্লম্ব ভাঙ্গতে পারে এবং সেগুলি মেরামত করা যায় না।

টার্ন অর্ডার

একটি ঘুরিয়ে একটি ধ্বংস পর্ব এবং একটি অ্যাক্টিভেশন পর্ব থাকে । ধ্বংসের পর্যায়ে, প্রতিটি বট একটি নিষ্ক্রিয় ভার্টেক্সকে ভেঙে দিতে পারে। সেই প্রান্তটি তখন থেকেই ভেঙে গেছে এবং কারও দ্বারা সক্রিয় করা হতে পারে না। অ্যাক্টিভেশন পর্যায়ে, প্রতিটি বট একটি নিষ্ক্রিয় প্রান্তকে সক্রিয় করতে পারে। তারপরে, তারা সেই শীর্ষস্থানটির মালিক, এবং এটি অন্য কারও দ্বারা পুনরায় সক্রিয় করা যায় না। বেশিরভাগ বট একক ভার্টেক্সের মালিক হতে পারে, যদি তারা সকলে একই পালাটি সক্রিয় করে। প্রতিটি পর্যায়ে, শীর্ষস্থানীয় নির্বাচনগুলি একই সাথে সম্পন্ন হয়।

স্কোরিং

এক রাউন্ড ঠিক বাঁক জন্য স্থায়ী । এর পরে, রাউন্ডটি নীচে স্কোর করা হয়। প্রতিটি সক্রিয় উত্স ভার্টেক্স থেকে আমরা বারবার অ্যাক্টিভ শীর্ষকোষের সাথে এলোমেলোভাবে গভীরতা-প্রথম অনুসন্ধান সম্পাদন করি (অর্থাত্ প্রতিটি প্রান্তের বাচ্চারা একটি এলোমেলো ক্রমে পরিদর্শন করা হয়)। যদি উত্স থেকে কিছুটা ডুবে যাওয়ার জন্য কোনও পাথ খুঁজে পাওয়া যায়, তবে সেই পথের সমস্ত প্রান্তের জন্য, শীর্ষবিন্দুর প্রতিটি মালিক একটি পয়েন্ট পাবেন।N2N

পুরো গেমটি 100 রাউন্ডের জন্য স্থায়ী হয় এবং সামগ্রিকভাবে সর্বাধিক পয়েন্ট সহ বট বিজয়ী হয়। স্কোরের বৈকল্পিকতা খুব বেশি হলে আমি এই সংখ্যাটি বাড়িয়ে তুলতে পারি।

অতিরিক্ত বিধি

  • নিয়ামক বা অন্যান্য জমা দেওয়ার সাথে কোনও বিশৃঙ্খলা নেই।
  • প্রতিযোগী প্রতি সর্বাধিক এক জমা।
  • গেমের শুরুতে একটি ব্যক্তিগত পাঠ্য ফাইল বাদে কোনও বাহ্যিক সংস্থান পরিষ্কার করা হয়নি।
  • নির্দিষ্ট প্রতিপক্ষকে বীট বা সমর্থন করতে আপনার বট ডিজাইন করবেন না।
  • আপনার বটটি সংকলন এবং চালনার জন্য আদেশগুলি সরবরাহ করুন। ডেবিয়ান লিনাক্সের জন্য অবাধে উপলভ্য যে কোনও সংকলক / দোভাষী গ্রহণযোগ্য।

নিয়ামক

কন্ট্রোলার পাইথন 3 এ লেখা এবং এটি গিটহাবে পাওয়া যায় । বিস্তারিত নির্দেশাবলীর জন্য README ফাইলটি দেখুন। আপনাকে শুরু করতে এখানে একটি এপিআই রয়েছে:

  • প্রতিটি রাউন্ডের শুরুতে বটগুলি শুরু হয় এবং রাউন্ডের শেষ অবধি অবিরত থাকে। নিউলাইন-সমাপ্ত বার্তা ব্যবহার করে STDIN এবং STDOUT এর মাধ্যমে নিয়ামকের সাথে যোগাযোগ।
  • 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

এএসসিআইআই আর্ট গ্রাফিক্সের সাথে সম্পূর্ণ লগটি নিয়ামকের সংগ্রহস্থলটিতে পাওয়া যাবে graphical_log.txt

কিছু পর্যবেক্ষণ:

  • এর সামনে একটি একক প্রান্তটি ভেঙে খুব সহজেই সংযোগকারী থামানো যেতে পারে। আমার সন্দেহ হয় বিরক্তি প্রায়শই এটি করে। যাইহোক, এটি বর্তমানে সামান্য অর্থবোধ করে কারণ কেবল সংযোজক কল্পনা করেই কোনও পথ তৈরি করতে পারে।
  • সংযোগ পথে চলার কারণেই তরমুজ একটি শালীন স্কোর অর্জন করতে পারে (যেহেতু ডিএফএস এর শীর্ষাংশগুলি খুব সম্ভবত ব্যবহার করে)।
  • এক্সপ্লোরার তরমুজ থেকে লতা বাড়তে পছন্দ করে।
  • সংযুক্তকারী সাধারণত গ্রিডের নীচের অর্ধেক অংশে এটি ল্যাচ করায় আপডেট হওয়া ফানেলওয়েব সত্যিই ভাল স্কোর পায়।
  • গেমগুলি বেশ দীর্ঘ হচ্ছে, আমার মেশিনে গড়ে প্রায় 25 সেকেন্ড সময় লাগে।

1
@ অ্যালেক্স আমি চ্যালেঞ্জটি ডিজাইনের চেষ্টা করেছি যাতে আত্মঘাতী বটগুলি সবকিছু বিঘ্নিত না করে। তিনটি ভাল নকশিত বট সর্বদা একটি বৈধ পথ তৈরি করতে সক্ষম হবে, যদি তারা একসাথে কাজ করে।
Zgarb

2
@ জাগারব আত্মহত্যার বিষয়টি অবহেলা করা উচিত নয়, তবে একসঙ্গে কাজ করা দু'জন ট্রল-বট সম্ভবত সমস্ত পথ অবরুদ্ধ করে, খেলাটি নষ্ট করে দিতে পারে।
জিওবিটস

2
@ কার্পেট পাইথন অ্যাক্টিভ নোডগুলি ধ্বংস করা যাবে না।
Zgarb

1
দেখে মনে হচ্ছে আমরা বর্তমান খেলোয়াড় এবং নিয়মগুলির সাথে কোনও আকর্ষণীয় গেম দেখার সম্ভাবনা নেই। আমি আপনাকে পরামর্শ দিচ্ছি যে আকর্ষণীয় গেমসের সুযোগ তৈরি করতে আপনি নিয়মগুলি কিছুটা পরিবর্তন করুন। গ্রিডের আকার 2 * N ^ 2 এর পরিবর্তে 1.5 * 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;
                    }
                }
            }
        }
    }
}

@ জগারব দুঃখিত, অন্যটি ঠিক করার সময় আমি একটি বাগ তৈরি করেছি। এটি এখন কাজ করে
কমনগ্যুই

@ মনু, আপনি খেলায় ফিরে এসেছেন এটা ভাল। অনেকগুলি শোষণকারী এবং যথেষ্ট বিল্ডার নেই not সংযোগকারী চলার সাথে সাথে, গেমগুলি আরও আকর্ষণীয় হয়ে উঠতে পারে (স্কোর সহ 100 এ 1 গেম)।
লজিক নাইট

সংযোগকারীটি সর্বশেষতম গেমগুলির মধ্যে একটিতে সাড়া দিতে 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


অ্যালগরিদম পরিবর্তন করে এটি পরীক্ষা করা হয়েছে। এটি এখন চালানো উচিত।
লজিক নাইট 19

এখন দুর্দান্ত কাজ!
জাগারব

6

চেকপয়েন্ট, জাভা

এই বটটি চেকপয়েন্টগুলি তৈরি করার চেষ্টা করে যাতে কোনও বৈধ পথ আমার এক শীর্ষে প্রবেশ করে। এন আছে যেহেতু 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;
                    }
                }
            }
        }
    }       
}

@ জগারব ধন্যবাদ, আমার এখনই এই সমস্যাটি সমাধান করা উচিত ছিল।
থ্রাক্স

পিস মেকার এখন কাজ করে, এবং লিডারবোর্ডে অন্তর্ভুক্ত রয়েছে। তবে এটি খুব বেশি কিছু করবে বলে মনে হচ্ছে না, তাই সম্ভবত এখনও কিছু বাগ বাকি রয়েছে।
জাগারব

আসলে, আপনার কোডটি দেখে আমি মনে করি সমস্যাটি পদ্ধতিটির whileলুপে রয়েছে activate। আপনি একবার অনুসন্ধানটি থামিয়েছেন যা আপনার নয় এবং ভাঙ্গা নয় এমন একটি প্রান্তকে খুঁজে পান - তবে এটি অন্য কারও মালিকানাধীন হতে পারে, তাই আপনি এটি সক্রিয় করতে পারবেন না।
জাগারব

@ জাগারব আমি চশমাগুলি ভুলভাবে পড়েছি এবং ভেবেছিলাম যে একাধিক খেলোয়াড় যে কোনও সময় একই ভার্টেক্স সক্রিয় করতে পারে। আমি অনুমান করি যে আমাকে কেবল আমার সন্ধানটি পরিবর্তন করতে হবে এবং কেবল নিষ্ক্রিয় ভার্টেক্স অনুসন্ধান করতে হবে।
থ্রাক্স

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
মাতসয়জাই

@ মজাদার ধন্যবাদ, আমি এটি জানতাম না। আমি পরে সংগ্রহস্থল সংস্করণ সম্পাদনা করব।
জাগারব

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 এ মুদ্রণ করে। এটি নিষিদ্ধ বা কিছু নয়, কেবল একটি বিরক্তি (শঙ্কিত উদ্দেশ্য)।
জাগারব

@ জগারব দুঃখিত, আমি ভুল সংস্করণটি পেস্ট করেছি। সংশোধন করা হয়েছে।
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
@ জাগারব আমি বুঝতে পারি হতে পারে কোনও দিন আমি একটি চ্যালেঞ্জকে যুক্তিসঙ্গত সময়সীমার জবাব দেব ...
মেগাটম
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.