প্রাচীরের রাজা


10

বিজ্ঞপ্তি

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

এই চ্যালেঞ্জটির লক্ষ্য হ'ল প্রতিপক্ষকে অবরুদ্ধ করার জন্য 25x25 গ্রিডে কৌশলগতভাবে একটি প্রাচীর অঙ্কন করে অন্য একটি এআইয়ের বিরুদ্ধে লড়াইয়ে জয়লাভ করা এআইকে তৈরি করা।

ইনপুট

25 লাইন পৃথক করে এবং ;কমান্ড-লাইন আর্গুমেন্ট হিসাবে শেষ হয় । এর মধ্যে অন্তর্ভুক্ত থাকবে:

  • খালি স্পেস .
  • দেয়াল #
  • খেলোয়াড় 1এবং 2(প্রতিপক্ষ সর্বদা থাকে 2)

উদাহরণ

###############..........;..............#..........;..............#..........;..............#..........;..............#..........;...........1###..........;.........................;.........................;.........................;.........................;.........................;.........................;.........................;.........................;.........................;.........................;.........................;.........................;.........................;...................###...;...................#.##..;2..................#..#..;#..................##.#..;#...................#.###;....................#####;

যা নিম্নলিখিত মানচিত্রের প্রতিনিধিত্ব করে:

###############..........
..............#..........
..............#..........
..............#..........
..............#..........
...........1###..........
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
...................###...
...................#.##..
2..................#..#..
#..................##.#..
#...................#.###
....................#####

আউটপুট

কনসোলটিতে লেখা একটি স্ট্রিং, এআইটি যে দিকে ঘুরতে চায় তার প্রতিনিধিত্ব করে অক্ষর দিয়ে শুরু হবে। এই হল কেস সংবেদনশীল!

  • উত্তর N
  • পূর্ব E
  • দক্ষিণ S
  • পশ্চিম W
  • ছেড়ে দিন (অন্য কিছু)

উদাহরণ

W

খেলার নিয়ম

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

র্যাঙ্কিং

1 ম স্থান - ফ্লাডবট (জাভা, 12 টি জয়)

২ য় স্থান - ফ্লুইডবট (পাইথন, 9 টি জয়)

তৃতীয় স্থান - ফিলআপ আপ (সি ++, 8 টি জয়)

চতুর্থ স্থান - অ্যাওবট (রুবি, 5 জয়)

5 ম স্থান - আরকবোট (পাইথন, 4 টি জয়)

6th ষ্ঠ স্থান - ব্লাইন্ডস্পেক (ব্যাচ, ২ টি জয়)

6th ষ্ঠ স্থান - র‌্যান্ডমবট (সি #, 2 জয়)

নিয়ন্ত্রণ প্রোগ্রাম (পাইথন ৩.৩.৩ এর জন্য পরীক্ষিত)

প্রোগ্রামটি দুটি কমান্ডের আর্গুমেন্ট এবং একটি একক যুক্তির ( ""যদি প্রয়োজন না হয়) এআই সহ উদাহরণস্বরূপ পরিচালিত হয় যেমন। Control.py "ruby" "AwayBot.rb" "FillUpBot.exe" ""। এটি এখানে ডাউনলোড করা যায়

import sys, subprocess

Program1, Argument1, Program2, Argument2, Player1, Player2, Grid = sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], [0, 0], [24, 24], [['.' for y in range(25)] for x in range(25)]
while True:
    Str  = ''
    for x in range(25):
        for y in range(25):
            if Grid[x][y] == '1' or Grid[x][y] == '2':
                Grid[x][y] = '#'
    Grid[Player1[0]][Player1[1]] = '1'
    Grid[Player2[0]][Player2[1]] = '2'
    for y in range(25):
        for x in range(25):
            Str += Grid[x][y]
        Str += ';'
    if Argument1 == '':
        move = subprocess.Popen([Program1, Str], stdout=subprocess.PIPE).stdout.read().decode('ASCII')[0]
    else:
        move = subprocess.Popen([Program1, Argument1, Str], stdout=subprocess.PIPE).stdout.read().decode('ASCII')[0]
    Lose1 = False
    if move == 'N':
        if Player1[1] > 0:
            Player1[1] -= 1
        else:
            Player1[1] = 24
    elif move == 'E':
        if Player1[0] < 24:
            Player1[0] += 1
        else:
            Player1[0] = 0
    elif move == 'S':
        if Player1[1] < 24:
            Player1[1] += 1
        else:
            Player1[1] = 0
    elif move == 'W':
        if Player1[0] > 0:
            Player1[0] -= 1
        else:
            Player1[0] = 24
    else:
        Lose1 = True
    if Grid[Player1[0]][Player1[1]] == '#' or Grid[Player1[0]][Player1[1]] == '2':
        Lose1 = True
    print('Player 1:', move)
    if Argument2 == '':
        move = subprocess.Popen([Program2, Str.replace('2','3').replace('1','2').replace('3','1')], stdout=subprocess.PIPE).stdout.read().decode('ASCII')[0]
    else:
        move = subprocess.Popen([Program2, Argument2, Str.replace('2','3').replace('1','2').replace('3','1')], stdout=subprocess.PIPE).stdout.read().decode('ASCII')[0]
    Lose2 = False
    if move == 'N':
        if Player2[1] > 0:
            Player2[1] -= 1
        else:
            Player2[1] = 24
    elif move == 'E':
        if Player2[0] < 24:
            Player2[0] += 1
        else:
            Player2[0] = 0
    elif move == 'S':
        if Player2[1] < 24:
            Player2[1] += 1
        else:
            Player2[1] = 0
    elif move == 'W':
        if Player2[0] > 0:
            Player2[0] -= 1
        else:
            Player2[0] = 24
    elif Lose1:
        Lose2 = True
    else:
        Lose2 = True
    print('Player 2:', move)
    print(Str.replace(';', '\n'))
    if Grid[Player2[0]][Player2[1]] == '#':
        Lose2 = True
    if Lose1 and Lose2:
        print('Draw!')
        break
    elif Lose1:
        print('Player 2 wins!')
        break
    elif Lose2:
        print('Player 1 wins!')
        break

5
আপনাকে এখনই একটি এপিআই এবং একটি পরীক্ষা প্রোগ্রাম যুক্ত করতে হবে! এর সাথে ইন্টারফেসের জন্য আমরা কীভাবে কোড লিখতে সক্ষম হব? অস্পষ্ট হিসাবে পতাকাঙ্কিত।
এজেম্যানসফিল্ড

3
দেখতে খুব সুন্দর চ্যালেঞ্জের মতো মনে হচ্ছে, তবে এ .., 'টেস্টিং প্রোগ্রাম' (এটির নিয়ামক প্রোগ্রামটি ঠিক?), এটি কোন ভাষা এবং এটি আমাকে সংকলন করতে হবে? দয়া করে এটি কীভাবে ব্যবহার করবেন তা আমাদের জানান।
হার্জান

3
আকর্ষণীয় চ্যালেঞ্জের মতো বলে মনে হচ্ছে যে আমি (এ) ওএস বিধিনিষেধ (লিনাক্স-কেবল ব্যবহারকারী) এবং (বি) ভাষার বিধিনিষেধের কারণে (মূলত
ফোর্টরান তবে

2
@ ডুরকনব আমি এখন রুবিকে ইনস্টল করছি এবং যাইহোক এটি ব্যবহার করতে শিখতে ভাবছি।
kitcar2000

2
@ কিটকার 2000 আহ আমি দেখতে পাচ্ছি যে এটি যথেষ্টই যথেষ্ট। বিকল্পভাবে আপনি স্ট্ডিনের মাধ্যমে এটি সরবরাহ করতে পারতেন, তবে একটি একক লাইনকে আর্গুমেন্ট হিসাবে ব্যবহার করা সুষ্ঠু খেলা। বলা হচ্ছে, যেহেতু আপনার মানচিত্র স্থির আকার, তাই আপনার কোনও ডিলিমিটারের দরকার নেই।
মার্টিন এন্ডার

উত্তর:


8

Floodbot

জাভা

এই লোকটি এড়ানো সবই। প্রতিপক্ষকে ফাঁদে ফেলার চেষ্টা করার সে যত্ন করে না, সে কেবল বাঁচতে চায়। এটি করার জন্য, তিনি প্রতিটি দিকে বন্যা পূর্ণ করে দেখেন যে কোন পথে বৃহত্তম উন্মুক্ত অঞ্চল নিয়ে যাবে।

তিনি শত্রুটিকে অনির্দেশ্যও বলে মনে করেন, তাই তিনি প্রতিটি বর্গকে অবিলম্বে তাদের চারপাশে ইতিমধ্যে প্রাচীর হিসাবে আচরণ করে। যদি এটি কোনও সম্ভাব্য দিকনির্দেশ না করে তবে তিনি "প্রকৃত" মানচিত্রে ফিরে যান।

public class Floodbot {

    boolean[][] walkable;
    boolean[][] actual;
    boolean[][] map;
    int px;
    int py;

    void run(String[] input){
        int direction = 0;
        if(read(input))
            direction = bestPath(findPaths(false), true);
        System.out.print(directions[direction]);
    }

    int bestPath(int[] paths, boolean first){
        if(!first)
            paths = findPaths(true);
        int bestDir = 0;
        int best = 0;
        for(int i=0;i<paths.length;i++)
            if(paths[i] > best){
                best = paths[i];
                bestDir = i;
            }
        if(best==0 && first)
            return bestPath(paths, false);
        return bestDir;
    }

    static int floodCount;
    void flood(boolean[][] visited, int x, int y){
        if(visited[x][y] || !map[x][y])
            return;
        floodCount++;
        visited[x][y] = true;
        for(int dir=0;dir<4;dir++){
            int nx = dir%2==1 ? wrap(x+dir-2) : x;
            int ny = dir%2==0 ? wrap(y+dir-1) : y;
            flood(visited, nx, ny);
        }       
    }

    int[] findPaths(boolean useActual){             
        int[] paths = new int[4];
        map = useActual ? actual : walkable;
        for(int i=0;i<4;i++){
            floodCount = 0;
            int nx = i%2==1 ? wrap(px+i-2) : px;
            int ny = i%2==0 ? wrap(py+i-1) : py;
            flood(new boolean[size][size], nx, ny);
            paths[i] = floodCount;
        }
        return paths;
    }

    boolean read(String[] input){
        if(input.length < 1 || input[0].length() < size*size)
            return false;
        String[] lines = input[0].split(";");
        if(lines.length < size)
            return false;
        walkable = new boolean[size][size];
        actual = new boolean[size][size];
        for(int x=0;x<size;x++)
            for(int y=0;y<size;y++){
                walkable[x][y] = true;
                actual[x][y] = true;
            }
        for(int y=0;y<size;y++)
            for(int x=0;x<size;x++){
                char pos = lines[y].charAt(x);
                switch(pos){
                case '.':
                    break;
                case '2':
                    actual[x][y] = false;
                    walkable[x][y] = false;
                    walkable[wrap(x+1)][y] = false;
                    walkable[wrap(x-1)][y] = false;
                    walkable[x][wrap(y+1)] = false;
                    walkable[x][wrap(y-1)] = false;
                    break;
                case '1':
                    px = x; py = y;
                case '#':
                default:
                    walkable[x][y] = false;
                    actual[x][y] = false;
                }
            }

        return true;
    }

    public static void main(String[] input){new Floodbot().run(input);}
    static int wrap(int c){return (size+c)%size;}   
    static final String[] directions = {"N","W","S","E"};
    static final int size = 25;
}

আমি মনে করি আপনি এটি ব্যাগে পেয়েছেন।
সিজেফুরে

@ ট্রিমস্টি ওহ? আমি এখনও সমস্ত প্রতিযোগিতার বিরুদ্ধে পরীক্ষা করিনি, সুতরাং আমি নিশ্চিত হয়ে উঠতে পারি নি যে এটি দুটির বিরুদ্ধে কীভাবে পেরেছে। জেনে রাখা ভাল :)
জিওবিটস

জয়ের জন্য অভিনন্দন! :)
টেমসডিং

4

BlindSnake

দল

এই বটটি কেবল তার কাছাকাছি পরিবেশ দেখে। যদি দেয়াল না থাকে তবে এটি সেখানে চলে যায়।

@echo off
setlocal enableextensions enabledelayedexpansion
set map=%1

REM find position
set I=0
set L=-1
:l
if "!map:~%I%,1!"=="" goto ld
if "!map:~%I%,1!"=="1" set L=%I%
set /a I+=1
goto l
:ld
set /a pos = %L%
set /a row = %pos% / 26
set /a col = %pos% %% 26

REM find surroundings
If %row%==0 (
    set /a northPos = 24 * 26 + %col%
) else (
    set /a rowDown = %row% - 1
    set /a northPos=!rowDown! * 26 + !col!
)
If %row%==24 (
    set /a southPos = %col%
) else (
    set /a rowDown = %row%+1
    set /a southPos=!rowDown!*26+!col!
)
If %col%==0 (
    set /a westPos = %row% * 26 + 24
) else (
    set /a westPos = %pos% - 1
)
If %col%==24 (
    set /a eastPos = %row% * 26
) else (
    set /a eastPos = %pos% + 1
)

REM choose move
if "!map:~%northPos%,1!" neq "#" (
    echo N
    goto end
)
if "!map:~%eastPos%,1!" neq "#" (
    echo E
    goto end
)
if "!map:~%southPos%,1!" neq "#" (
    echo S
    goto end
)
if "!map:~%westPos%,1!" neq "#" (
    echo W
    goto end
)
echo N
:end

আমি কেবল ব্যাচে একটি বট তৈরি করতে চেয়েছিলাম ... এবং এটি আর কখনও করব না


4

FluidBot

পাইথন ঘ

সর্বনিম্ন প্রতিরোধের পথ ধরে এবং প্রতিপক্ষের পূর্বাভাস দেওয়ার চেষ্টা করে

import sys, math

def mvs(j,x,y,d,*args):
    score = sum([
                    ((j[y-1][x]=='.') * ((j[rgpos[1][1]+1][rgpos[1][0]]=='#')/3+1)) /
                        ([j[y-1][x+1], j[y-1][x-1]].count('#')+1)
                        * (d != 'S'),
                    ((j[y+1][x]=='.')*((j[rgpos[1][1]-1][rgpos[1][0]]=='#')/3+1)) /
                        ([j[y+1][x+1], j[y+1][x-1]].count('#')+1)
                        *(d != 'N'),
                    ((j[y][x-1]=='.')*((j[rgpos[1][1]][rgpos[1][0]+1]=='#')/3+1)) /
                        ([j[y+1][x-1], j[y-1][x-1]].count('#')+1)
                        *(d != 'W'),
                    ((j[y][x+1]=='.')*((j[rgpos[1][1]][rgpos[1][0]-1]=='#')/3+1)) /
                        ([j[y-1][x+1], j[y+1][x+1]].count('#')+1)
                        *(d != 'E')
                ]) * (j[y][x]=='.')
    if len(args):
        if args[0] > 0:
            mvx = {'N': [x, y-1], 'S': [x, y+1], 'E': [x+1, y], 'W': [x-1, y]}
            nscr = score * (args[0] + mvs(j,mvx[d][0],mvx[d][1],d,args[0]-1))
            return(nscr)
        else:
            return(score)
    else:
        return(score*mvs(j,x,y,d,[len(g),len(g[0])][d in ['E','W']]-1))

g = sys.argv[1].split(';')[:-1]
fg = sys.argv[1].replace(';', '')

pos = [fg.index('1'), fg.index('2')]
pos = [
        [pos[0]%len(g[0]), math.floor(pos[0]/len(g[0]))],
        [pos[1]%len(g[0]), math.floor(pos[1]/len(g[0]))]
    ]
rg = ';'.join(g).replace('1', '#').replace('2', '#').split(';')
mg = [c+c+g[i]+c+c for i,c in enumerate(rg)]
rg = [i*5 for i in rg]

rg = rg + rg + mg + rg + rg
rgpos = [
        [pos[0][0]+len(g[0]), pos[0][1]+len(g)],
        [pos[1][0]+len(g[0]), pos[1][1]+len(g)]
    ]
relpos = [
            rgpos[1][0]-rgpos[0][0],
            rgpos[1][1]-rgpos[0][1]
        ]

moves = {
        'N': ((relpos[1]>0)/3+1)*mvs(rg, rgpos[0][0], rgpos[0][1]-1, 'N'),
        'S': ((relpos[1]<0)/3+1)*mvs(rg, rgpos[0][0], rgpos[0][1]+1, 'S'),
        'E': ((relpos[0]<0)/3+1)*mvs(rg, rgpos[0][0]+1, rgpos[0][1], 'E'),
        'W': ((relpos[0]>0)/3+1)*mvs(rg, rgpos[0][0]-1, rgpos[0][1], 'W')
        }

sys.stdout.write(sorted(moves, key=lambda x:-moves[x])[0])

প্রায় এক ঘন্টা ধরে এ নিয়ে কাজ করেছি। ._।

অ্যাওবোটের বিরুদ্ধে পরীক্ষিত:

Player 1: E
Player 2: W
#.....#####.......##.....
#.....###1.........##...#
....................#####
.........................
.........................
.........................
......######.............
......#....####..........
......#.......##.........
......#........###.......
.....##..........#.......
.....#...........#.......
.....#...........#.......
....##......##...#.......
....###.....##...#.......
......#...#####..#.......
....###...#...#..#.......
....#..####...##.##......
....#..#.......#..##.....
....##2#.......#...##....
.......#.......##...##...
.......#........#....##..
.......#........#.....##.
.......##.......##.....##
........###......##.....#

Player 1 wins!

FillUpBot:

Player 1: W
Player 2: E
#......................#2
#......................##
......................##.
......................#..
.....................##..
....................##...
....................#....
...................##....
..................##.....
..................#......
.......1###########......
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
.........................
#########################
.......................##

Player 1 wins!

সম্পাদনা 5 : আরও ভবিষ্যত সচেতন; অঞ্চল বন্ধ বন্ধ এড়ানোর চেষ্টা করে (যদি না, অবশ্যই, প্রতিপক্ষটি এতে না থাকে)।

সম্পাদনা 4 : কোড সাফ করা।

সম্পাদনা 3 : আয়তক্ষেত্রাকার খেলার ক্ষেত্রগুলির জন্য আরও ভাল কাজ করে।

সম্পাদনা 2 : ক্লিনার কোড, অ্যালগরিদম আরও যৌক্তিক এবং ভবিষ্যতে কিছু পদক্ষেপের পূর্বাভাস দেয়

সম্পাদনা : আরও প্রতিরক্ষামূলক অ্যালগরিদম, ভুত আত্মাকে খালি জায়গা হিসাবে গণনা করে না।


3

AwayBot

রুবিতে লিখিত (1.9)

যথাযথভাবে নামকরণ করা হয়েছে, অ্যাওবট যেকোন প্রতিবন্ধকতা থেকে দূরে যাওয়ার চেষ্টা করে। এটি নিজের আশেপাশে একটি 15x15 বর্গক্ষেত্র অনুসন্ধান করে, সেই অনুযায়ী দিকনির্দেশকে ওজন করে এবং সর্বনিম্ন বাধাগুলির সাথে দিকটি চয়ন করে। (এটিরও অর্থ হ'ল এটি প্রান্তগুলি এড়িয়ে চলে, যা ভাল তাই এটির মধ্যে আটকা পড়ে না))

এটি দেয়ালগুলি আরও বেশি বিপদ হিসাবে বিবেচনা করে। এর ঠিক পাশের দেয়ালগুলি অনেক দূরের দেয়ালের তুলনায় আরও বেশি ওজনযুক্ত।

আপনার নমুনা ইনপুট জন্য, এটি আউটপুট S। নমুনা ইনপুট প্রতিটি দিকের জন্য ওজন হয় [["N", 212], ["E", 140], ["S", 0], ["W", 84]]

বাধা: আমি কেবল লক্ষ্য করেছি যে আখড়াটি জড়িয়ে আছে। ঠিক আছে তবে, আমার প্রান্ত-এড়ানোর কৌশলটি এখন কিছুটা অর্থহীন তবে মেহ। আমি পরে এটি ঠিক করব।

arena = ARGF.argv[0]

# we're considering the enemy a wall, for simplicity.
# no need to weight him any more than the other walls because he will
# always be surrounded by walls anyway.
arena = arena.sub(?2, ?#).split(?;)

# pad the arena with extra walls (edges of the arena)
searchRadius = 7
arenaSize = arena.first.size

verticalEdgeWalls = [?# * arenaSize] * searchRadius
arena = verticalEdgeWalls + arena + verticalEdgeWalls

horizontalEdgeWalls = ?# * searchRadius
arena.map! {|row| (horizontalEdgeWalls + row + horizontalEdgeWalls).split('') }

# now get the area around the bot
botRow = arena.index{|row| row.index ?1 }
botCol = arena[botRow].index ?1

searchZone = arena.slice(botRow-searchRadius..botRow+searchRadius)
searchZone.map! {|row| row.slice(botCol-searchRadius..botCol+searchRadius) }

# second to last step: assign values to each square depending on how far away they are
# from the player (Manhattan distance)
# this is so that the player avoids running directly into a wall; higher value means closer tile
# 0123210
# 1234321
# 2345432
# 1234321
# 0123210
centerSquare = searchRadius
searchZone = searchZone.each_with_index.map {|row, rowIndex| row.each_with_index.map{|tile, tileIndex|
    [tile, searchRadius*2 - ((rowIndex - centerSquare).abs + (tileIndex - centerSquare).abs)]
} }
puts searchZone.map{|x|x.map{|y|y[1].to_s.rjust(2, ?0)}.join ' '} * "\n"

# finally, assign weights to each direction
# first, create a map of directions. each direction has an array, the first element being
# what rows to slice and the second being what column.
sBeg = 0
sMdl = searchRadius
sEnd = searchRadius*2
directions = {
    ?N => [sBeg..sMdl-1, sBeg..sEnd],
    ?E => [sBeg..sEnd, sMdl+1..sEnd],
    ?S => [sMdl+1..sEnd, sBeg..sEnd],
    ?W => [sBeg..sEnd, sBeg..sMdl-1]
}
# then, create another hash of weights
weights = directions.map{|dir, arr|
    section = searchZone.slice(arr[0]).map{|x| x.slice(arr[1]) }.flatten(1)
    [dir, (section.select{|tile| tile[0] == ?# }.map{|tile| tile[1] }.reduce(:+) || 0)] # return the sum of the values of the walls in the area
}
# yay! we have our weights! now just find the smallest one...
dirToGo = weights.min_by{|_, walls| walls }
# and output!
print dirToGo[0]

"এর অর্থ হ'ল এটি প্রান্তগুলি এড়িয়ে চলে, যা ভাল তাই এটি তাদের মধ্যে আটকা পড়ে না" " - কিনারা মোড়ানো হয় না?
হোভারকচ

1
@ হুম উম, হ্যাঁ, আপনি শেষ অনুচ্ছেদটি পড়েন নি? ;-)
ডুরকনব

@ ডুরকনব নিশ্চিত করুন যে আপনি প্রথম লাইনটির ARGF.argv[0].chompপরিবর্তে কমান্ড-লাইনের মাধ্যমে আপনার ইনপুটটি পাচ্ছেন gets.chomp!
টমসডিং করুন

@ ডুরকনব আপনার সম্ভবত রুবি সংস্করণটি নির্দিষ্ট করা উচিত। আমি মনে করি
নয়

@ টমসডিং আহ, সেটা বুঝতে পারিনি। ধন্যবাদ, সম্পাদনা
ডোরকনব

3

FillUpBot

সি ++ এ লিখিত

ভাববেন না যে আমি জিততে যাচ্ছি, তবে যাইহোক এটি এখানে যাচ্ছি:

#include <iostream>
#include <cassert>
#include <cmath>
#include <cstdlib>

#define SIZE 25

using namespace std;

class Board{
public:
    unsigned long long walls[SIZE]; //each int is a bitmap with the LSbit being the left side
    int p1x,p1y,p2x,p2y;
    void read(const char *arg){
        int map,i,j;
        for(i=0;i<SIZE;i++){
            for(map=1,j=0;j<SIZE;map<<=1,j++){
                if(arg[(SIZE+1)*i+j]=='1'){
                    p1x=j;
                    p1y=i;
                } else if(arg[(SIZE+1)*i+j]=='2'){
                    p2x=j;
                    p2y=i;
                }
                walls[i]=(walls[i]&~map)|(map*(arg[(SIZE+1)*i+j]=='#'));
            }
        }
    }
    bool operator==(const Board &other){
        int i;
        for(i=0;i<SIZE;i++)if(walls[i]!=other.walls[i])return false;
        if(p1x!=other.p1x||p1y!=other.p1y||p2x!=other.p2x||p2y!=other.p2y)return false;
        return true;
    }
};

inline int mod(int a,int b){return (a+b)%b;}
inline int min(int a,int b){return a<b?a:b;}

int main(int argc,char **argv){
    assert(argc==2);
    Board B;
    B.read(argv[1]);
    //cerr<<"KOTW: read"<<endl;
    if(hypot(B.p2x-B.p1x,B.p2y-B.p1y)<=3||hypot(mod(B.p2x+SIZE/2,SIZE)-mod(B.p1x+SIZE/2,SIZE),mod(B.p2y+SIZE/2,SIZE)-mod(B.p1y+SIZE/2,SIZE))<=3){
        double maxdist=-1,d;
        int maxat=-1; //0=E, 1=N, 2=W, 3=S
        //cerr<<B.walls[B.p1y]<<endl;
        if(!(B.walls[B.p1y]&(1<<mod(B.p1x+1,SIZE)))){
            d=min(hypot(mod(B.p2x-(B.p1x+1),SIZE),mod(B.p2y-B.p1y,SIZE)),hypot(mod(B.p1x+1-B.p2x,SIZE),mod(B.p1y-B.p2y,SIZE)));
            //cerr<<"E: "<<d<<endl;
            if(d>maxdist){
                maxdist=d;
                maxat=0; //E
            }
        }
        //cerr<<B.walls[mod(B.p1y-1,SIZE)]<<endl;
        if(!(B.walls[mod(B.p1y-1,SIZE)]&(1<<B.p1x))){
            d=min(hypot(mod(B.p2x-B.p1x,SIZE),mod(B.p2y-(B.p1y-1),SIZE)),hypot(mod(B.p1x-B.p2x,SIZE),mod(B.p1y-1-B.p2y,SIZE)));
            //cerr<<"N: "<<d<<endl;
            if(d>maxdist){
                maxdist=d;
                maxat=1; //N
            }
        }
        //cerr<<B.walls[B.p1y]<<endl;
        if(!(B.walls[B.p1y]&(1<<mod(B.p1x-1,SIZE)))){
            d=min(hypot(mod(B.p2x-(B.p1x-1),SIZE),mod(B.p2y-B.p1y,SIZE)),hypot(mod(B.p1x-1-B.p2x,SIZE),mod(B.p1y-B.p2y,SIZE)));
            //cerr<<"W: "<<d<<endl;
            if(d>maxdist){
                maxdist=d;
                maxat=2; //W
            }
        }
        //cerr<<B.walls[mod(B.p1y+1,SIZE)]<<endl;
        if(!(B.walls[mod(B.p1y+1,SIZE)]&(1<<B.p1x))){
            d=min(hypot(mod(B.p2x-B.p1x,SIZE),mod(B.p2y-(B.p1y+1),SIZE)),hypot(mod(B.p1x-B.p2x,SIZE),mod(B.p1y+1-B.p2y,SIZE)));
            //cerr<<"S: "<<d<<endl;
            if(d>maxdist){
                maxdist=d;
                maxat=3; //S
            }
        }
        if(maxat==-1){ //help we're stuck!
            cout<<"ENWS"[(int)((double)rand()/RAND_MAX*4)]<<endl;
            return 0;
        }
        cout<<"ENWS"[maxat]<<endl;
        return 0;
    }
    //cerr<<"KOTW: <=3 checked"<<endl;
    //cerr<<B.p1x<<","<<B.p1y<<endl;
    if(!(B.walls[B.p1y]&(1<<mod(B.p1x+1,SIZE))))cout<<'E'<<endl;
    else if(!(B.walls[mod(B.p1y+1,SIZE)]&(1<<B.p1x)))cout<<'S'<<endl;
    else if(!(B.walls[mod(B.p1y-1,SIZE)]&(1<<B.p1x)))cout<<'N'<<endl;
    else if(!(B.walls[B.p1y]&(1<<mod(B.p1x-1,SIZE))))cout<<'W'<<endl;
    else cout<<"ENWS"[(int)((double)rand()/RAND_MAX*4)]<<endl; //help we're stuck!
    //cerr<<"KOTW: done"<<endl;
    return 0;
}

আপনার স্ট্যান্ডার্ড সি ++ সংকলক এটি হ্যান্ডেল করতে সক্ষম হওয়া উচিত।


সংকলন বলে মনে হচ্ছে না। জিসিসি ৪.৮.১, উইন্ডোজ rand. র‌্যান্ড এবং RAND_MAX সংজ্ঞায়িত না হওয়া সম্পর্কে ত্রুটি ছুড়ে দেয়।
সিজেফায়ার

@ ট্রাইমস্টি একটি #include <cstdlib>সাহায্য করে? (এটিকে কেবল নতুন লাইন হিসাবে শীর্ষে সন্নিবেশ করুন)
টমসডিং করুন

প্রকৃতপক্ষে! এটি এখন সংকলন। ধন্যবাদ।
সিজেফায়ার

ফ্লুডবটের বিরুদ্ধে এটি চালান, এই পদক্ষেপে আউটপুট উত্পাদন করতে ব্যর্থ: pastie.org/private/azmwkybqrxqlfvpwidlpw (ফ্লুইডবট খেলোয়াড় 1)
সিজেফায়ার

@ ট্রিমস্টি আম ... gist.github.com/tomsmeding/96060c7db3f1c3483668 (1 এবং 2 অদলবদল; আমি যদি সেগুলি পরিবর্তন না করি তবে এটি একই ফলাফল দেয়)
টমসমেডিং

3

Arcbot

পাইথন ঘ

আগ্রাসন-ভিত্তিক অ্যালগরিদমকে শত্রু হিসাবে হিসাবে খেলে এবং প্রভাবের সাথে জঞ্জাল উত্তর দেয়

আমার ধারণা, এই অ্যালগরিদম একধরণের 'আবেগ-ভিত্তিক'। এটি বিকাশে, আমি বুঝতে পেরেছিলাম যে ফ্লুইডবট প্রায় প্রতিবারই এটি পরাজিত করে। আর্কবোট দ্রুততম অ্যালগরিদম বা সেরা নয়, তবে এটির শক্তিও রয়েছে।

এটা তোলে নেই দেয়ালের মধ্যে ক্র্যাশ করলে কে। কেন জানি না।

ফ্লাইবোট ভাল হয়

#   Arcbot
#   
#   This is a more dynamic bot than the earlier Fluidbot.
#   I'm also commenting on the code to make my algorithm
#   more clear.

#** Some intial definitions **#

import math, sys # math for the 'arc' part

class edgeWrapList: # yay, such efficient
    def __init__(self, l):
        self.l = list(l)
    def __getitem__(self, i):
        it = i%len(self.l)
        if it == i: # no wrapping, include players
            return(self.l[i])
        else: # wrapping, replace players with walls
            if not isinstance(self.l[it], str):
                return(self.l[it])
            else:
                return(self.l[it].replace('1', '#').replace('2', '#'))
    def __len__(self):
        return(len(self.l))
    def __str__(self):
        return(''.join(str(i) for i in self.l))
    def __setitem__(self, i, v):
        self.l[i%len(self.l)] = v

grid = edgeWrapList([edgeWrapList([j for j in i]) for i in sys.argv[1].split(';')[:-1]]) # a 2D edgeWrapList. Access via grid[y][x]

attackStr = 1 # distance to attack from
attackEnd = 12 # distance to avoid again

predictTurns = 6 # how many turns to play as the opponent as well. Keep low for performance.

#** Arcbot's main class **#

class arcbot:
    def __init__(self, g, astr, aend):
        self.g = g # g is a 2D edgeWrapList
        self.p1p = str(g).index('1')
        self.p1p = [self.p1p%len(g[0]), math.floor(self.p1p/len(g[0]))] # x, y of player 1
        self.p2p = str(g).index('2')
        self.p2p = [self.p2p%len(g[0]), math.floor(self.p2p/len(g[0]))] # x, y of player 2
        self.astr = astr
        self.aend = aend
    def getAggr(self, d):
        if self.astr < d < self.aend:
            return(0)
        else:
            return(math.cos((d-self.astr)*(math.pi*2/self.aend))) # sort-of bell curve between -1 and 1
    def getMove(self, p): # p is either 1 or 2
        scrg = edgeWrapList(self.scoreGridGen(p)) # get dem position scores
        pos = self.p1p if p==1 else self.p2p
        dir = {
            'N': scrg[pos[1]-1][pos[0]], 
            'S': scrg[pos[1]+1][pos[0]],
            'E': scrg[pos[1]][pos[0]+1],
            'W': scrg[pos[1]][pos[0]-1]
            }
        o = sorted(dir, key=lambda x:-dir[x])[0]
        return([o, dir[o]]) # return direction with highest scoring position and it's score
    def getScore(self, x, y, p, d='*'):
        epos = self.p2p if p == 1 else self.p1p
        dist = math.sqrt((y - epos[1])**2 + (x - epos[0])**2)
        return((sum([
                (self.g[y][x-1] == '.') * (((self.g[y][x+1] == '.')+1) * ((self.g[y][x-2] == '.')*4+1)),
                (self.g[y][x+1] == '.') * (((self.g[y][x-1] == '.')+1) * ((self.g[y][x+2] == '.')*4+1)),
                (self.g[y-1][x] == '.') * (((self.g[y+1][x] == '.')+1) * ((self.g[y-2][x] == '.')*4+1)),
                (self.g[y+1][x] == '.') * (((self.g[y-1][x] == '.')+1) * ((self.g[y+2][x] == '.')*4+1))
            ]) * 2 + 1) * (self.getAggr(dist) / 10 + 1) * (self.g[y][x] == '.'))
    def scoreGridGen(self, p): # turn .s into numbers, higher numbers are better to move to
        o = []
        for y,r in enumerate(self.g.l): # y, row
            o.append(edgeWrapList(
                    self.getScore(x, y, p) for x,v in enumerate(r.l) # x, value
                )
            )
        return(o)
    def play(self, turns, movestr): # movestr is [p1moves, p2moves]
        p2move = self.getMove(2)
        movestr[1] += [p2move[0]]
        p1move = self.getMove(1)
        if len(movestr[0]) == turns:
            return([p1move[1], p1move[0]]) # Score for final block
        scores = {}
        for i in 'N S E W'.split():
            movestr[0] += [i]
            og = self.simMoves(movestr)
            if og == 'LOSE:2':
                scores[i] = 1000000 # we win!
            elif og == 'LOSE:1':
                scores[i] = -1000000 # we lose!
            else:
                scores[i] = og[1] * ((i == p1move[0]) / 1.2 + 1) * (turns-len(movestr[0])) * (self.play(turns, movestr)[0]+1)
            movestr[0] = movestr[0][:-1]
        hst = sorted(scores, key=lambda x:-scores[x])[0]
        return([scores[hst], hst]) # highest scoring turn in total and it's score
    def simMove(self, p, d): # move player p in direction d
        pos = self.p1p if p == 1 else self.p2p
        target = {
            'N': [pos[0], pos[1]-1],
            'S': [pos[0], pos[1]+1],
            'E': [pos[0]+1, pos[1]],
            'W': [pos[0]-1, pos[1]]
            }[d]
        v = self.g[target[1]][target[0]] # contents of target block
        if v == '.': # yay let's move here
            self.g[target[1]][target[0]] = str(p)
            self.g[pos[1]][pos[0]] = '#'
            if p == 1:
                self.p1p = [target[0], target[1]]
            else:
                self.p2p = [target[0], target[1]]
        else: # nuu crash
            raise(ValueError) # doesn't matter, caught later
    def simMoves(self, mvl): # return simmed copy
        op = [self.p1p, self.p2p]
        og = self.g
        finalScore = 0
        for i in range(len(mvl[0])):
            try:
                if i == len(mvl[0])-2:
                    finalScore = {
                        'N': self.getScore(self.p1p[0], self.p1p[1]-1, 'N'),
                        'S': self.getScore(self.p1p[0], self.p1p[1]+1, 'S'),
                        'E': self.getScore(self.p1p[0]+1, self.p1p[1], 'E'),
                        'W': self.getScore(self.p1p[0]-1, self.p1p[1], 'W')
                        }[mvl[0][i]]
                self.simMove(1, mvl[0][i])
            except:
                return('LOSE:1')
            try:
                self.simMove(2, mvl[1][i])
            except:
                return('LOSE:2')
        o = self.g
        self.g = og
        self.p1p, self.p2p = op
        return([o, finalScore])

arcbotMove = arcbot(grid, attackStr, attackEnd)
sys.stdout.write(arcbotMove.play(predictTurns, [[], []])[1])

সম্পাদনা : সংখ্যা এবং সূত্রটি সামঞ্জস্য করা, এটি এখন আরও ভাল খেলে তবে এখনও ফ্লুইডবোটের কাছে হেরে যায়।

সম্পাদনা 2 : ওফ, কিছু কোড পরিবর্তন করতে ভুলে গেছি।


1

RandomBot

সি শার্প

র্যান্ডমবট পথটি নিখরচায় এলোমেলোভাবে একটি দিক নির্বাচন করে। কোনও সুরক্ষিত দিকনির্দেশ না থাকলে এটি কেবল টাইপ করে *এবং হেরে যায়।

using System;

class AI
{
    static void Main(string[] args)
    {
        char[,] grid = new char[25, 25];
        char[] directions = { 'N', 'E', 'S', 'W' };
        string map = args[0];
        Random rand = new Random();
        int[] pos = new int[2];
        for (var x = 0; x < 25; x++)
        {
            for (var y = 0; y < 25; y++)
            {
                grid[x, y] = map.Split(';')[y][x];
                if (grid[x,y] == '1') {
                    pos[0] = x;
                    pos[1] = y;
                }
            }
        }
        if (grid[(pos[0] + 1) % 25, pos[1]] != '.' && grid[pos[0], (pos[1] + 1) % 25] != '.' && grid[(pos[0] + 24) % 25, pos[1]] != '.' && grid[pos[0], (pos[1] + 24) % 25] != '.')
        {
            if (grid[pos[0], (pos[1] + 24) % 25] == '2')
            {
                Console.Write("N");
            }
            else if (grid[(pos[0] + 1) % 25, pos[1]] == '2')
            {
                Console.Write("E");
            }
            else if (grid[pos[0], (pos[1] + 1) % 25] == '2')
            {
                Console.Write("S");
            }
            else if (grid[(pos[0] + 24) % 25, pos[1]] == '2')
            {
                Console.Write("W");
            }
            else
            {
                Console.Write("*");
            }
        }
        else
        {
            while (true)
            {
                char direction = directions[Convert.ToInt32(rand.Next(4))];
                if (direction == 'N' && grid[pos[0], (pos[1] + 24) % 25] == '.')
                {
                    Console.Write("N");
                    break;
                }
                else if (direction == 'E' && grid[(pos[0] + 1) % 25, pos[1]] == '.')
                {
                    Console.Write("E");
                    break;
                }
                else if (direction == 'S' && grid[pos[0], (pos[1] + 1) % 25] == '.')
                {
                    Console.Write("S");
                    break;
                }
                else if (direction == 'W' && grid[(pos[0] + 24) % 25, pos[1]] == '.')
                {
                    Console.Write("W");
                    break;
                }
            }
        }
    }
}

এটি কেবল এআই এর উদাহরণ - এটি জয়ের জন্য ডিজাইন করা হয়নি!


-1

বটটি পূরণ করুন (90 ডিগ্রি অ্যান্টিকলোকের দিকে পরিণত হয়, যখন কোনও বাধার সম্মুখীন হয়)

সি ++

আমার কোডে, দুই খেলোয়াড় (1 এবং 2) বন্যার চেষ্টা করে। অর্থ যখনই তারা কোনও বাধার মুখোমুখি হন তারা ঘড়ির কাঁটার বিপরীতে পরিণত হয়।
মনে রাখবেন, ইনপুটটিতে থাকা রেখাগুলি একটি দ্বারা spaceবা পৃথক newlineনয় by;

#include<iostream>
#include<conio.h>
#include<windows.h>
char draw(char plot[][25],char dir,char num)
{
    int a=1,i,j;
    for(i=0;i<25;i++)
    {
        for(j=0;j<25;j++)
        {
            if(plot[i][j]==num&&a)
            {
                a--;
                switch(dir)
                {
                    case 'S':{
                        if(i==24||plot[i+1][j]=='#')
                        {
                            dir='E';
                            plot[i][j]='#';
                            plot[i][j+1]=num;
                        }
                        else if(i<24||plot[i+1][j]=='.')
                        {
                            plot[i][j]='#';
                            plot[i+1][j]=num;
                        }
                        break;
                    }
                    case 'E':{
                        if(j==24||plot[i][j+1]=='#')
                        {
                            dir='N';
                            plot[i][j]='#';
                            plot[i-1][j]=num;
                        }
                        else if(j<24||plot[i][j+1]=='.')
                        {
                            plot[i][j]='#';
                            plot[i][j+1]=num;
                        }
                        break;
                    }
                    case 'N':{
                        if(i==0||plot[i-1][j]=='#')
                        {
                            dir='W';
                            plot[i][j]='#';
                            plot[i][j-1]=num;
                        }
                        else if(i>0||plot[i-1][j]=='.')
                        {
                            plot[i][j]='#';
                            plot[i-1][j]=num;
                        }
                        break;
                    }
                    case 'W':{
                        if(j==0||plot[i][j-1]=='#')
                        {
                            dir='S';
                            plot[i][j]='#';
                            plot[i+1][j]=num;
                        }
                        else if(j>0||plot[i][j-1]=='.')
                        {
                            plot[i][j]='#';
                            plot[i][j-1]=num;
                        } 
                        break;
                    }
                }
            }
        }
    }
    return dir;
}
void run()
{
    int i,j,crash=1,count,k,a;
    char plot[25][25],dir1='S',dir2='N';
    for(i=0;i<25;i++)
        std::cin>>plot[i];
    plot[0][0]='1';
    plot[24][24]='2';
    while(crash)
    {
        system("cls");
        dir1=draw(plot,dir1,'1');
        dir2=draw(plot,dir2,'2');
        count=0;
        for(i=0;i<25;i++)
            for(j=0;j<25;j++)
                if(plot[i][j]=='.')count++;
        if(count==1)
        {
            crash--;
            plot[12][12]='*';
            plot[11][12]='#';
            plot[13][12]='#';
        }
        for(i=0;i<25;i++)
        {
            for(j=0;j<25;j++)
                std::cout<<plot[i][j];
            std::cout<<'\n';
        }
        Sleep(25);
    }
}
int main()
{
    run();
    getch();
    return 0;
}

2
আমি এই প্রোগ্রামটি এটির মতো পরীক্ষা করতে সক্ষম হবো না কারণ এটি কিছু প্রয়োজনীয় স্পেসিফিকেশন মেনে চলে না এবং নিয়ন্ত্রণ প্রোগ্রাম দ্বারা ব্যবহার করা যায় না।
kitcar2000
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.