ব্যাটালবটস: দ্য টুর্নামেন্ট


69

ফলাফল আছে, প্রতিযোগিতা শেষ।
বিজয়ী হলেন আরশাজির অ্যাভিলবট ১৩ টি জয়ের সাথে নব্য-বটের সাথে ১৩ টি জয় এবং সেন্ট্রেবট এবং লাস্টস্ট্যান্ডের সাথে ১১ টি জয়ের সাথে।

চূড়ান্ত রান থেকে স্কোর

Results:
java Rifter:                 9  match wins (45 total bout wins)
java EvadeBot:               10 match wins (44 total bout wins)
java EvilBot:                14 match wins (59 total bout wins)
java LastStand:              11 match wins (43 total bout wins)
java UltraBot:               9  match wins (40 total bout wins)
python ReadyAimShoot.py:     8  match wins (36 total bout wins)
./SpiralBot:                 0  match wins (1 total bout wins)
python DodgingTurret.py:     8  match wins (43 total bout wins)
ruby1.9 TroubleAndStrafe.rb: 8  match wins (41 total bout wins)
./RandomBot:                 1  match wins (6 total bout wins)
python StraightShooter.py:   8  match wins (41 total bout wins)
python mineminemine.py:      3  match wins (14 total bout wins)
./CamperBot:                 5  match wins (20 total bout wins)
python3.3 CunningPlanBot.py: 3  match wins (15 total bout wins)
node CentreBot.js:           11 match wins (44 total bout wins)
node Neo-Bot.js:             13 match wins (59 total bout wins)
python NinjaPy.py:           3  match wins (19 total bout wins)

এটি এক চ্যালেঞ্জ। উদ্দেশ্য হ'ল এমন একটি বট লিখুন যা অন্য যে কোনও বোটের তুলনায় আরও বেশি পরাজিত করবে।

খেলাাটি

প্রতিস্থাপকের নিজস্ব শক্তি 0 থেকে কমিয়ে 0 নামানোর আগে প্রতিপক্ষের শক্তি 10 থেকে 0 কমিয়ে দেওয়ার জন্য 10x10 অঙ্গনে একসাথে 2 টি একে অপরের বিরুদ্ধে বিস্ফোরিত হবে।

প্রতিটি ম্যাচ 5 টি আউটআউট নিয়ে গঠিত। ম্যাচের বিজয়ী সর্বাধিক বাউন্ডের বিজয়ী। মোট ম্যাচ জিত এবং বাউত জয়ের সংখ্যা নিয়ন্ত্রণ প্রোগ্রাম দ্বারা সংরক্ষণ করা হবে এবং প্রতিযোগিতার সামগ্রিক বিজয়ী নির্ধারণ করতে ব্যবহৃত হবে। বিজয়ী বড় সবুজ টিক এবং জনসাধারণের কাছে আনন্দিত হয়।

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

অস্ত্র

প্রতিটি বোটের হাতে বেশ কয়েকটি অস্ত্র থাকবে:

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

বুলেট / ক্ষেপণাস্ত্রগুলি কেবল বট বা দেয়াল দিয়ে প্রভাব ফেলতে পারে। তারা যে স্কোয়ারের মধ্য দিয়ে যে কোনও স্কোয়ারের যে কোনও বটকে আঘাত করবে। তারা কিছু আঘাত করার পরে তারা অদৃশ্য হয়ে যায়।

সব ক্ষেত্রে immediately surrounding squares8 টি স্কোয়ারের অর্থ বট তার পরবর্তী পদক্ষেপে যেতে পারে - মুর পাড়া।

আদেশগুলি

  • 0 কিছু করনা.
  • N, NE, E, SE, S, SW, W, NWসব দিক কমান্ড হয় এবং প্রদত্ত দিক বট বর্গ সরানো। স্কয়ারে প্রাচীর বা অন্য একটি বট রয়েছে বলে বটটি যদি সেদিকে যেতে না পারে তবে বটটি যেখানে রয়েছে সেখানেই রয়েছে। ইতিমধ্যে একটি বুলেট বা ক্ষেপণাস্ত্র রয়েছে এমন স্কোয়ারে স্থানান্তর করা নিরাপদ কারণ বুলেট / ক্ষেপণাস্ত্রটি ইতিমধ্যে সেই বর্গক্ষেত্রের বাইরে যাওয়ার পথে বিবেচিত হবে।
  • B তারপরে একটি স্পেস এবং তারপরে একটি দিক নির্দেশ কমান্ড সেই দিকে একটি বর্ম ছিদ্রকারী বুলেটটিকে গুলি করে।
  • M তারপরে একটি স্পেস এবং তারপরে কোনও দিক নির্দেশের একটি দিক দিয়ে একটি ক্ষেপণাস্ত্র চালিত।
  • Lতারপরে একটি স্পেস এবং তারপরে একটি দিক নির্দেশ কমান্ড বটের পাশে that স্কোয়ারে একটি ল্যান্ড মাইন ফেলে দেয়। বর্গটি ইতিমধ্যে কোনও প্রাচীর বা বট দ্বারা দখল করা থাকলে, আদেশটি উপেক্ষা করা হবে। যদি একটি ল্যান্ডমাইন অন্য ল্যান্ডমাইনটিতে ফেলে দেওয়া হয়, তবে এটি বিস্ফোরণ ঘটায়। এটি ড্রপিং করা বটকে এবং আসল ল্যান্ডমাইনের সীমার মধ্যে অন্য কোনও বটকে ক্ষতিগ্রস্থ করবে।
  • P EMP গুলি।

যেহেতু প্রতি রাউন্ডে কেবল একটি কমান্ড দেওয়া যেতে পারে, একটি বট কেবল একটি অস্ত্র সরিয়ে বা গুলি চালাতে / মোতায়েন করতে পারে, একই সাথে উভয়ই না করে।

আদেশের আদেশ
উভয়ই বটের চলাচল সর্বদা প্রথমে আসবে এবং অন্য বটটি পথে চলতে থাকলেও উপায়টি থেকে বেরিয়ে যাওয়ার জন্য সমস্ত নড়াচড়া দু'বার চেষ্টা করা হবে।

উদাহরণ

  • বট 1 সরানোর চেষ্টা করে Eতবে বট 2 ইতিমধ্যে সেই স্কোয়ারে রয়েছে
  • কন্ট্রোল প্রোগ্রাম বট 2 এ চলে যায়।
  • বট 2 চলাচল করার চেষ্টা করে Sএবং সফল হয় কারণ কিছুই কিছুই নেই।
  • বোট 1 এর পদক্ষেপটি নিয়ে দ্বিতীয় চেষ্টা পায়। এই সময় এটি সফল এবং Bot1 প্যাচসমূহ E

একবার বটগুলি তাদের তৈরি করতে চান এমন কোনও আন্দোলন শুরু করলে, অস্ত্রগুলি চালিত করা হবে এবং সমস্ত প্রজেক্টেলগুলি (নতুন এবং পূর্বে নিক্ষেপ করা হয়েছে) তাদের পূর্বনির্ধারিত সংখ্যার স্কোয়ার স্থানান্তরিত করবে।

আখড়া

প্রতিটি রাউন্ডের শুরুতে বট প্রোগ্রামটির একমাত্র কমান্ড লাইনের যুক্তি হিসাবে বর্তমান খেলার অবস্থাটি গ্রহণ করবে:

X.....LLL.
..........
..........
..........
M.........
..........
..........
..........
..........
...B.....Y
Y 10
X 7
B 3 9 W
M 0 4 S
L 6 0
B 3 9 S
L 7 0
L 8 0

10 টি অক্ষরের 10 টি লাইন নিয়ে প্রথমে আখড়াটি আসে। এটি দেয়াল দিয়ে ঘিরে রয়েছে যা প্রদর্শিত হয়নি। অক্ষরের অর্থ নীচে রয়েছে:

  • . একটি খালি বর্গ প্রতিনিধিত্ব করে
  • Y আপনার বট প্রতিনিধিত্ব করে
  • X প্রতিপক্ষের বট প্রতিনিধিত্ব করে।
  • L একটি ল্যান্ডমাইন উপস্থাপন করে।
  • B ফ্লাইট একটি বুলেট প্রতিনিধিত্ব করে।
  • M ফ্লাইটে একটি ক্ষেপণাস্ত্র প্রতিনিধিত্ব করে।

এটি বোটের বাকী শক্তি অনুসরণ করে, প্রতি লাইনে একটি বট। কেবলমাত্র একটি স্থান বট শনাক্তকারীকে তার শক্তি স্তর থেকে পৃথক করবে। আখড়ার মতো, Yআপনার বট Xপ্রতিনিধিত্ব করে এবং আপনার প্রতিপক্ষকে উপস্থাপন করে। পরিশেষে প্রজেক্টিলেস এবং ল্যান্ডমাইনগুলি, তাদের অবস্থান এবং (উপযুক্ত হলে) শিরোনামগুলির একটি তালিকা আসে, আবার প্রতি লাইনে একটি করে।

নিয়ন্ত্রণ প্রোগ্রাম

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#define NUMBOTS 2
#define BOUTSPERMATCH 5
#define ROUNDSPERBOUT 1000
#define MAXFILENAMESIZE 100
#define MAXWEAPONS 100
#define DISPLAYBOUTS true

typedef struct
{
  int x, y, energy;
  char cmd[5];
} Bot;

int getxmove(char cmd[5]);
int getymove(char cmd[5]);
int newposinbounds(int oldx, int oldy, int dx, int dy);
int directhit(Bot bot, int landmine[2]);
int landminecollision(int landmine1[2], int landmine2[2]);
int inshrapnelrange(Bot bot, int landmine[2]);
int directiontoint(char direction[5], char directions[8][3]);
void deployweapons(Bot *bot, Bot *enemy, int bullets[MAXWEAPONS][3], int missiles[MAXWEAPONS][3], int landmines[MAXWEAPONS][2], char directions[8][3]);
void cleararena(char arena[10][11]);

int main()
{
  FILE *fp;
  Bot b1, b2;
  int bot1, bot2, bot1bouts, bot2bouts;
  int bout, round, loop, totalprojectiles, dx, dy;
  char bots[NUMBOTS][MAXFILENAMESIZE]=
  {
    "./donowt              ",
    "php -f huggybot.php   "
  };
  char directions[8][3]={"N", "NE", "E", "SE", "S", "SW", "W", "NW"};
  char openstring[5000], argumentstring[4000], bot1string[6], bot2string[6];
  int matcheswon[NUMBOTS],boutswon[NUMBOTS];
  int missiles[MAXWEAPONS][3];
  int bullets[MAXWEAPONS][3];
  int landmines[MAXWEAPONS][2];
  int paralyzedturnsremaining=0;
  bool bot1moved;
  char arena[10][11];
  char projectiles[300][10];

  for(loop=0;loop<NUMBOTS;loop++)
  {
    matcheswon[loop]=0;
    boutswon[loop]=0;
  }

  srand(time(NULL));

  for(bot1=0;bot1<NUMBOTS-1;bot1++)
  {
    for(bot2=bot1+1;bot2<NUMBOTS;bot2++)
    {
      bot1bouts=bot2bouts=0;
      printf("%s vs %s ",bots[bot1],bots[bot2]);
      for(bout=0;bout<BOUTSPERMATCH;bout++)
      {
        printf("%d ",bout);
        //setup the arena for the bout
        b1.x=1;b1.y=1;
        b2.x=9;
        //b1.y=rand()%10;
        b2.y=rand()%10;
        b1.energy=b2.energy=10;
        //clear the previous stuff
        memset(missiles, -1, sizeof(missiles));
        memset(bullets, -1, sizeof(bullets));
        memset(landmines, -1, sizeof(landmines));
        for(round=0;round<ROUNDSPERBOUT;round++)
        {
          //draw the arena based on current state
          cleararena(arena);
          totalprojectiles=0;
          for(loop=0;loop<MAXWEAPONS;loop++)
          {
            if(bullets[loop][0]!= -1)
            {
              arena[bullets[loop][1]][bullets[loop][0]]='B';
              sprintf(projectiles[totalprojectiles], "%c %d %d %s\n", 'B', bullets[loop][0], bullets[loop][1], directions[bullets[loop][2]]);
              totalprojectiles+=1;
            }
            if(missiles[loop][0]!= -1)
            {
              arena[missiles[loop][1]][missiles[loop][0]]='M';
              sprintf(projectiles[totalprojectiles], "%c %d %d %s\n", 'M', missiles[loop][0], missiles[loop][1], directions[missiles[loop][2]]);
              totalprojectiles+=1;
            }
            if(landmines[loop][0]!= -1)
            {
              arena[landmines[loop][1]][landmines[loop][0]]='L';
              sprintf(projectiles[totalprojectiles], "%c %d %d\n", 'L', landmines[loop][0], landmines[loop][1]);
              totalprojectiles+=1;
            }
          }

          //send the arena to both bots to get the commands
          // create bot1's input
          arena[b1.y][b1.x]='Y';
          arena[b2.y][b2.x]='X';
          sprintf(bot1string, "Y %d\n", b1.energy);
          sprintf(bot2string, "X %d\n", b2.energy);
          strcpy(argumentstring, "'");
          strncat(argumentstring, *arena, 10*11);
          strcat(argumentstring, bot1string);
          strcat(argumentstring, bot2string);
          for(loop=0;loop<totalprojectiles;loop++)
          {
            strcat(argumentstring, projectiles[loop]);
          }
          strcat(argumentstring, "'");
          sprintf(openstring, "%s %s", bots[bot1], argumentstring);
          // send it and get the command back
          fp=popen(openstring, "r");
          fgets(b1.cmd, 5, fp);
          fflush(NULL);
          pclose(fp);

          // create bot2's input
          arena[b2.y][b2.x]='Y';
          arena[b1.y][b1.x]='X';
          sprintf(bot2string, "Y %d\n", b2.energy);
          sprintf(bot1string, "X %d\n", b1.energy);
          strcpy(argumentstring, "'");
          strncat(argumentstring, *arena, 10*11);
          strcat(argumentstring, bot2string);
          strcat(argumentstring, bot1string);
          for(loop=0;loop<totalprojectiles;loop++)
          {
            strcat(argumentstring, projectiles[loop]);
          }
          strcat(argumentstring, "'");
          sprintf(openstring, "%s %s", bots[bot2], argumentstring);
          // send it and get the command back
          fp=popen(openstring, "r");
          fgets(b2.cmd, 5, fp);
          fflush(NULL);
          pclose(fp);

          if(DISPLAYBOUTS)
          {
            arena[b1.y][b1.x]='A';
            arena[b2.y][b2.x]='B';
            printf("\033c");
            printf("Round: %d\n", round);
            printf("%s", arena);
            sprintf(bot1string, "A %d\n", b1.energy);
            sprintf(bot2string, "B %d\n", b2.energy);
            printf("%s%s", bot1string, bot2string);
          }

          //do bot movement phase
          if(paralyzedturnsremaining==0)
          {
            // move bot 1 first
            bot1moved=false;
            dx=dy=0;
            dx=getxmove(b1.cmd);
            dy=getymove(b1.cmd);
            if(newposinbounds(b1.x, b1.y, dx, dy))
            {
              if(!(b1.x+dx==b2.x) || !(b1.y+dy==b2.y))
              {
                bot1moved=true;
                b1.x=b1.x+dx;
                b1.y=b1.y+dy;
              }
            }
            // move bot 2 next
            dx=dy=0;
            dx=getxmove(b2.cmd);
            dy=getymove(b2.cmd);
            if(newposinbounds(b2.x, b2.y, dx, dy))
            {
              if(!(b2.x+dx==b1.x) || !(b2.y+dy==b1.y))
              {
                b2.x=b2.x+dx;
                b2.y=b2.y+dy;
              }
            }
            if(!bot1moved) // if bot2 was in the way first time, try again
            {
              dx=dy=0;
              dx=getxmove(b1.cmd);
              dy=getymove(b1.cmd);
              if(newposinbounds(b1.x, b1.y, dx, dy))
              {
                if(!(b1.x+dx==b2.x) || !(b1.y+dy==b2.y))
                {
                  b1.x=b1.x+dx;
                  b1.y=b1.y+dy;
                }
              }
            }
            //check for landmine hits
            for(loop=0;loop<MAXWEAPONS;loop++)
            {
              if(landmines[loop][0]!= -1)
              {
                if(directhit(b1, landmines[loop]))
                {
                  b1.energy-=2;
                  if(inshrapnelrange(b2, landmines[loop]))
                  {
                    b2.energy-=1;
                  }
                  landmines[loop][0]= -1;
                  landmines[loop][1]= -1;
                }
                if(directhit(b2, landmines[loop]))
                {
                  b2.energy-=2;
                  if(inshrapnelrange(b1, landmines[loop]))
                  {
                    b1.energy-=1;
                  }
                  landmines[loop][0]= -1;
                  landmines[loop][1]= -1;
                }
              }
            }
          }
          else
          {
            paralyzedturnsremaining-=1;
          }
          //do weapons firing phase
          if(strcmp(b1.cmd, "P")==0)
          {
            paralyzedturnsremaining=2;
            b1.energy--;
          }
          else if(strcmp(b2.cmd, "P")==0)
          {
            paralyzedturnsremaining=2;
            b2.energy--;
          }
          deployweapons(&b1, &b2, bullets, missiles, landmines, directions);
          deployweapons(&b2, &b1, bullets, missiles, landmines, directions);
          //do weapons movement phase
          int moves;
          for(loop=0;loop<MAXWEAPONS;loop++)
          {
            dx=dy=0;
            if(bullets[loop][0]!= -1)
            {
              dx=getxmove(directions[bullets[loop][2]]);
              dy=getymove(directions[bullets[loop][2]]);
              for(moves=0;moves<3;moves++)
              {
                if(newposinbounds(bullets[loop][0], bullets[loop][1], dx, dy))
                {
                  bullets[loop][0]+=dx;
                  bullets[loop][1]+=dy;
                  if(directhit(b1, bullets[loop]))
                  {
                    b1.energy-=1;
                    bullets[loop][0]= -1;
                    bullets[loop][1]= -1;
                    bullets[loop][2]= -1;
                  }
                  if(directhit(b2, bullets[loop]))
                  {
                    b2.energy-=1;
                    bullets[loop][0]= -1;
                    bullets[loop][1]= -1;
                    bullets[loop][2]= -1;
                  }
                }
                else
                {
                  bullets[loop][0]= -1;
                  bullets[loop][1]= -1;
                  bullets[loop][2]= -1;
                  dx=dy=0;
                }
              }
            }
          };
          for(loop=0;loop<MAXWEAPONS;loop++)
          {
            dx=dy=0;
            if(missiles[loop][0]!= -1)
            {
              dx=getxmove(directions[missiles[loop][2]]);
              dy=getymove(directions[missiles[loop][2]]);
              for(moves=0;moves<2;moves++)
              {
                if(newposinbounds(missiles[loop][0], missiles[loop][1], dx, dy))
                {
                  missiles[loop][0]+=dx;
                  missiles[loop][1]+=dy;
                  if(directhit(b1, missiles[loop]))
                  {
                    b1.energy-=3;
                    if(inshrapnelrange(b2, missiles[loop]))
                    {
                      b2.energy-=1;
                    }
                    missiles[loop][0]= -1;
                    missiles[loop][1]= -1;
                    missiles[loop][2]= -1;
                  }
                  if(directhit(b2, missiles[loop]))
                  {
                    b2.energy-=3;
                    if(inshrapnelrange(b1, missiles[loop]))
                    {
                      b1.energy-=1;
                    }
                    missiles[loop][0]= -1;
                    missiles[loop][1]= -1;
                    missiles[loop][2]= -1;
                  }
                }
                else
                {
                  if(inshrapnelrange(b1, missiles[loop]))
                  {
                    b1.energy-=1;
                  }
                  if(inshrapnelrange(b2, missiles[loop]))
                  {
                    b2.energy-=1;
                  }
                  missiles[loop][0]= -1;
                  missiles[loop][1]= -1;
                  missiles[loop][2]= -1;
                  dx=dy=0;
                }
              }
            }
          }
          //check if there's a winner
          if(b1.energy<1 || b2.energy<1)
          {
            round=ROUNDSPERBOUT;
          }
        }
        // who has won the bout
        if(b1.energy<b2.energy)
        {
          bot2bouts+=1;
          boutswon[bot2]+=1;
        }
        else if(b2.energy<b1.energy)
        {
          bot1bouts+=1;
          boutswon[bot1]+=1;
        }
      }
      if(bot1bouts>bot2bouts)
      {
        matcheswon[bot1]+=1;
      }
      else if(bot2bouts>bot1bouts)
      {
        matcheswon[bot2]+=1;
      }
      printf("\n");
    }
  }
  // output final scores
  printf("\nResults:\n");
  printf("Bot\t\t\tMatches\tBouts\n");
  for(loop=0;loop<NUMBOTS;loop++)
  {
    printf("%s\t%d\t%d\n", bots[loop], matcheswon[loop], boutswon[loop]);
  }
}

int getxmove(char cmd[5])
{
  int dx=0;
  if(strcmp(cmd, "NE")==0)
    dx= 1;
  else if(strcmp(cmd, "E")==0)
    dx= 1;
  else if(strcmp(cmd, "SE")==0)
    dx= 1;
  else if(strcmp(cmd, "SW")==0)
    dx= -1;
  else if(strcmp(cmd, "W")==0)
    dx= -1;
  else if(strcmp(cmd, "NW")==0)
    dx= -1;

  return dx;
}
int getymove(char cmd[5])
{
  int dy=0;
  if(strcmp(cmd, "N")==0)
    dy= -1;
  else if(strcmp(cmd, "NE")==0)
    dy= -1;
  else if(strcmp(cmd, "SE")==0)
    dy= 1;
  else if(strcmp(cmd, "S")==0)
    dy= 1;
  else if(strcmp(cmd, "SW")==0)
    dy= 1;
  else if(strcmp(cmd, "NW")==0)
    dy= -1;

  return dy;
}
int newposinbounds(int oldx, int oldy, int dx, int dy)
{
  return (oldx+dx>=0 && oldx+dx<10 && oldy+dy>=0 && oldy+dy<10);
}
int directhit(Bot bot, int landmine[2])
{
  return (bot.x==landmine[0] && bot.y==landmine[1]);
}
int landminecollision(int landmine1[2], int landmine2[2])
{
  return ((landmine1[1]==landmine2[1]) && abs(landmine1[0]==landmine2[0]));
}
int inshrapnelrange(Bot bot, int landmine[2])
{
  return (abs(bot.x-landmine[0])<2 && abs(bot.y-landmine[1])<2);
}
int directiontoint(char direction[5], char directions[8][3])
{
  int loop,returnval=8;
  for(loop=0;loop<8;loop++)
  {
    if(strcmp(directions[loop], direction)==0)
      returnval=loop;
  }
  return returnval;
}
void deployweapons(Bot *bot, Bot *enemy, int bullets[MAXWEAPONS][3], int missiles[MAXWEAPONS][3], int landmines[MAXWEAPONS][2], char directions[8][3])
{
  int loop;
  if(strlen(bot->cmd)>2)
  {
    if(bot->cmd[0]=='B')
    {
      int weaponslot=0;
      while(bullets[weaponslot][0]!= -1)
        weaponslot+=1;
      bullets[weaponslot][0]=bot->x;
      bullets[weaponslot][1]=bot->y;
      bullets[weaponslot][2]=directiontoint(bot->cmd+2, directions);
      if(bullets[weaponslot][2]>7)
      {
        // direction wasn't recognized so clear the weapon
        bullets[weaponslot][0]= -1;
        bullets[weaponslot][1]= -1;
        bullets[weaponslot][2]= -1;
      }
    }
    if(bot->cmd[0]=='M')
    {
      int weaponslot=0;
      while(missiles[weaponslot][0]!= -1)
        weaponslot+=1;
      missiles[weaponslot][0]=bot->x;
      missiles[weaponslot][1]=bot->y;
      missiles[weaponslot][2]=directiontoint(bot->cmd+2, directions);
      if(missiles[weaponslot][2]>7)
      {
        // direction wasn't recognized so clear the weapon
        missiles[weaponslot][0]= -1;
        missiles[weaponslot][1]= -1;
        missiles[weaponslot][2]= -1;
      }
    }
    if(bot->cmd[0]=='L')
    {
      int weaponslot=0;
      while(landmines[weaponslot][0]!= -1)
        weaponslot+=1;
      if(newposinbounds(bot->x, bot->y, getxmove(bot->cmd+2), getymove(bot->cmd+2)))
      {
        landmines[weaponslot][0]=bot->x+getxmove(bot->cmd+2);
        landmines[weaponslot][1]=bot->y+getymove(bot->cmd+2);

        //check for landmine hits
        for(loop=0;loop<MAXWEAPONS;loop++)
        {
          if(landmines[loop][0]!= -1)
          {
            if(landminecollision(landmines[weaponslot], landmines[loop]) && weaponslot!=loop)
            {
              if(inshrapnelrange(*bot, landmines[loop]))
              {
                bot->energy-=1;
              }
              if(inshrapnelrange(*enemy, landmines[loop]))
              {
                enemy->energy-=1;
              }
              landmines[loop][0]= -1;
              landmines[loop][1]= -1;
              landmines[weaponslot][0]= -1;
              landmines[weaponslot][1]= -1;
            }
          }
        }
      }
    }
  }
}
void cleararena(char arena[10][11])
{
  int loop;
  memset(arena, '.', 110);
  for(loop=0;loop<10;loop++)
  {
    arena[loop][10]='\n';
  }
}

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

ইন্টেক্স 13 কিছু বাগ বাগের সাহায্যে কন্ট্রোল প্রোগ্রামের আরও দৃ version় সংস্করণ লিখেছিল যা আপনি এখানে দেখতে পাচ্ছেন ।

নিয়ন্ত্রণ প্রোগ্রামে উন্নতি বা বাগ-সমাধানের পরামর্শগুলি স্বাগত।

পরীক্ষা বট

কোনটি পরীক্ষা বট এর স্কোরিং রানে অন্তর্ভুক্ত করা হবে। তারা কেবল পরীক্ষার উদ্দেশ্যে।

ডডলি ডনউট (সি)

int main(int argc, char *argv)
{
  printf("0");
}

পরিস্থিতি নির্বিশেষে কিছুই করে না। বেশি জয়ের আশা করা যায় না।

হিউজিবট (পিএইচপি)

<?php
$arena=$argv[1];
list($meX, $meY)=findMe($arena);
list($oppX, $oppY)=findOpp($arena);
if($meY<$oppY)
{
  if($meX<$oppX)
    echo "SE";
  elseif($meX==$oppX)
    echo "S";
  else
    echo "SW";
}
elseif($meY==$oppY)
{
  if($meX<$oppX)
    echo "E";
  else
    echo "W";
}
else
{
  if($meX<$oppX)
    echo "NE";
  elseif($meX==$oppX)
    echo "N";
  else
    echo "NW";
}

function findMe($arena)
{
  return find("Y", explode("\n", $arena));
}

function findOpp($arena)
{
  return find("X", explode("\n", $arena));
}

function find($char, $array)
{
  $x=0;
  $y=0;
  for($loop=0;$loop<10;$loop++)
  {
    if(strpos($array[$loop], $char)!==FALSE)
    {
      $x=strpos($array[$loop], $char);
      $y=$loop;
    }
  }
  return array($x, $y);
}
?>

প্রতিপক্ষের ঠিক পাশেই যাওয়ার চেষ্টা করে। ল্যান্ডমাইনগুলির পক্ষে ক্ষতিগ্রস্থ কারণ এটি তাদের সন্ধান করে না। প্রতিপক্ষ যখন লক্ষ্য অর্জন করে তখন গুলি চালানোর ক্ষেপণাস্ত্রগুলি কম কার্যকর কৌশল করে তোলে।

ফলাফলগুলো

চূড়ান্ত স্কোরিং রান 24 শে মার্চ 2014 এ 23:59 এর পরে করা হবে । আমি নিয়মিত পরীক্ষার রান চালাতাম যাতে প্রবেশকারীরা দেখতে পান যে তাদের বट्स কীভাবে বর্তমান বিরোধী দলের বিরুদ্ধে সজ্জিত করছে।

এন্ট্রি

এন্ট্রিগুলিতে আপনার বটের উত্স এবং কমান্ড লাইন যুক্তিটি এটি চালাতে ব্যবহার করা উচিত। আপনার পছন্দমতো আলাদা আলাদা পোস্ট পোস্ট করা আপনাকে স্বাগত জানায় তবে প্রতিটি উত্তরে কেবল একটি বট থাকা উচিত ।

গুরুত্বপূর্ণ

মনে হচ্ছে কিছু এন্ট্রি রানের মাঝে কিছুটা স্থিতি বজায় রাখতে ডিস্কে লিখতে চায়। এগুলি ডিস্কে লেখার বিষয়ে নতুন নিয়ম।

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

1
দুঃখিত আমি এটি স্যান্ডবক্সে ধরিনি: সমস্ত অস্ত্র সরবরাহ কি অসীম?
জোনাথন ভ্যান মাত্রে

2
@ ইন্টেক্স 13 সম্ভবত বট 1 এবং বট 2 এর সাথে বোটটি যথাযথভাবে প্রতিটি প্রতিদ্বন্দ্বী হওয়া উচিত নয়, বরং এলোমেলোভাবে কেবল প্রথম প্রথম বাউটে বেছে নেওয়া হবে এবং প্রতিটি নিম্নলিখিত লড়াইয়ের শুরুতে অদলবদল করা হবে।
আরশাজী

2
আমি মনে করি @ intx13 এর কোডটিতে আমি একটি বাগ পেয়েছি। যখন উভয় বট একই সময়ে EMP ফায়ার করে, তখন আমি মনে করি উভয়ের শক্তি হারাতে হবে। আমি তার কোডটি চালাইনি, তবে এটির দিকে তাকালে এটি কেস বলে মনে হয় না। লাইনগুলি দেখুন 295-304 github.com/gazrogers/CodegolfBattlebotsScorer/blob/master/…
টমাস এডিং

2
আর একটি সম্ভাব্য বাগ। দেখে মনে হচ্ছে যে বট শক্তি শূন্যের নীচে যেতে পারে। এটি ঠিক আছে, তবে যদি বট 1 এর -1 শক্তি থাকে এবং বট 2 এর 0 শক্তি থাকে, উভয়ই কোনও জয় অর্জন করতে পারে না।
থমাস এডিং

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

উত্তর:


14

EvilBot

একটি বট যা যতটা সম্ভব দুষ্ট হওয়ার চেষ্টা করে

আমি যা পেয়েছি তা এখানে: একটি জাভা বট যা প্রতিপক্ষের কাছে যতটা সম্ভব আখেরার কেন্দ্রের চারদিকে 2.5 ব্যাসার্ধের একটি বৃত্তাকার স্ট্রিপটি পেতে চেষ্টা করে এবং তারপরে যতটা সম্ভব ক্ষতি করতে পারে damage তার আন্দোলন প্যাটার্ন প্রতিবেশী স্কোয়ার প্রতিটি একটি "বিপদ" মান নির্ধারণের, এবং এই মান উপর ভিত্তি করে সরাতে করার সিদ্ধান্ত নেওয়ার উপর ভিত্তি করে তৈরি এবং একটা প্রবণতা তার উপর ভিত্তি করে এরিনা কেন্দ্রে সম্পর্কে ব্যাসার্ধ 2.5 একটি বৃত্তাকার অঞ্চলে যেমন ঘনিষ্ঠ যাবে। আমি @ জিওবিটসের উত্তর থেকে কিছু বাদাম এবং বল্ট ব্যবহার করেছি (যেমন একটি বিমূর্ততা থাকা)BattleBotক্লাস এবং পার্সিং কৌশল), তাই ধন্যবাদ! আমি সম্ভবত আমার এতদূর যা কিছু আছে তা সংশোধন / প্রসারিত করতে যাচ্ছি, যদিও এটি এখন পর্যন্ত পোস্ট করা অন্যান্য বটগুলির সাথে যথেষ্ট পরিমাণে ভাড়াও দেয়। কোডটি নীচে রয়েছে। (অন্য কেউ যদি জাভা ব্যবহার করে থাকে তবে আমার বিমূর্ত / সহায়ক ক্লাসগুলি নির্দ্বিধায় ব্যবহার করুন))

( EvilBot.java)

import java.io.File; // debugging
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner; // debugging

class Point {

    private int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public int distTo(Point other) {
        return Math.max(Math.abs(x - other.x), Math.abs(y - other.y));
    }

    public double conventionalDistTo(Point other) {
        return Math.hypot(x - other.x, y - other.y);
    }

    @Override
    public boolean equals(Object other) {
        if (!(other instanceof Point))
            return false;

        Point otherPoint = (Point) other;

        return x == otherPoint.x && y == otherPoint.y;
    }

    @Override
    public int hashCode() {
        return x * (1 << Arena.ARENA_SIZE) + y;
    }

    @Override
    public String toString() {
        return "(" + x + "," + y + ")";
    }
}

interface ArenaElement {
    char getSymbol();
}

enum Projectile implements ArenaElement {

    BULLET('B', 3, 1) {

    },

    MISSILE('M', 2, 3) {

    },

    LANDMINE('L', 0, 2) {
        @Override
        public int timeUntilImpact(Point current, Point target, Direction dir) {
            return current.equals(target) ? 0 : -1;
        }
    };

    private final char symbol;
    private final int speed;
    private final int damage;

    private Projectile(char symbol, int speed, int damage) {
        this.symbol = symbol;
        this.speed = speed;
        this.damage = damage;
    }

    @Override
    public char getSymbol() {
        return symbol;
    }

    public int getSpeed() {
        return speed;
    }

    public int getDamage() {
        return damage;
    }

    public static Projectile fromSymbol(char symbol) {
        for (Projectile p : values()) {
            if (p.getSymbol() == symbol)
                return p;
        }

        return null;
    }

    public int timeUntilImpact(Point current, Point target, Direction dir) {

        final int dx = target.getX() - current.getX();
        final int dy = target.getY() - current.getY();

        if (!(dx == 0 || dy == 0 || dx == dy || dx == -dy))
            return -1;

        if (dx == 0) {
            if (dy > 0 && dir != Direction.N)
                return -1;

            if (dy < 0 && dir != Direction.S)
                return -1;
        }
        if (dy == 0) {
            if (dx > 0 && dir != Direction.E)
                return -1;

            if (dx < 0 && dir != Direction.W)
                return -1;
        }
        if (dx == dy) {
            if (dx > 0 && dir != Direction.NE)
                return -1;

            if (dx < 0 && dir != Direction.SW)
                return -1;
        }
        if (dx == -dy) {
            if (dx > 0 && dir != Direction.SE)
                return -1;

            if (dx < 0 && dir != Direction.NW)
                return -1;
        }

        int dist = target.distTo(current);

        return (dist / speed) + (dist % speed == 0 ? 0 : 1);
    }
}

enum BotType implements ArenaElement {

    ME('Y'), ENEMY('X');

    private final char symbol;

    private BotType(char symbol) {
        this.symbol = symbol;
    }

    @Override
    public char getSymbol() {
        return symbol;
    }

    public static BotType fromSymbol(char symbol) {
        for (BotType bt : values()) {
            if (bt.getSymbol() == symbol)
                return bt;
        }

        return null;
    }
}

enum EmptySpot implements ArenaElement {

    EMPTY;

    @Override
    public char getSymbol() {
        return '.';
    }

    public static EmptySpot fromSymbol(char symbol) {
        for (EmptySpot es : values()) {
            if (es.getSymbol() == symbol)
                return es;
        }

        return null;
    }
}

enum Direction {
    N, NE, E, SE, S, SW, W, NW
}

class Arena {

    public static final int ARENA_SIZE = 10;
    public static final Point center = new Point(ARENA_SIZE / 2, ARENA_SIZE / 2);

    private ArenaElement[][] arena;

    private Arena(boolean fill) {
        arena = new ArenaElement[ARENA_SIZE][ARENA_SIZE];

        if (!fill)
            return;

        for (int i = 0; i < ARENA_SIZE; i++) {
            for (int j = 0; j < ARENA_SIZE; j++) {
                arena[i][j] = EmptySpot.EMPTY;
            }
        }
    }

    public boolean inBounds(int x, int y) {
        return x >= 0 && x < ARENA_SIZE && y >= 0 && y < ARENA_SIZE;
    }

    public boolean inBounds(Point p) {
        final int x = p.getX(), y = p.getY();
        return inBounds(x, y);
    }

    public ArenaElement get(int x, int y) {
        if (!inBounds(x, y)) {
            return null; // be cautious of this
        }

        return arena[ARENA_SIZE - 1 - y][x];
    }

    public ArenaElement get(Point p) {
        return get(p.getX(), p.getY());
    }

    // note: a point is considered its own neighbor
    public List<Point> neighbors(Point p) {
        List<Point> neighbors = new ArrayList<Point>(9);

        for (int i = -1; i <= 1; i++) {
            for (int j = -1; j <= 1; j++) {
                Point p1 = new Point(p.getX() + i, p.getY() + j);

                if (get(p1) != null)
                    neighbors.add(p1);
            }
        }

        return neighbors;
    }

    public Point findMe() {
        for (int i = 0; i < ARENA_SIZE; i++) {
            for (int j = 0; j < ARENA_SIZE; j++) {
                if (get(i, j) == BotType.ME)
                    return new Point(i, j);
            }
        }

        return null;
    }

    public Point findEnemy() {
        for (int i = 0; i < ARENA_SIZE; i++) {
            for (int j = 0; j < ARENA_SIZE; j++) {
                if (get(i, j) == BotType.ENEMY)
                    return new Point(i, j);
            }
        }

        return null;
    }

    public Point impactOfRayFromPointInDirection(Point p, Direction dir) {
        int x = p.getX(), y = p.getY();

        switch (dir) {
        case N:
            y += (Arena.ARENA_SIZE - 1 - y);
            break;
        case NE: {
            int dx = (Arena.ARENA_SIZE - 1 - x);
            int dy = (Arena.ARENA_SIZE - 1 - y);

            int off = Math.max(dx, dy);

            x += off;
            y += off;
            break;
        }
        case E:
            x += (Arena.ARENA_SIZE - 1 - x);
            break;
        case SE: {
            int dx = (Arena.ARENA_SIZE - 1 - x);
            int dy = y;

            int off = Math.max(dx, dy);

            x += off;
            y -= off;
            break;
        }
        case S:
            y = 0;
            break;
        case SW: {
            int dx = x;
            int dy = y;

            int off = Math.max(dx, dy);

            x -= off;
            y -= off;
            break;
        }
        case W:
            x = 0;
            break;
        case NW: {
            int dx = x;
            int dy = (Arena.ARENA_SIZE - 1 - y);

            int off = Math.max(dx, dy);

            x -= off;
            y += off;
            break;
        }
        }

        return new Point(x, y);
    }

    private static ArenaElement fromSymbol(char symbol) {
        ArenaElement e = EmptySpot.fromSymbol(symbol);

        if (e != null)
            return e;

        e = Projectile.fromSymbol(symbol);

        if (e != null)
            return e;

        return BotType.fromSymbol(symbol);
    }

    public static Arena parse(String[] input) {
        Arena arena = new Arena(false);

        for (int i = 0; i < ARENA_SIZE; i++) {
            for (int j = 0; j < ARENA_SIZE; j++) {
                char symbol = input[i].charAt(j);

                arena.arena[i][j] = fromSymbol(symbol);
            }
        }

        return arena;
    }
}

abstract class BaseBot {

    protected static class ProjectileInfo {
        Projectile projectile;
        Point position;
        Direction direction;

        @Override
        public String toString() {
            return projectile.toString() + " " + position + " " + direction;
        }
    }

    protected Arena arena;

    protected Point myPos;
    protected int energy;

    protected Point enemyPos;
    protected int enemyEnergy;

    public List<ProjectileInfo> projectiles;

    public BaseBot(String[] args) {
        if (args.length < 1)
            return;

        String[] lines = args[0].split("\r?\n");

        projectiles = new ArrayList<ProjectileInfo>(lines.length
                - Arena.ARENA_SIZE - 2);

        arena = Arena.parse(lines);
        myPos = arena.findMe();
        enemyPos = arena.findEnemy();

        for (int i = Arena.ARENA_SIZE; i < lines.length; i++) {
            parseInputLine(lines[i]);
        }
    }

    private void parseInputLine(String line) {
        String[] split = line.split(" ");

        char c0 = line.charAt(0);
        if (c0 == 'Y') {
            energy = Integer.parseInt(split[1]);
        } else if (c0 == 'X') {
            enemyEnergy = Integer.parseInt(split[1]);
        } else {
            ProjectileInfo pinfo = new ProjectileInfo();
            pinfo.projectile = Projectile.fromSymbol(split[0].charAt(0));
            pinfo.position = new Point(Integer.parseInt(split[1]),
                    Arena.ARENA_SIZE - 1 - Integer.parseInt(split[2]));

            if (split.length > 3)
                pinfo.direction = Direction.valueOf(split[3]);

            projectiles.add(pinfo);
        }
    }

    abstract String getMove();
}

public class EvilBot extends BaseBot {

    public static final boolean DEBUG = false;

    public static void main(String... args) throws Exception {
        if (DEBUG) {
            StringBuffer input = new StringBuffer();
            Scanner scan = new Scanner(new File("a.txt"));

            while (scan.hasNextLine()) {
                input.append(scan.nextLine());
                input.append('\n');
            }

            scan.close();

            args = new String[] { input.toString() };
        }

        System.out.print(new EvilBot(args).getMove());
    }

    public EvilBot(String[] args) {
        super(args);
    }

    /*
     * Direction to p if perfectly aligned, null otherwise
     */
    private Direction getDirTo(Point p) {

        final int dx = p.getX() - myPos.getX();
        final int dy = p.getY() - myPos.getY();

        if (dx == 0) {
            return (dy > 0) ? Direction.N : Direction.S;
        }
        if (dy == 0) {
            return (dx > 0) ? Direction.E : Direction.W;
        }
        if (dx == dy) {
            return (dy > 0) ? Direction.NE : Direction.SW;
        }
        if (dx == -dy) {
            return (dy > 0) ? Direction.NW : Direction.SE;
        }

        return null;
    }

    /*
     * Direction towards p (best approximation)
     */
    private Direction getDirTowards(Point p) {
        Direction minDir = null;
        double minDist = 0;

        for (Direction dir : Direction.values()) {
            double dist = arena.impactOfRayFromPointInDirection(myPos, dir)
                    .conventionalDistTo(p);

            if (minDir == null || dist < minDist) {
                minDir = dir;
                minDist = dist;
            }
        }

        return minDir;
    }

    private boolean isEnemyCloseToWall() {
        return (enemyPos.getX() < 2 || enemyPos.getY() < 2
                || enemyPos.getX() > Arena.ARENA_SIZE - 3 || enemyPos.getY() > Arena.ARENA_SIZE - 3);
    }

    private String missileAttack() {
        return "M " + getDirTowards(enemyPos);
    }

    @Override
    public String getMove() {
        List<Point> neighbors = arena.neighbors(myPos);

        Map<Point, Double> dangerFactors = new HashMap<Point, Double>();

        for (Point neighbor : neighbors) {

            double dangerFactor = 0;

            if (arena.get(neighbor) == Projectile.LANDMINE) {
                dangerFactor += 2;
            }

            for (ProjectileInfo pi : projectiles) {

                int time = pi.projectile.timeUntilImpact(pi.position, neighbor,
                        pi.direction);

                if (time > 0) {
                    dangerFactor += ((double) pi.projectile.getDamage()) / time;
                }
            }

            dangerFactors.put(neighbor, dangerFactor);
        }

        if (dangerFactors.get(myPos) == 0) {
            // we are safe for now...

            Direction dir = getDirTo(enemyPos);
            boolean closeToWall = isEnemyCloseToWall();

            if (dir != null) {
                int dist = myPos.distTo(enemyPos);

                if (dist < Projectile.MISSILE.getSpeed() * 2) {
                    return "M " + dir;
                } else {
                    return "B " + dir;
                }
            } else if (closeToWall) {

                if (Math.random() > 0.5) // so we don't get caught in loops
                    return missileAttack();
            }
        }

        // move!
        double leastDanger = Double.POSITIVE_INFINITY;

        for (Entry<Point, Double> entry : dangerFactors.entrySet()) {
            if (entry.getValue() < leastDanger)
                leastDanger = entry.getValue();
        }

        Point moveTo = null;

        for (Entry<Point, Double> entry : dangerFactors.entrySet()) {
            if (entry.getKey().equals(myPos))
                continue;

            if (entry.getValue() == leastDanger) {

                double d1 = entry.getKey().conventionalDistTo(Arena.center);
                double d2 = moveTo == null ? 0 : moveTo
                        .conventionalDistTo(Arena.center);

                if (moveTo == null || Math.abs(d1 - 2.5) < Math.abs(d2 - 2.5)) {

                    moveTo = entry.getKey();
                }
            }
        }

        if (moveTo == null) {
            return missileAttack();
        }

        return getDirTo(moveTo).toString();
    }
}

ব্যবহার:

javac EvilBot.java
java EvilBot <input>

নোট:

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

  • বর্তমানে ইএমপি ব্যবহার হচ্ছে না। আমি প্রতিপক্ষের সাথে সারিবদ্ধ হওয়ার এবং মিসাইলের পরে EMP গুলি চালানোর কৌশল চেষ্টা করেছি, তবে এর কয়েকটি পাল্টে কৌশল রয়েছে যা প্রায় 100% সময় জিততে পারে, তাই আমি সেই পথটি ত্যাগ করার সিদ্ধান্ত নিয়েছিলাম। আমি পরে বিভিন্ন উপায়ে ইএমপি ব্যবহার করে অন্বেষণ করতে পারি।


গড়ে, এভিলবট স্ট্রেট শ্যুটারকে 5-0 এবং ডজিং ট্র্যাজেটকে 2-0 ব্যবধানে পরাজিত করে। এটি ডডজিং ট্যুরেটের সাথে অনেকগুলি সম্পর্কযুক্ত।
intx13

@ intx13 হ্যাঁ আমি এটিও লক্ষ্য করেছি। এভিলবট এবং ডজিং ট্যুরেট উভয়ই কিংয়ের শেষ স্ট্যান্ডের সাথে টাই করে; গেমটি অসীম লুপকে হ্রাস করে।
আর্শাজি

2
অভিনন্দন, আপনি জিতেছেন!
গ্যারেথ

17

Rifter

এই বটটি কী বট লড়াই করছে তার ভিত্তিতে বিভিন্ন পদক্ষেপ নেয়। প্রতিপক্ষকে নির্ধারণ করার জন্য, এটি তার নিজের রাজ্যে উল্টায় এবং তারা কী করবে তা দেখার জন্য এটি অন্য বোটগুলিতে ফিড করে এবং তারা আসলে কী করে তার সাথে তার তুলনা করে। একবার তারা 'সঠিক' পদক্ষেপের একটি প্রান্তে আঘাত করলে এটি অন্যদের পরীক্ষা করা বন্ধ করে দেয়।

এটি একবার কী যুদ্ধ করছে তা জানার পরে পরবর্তী বারে এটি কোথায় থাকবে তা সাধারণত তা জানে তাই এটি তাদের বর্তমান অবস্থানের পরিবর্তে সেখানে গুলি চালাতে পারে।

অবশ্যই, কিছু ত্রুটি আছে। একটি হ'ল "ব্যান্ডম" ক্রিয়াকলাপযুক্ত বটগুলি এত ভালভাবে সনাক্ত করা যায় নি। প্রতিপক্ষের জানা না থাকলে রাজার সর্বশেষ স্ট্যান্ড যুক্তি ব্যবহার করে এটি ভারসাম্যপূর্ণ।

তবে, যদি কোনও বট নিখুঁতভাবে নির্জনবাদী হয় তবে এটি কে তা খুঁজে বের করার কোনও সমস্যা নেই । এরপরে প্রতিটি প্রতিপক্ষের পক্ষে তার যুক্তিতে আরও কেস যুক্ত করে সহজেই পরিস্থিতির সাথে মানিয়ে নেওয়া যায়। উদাহরণস্বরূপ, লাস্ট স্ট্যান্ডের সাথে লড়াই করা, এটি তাকে কোণঠাসা করবে, 2x1 দূরে দাঁড়াবে যাতে সে সরাসরি সরানো বা আগুন জ্বালাতে না পারে এবং পিছনে প্রাচীরের মধ্যে ক্ষেপণাস্ত্রগুলি গুলি করতে পারে এবং স্প্ল্যাশ ক্ষতির সাথে হত্যা করে killing

আমার অন্যদের মতো এটিও ব্যাটেলবট.জভা প্রসারিত করে:

import java.awt.Point;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Rifter extends BattleBot{

    String output="0";
    String state;
    String oldState = null;
    List<Rift> rifts;
    Rift chosen;
    List<Point> safe;
    Point probable;
    int round;

    final int testCount = 100;

    Rifter(String[] args) {
        super(args.length>0?args:testState);
        state = args.length>0?args[0]:testState[0];
        round = 0;
    }

    public static void main(String[] args) {
        debug = false;
        System.out.print(new Rifter(args).execute());
    }

    @Override
    String execute() {
        if(!valid)
            return "0";
        init();
        probable = getLikelyPosition();
        if(!safe.contains(yPosition) && evade())
            return output;
        if(riftShift())
            return output;
        return fallback();
    }

    boolean riftShift(){
        if(chosen==null)
            return false;
        if("P".equals(chosen.nextAction))
            return fireAt(xPosition, true);
        switch(getChosenIndex()){
        case 1:
            output = fightStand();
            break;
        case 2:
            output = fightEvil();
            break;
        default:
            output = fallback();
        }
        return output.equals("0")?false:true;
    }

    int getChosenIndex(){
        for(int i=0;i<baseBots.length;i++)
            if(chosen.bot.equals(baseBots[i]))
                return i;
        return -1;
    }

    int distanceToWall(Point pos){
        int min = Math.min(pos.x,  pos.y);
        min = Math.min(min, (arenaSize - 1) - pos.x);
        return Math.min(min, (arenaSize - 1) - pos.y);
    }

    String fightStand(){
        int wall = distanceToWall(xPosition);
        if(wall > 0 || distance(yPosition, probable) > 2){
            if(moveToward(probable, NONE))
                return output;
            if(fireAt(probable, false))
                return output;
        }

        if(probable.x==0 && probable.y==0)
            return "M NW";
        if(probable.x==arenaSize-1 && probable.y==0)
            return "M NE";
        if(probable.x==arenaSize-1 && probable.y == arenaSize-1)
            return "M SE";
        if(probable.x==0 && probable.y == arenaSize-1)
            return "M SW";
        if(probable.x==0)
            return "M W";
        if(probable.x==arenaSize-1)
            return "M E";
        if(probable.y==0)
            return "M N";
        if(probable.y==arenaSize-1)
            return "M S";

        return "M " + headings[headingToPoint(probable)];
    }

    String fightEvil(){
        if(areAligned(yPosition,xPosition)){
            if(distance(yPosition,xPosition)>3)
                if(moveToward(probable,UNALIGN))
                    return output;
            if(fireAt(probable, false))
                return output;
        }
        if(fireAt(probable, false))
            return output;
        if(moveToward(center, ALIGN))
            return output;
        return "0";
    }

    String fallback(){
        output = getOutputFrom(fallbackBots[rand.nextInt(fallbackBots.length)]);
        if(output==null)
            output="0";
        return output;
    }

    int NONE = 0;
    int ALIGN = 1;
    int UNALIGN = 2;

    boolean moveToward(Point target, int align){
        Point closest = new Point(-99,-99);
        for(Point pos : safe){
            if(pos.equals(yPosition))
                continue;
            if(distance(pos,target) < distance(closest,target)){
                if(areAligned(pos,target) && align == UNALIGN)
                    continue;
                if(!areAligned(pos,target) && align == ALIGN)
                    continue;
                closest = pos;
            }
        }

        if(isOutside(closest))
            for(Point pos : safe)
                    if(distance(pos,target) < distance(closest,target))
                        closest = pos;      
        if(distance(closest,target) > distance(yPosition,target))
            return false;
        output = headings[headingToPoint(closest)];
        return true;
    }

    boolean fireAt(Point target, boolean override){
        if(!override && !areAligned(yPosition, target))
            return false;
        int dist = distance(yPosition, target);
        if(!override && dist>3)
            return false;
        int heading = headingToPoint(target);
        output = "M ";
        if(dist > 3 || dist == 1)
            output = "B ";
        output += headings[heading];
        return true;
    }

    String getOutputFrom(String bot){
        return new Rift(bot,0).foretell(state);
    }

    boolean evade(){
        if(safe.isEmpty())
            return false;
        Point dest = null;
        for(Point pos : safe)
            if(areAligned(pos,probable))
                dest = pos;
        if(dest==null){
            output = getOutputFrom("java LastStand");
            return true;
        }
        output = headings[headingToPoint(dest)];
        return true;
    }

    Point getLikelyPosition(){
        if(chosen!=null)
            return chosen.getNextPosition(null);
        if(round > testCount)
            return xPosition;

        int[] arena = new int[arenaSize*arenaSize];
        for(Rift rift : rifts){
            Point next = rift.getNextPosition(null);
            if(!isOutside(next))
                arena[next.y*arenaSize+next.x]++;
        }
        int max = 0, index = -1;
        for(int i=0;i<arena.length;i++){
            if(arena[i] > max){
                max = arena[i];
                index = i;
            }
        }
        Point dest = new Point(index%arenaSize, index/arenaSize);
        return isOutside(dest)?xPosition:dest;
    }

    boolean areAligned(Point a, Point b){
        int x = Math.abs(a.x - b.x);
        int y = Math.abs(a.y - b.y);
        if(x==0 || y==0 || x==y)
            return true;
        return false;
    }

    void init(){
        safe = new ArrayList<Point>();
        if(spotCollision(yPosition)==null)
            safe.add(yPosition);

        for(int heading=0;heading<8;heading++){
            Point pos = nextPosition(heading, yPosition);
            if(isOutside(pos))
                continue;
            if(spotCollision(pos)==null)
                safe.add(pos);
        }

        loadBots(readState());
        updateRifts();
        writeState();
    }

    void updateRifts(){
        if(chosen == null && round < testCount)
            for(Rift rift : rifts)
                if(rift.validate(oldState))
                    rift.correct++;
    }

    Rift chooseBot(){
        double avg = 0.0;
        int highest = 0;
        Rift choice = null;

        for(Rift rift : rifts){
            avg += rift.correct;
            if(rift.correct >= highest){
                highest = rift.correct;
                choice = rift;
            }
        }
        avg /= rifts.size();
        if(choice!= null && (choice.correct > 8) && choice.correct > avg*2)
            return choice;
        else
            return null;
    }

    boolean writeState(){
        File dir = new File("state");
        dir.mkdirs();
        File file = new File("state/rifter.state");
        try {
            BufferedWriter writer = new BufferedWriter(new FileWriter(file));
            writer.write(">" + round + "\n");
            for(Rift rift : rifts)
                writer.write(":" + rift.correct + "|" + rift.bot + "\n");
            writer.write(state);
            writer.flush();
            writer.close();
        } catch (IOException e) {
            log(e.getMessage());
            return false;
        }
        return true;
    }

    List<String> readState(){
        List<String> bots = new ArrayList<String>();
        File file = new File("state/rifter.state");
        if(file.exists()){
            try {
                BufferedReader reader = new BufferedReader(new FileReader(file));
                String line;
                String oldState = "";
                line = reader.readLine();
                if(line != null && line.startsWith(">"))
                    round = Integer.valueOf(line.substring(1)) + 1;
                while((line = reader.readLine()) != null){
                    if(line.startsWith(":"))
                        bots.add(line.substring(1));
                    else 
                        oldState += line + "\n";                                            
                }
                reader.close();
                BattleBot bot = new Rifter(new String[]{oldState});
                if(isStateInvalid(bot)){
                    bots.clear();
                    oldState = "";
                    round = 0;
                }
                this.oldState = oldState;
            } catch(Exception e){
                log(e.getMessage());
                bots.clear();
                this.oldState = "";
            }
        }
        return bots.isEmpty()?Arrays.asList(baseBots):bots;
    }

    boolean isStateInvalid(BattleBot bot){
        if(!bot.valid)
            return true;
        if(distance(bot.xPosition, xPosition) > 1)
            return true;
        if(distance(bot.yPosition, yPosition) > 1)
            return true;
        if(xEnergy > bot.xEnergy || yEnergy > bot.yEnergy)
            return true;
        return false;
    }

    List<Rift> loadBots(List<String> bots){
        rifts = new ArrayList<Rift>();
        String flipped = flipState(state);
        for(String bot : bots){
            String[] tokens = bot.split("\\|");
            Rift rift;
            if(tokens.length < 2)
                rift = new Rift(bot, 0);
            else
                rift = new Rift(tokens[1], Integer.valueOf(tokens[0]));         
            rifts.add(rift);
        }
        if((chosen = chooseBot()) == null)
            if(round < testCount)
                for(Rift rift : rifts)
                    rift.nextAction = rift.foretell(flipped);
        else
            chosen.nextAction = chosen.foretell(flipped);

        return rifts;
    }

    String flipState(String in){
        String tmp = in.replaceAll("X", "Q");
        tmp = tmp.replaceAll("Y", "X");
        tmp = tmp.replaceAll("Q", "Y");
        String[] lines = tmp.split("\\r?\\n");
        tmp = lines[arenaSize];
        lines[arenaSize] = lines[arenaSize+1];
        lines[arenaSize+1] = tmp;
        String out = "";
        for(int i=0;i<lines.length;i++)
            out += lines[i] + "\n";
        return out.trim();
    }

    class Rift{
        String bot;
        String nextAction;
        String state;
        String nextState;
        int correct;

        Rift(String name, int count){
            bot = name;
            correct = count;
        }

        Point getNextPosition(String action){
            if(action==null)
                action = nextAction;
            if(action==null || action.length()<1)
                return xPosition;
            int heading = getHeading(action.split(" ")[0]);
            return nextPosition(heading, xPosition);
        }

        boolean validate(String oldState){
            boolean valid = true;
            if(oldState == null)
                return valid;
            if(oldState.split("\\r?\\n").length < 12)
                return valid;
            String action = foretell(flipState(oldState));
            if(action==null || action.length() < 1){
                log(this.bot + " : " + "invalid action");
                return valid;
            }
            BattleBot bot = new Rifter(new String[]{oldState});
            switch(action.charAt(0)){
            case 'B':
            case 'M':
            case 'L':
                valid = testShot(action, bot);
                break;
            case 'P':
            case '0':
                valid = testNothing(bot);
                break;
            default:
                valid = testMovement(action, bot);
                break;
            }
            log(this.bot + " : " + action + " : " + valid); 

            return valid;
        }

        boolean testNothing(BattleBot bot){
            if(!xPosition.equals(bot.xPosition))
                return false;
            for(Weapon weapon : weapons){
                int dist = weapon.type==LANDMINE?1:weapon.speed;
                log(dist);
                if(distance(weapon.position, bot.xPosition) != dist)
                    continue;
                int dir = weapon.heading;
                if(isHeadingExact(dir,bot.xPosition,weapon.position))
                    return false;
            }
            return true;
        }

        boolean testShot(String act, BattleBot bot){
            if(!xPosition.equals(bot.xPosition))
                return false;
            if(weapons == null)
                return false;
            String[] tokens = act.split(" ");
            char which = tokens[0].charAt(0);
            int type = which=='B'?BULLET:
                   which=='M'?MISSILE:
                              LANDMINE;

            for(Weapon weapon : weapons){
                if(weapon.type != type)
                    continue;
                int dist = weapon.type==LANDMINE?1:weapon.speed;
                log(dist);
                if(distance(weapon.position, bot.xPosition) != dist)
                    continue;
                int dir;
                if(act==null)
                    dir = weapon.heading;
                else if(tokens.length < 2)
                    return false;
                else
                    dir = getHeading(tokens[1]);
                if(isHeadingExact(dir,bot.xPosition,weapon.position))
                    return true;
            }
            return false;

        }

        boolean testMovement(String act, BattleBot bot){
            return xPosition.equals(nextPosition(getHeading(act), bot.xPosition));
        }

        String foretell(String state){
            this.state = state;
            String[] cmdRaw = bot.split(" ");
            String[] cmd = new String[cmdRaw.length+1];
            for(int i=0;i<cmdRaw.length;i++)
                cmd[i] = cmdRaw[i];
            cmd[cmd.length-1]=state;

            String out = null;
            try {
                Process p = Runtime.getRuntime().exec(cmd);
                p.waitFor();
                BufferedReader err = new BufferedReader(new InputStreamReader(p.getErrorStream()));
                String line;
                while((line = err.readLine()) != null){
                    out = line;
                }
                err.close();
                BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
                while((line = reader.readLine()) != null){
                    out = line;
                }
                reader.close();
            } catch (Exception e) {
                log(e.getMessage());
            }
            return out!=null&&out.length()<6&&out.length()>0?out:null;
        }
    }   

    String fallbackBots[] = {"node Neo-Bot.js"};

    String[] baseBots =     {
                             "java EvadeBot", 
                             "java LastStand",
                             "java EvilBot",
                             "python ReadyAimShoot.py",
                             "python DodgingTurret.py",
                             "python mineminemine.py",
                             "python StraightShooter.py",
                             "./RandomBot",
                             "./SpiralBot",
                             "ruby1.9 TroubleAndStrafe.rb",
                             "python3 CunningPlanBot.py",
                             "./CamperBot",
                             "node CentreBot.js",
                             "node Neo-Bot.js",
                             "java UltraBot",
                             "python NinjaPy.py"
    };

    static String[] testState = {".X....LLL.\n..........\n.M........\n..........\nM.........\n..........\n..........\n..........\n.Y........\n...B......\nY 10\nX 7\nM 1 2 S"};
}

বাহ ... আমি কৌতূহল ছিলাম যে বটগুলি নির্দিষ্ট বটগুলিতে প্রতিক্রিয়া জানাতে কত সময় লাগবে! খুব দেরিতে এন্ট্রি থাকলে কীভাবে চলবে?
lochok

ঠিক আছে, আমি আরও বটগুলি আসার সাথে সাথে তাদের পরিকল্পনার পরিকল্পনা করছি custom
জিওবিটস

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

1
@TomVerelst আমি ইতিমধ্যে সহজে এই এক ব্যর্থ করার কয়েকটি উপায় আপ চিন্তা করেছি, তাই আমি না খুব একটা নতুন বট এটাকে দেখে বিস্মিত। বলা হচ্ছে, এটি বর্তমানে মাঠে থাকা বটদের বিরুদ্ধে খুব সুন্দরভাবে কাজ করে , যা আমি লক্ষ্য করেছিলাম। এটি আমার সর্বশেষ স্থানীয় পরীক্ষার দৌড়ে 8/8 ম্যাচ জিতেছে। মাঝে মাঝে DodgingTurret বেঁধে, কিন্তু আমি একটি যুদ্ধ প্যাটার্ন খুঁজে পাচ্ছি না ধারাবাহিকভাবে বীট যে এক, তাই এটি শুধু এটা উভয় জয় অস্বীকার করার গিঁট দিন করা আরো সহজ।
জিওবিটস

যদি এটি নিজে খেলে?
পাইরুলেজ

10

ReadyAimShoot

একটি আর বট

input <- strsplit(commandArgs(TRUE),split="\\\\n")[[1]]
arena <- do.call(rbind,strsplit(input[1:10],"")) #Parse arena
life <- as.integer(strsplit(input[11:12]," ")[[1]][2]) #Parse stats
stuff <- strsplit(input[13:length(input)]," ") #Parse elements
if(length(input)>12){ #What are they
    stuff <- strsplit(input[13:length(input)]," ")
    whatstuff <- sapply(stuff,`[`,1)
    }else{whatstuff<-""}
if(sum(whatstuff=="L")>1){ #Where are the mines
    mines <- t(apply(do.call(rbind,stuff[whatstuff=="L"])[,3:2],1,as.integer))+1
    }else if(sum(whatstuff=="L")==1){
        mines <- as.integer(stuff[whatstuff=="L"][[1]][3:2])+1
    }else{mines <- c()}
me <- which(arena=="Y",arr.ind=T) #Where am I
other <- which(arena=="X",arr.ind=T) #Where is the target
direction <- other-me #Direction of the other bot in term of indices
if(length(mines)>2){ #Direction of mines in term of indices
    dirmines <- mines-matrix(rep(me,nrow(mines)),nc=2,byrow=T)
    }else if(length(mines)==1){
        dirmines <- mines-me
        }else{dirmines<-c()}
file <- normalizePath(gsub("^--file=","",grep("^--file=",commandArgs(FALSE),v=TRUE))) #Path to this very file
f1 <- readLines(file) #Read-in this source file
where <- function(D){ #Computes direction of something in term of NSWE
    d <- ""
    if(D[2]<0) d <- paste(d,"W",sep="")
    if(D[2]>0) d <- paste(d,"E",sep="")
    if(D[1]<0) d <- paste(d,"N",sep="")
    if(D[1]>0) d <- paste(d,"S",sep="")
    d
    }
d <- where(direction) #Direction of the other bot in term of NSWE
M <- dirmines[dirmines[,1]%in%(-1:1) & dirmines[,2]%in%(-1:1),] #Which mines are next to me
if(length(M)>2){m<-apply(M,1,where)}else if(length(M)==1){m<-where(M)}else{m<-""} #Direction of close-by mines in term of NSWE
if(any(direction==0) & life >1 & !grepl("#p_fired", tail(f1,1))){
    # If aligned with target, if life is more than one 
    # and if this source file doesn't end with a comment saying the EMP was already fired
    # Fire the EMP, and leave comment on this file saying so
    action <- "P"
    f2 <- c(f1,"#p_fired2")
    cat(f2, file=file, sep="\n")
    }else if(tail(f1,1)=="#p_fired2"){
    # If EMP have been fired last turn
    # Send missile in direction of target
    # Change comment on file.
    action <- paste("M", d)
    f2 <- c(f1[-length(f1)], "#p_fired1")
    cat(f2, file=file, sep="\n")
    }else if(tail(f1,1)=="#p_fired1"){
    # If EMP was fired two turns ago
    # Send bullet and erase comment line.
    action <- paste("B", d)
    f2 <- f1[-length(f1)]
    cat(f2, file=file, sep="\n")
    }
if (any(direction==0) & life<2){
    # If aligned but life is 1 don't fire the EMP, but send missile instead
    action <- paste("M",d)
    }
if (!any(direction==0)){
    # If not aligned, try to align using shortest, landmine-free direction
    if(direction[2]<direction[1]){
        if(grepl('W',d) & !'W'%in%m){action <- 'W'}
        if(grepl('E',d) & !'E'%in%m){action <- 'E'}
        }else if(direction[2]>=direction[1]){
            if(grepl('N',d) & !'N'%in%m){action <- 'N'}
            if(grepl('S',d) & !'S'%in%m){action <- 'S'}
            }else{ #If no landmine-free direction, don't move
                action <- 0
                }
    }
cat(action,"\n")

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

কমান্ড লাইনটি Rscript ReadyAimShoot.Rউদাহরণ হিসাবে যেমন আর্গুমেন্ট অনুসরণ করা উচিত , কমপক্ষে ইউনিক্স সিস্টেমে তবে সম্ভবত উইন্ডোতেও (আমি এটি পরীক্ষা করব যখন আমি এটি অন্যান্য বটগুলির বিরুদ্ধে পরীক্ষা করব)।

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

import sys, os

def Position(arena, element):
    y = [i for i,j in enumerate(arena) if element in arena[i]][0]
    x = arena[y].index(element)
    return (x,y)

def Direction(coord1, coord2):
    d0 = coord1[0]-coord2[0]
    d1 = coord1[1]-coord2[1]
    if d1!=0:
        a = ['N','S'][d1<0]
    else: a = ""
    if d0!=0:
        b = ['W','E'][d0<0]
    else: b = ""
    return a+b

def Shortest(coord1,coord2):
    d = abs(coord1[0]-coord2[0])-abs(coord1[1]-coord2[1])
    if d>0: a = 'EW'
    if d<=0: a = 'NS'
    return a

input = sys.argv[1].splitlines()
arena = input[0:10]
life = input[10].split(" ")
stuff = input[12:]
path = os.path.dirname(__file__)
f1 = os.path.join(path,'state','RAS')
try:
    with open(f1, 'r') as f:
        fired = int(f.read())
except:
    fired = 0

me = Position(arena, "Y")
other = Position(arena, "X")
target = Direction(me,other)
m = []
if len(stuff):
    s = [i.split(" ") for i in stuff]
    for i in s:
        if i[0]=='L': m += [(int(i[1]),int(i[2]))]


near = [(me[0]+i,me[1]) for i in range(-1,2,2)]+[(me[0],me[1]+i) for i in range(-1,2,2)]+[(5+me[0],5+me[1]) for i in range(-1,2,2)]
closeMines = [i for i in m if i in near]
dirmines = []
for j in closeMines:
    dirmines += Direction(me, j)


if target in ['N','S','E','W']:
    if int(life[1])>1 and fired==0:
        action = "P"
        with open(f1,'w') as f:
            f.write('2')
    else:
        if fired==2:
            action = "M "+target
            with open(f1,'w') as f:
                f.write('1')
        if fired==1:
            action = "B "+target
            with open(f1,'w') as f:
                f.write('0')
        if int(life[1])==1:
            action = "M "+target
else:
    s = Shortest(me,other)
    d1 = Direction((me[0],other[1]), other)
    d2 = Direction((other[0],me[1]), other)
    if s=='EW' and d1 not in dirmines:
        action = d1
    if s=='NS' and d2 not in dirmines:
        action = d2
    else:
        if d2 not in dirmines: action = d2
        if d1 not in dirmines: action = d1
        else: action = 0


sys.stdout.write(action)

আহ, আপনি একই কৌশলটি নিয়ে এসেছিলেন যা আমি ভেবেছিলাম (এবং মন্তব্যগুলিতে আইনাসিওর কাছে উল্লেখ করেছেন)। আমি মনে করি এই মুহুর্তে এটিই প্রথম রানার হবে। :-) আমি কাজ থেকে বাড়ি এলে পরীক্ষা করব।
গ্যারেথ

1
আমি ডিস্কে লেখার বিষয়ে প্রশ্নের শেষে একটি বিভাগ যুক্ত করেছি। আমি আমার প্রথম পরীক্ষার রানও করেছি - ফলাফল প্রশ্নের শেষের কাছাকাছি। আমি চেষ্টা করব এবং এখনই নিয়মিত এগুলি করব।
গ্যারেথ

সুতরাং আমি অনুমান করি যে এই বটটি এখন আপনার স্কোরারের সাথে যেমন কাজ করে তেমনি কাজ করে? মহান!
প্ল্যানেপাস

এটা মনে হয়. এটি মাইনমাইন এবং র‌্যান্ডমবোট সহজেই পরাজিত করে তবে এভাডবট এবং আপনার ডডিংটুরেটের কাছ থেকে মারধর করে।
গ্যারেথ

আমি যে বিস্মিত হই না: কারণ এটি লক্ষ্য করতে তার সময় নেয় (শত্রুদের খুব কাছাকাছি থাকার চেষ্টা না করা) আমি ভেবেছিলাম এটি ডজরের বিরুদ্ধে হারাবে। এখনও বেশ ভাল ফলাফল যদিও!
প্ল্যানাপাস

8

কিং এর শেষ স্ট্যান্ড

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

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

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

ওহ, এবং যদি এটি ইতিমধ্যে অফ-অক্ষ এবং প্রজেক্টেলগুলি থেকে নিরাপদ থাকে তবে এটি কেবল শত্রুর সাধারণ দিকে একটি পটশট নেবে।

LastStand.java

import java.awt.Point;
import java.util.ArrayList;

public class LastStand extends BattleBot{

    String output = "0";
    ArrayList<Point> safeFromEnemy;
    ArrayList<Point> safeFromWeapons;
    ArrayList<Point> safeFromBoth;

    public static void main(String[] args){
        System.out.print(new LastStand(args).execute());
    }

    LastStand(String[] args){
        super(args);
        debug = false;
    }

    @Override
    String execute() {
        findSafeSpots();
        if(attack())
            return output;
        if(evade(safeFromBoth))
            return output;
        if(evade(safeFromEnemy))
            return output;

        return output;
    }

    boolean evade(ArrayList<Point> points){
        Point dest = closestToCenter(points);
        if(dest==null)
            return false;
        int heading = headingToPoint(dest);
        output = headings[heading];
        return true;
    }

    boolean attack(){
        if(safeFromEnemy.isEmpty() || safeFromBoth.contains(yPosition))
            return fire();
        return false;
    }

    Point closestToCenter(ArrayList<Point> points){
        Point closest = null;
        int dist = 15;
        for(Point pos : points){
            if(distance(center, pos) < dist){
                closest = pos;
                dist = distance(center, pos);
            }
        }
        return closest;
    }

    boolean isOnEnemyAxis(Point pos){
        int x = Math.abs(pos.x - xPosition.x);
        int y = Math.abs(pos.y - xPosition.y);
        if(x==0 || y==0 || x==y)
            return true;
        return false;
    }

    void findSafeSpots(){
        safeFromEnemy = new ArrayList<Point>();
        safeFromWeapons = new ArrayList<Point>();
        safeFromBoth = new ArrayList<Point>();

        if(!isOnEnemyAxis(yPosition))
            safeFromEnemy.add(yPosition);
        if(spotCollision(yPosition)==null)
            safeFromWeapons.add(yPosition);

        for(int heading=0;heading<8;heading++){
            Point pos = nextPosition(heading, yPosition);
            if(isOutside(pos))
                continue;
            if(!isOnEnemyAxis(pos))
                safeFromEnemy.add(pos);
            if(spotCollision(pos)==null)
                safeFromWeapons.add(pos);
        }
        for(Point pos : safeFromEnemy){
            if(safeFromWeapons.contains(pos))
                safeFromBoth.add(pos);
        }
    }

    boolean fire(){
        int heading = headingToPoint(xPosition);
        int dist = distance(xPosition, yPosition);
        if(dist>1 || yEnergy>4)
            output = "M " + headings[heading];
        else
            output = "B " + headings[heading];
        return true;
    }   
}

রান কম্পাইল করতে, একটি ফোল্ডারে দিয়ে BattleBot.javaএনে চালিত করুন:

javac LastStand.java
java LastStand <arena-argument>

8

EvadeBot

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

যদি কোনও সংঘর্ষ না ঘটে (বা সংঘর্ষের ক্ষেত্রে নিরাপদ দাগ), এটি আক্রমণ পরীক্ষা করে। যদি প্রতিপক্ষ 8-অক্ষ সারিবদ্ধ থাকে তবে এটি 80% সময় চালায়। যদি এটি সারিবদ্ধ না হয় তবে এটি নিকটবর্তী শিরোনামে 50% সময় নিক্ষেপ করে। এটি দূরত্বের ভিত্তিতে একটি অস্ত্র বেছে নেয়। এটি কাছাকাছি থাকলে, একটি ল্যান্ডমাইন বা বুলেট (সঠিক দূরত্ব এবং আপেক্ষিক স্বাস্থ্যের উপর নির্ভর করে), দূর থেকে মিসাইল

যদি এটি অগ্নিসংযোগ না করার সিদ্ধান্ত নেয়, তবে এটি এলোমেলো হাঁটা লাগে (আবার নিরাপদ দাগগুলির জন্য পরীক্ষা করা)।

যদি উপরের কোনওটি কাজ না করে তবে এটি পরবর্তী আগমন পর্যন্ত কেবল সেখানেই বসে।

এটি ইএমপি ব্যবহার করে না, এবং এর বিরুদ্ধে স্কোয়ারিংয়ের সম্পর্কে আমার খারাপ ধারণা আছে ReadyAimShootতবে এটি কীভাবে হয় তা আমরা দেখতে পাব।


কোডটি দুটি টুকরোয়। যেহেতু আমি একাধিক বট করতে পারি, তাই আমি একটি বিমূর্ত BattleBotক্লাস তৈরি করেছি । এটিতে আখড়া পড়া, সংঘর্ষের চেক করা, শিরোনাম পরিচালন ইত্যাদির মতো সহায়ক ফাংশন অন্তর্ভুক্ত রয়েছে deb যদি debug==false, এটি কেবল আসল আউটপুট প্রিন্ট করবে। যদি কেউ এটি ব্যবহার / প্রসারিত করতে চান তবে নির্দ্বিধায়। এটি সুন্দর কোড নয়, তবে এটি বয়লারপ্লেট লিখে মারধর করে।

BattleBot.java

import java.awt.Point;
import java.util.Random;

abstract class BattleBot {
    static boolean debug;

    Random rand;
    final String[] headings = {"N","NE","E","SE","S","SW","W","NW"};
    final int           BULLET      = 0,
                        MISSILE     = 1,
                        LANDMINE    = 2;

    final int arenaSize = 10;
    final Point center  = new Point(arenaSize/2, arenaSize/2);

    boolean valid = false;
    Weapon[] weapons;
    Point xPosition, yPosition; 
    int xEnergy, yEnergy;

    abstract String execute();

    Point nextPosition(int heading, Point from){
        if(from == null)
            from = yPosition;
        Point next = new Point(from);
        if(heading<0||heading>7)
            return next; 
        if(heading<2 || heading>6)
            next.y--;
        if(heading<6 && heading>2)
            next.y++;
        if(heading>4)
            next.x--;
        if(heading<4 && heading>0)
            next.x++;
        return next;        
    }

    boolean isHeadingExact(int heading, Point from, Point to){
        Point next = new Point(from);
        while(!isOutside(next)){
            next = nextPosition(heading, next);
            if(next.equals(to))
                return true;
        }
        return false;
    }

    int headingToPoint(Point to){
        int x = yPosition.x - to.x;
        int y = yPosition.y - to.y;
        if(x<0){
            if(y<0) return 3;
            if(y>0) return 1;
            return 2;
        }else if(x>0){
            if(y<0) return 5;
            if(y>0) return 7;
            return 6;
        }else{
            if(y<0) return 4;
            return 0;
        }
    }

    BattleBot(String[] args){
        rand = new Random();
        if(args.length < 1 || args[0].length() < arenaSize*arenaSize)
            return;
        String[] lines = args[0].split("\\r?\\n");
        if(lines.length<12)
            return;
        weapons = new Weapon[lines.length - 12];
        int wIndex = 0;
        for(int i=0;i<lines.length;i++){
            String line = lines[i];
            if(i<arenaSize){
                if(line.contains("X"))
                    xPosition = new Point(line.indexOf("X"),i);
                if(line.contains("Y"))
                    yPosition = new Point(line.indexOf("Y"),i);
            } else {
                String[] tokens = line.split(" ");
                switch(tokens[0].charAt(0)){
                case 'X':
                    xEnergy = Integer.parseInt(tokens[1]);
                    break;
                case 'Y':
                    yEnergy = Integer.parseInt(tokens[1]);
                    break;
                case 'B':
                case 'M':
                case 'L':
                    weapons[wIndex++] = new Weapon(tokens);
                    break;
                }
            }
        }
        valid = true;
    }

    int distance(Point a, Point b){
        return Math.max(Math.abs(a.x-b.x), Math.abs(a.y-b.y));
    }

    Point spotCollision(Point pos){
        for(int i=0;i<weapons.length;i++){
            Point collision = weapons[i].collisionPoint(pos);
            if(collision != null){
                log("Collision at " + collision.x + "," + collision.y + " with weapon type " + weapons[i].type);
                if(collision.equals(pos))
                    return collision;
                else if(weapons[i].type==MISSILE && distance(collision,pos) < 2)
                    return collision;
                log("Collision disregarded");
            }
        }
        return null;
    }

    boolean isOutside(Point pos){
        if(pos.x<0||pos.y<0||pos.x>=arenaSize||pos.y>=arenaSize)
            return true;
        return false;
    }

    static <T> void log(T msg){
        if(debug) System.out.println(msg);
    }

    int getHeading(String in){
        for(int i=0;i<headings.length;i++){
            if(in.equalsIgnoreCase(headings[i]))
                return i;
        }
        return -1;
    }

    class Weapon{

        final int[] speeds = {3,2,0};   
        Point position;
        int type;
        int heading;
        int speed;

        Weapon(String[] tokens){
            char which = tokens[0].charAt(0);
            type = which=='B'?BULLET:
                   which=='M'?MISSILE:
                              LANDMINE;

            speed = speeds[type];

            position = new Point(Integer.parseInt(tokens[1]), Integer.parseInt(tokens[2]));

            if(type==BULLET || type == MISSILE)
                heading = getHeading(tokens[3]);
            else
                heading = -1;
        }

        Point collisionPoint(Point pos){
            Point next = new Point(position);
            if(type==LANDMINE)
                return next;
            for(int i=0;i<speed;i++){
                next = nextPosition(heading, next);
                if(isOutside(next))
                    return next;
                if(next.equals(xPosition) || next.equals(yPosition))
                    return next;
                if(next.equals(pos))
                    return next;
            }
            return null;            
        }
    }   
}

এই বিশেষ বট হয় EvadeBot। সংকলন করতে / চালাতে, এটিকে দিয়ে একটি ফোল্ডারে রাখুন BattleBot.javaএবং চালান:

javac EvadeBot.java
java EvadeBot <arena-argument>

আপনি যদি আর্গুমেন্টটি বাদ দেন বা এটি সঠিকভাবে পার্স করতে না পারেন তবে এটি "0"আউটপুটে ডিফল্ট হয় ।

EvadeBot.java

import java.awt.Point;

public class EvadeBot extends BattleBot{

    String output = "0";

    public static void main(String[] args){
        System.out.print(new EvadeBot(args).execute());
    }

    EvadeBot(String[] args) {
        super(args);
        debug = false;
    }

    @Override
    String execute() {
        if(!valid)
            return output;
        if(evade())
            return output;
        if(attack())
            return output;
        if(walk())
            return output;
        return output;
    }

    boolean evade(){
        Point collision = spotCollision(yPosition);
        if(collision!=null){
            log("Incoming! " + collision.x + "," + collision.y);
            return moveAwayFrom(collision);
        }
        return false;
    }

    boolean attack(){
        int dist = distance(yPosition, xPosition);
        int heading = headingToPoint(xPosition);
        int odds = rand.nextInt(100);

        if(isHeadingExact(heading, yPosition, xPosition)){
            if(odds<20)
                return false;
        } else {
            if(odds<50)
                return false;
        }
        log("Odds of firing " + headings[heading] + " to " + xPosition.x + "," + xPosition.y + " checked, preparing to attack.");
        if(dist==2){
            if(yEnergy > 3 || (xEnergy < 2 && yEnergy > 1)){
                output = "L " + headings[heading]; 
                return true;
            }
        }else if(dist<4){
            output = "B " + headings[heading];
            return true;
        }else{
            output = "M " + headings[heading];
            return true;
        }
        return false;
    }

    boolean walk(){
        log("Trying to random walk...");
        int heading = rand.nextInt(8);
        for(int i=0;i<8;i++,heading=(heading+1)%8){
            Point next = nextPosition(heading, yPosition);
            if(!isOutside(next) && spotCollision(next)==null){
                output = headings[heading];
                return true;
            }
        }
        return false;
    }

    boolean moveAwayFrom(Point from){
        int heading;
        if(from.equals(yPosition))
            heading = rand.nextInt(8);
        else
            heading = (headingToPoint(from) + (rand.nextBoolean()?2:6)) % 8;
        Point next = nextPosition(heading, yPosition);
        for(int i=0;i<8;i++){
            log("Checking move " + headings[heading] + " to " + next.x + "," + next.y);
            if(!isOutside(next) && spotCollision(next)==null){
                output = headings[heading];
                return true;
            }
            heading = (heading + 1) % 8;
            next = nextPosition(heading, yPosition);
        }
        return false;
    }
}

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

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

@ গ্যারেথ আমি একটি বাগ ঠিক করেছি BattleBots.java। আপনি কি দয়া করে পরের রানের আগে আমার বটগুলি পুনরায় সংকলন করতে পারেন?
জিওবিটস

@ জিওবিটস ঠিক আছে, করবে।
গ্যারেথ

8

সর্পিল বট সাহিত্যের হাস্কেল

সাক্ষর হ্যাসকেলে, মন্তব্যগুলি ডিফল্ট হয়, সুতরাং এই পুরো পোস্টটিই প্রোগ্রাম। এই বট ইনপুট উপেক্ষা করে চারপাশে সর্পিলগুলিতে ক্ষেপণাস্ত্র গুলি করবে। এটি একটি ফাইলে স্টেট সংরক্ষণ করে (যা আশা করি প্রতিযোগী দ্বারা পোস্ট করা হবে না))

> import System.Directory (doesFileExist, createDirectoryIfMissing, setCurrentDirectory)
> import Control.Monad (unless)

প্রথমে আমরা ক্ষেপণাস্ত্র ক্রিয়া তালিকাভুক্ত করি।

> missiles = map ("M "++) $ cycle ["N", "NE", "E", "SE", "S", "SW", "W", "NW"]

পরবর্তী আমরা সরাসরি আইও মনাদে .ুকি। যদি "spiral.txt" উপস্থিত না থাকে, আমরা এটিতে "0" লিখি। আমরা ডিরেক্টরিটিও পরীক্ষা করি।

> main = do
>   createDirectoryIfMissing True "state"
>   setCurrentDirectory "state"
>   exists <- doesFileExist "spiral.txt"
>   unless exists $ writeFile "spiral.txt" "0"

তারপরে আমরা এটি পড়ি এবং ক্রিয়াটি মুদ্রণ করি।

>   actPos <- fmap read $ readFile "spiral.txt" :: IO Int
>   putStr $ missiles !! actPos

এবং পরিশেষে আমরা ফাইল এখন লিখুন।

>   writeFile "spiral.txt" (show $ actPos + 1)

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

আমি কি আপনাকে ফাইলগুলিতে লেখার বিষয়ে নিয়মগুলি দেখতে জিজ্ঞাসা করতে পারি? আমার কেবলমাত্র অনুরোধ করা হয়েছে যে আপনার লিখিত ফাইলটি stateঅন্য কোনও রাষ্ট্র-রাষ্ট্রের ফাইলগুলির সাথে কোনও দুর্ঘটনাজনিত সংঘর্ষ এড়াতে ডাকা একটি উপ-ডিরেক্টরিতে থাকতে হবে।
গ্যারেথ

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

আমি মনে করি আপনার নতুন সংস্করণটিতে একটি বা দুটি আমদানি অনুপস্থিত। আমি পেয়ে করছি LiterateHaskell.lhs:13:5: Not in scope: 'createDirectoryIfMissing'এবং LiterateHaskell.lhs:14:5: Not in scope: setCurrentDirectory'` যখন আমি কম্পাইল করার চেষ্টা করুন।
গ্যারেথ

1
অদ্ভুত, আমার বটটি শেষ পয়েন্টে রয়েছে তবে সবচেয়ে বেশি ভোট রয়েছে। জয়ের জন্য সাহিত্যের প্রোগ্রামিং!
পাইরুলেজ

7

DodgingTurret

একটি পাইথন বট

এখানে অন্য একটি প্রচেষ্টা। যেহেতু রেডিএইমশুট কিছুক্ষণের জন্য মেরামতের দোকানে রয়েছে :) আমি অনুভব করেছি যে আমি পাইথনটি ব্যবহার করে এর মধ্যে আরও কিছু চেষ্টা করব।

import sys

def Position(arena, element):
    y = [i for i,j in enumerate(arena) if element in arena[i]][0]
    x = arena[y].index(element)
    return (x,y)

def Direction(coord1, coord2):
    d0 = coord1[0]-coord2[0]
    d1 = coord1[1]-coord2[1]
    if d1!=0:
        a = ['N','S'][d1<0]
    else: a = ""
    if d0!=0:
        b = ['W','E'][d0<0]
    else: b = ""
    return a+b

def GetPath(coord, direction):
    if direction=='N': path = [(coord[0],coord[1]-i) for i in xrange(3)]
    if direction=='S': path = [(coord[0],coord[1]+i) for i in xrange(3)]
    if direction=='E': path = [(coord[0]+i,coord[1]) for i in xrange(3)]
    if direction=='W': path = [(coord[0]-i,coord[1]) for i in xrange(3)]
    if direction=='NE': path = [(coord[0]+i,coord[1]-i) for i in xrange(3)]
    if direction=='NW': path = [(coord[0]-i,coord[1]-i) for i in xrange(3)]
    if direction=='SE': path = [(coord[0]+i,coord[1]+i) for i in xrange(3)]
    if direction=='SW': path = [(coord[0]-i,coord[1]+i) for i in xrange(3)]
    return path

def Danger(coord, stuff):
    if len(stuff):
        s = [i.split(" ") for i in stuff]
        for i in s:
            if i[0] in ['M','B']:
                path = GetPath((int(i[1]),int(i[2])),i[3])
                if coord in path:
                    return ['unsafe',path]
        return ['safe',()]
    else:
        return ['safe',()]

input = sys.argv[1].splitlines()
arena = input[0:10]
stuff = input[12:]
me = Position(arena, "Y")
center = Direction(me, (5,5))
if center != "":
    action = center
else:
    d = Danger(me,stuff)
    if d[0]=='safe':
        other = Position(arena,"X")
        target = Direction(me, other)
        action = 'M '+target
    if d[0]=='unsafe':
        escape = [(me[0]+i,me[1]) for i in range(-1,2,2)]+[(me[0],me[1]+i) for i in range(-1,2,2)]+[(5+me[0],5+me[1]) for i in range(-1,2,2)]
        esc_choice = [i for i in escape if i not in d[1]][0]
        action = Direction(me,esc_choice)

sys.stdout.write(action)

আমি নির্লজ্জভাবে sys.argv[1].splitlines()@ গ্যারেথ থেকে লাইনটি চুরি করেছি তবে কমপক্ষে এবার এর অর্থ এই যে ইনপুট পার্স করতে আমার কোনও সমস্যা হবে না।

এই বোটটি বাউটের শুরুতে কেন্দ্রে চলে, তারপরে সেখানে থাকে এবং প্রতিপক্ষের দিকে লক্ষ্য করে ক্ষেপণাস্ত্র গুলি করে shoot তিনি কাছাকাছি গুলি এবং ক্ষেপণাস্ত্রগুলি যদি তাদের পথে থাকে তবে এটি আবার চালানোর চেষ্টা করে তবে আবার শ্যুটিং শুরু করার আগে কেন্দ্রে ফিরে যান।


2
আমি এখানে বড় হাতের অক্ষরের নাম পছন্দ করি না।
কেবা

এটি আমার "স্ট্রেইট শ্যুটার "কে গড়ে প্রায় 3-2 বাজে।
intx13

7

স্ট্রেট শ্যুটার

এটি পরীক্ষার জন্য আপনি ব্যবহার করতে পারেন এমন আরও একটি সহজ বট। যদি এটির প্রতিপক্ষের কাছে প্রত্যক্ষ দৃষ্টিভঙ্গি থাকে তবে এটি অঙ্কুরিত হয়, অন্যথায় এটি এলোমেলোভাবে পদক্ষেপ নেয়।

import sys
try:
  map = sys.argv[1][0:110].split()
except:
  sys.exit(1)

# Locate us and the opponent.
#
for y in range(0,10):
  for x in range(0, 10):
    if 'Y' == map[y][x]:
      me_y = y
      me_x = x
    elif 'X' == map[y][x]:
      him_y = y
      him_x = x

# If we're on a direct line with the opponent, fire a missile.
#
if me_y == him_y or me_x == him_x or abs(me_y - him_y) == abs(me_x - him_x):
  if   him_y < me_y and him_x < me_x:
    sys.stdout.write('M NW')
  elif him_y < me_y and him_x == me_x:
    sys.stdout.write('M N')
  elif him_y < me_y and him_x > me_x:
    sys.stdout.write('M NE')
  elif him_y == me_y and him_x < me_x:
    sys.stdout.write('M W')
  elif him_y == me_y and him_x > me_x:
    sys.stdout.write('M E')
  elif him_y > me_y and him_x < me_x:
    sys.stdout.write('M SW')
  elif him_y > me_y and him_x == me_x:
    sys.stdout.write('M S')
  elif him_y > me_y and him_x > me_x:
    sys.stdout.write('M SE')

# Otherwise, move randomly.
#
else:
  import random
  sys.stdout.write(random.choice(['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW']))

7

নব্য-বট

coffeescript

মিশ্রণে যুক্ত করতে আরেকটি জাভাস্ক্রিপ্ট বট। এটি একটি নোড.জেএসকে লক্ষ্য করে এবং কফিস্ক্রিপ্টে রচিত। আর্কিটেকচারটি জাভা ভিড় থেকে অনুসরণ করে একটি বেস ক্লাস পরিচালনা করে সাধারণ বোতলতা এবং হাতের বটের জন্য বিশেষীকরণের সাথে অন্য একটি ফাইল।

এই বটটির মূল কৌশলটি আপনার প্রজেক্টিলেসের দ্বারা আঘাত না পাওয়া। আপনি যদি তাত্ক্ষণিক হুমকি না হন তবে নব্য-বট কেবল শুটিং শুরু করবে।

বেস ফাইল shared.coffee

# entry point

deserializeBoard = (board) ->
  me = no
  you = no
  rows = board.split '\n'
  all = for i in [0...rows.length]
    row = rows[i]
    me = row: i, col: row.indexOf 'Y' if /Y/.test row
    you = row: i, col: row.indexOf 'X' if /X/.test row
    row.split ''
  throw new Error "missing player" unless me and you
  all.me = me
  all.you = you
  all

deserializeState = (state) ->
  board = deserializeBoard state[0...110]
  rest = state[110...]
    .split '\n'
    .filter (d) -> d
  if rest[0][0] is 'Y'
    board.me.health = +rest[0][2...]
    board.you.health = +rest[1][2...]
  else
    board.you.health = +rest[0][2...]
    board.me.health = +rest[1][2...]
  board.mines = []
  board.projectiles = []
  for weapon in rest[2...]
    parts = weapon[2...].split ' '
    if weapon[0] is 'L'
      board.mines.push
        row: +parts[1]
        col: +parts[0]
    else
      board.projectiles.push
        type: weapon[0]
        row: +parts[1]
        col: +parts[0]
        dir: parts[2]
  board

module.exports = bot = (handle) ->

  state = process.argv[-1...][0]
  board = deserializeState state

  move = handle board
  process.stdout.write move

এবং neo-bot.coffee, বট কোড।

# i know kung fu

bot = require "./shared"

board_rows = [0...10]
board_cols = [0...10]

directions = [
  'NW', 'N', 'NE'
   'W',       'E'
  'SW', 'S', 'SE'
]

direction = (a, b) ->
  if a.row < b.row
    if a.col < b.col
      "SE"
    else if a.col is b.col
      "S"
    else
      "SW"
  else if a.row is b.row
    if a.col < b.col
      "E"
    else
      "W"
  else
    if a.col < b.col
      "NE"
    else if a.col is b.col
      "N"
    else
      "NW"

move = (me, dir) ->
  row = me.row
  col = me.col
  if /N/.test dir
    row--
  if /S/.test dir
    row++
  if /W/.test dir
    col--
  if /E/.test dir
    col++
  {row, col}

clamp = (v) ->
  Math.max 0, Math.min 9, v

legal = (pos) ->
  clamp(pos.row) is pos.row and clamp(pos.col) is pos.col

randOf = (choices) ->
  i = Math.floor Math.rand * choices.length
  choices[i]

moves =
  B: 3
  M: 2

damage =
  B: 1
  M: 3

danger = (board) ->
  n = ((0 for i in [0...10]) for j in [0...10])
  for projectile in board.projectiles
    next = projectile
    for i in [0...moves[projectile.type]]
      next = move next, projectile.dir
      if projectile.type is 'M' and not legal next
        for d in directions
          schrapnel = move next, d
          if legal schrapnel
            n[schrapnel.row][schrapnel.col] += 1
      continue unless legal next
      n[next.row][next.col] += damage[projectile.type]
  for mine in board.mines
    n[mine.row][mine.col] += 2
  n

warning = (board) ->
  n = ((0 for i in [0...10]) for j in [0...10])
  for dir in directions
    p = board.you
    p = move p, dir
    continue unless legal p
    n[p.row][p.col] = damage.M - 1 # relative damage
    p = move p, dir
    continue unless legal p
    n[p.row][p.col] = damage.M
    p = move p, dir
    continue unless legal p
    n[p.row][p.col] = damage.B
  for mine in board.mines
    for dir in directions
      p = move mine, dir
      continue unless legal p
      n[p.row][p.col] += 1
  n

board_map = (map) ->
  (a) ->
    ((map a[i][j] for j in board_cols) for i in board_rows)

board_pair = (join) ->
  (a, b) ->
    ((join a[i][j], b[i][j] for j in board_cols) for i in board_rows)

boards =
  sum: board_pair (a, b) -> a + b
  scale: (n) -> board_map (a) -> a * n

chooseSafeDir = ({me, you}, lava) ->
  dirs = []
  min = +Infinity
  for dir in directions
    guess = move me, dir
    continue unless legal guess
    guess.dir = dir
    guess.damage = lava[guess.row][guess.col]
    min = guess.damage if guess.damage < min
    dirs.push guess
  dirs.sort (a, b) ->
    if a.damage < b.damage
      -1
    else if b.damage < a.damage
      1
    else
      0
  choice = randOf dirs.filter (d) ->
    d.damage < min + 1
  choice = choice or dirs[0]
  choice.dir

neo = (WARNING_FACTOR, MISSILE_FACTOR, MOVE_FACTOR) ->
  WARNING_FACTOR ?= 0.8
  MISSILE_FACTOR ?= 0.2
  MOVE_FACTOR ?= 0.1

  combine = (d, w) ->
    boards.sum d, boards.scale(WARNING_FACTOR)(w)

  shoot = ({me, you}) ->
    weapon = if Math.random() < MISSILE_FACTOR then 'M' else 'B'
    dir = direction me, you
    "#{weapon} #{dir}"

  (board) ->
    lava = combine danger(board), warning(board)

    if lava[board.me.row][board.me.col] or Math.random() < MOVE_FACTOR
      chooseSafeDir board, lava
    else
      shoot board

bot neo()

আমি চালানোর আগে জাভাস্ক্রিপ্টে কফি ফাইলগুলি সংকলন করার জন্য সুপারিশ করতাম; এটি বেশ খানিকটা দ্রুত মূলত আপনি এটি করতে চান:

> coffee -c *.coffee
> ./bb "java EvilBot" "node ./neo-bot.js"

7

CamperBot

এই বটটি যেখানে রয়েছে সেখানেই গুলি করে। আমি কেবল গুলি প্রয়োগ করেছি, যেহেতু অন্যান্য অস্ত্র বটকে ক্ষতি করে। দয়া করে আমার ভয়াবহ সি-দক্ষতা আমাকে ক্ষমা করুন;)

#include <stdio.h>
#include <time.h>

int main(int argc, char *argv[])
{
    int direction = 0;
    char directions[][3] = {"N", "NE", "E", "SE", "S", "SW", "W", "NW"};
    srand(time(NULL));

    direction = rand() % 8;
    printf("B %s", directions[direction]);
    return 0;
}

আসলেই বেশি জয়ের প্রত্যাশা নেই।


1
সাইটে স্বাগতম!
জোনাথন ভ্যান মাত্রে

1
একটু বাগ ঠিক করা ... চূড়ান্ত রান জন্য আপনি এটি পুনরায় সংকলন করতে পারেন? আপনাকে ধন্যবাদ :)
কমনগ্যুই

5

যেহেতু এখনও কোনও এন্ট্রি নেই আমি সেখানে একটি রেখে দেব যাতে আপনার মারধরের জন্য কিছু থাকে। আমি আপনাকে দিতে:

খনি! খনি! খনি!

import sys
import random
from itertools import product

def getMyPos(arena):
    x=0
    y=0
    for idx, line in enumerate(arena):
        if(line.find('Y')!= -1):
            x=line.find('Y')
            y=idx
    return [x, y]

def isNearMine(pos, badstuff):
    returnval=False
    for badthing in badstuff:
        thinglist=badthing.split(" ")
        if(thinglist[0]=='L'):
            returnval=returnval or isNear(pos, map(int, thinglist[1:3]))
    return returnval

def isNear(pos1, pos2):
    return ((abs(pos1[0]-pos2[0])<2) and (abs(pos1[1]-pos2[1])<2))

def newpos(mypos, move):
    return [mypos[0]+move[0], mypos[1]+move[1]]

def inBounds(pos):
    return pos[0]<10 and pos[0]>=0 and pos[1]<10 and pos[1]>=0

def randomSafeMove(arena, badstuff):
    mypos=getMyPos(arena)
    badsquares=[mypos] #don't want to stay still
    for badthing in badstuff:
        thinglist=badthing.split(" ")
        if(thinglist[0]=='L'):
            badsquares.append(map(int, thinglist[1:3]))
    possiblemoves=list(product(range(-1, 2), repeat=2))
    possiblemoves=[list(x) for x in possiblemoves]
    safemoves=[x for x in possiblemoves if newpos(mypos, x) not in badsquares]
    safemoves=[x for x in safemoves if inBounds(newpos(mypos, x))]
    move=random.choice(safemoves)
    return (("N S"[move[1]+1])+("W E"[move[0]+1])).strip()

def randomDropMine(arena):
    mypos=getMyPos(arena)
    badsquares=[mypos] #don't want to drop a mine under myself
    possiblemoves=list(product(range(-1, 2), repeat=2))
    possiblemoves=[list(x) for x in possiblemoves]
    possiblemoves=[x for x in possiblemoves if newpos(mypos, x) not in badsquares]
    possiblemoves=[x for x in possiblemoves if inBounds(newpos(mypos, x))]
    move=random.choice(possiblemoves)
    return "L "+(("N S"[move[1]+1])+("W E"[move[0]+1])).strip()

input=sys.argv[1].splitlines()
arena=input[0:10]
energy=input[10:12]
badstuff=input[12:]

if(isNearMine(getMyPos(arena), badstuff)):
    sys.stdout.write(randomSafeMove(arena, badstuff))
else:
    sys.stdout.write(randomDropMine(arena))

বিশেষত চালাক কিছু করে না। আশেপাশের স্কোয়ারগুলির মধ্যে যদি না থাকে তবে একটি খনি ফেলে দিন অন্যথায় নিরাপদ আশেপাশের স্কোয়ারগুলির মধ্যে একটিতে moves সবেমাত্র হিউজিবটকে পরাস্ত করতে পারে।

দয়া করে নাফ পাইথন কোডিংটি ক্ষমা করুন।


5

র্যান্ডম বট

এই বট প্রতিটি পদক্ষেপে কেবল একটি এলোমেলো পদক্ষেপ করে। এটি EMP ফায়ার করে না এবং এটি মানচিত্রে মোটেও দেখে না। আধা সময় শুধু দেয়ালে গুলি ছোঁড়াচ্ছে!

#include <stdio.h>
#include <sys/time.h>

void main(int argc, char **argv)
{
  char dirs[][3] = {"N", "NE", "E", "SE", "S", "SW", "W", "NW"};

  struct timeval tv;
  gettimeofday(&tv, NULL);
  srand(tv.tv_usec);

  int action = rand()%11;
  int dir = rand()%7;

  switch(action)
  {
    case 8:
      printf("B %s", dirs[dir]);
      break;

    case 9:
      printf("M %s", dirs[dir]);
      break;

    case 10:
      printf("L %s", dirs[dir]);
      break;

    default:
      printf(dirs[action]);
      break;
  }
}

এটি নীচে হিসাবে (নিজের বিরুদ্ধে) পরীক্ষা করুন।

$ gcc random.c -o random
$ ./bb random

এটা ঠিক হওয়া উচিত int main?
আরশাজি


বোকা জিসিসি। void mainবিএস হয়।
টমসডিং

5

ঝামেলা এবং স্ট্রাফ

লড়াইয়ে কিছু রুবির উপস্থাপনা। বিপরীত দেয়ালে এলোমেলোভাবে নির্ধারিত দেয়াল ফায়ারিং মিসাইলগুলি উপরে এবং নীচে সরানো হয়। উপরে এবং নীচে কিছুটা চটকদার।

def getInput()
    inputlines=ARGV[0].split(/\n/)
    return [inputlines[0, 10], inputlines[10, 2], inputlines[12..-1]]
end

def getMyPos(arena)
    pos=[]
    arena.each_with_index{|str, index| pos=[str.index('Y'), index] if(!str.index('Y').nil?)}
    return pos
end

def parseProjectiles(projectiles)
    projectiles.map!{|prj| prj.split(' ')}
    missiles=projectiles.select{|prj| prj[0]=='M'}
    bullets=projectiles.select{|prj| prj[0]=='B'}
    landmines=projectiles.select{|prj| prj[0]=='L'}
    return [missiles, bullets, landmines]
end

def haveFired?(ypos, direction, projectiles)
    return projectiles.select{|prj| prj[2]==ypos.to_s && prj[3]==direction}.size>0
end

arena, botenergy, projectiles=getInput()
missiles, bullets, landmines=parseProjectiles(projectiles)

myposX=getMyPos(arena)[0]
myposY=getMyPos(arena)[1]

direction="WE"[myposX!=0 ? 0 : 1]

if haveFired?(myposY, direction, missiles)
    if myposY==0
        print "S"
    elsif myposY==9
        print "N"
    else
        if haveFired?(myposY-1, direction, missiles)
            print "S"
        elsif haveFired?(myposY+1, direction, missiles)
            print "N"
        else
            if(Random.rand(2)==0)
                print "N"
            else
                print "S"
            end
        end
    end
else
    print "M "+direction
end

5

একটি জাভাস্ক্রিপ্ট কোর

আমি ভেবেছিলাম আমি সদয় হব এবং আপনাকে আমার মূল জেএস বট দেব। এটি একটি বট তৈরির জন্য প্রয়োজনীয় সমস্ত কার্যাদি পেয়েছে, এটি আপনাকে যে ডেটা দেয় তার উপর ভিত্তি করে আপনাকে কিছু কাজ করতে হবে। এখনও শেষ হয়নি, যেহেতু আমি সত্যিই এটি পরীক্ষা করতে পারছি না (সংকলনের জন্য আখড়া কোডটি পেতে পারি না)।

এটি বিনা দ্বিধায়, আমি মিশ্রণে কিছু জেএস বট দেখার অপেক্ষায় রয়েছি।

করতে:

  • অস্ত্রের অবস্থান গণনা করতে ফাংশন যুক্ত করুন

    var stdi = WScript.StdIn;
    var stdo = WScript.StdOut;
    
    function botLog(toLog){
        var fso  = new ActiveXObject("Scripting.FileSystemObject");
        var fh = fso.CreateTextFile("./botLog.txt", 8, true);
        fh.WriteLine(toLog); 
        fh.Close(); 
    }
    
    var directions = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW'];
    
    // READ ARGUMENTS AND CREATE THE ARENA
    var arena = {};
    
    arena.map = WScript.Arguments.Item(0); // Get the arena from arguments
    arena.rows = arena.map.split('\\n');
    
    
    arena.find = function(toFind){ //Find a character in the arena.
        for(var i = 0; i < 10; i++){
            if(arena.rows[i].indexOf(toFind) !== -1){
                return [arena.rows[i].search(toFind), i];
            }
        }
    };
    arena.findAtPos = function(x, y){
        return arena.rows[y].charAt(x);
    };
    
    me = {};
        me.pos = arena.find('Y');
        me.x = me.pos[0];
        me.y = me.pos[1];
        me.energy = parseInt(arena.rows[10].replace("Y ", ""));
        me.nearby = {
            N : arena.findAtPos(me.x, me.y - 1),
            NE : arena.findAtPos(me.x + 1, me.y - 1),
            E : arena.findAtPos(me.x + 1, me.y),
            SE : arena.findAtPos(me.x + 1, me.y + 1),
            S : arena.findAtPos(me.x, me.y + 1),
            SW : arena.findAtPos(me.x - 1, me.y + 1),
            W : arena.findAtPos(me.x - 1, me.y),
            NW : arena.findAtPos(me.x -1, me.y - 1),
    
            contains : function(checkFor){
                for(var j = 0; j < 8; j++){
                    if(me.nearby[j] === checkFor){
                        return true;
                    }
                }
            }
        }
    
    foe = {};
        foe.pos = arena.find('X');
        foe.x = foe.pos[0];
        foe.y = foe.pos[1];
        foe.energy = parseInt(arena.rows[11].replace("X ", ""));
    

দয়া করে নোট করুন যে এখানে কিছু জিনিস অন্য ওএসের জন্য সংশোধন করতে হতে পারে (এটি কেবল উইন্ডোজে কাজ করে)। রাইনো সংস্করণটি এখানে: http://pastebin.com/FHvmHCB8


ডাউনভোট এবং কোন মন্তব্য নেই? যে কেউ এটিকে হ্রাস করেছে দয়া করে আমাকে কারণ জানাতে পারেন? আমার কোডে কোন ভুল আছে?
করউইন

হ্যাঁ, নিচে ভোটারদের তাদের আপত্তিটি এখানে ব্যাখ্যা করা দরকার।
গ্যারেথ

4

কেন্দ্র-বট

একটি জাভাস্ক্রিপ্ট বট

এই বটটি আখেরার মাঝামাঝি জায়গায় getোকার লক্ষ্য নিয়েছে, এটি প্রতিটি ঘুরতে লক্ষ্য করে গুলি বা ক্ষেপণাস্ত্র গুলি চালানোর আগে এটি কতটা কাছাকাছি তার উপর নির্ভর করে। শত্রু যদি মাঝখানে থাকে তবে এটি অস্পষ্ট দিকে গুলি চালিয়ে যাবে।

আমি এটি খুব ভাল করার প্রত্যাশা করি না, তবে এটি আরও একটি পরীক্ষামূলক it

    var arena = {};
var sys = require("sys");
var fs = require("fs");

arena.map = process.argv[2];
arena.rows = arena.map.split('\n');


arena.find = function(toFind){
    for(var i = 0; i < 10; i++){
            if(arena.rows[i].indexOf(toFind) !== -1){
                return [arena.rows[i].search(toFind), i];
            }
    }
};
arena.findAtPos = function(x, y){
    return arena.rows[y].charAt(x);
};

me = {};
    me.pos = arena.find('Y');
    me.x = me.pos[0];
    me.y = me.pos[1];
    me.energy = parseInt(arena.rows[10].replace("Y ", ""));

foe = {};
    foe.pos = arena.find('X');
    foe.x = foe.pos[0];
    foe.y = foe.pos[1];
    foe.energy = parseInt(arena.rows[11].replace("X ", ""));
function findFoe(){ 
    if(me.x < foe.x){
        if(me.y < foe.y){
            foe.direction = 'SE';
        }
        else if(me. y  === foe.y){
            foe.direction  = 'E';
        }
        else{
            foe.direction = 'NE';
        }
    }
    if(me.x === foe.x){
        if(me.y < foe.y){
            foe.direction = 'S';
        }
        else{
            foe.direction = 'N';
        }
    }
    if(me.x > foe.x){
        if(me.y < foe.y){
            foe.direction = 'SW';
        }
        else if(me. y  === foe.y){
            foe.direction  = 'W';
        }
        else{
            foe.direction = 'NW'
        }
    }
}

function findCentre(){
    if(me.x < 5){
        if(me.y < 5){
            centreDirection = 'SE';
        }
        else if(me.y  === 5){
            centreDirection  = 'E';
        }
        else{
            centreDirection = 'NE'
        }
    }
    if(me.x === 5){
        if(me.y < 5){
            centreDirection = 'S';
        }
        else{
            centreDirection = 'N'
        }
    }
    if(me.x > 5){
        if(me.y < 5){
            centreDirection = 'SW';
        }
        else if(me. y  === 5){
            centreDirection  = 'W';
        }
        else{
            centreDirection = 'NW'
        }
    }
}
findCentre();
findFoe();
if(me.x !== 5 && me.y !== 5){
    process.stdout.write(centreDirection);
}else{
    if(foe.x >= me.x + 2 || foe.x <= me.x - 2  || foe.y >= me.y + 2 || foe.y <= me.y - 2){
        process.stdout.write('M ' + foe.direction);
    }else process.stdout.write('B ' + foe.direction);
}

.js ফাইল হিসাবে সংরক্ষণ করুন এবং এর সাথে সম্পাদন করুন node centrebot.js। এটি নোড.জেএস এর সাথে কাজ করবে, তবে আপনাকে অন্য প্রোগ্রামের জন্য এটি সংশোধন করতে হতে পারে, দুঃখিত!

আমার পরীক্ষায়:

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

শীর্ষ জাভা বটগুলির কোনও পরীক্ষা করা হয়নি এবং আমি খুব আত্মবিশ্বাসীও না ...


আমি টেস্ট মেশিনে স্পাইডারমোনকি ইনস্টল করেছি, সুতরাং আমি putstr(...)আপনার পরিবর্তে ব্যবহার করছি stdo.writeLine(...)এবং ইনপুটটি আসছে scriptArgs[0]। এটি করার পরে আমি মানচিত্রকে লাইনে বিভক্ত \\nকরার \nজন্য পরিবর্তন করতে হবে । যখন আমি এটি চালানোর আমি কোনো ত্রুটির সম্মুখীন হয়েছেন কারণ FindFoe()এবং findCentre()সংজ্ঞায়িত করা হয় কিন্তু বলা হয় না।
গ্যারেথ

ওহো! সবেমাত্র একটি ত্রুটিযুক্ত! আমি ফাংশনগুলি পেয়েছি কিন্তু বাস্তবে সেগুলি চালাচ্ছি না! আমার খারাপ, আমি এটি পরিবর্তন করব। ধন্যবাদ!
করউইন

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

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

3

কুনিংপ্লানবট (পাইথন ৩.৩)

এটি প্রকৃত ইন্টারফেসের অধীনে সম্পূর্ণ অনির্ধারিত ... এটি কমপক্ষে মানচিত্রের সাথে সঠিকভাবে কাজ করে!

এটি পাইথন ৩.৩ এর জন্য লেখা

এর মানে কি:

যদি প্রথম পর্যায়ে থাকে - যদি দেয়াল এবং দিকের দিকে প্রাচীরের দিকে চলে যায় বা একটি ল্যান্ডমাইনটিতে চলে যায়, এলোমেলোভাবে দিকটি একটি অ প্রাচীর বা ল্যান্ডমাইন দিকের দিকে পরিবর্তন করুন - বর্তমান দিকের দিকে যান - দ্বিতীয় পর্যায়ে যান

যদি দ্বিতীয় ধাপে - শত্রুর নিকটতম দিকে গুলি চালান - তৃতীয় ধাপে যান

যদি 3 ম পর্যায়ে থাকে - যদি জমি খনি না হয় তবে স্থল খনিটি ড্রপ করুন - পর্ব 1 এ যান

একটি ক্ষেপণাস্ত্র গুলি করা হবে কিনা তা এখনও খুঁজে বের করা প্রয়োজন। এছাড়াও ল্যান্ডমাইনটি এড়ানো জিনিসগুলি কাজ করে কিনা সে সম্পর্কে আমার কোনও ধারণা পাওয়া যায়নি। কাল সন্ধ্যায় আরও পরীক্ষার প্রয়োজন।

#!/usr/bin/python
import sys
import os.path
import random
import math

def iround(x):
    return int(round(x) - .5) + (x > 0)   

currentphase = 0
currentdir = 0

#
#     4  
#   5   3  
# 6  DIR  2
#   7   1
#     0

if os.path.isfile('state/cpb'):
  statein = open('state/cpb', 'r')  
  currentdir = int(statein.read(1))
  currentphase = int(statein.read(1))
  statein.close()

Landmines = []    

#Loads the map bit. The bits we care about anyway.
line=sys.argv[1].splitlines()
for y in range(0, 10):
  for x in range(0, 10):
    if line[x][y] == "X":
      hisloc = (x, y)
    elif line[x][y] == "Y":    
      myloc = (x, y)
    elif line[x][y] == "L":
      Landmines.append((x,y))

#print(myloc[0])
#print(myloc[1])

newdir = False
if (currentphase == 0):
  if (currentdir == 7) or (currentdir == 0) or (currentdir == 1) and (myloc[1] == 9):
    newdir = True
  if (currentdir == 5) or (currentdir == 4) or (currentdir == 3) and (myloc[1] == 0):
    newdir = True
  if (currentdir == 3) or (currentdir == 2) or (currentdir == 1) and (myloc[0] == 9):
    newdir = True
  if (currentdir == 5) or (currentdir == 6) or (currentdir == 7) and (myloc[0] == 0):
    newdir = True    
  if newdir:
    newdirs = []
    #Test 0
    if (myloc[1] < 9) and not (myloc[0], myloc[1] + 1) in Landmines:
      newdirs.append(0)
    #Test 1
    if (myloc[0] < 9) and (myloc[1] < 9) and not (myloc[0] + 1, myloc[1] + 1) in Landmines:
      newdirs.append(1)
    #Test 2
    if (myloc[0] < 9) and not (myloc[0] + 1, myloc[1]) in Landmines:
      newdirs.append(2)
    #Test 3
    if (myloc[0] < 9) and (myloc[1] > 0) and not (myloc[0] + 1, myloc[1] - 1) in Landmines:
      newdirs.append(3)      
    #Test 4
    if (myloc[1] > 0) and not (myloc[0], myloc[1] - 1) in Landmines:
      newdirs.append(4)
    #Test 5
    if (myloc[0] > 0) and (myloc[1] > 0) and not (myloc[0] - 1, myloc[1] - 1) in Landmines:
      newdirs.append(5)    
    #Test 6
    if (myloc[0] > 0) and not (myloc[0] - 1, myloc[1] ) in Landmines:
      newdirs.append(6)      
    #Test 7
    if (myloc[0] > 0) and (myloc[1] > 9) and not (myloc[0] - 1, myloc[1] + 1) in Landmines:
      newdirs.append(7)     
    if len(newdirs) == 0:
      if currendir == 0: currentdir = 4
      elif currendir == 1: currentdir = 5
      elif currendir == 2: currentdir = 6
      elif currendir == 3: currentdir = 7
      elif currendir == 4: currentdir = 0
      elif currendir == 5: currentdir = 1
      elif currendir == 6: currentdir = 2
      elif currendir == 7: currentdir = 3
    else:
      currentdir = random.SystemRandom().choice(newdirs)
  if currentdir == 0: print ("S", end="")
  elif currentdir == 1: print ("SE", end="")
  elif currentdir == 2: print ("E", end="")
  elif currentdir == 3: print ("NE", end="")
  elif currentdir == 4: print ("N", end="")
  elif currentdir == 5: print ("NW", end="")
  elif currentdir == 6: print ("W", end="")
  elif currentdir == 7: print ("SW", end="")

elif (currentphase == 1):
  dx = (myloc[0] - hisloc[0])
  dy = (myloc[1] - hisloc[1])
  distance = math.pow(dx*dx+dy*dy, 0.5)
  angle = int(iround(math.degrees(math.atan2(dx, -dy)) / 45) ) % 8
  if angle == 5: print ("B S", end="")
  elif angle == 1: print ("B SE", end="")
  elif angle == 2: print ("B E", end="")
  elif angle == 3: print ("B NE", end="")
  elif angle == 4: print ("B N", end="")
  elif angle == 5: print ("B NW", end="")
  elif angle == 6: print ("B W", end="")
  elif angle == 7: print ("B SW", end="") 

elif (currentphase == 2):
  if not (myloc in Landmines): print ("L", end="")

currentphase = (currentphase + 1) % 3    

stateout = open ('state/cpb', 'w')
stateout.write(str(currentdir))
stateout.write(str(currentphase))
stateout.close()

2
এটি স্কোরার প্রোগ্রামের সাথে কাজ করার জন্য আমাকে বেশ কয়েকটি জিনিস করতে হয়েছিল: আমি sys.argv[1].splitlines()কমান্ড-লাইন থেকে ইনপুটটি দখল করতাম , এবং তারপরে line[x][y]নিম্নলিখিত ব্লকে ব্যবহার করতাম ; end=""স্কোরারকে বিভ্রান্ত করে এমন নতুন লাইন থেকে মুক্তি পেতে মুদ্রণ কমান্ডগুলিতে যুক্ত ; নিজের stateপরিবর্তে ডিরেক্টরিতে কোনও ফাইলে লেখার জন্য রাষ্ট্রকে পরিবর্তন করে changed state
গ্যারেথ

Eek! আমার ক্ষমা। এটা রাতের পরে তখন আমার সম্ভবত এটি পাঠানো উচিত ছিল। আমি এটি ASAP হিসাবে অনুগত অনুগ্রহ করে পাবেন!
lochok

কোনও সমস্যা নেই, যতক্ষণ না আপনার এটি পর্যালোচনা করা হয় ততক্ষণ আমি কোনও টেস্ট স্কোরিং রান করার জন্য আমার ফিক্সগুলি ব্যবহার করব।
গ্যারেথ

আমি একই সংশোধনগুলি প্রয়োগ করেছি তবে আমি 'পাই_ইনাইটালাইজ: এস স্ট্যান্ডার্ড স্ট্রিম শুরু করতে পারি না'। কোনও উত্স আপনার উত্সটির সংস্করণটি দখল করতে পারে তা দেখতে কি এটি একই হয়?
lochok

1
আমি উত্সটির আমার সংস্করণটি আপনার পোস্টে সম্পাদনা হিসাবে যুক্ত করেছি (সবচেয়ে সহজ উপায় বলে মনে হয়েছিল)। আপনি উত্সটি ধরলে কেবল এটিকে আবার রোল করুন।
গ্যারেথ

3

UltraBot

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

import java.awt.Point;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;

public class UltraBot {
    private static final int arenaSize = 10;
    private static ArrayList<Weapon> weapons = new ArrayList<Weapon>();
    private static Bot me;
    private static Bot enemy;

    public static void main(String args[]) {
        Direction suggestedMove;
        readInput(args[0]);
        suggestedMove = suggestedMove();

        if (suggestedMove != Direction.STAY) {
            System.out.print(suggestedMove.name());
            return;
        }

        System.out.print(shootCmd());
    }

    public static void readInput(String args) {
        String[] lines = args.split("\\r?\\n");

        for(int i=0;i<lines.length;i++){
            String line = lines[i];
            if(i<arenaSize){
                if(line.contains("X"))
                    enemy = new Bot(new Field(line.indexOf("X"),i));
                if(line.contains("Y"))
                    me = new Bot(new Field(line.indexOf("Y"),i));
            } else {
                String[] tokens = line.split(" ");
                switch(tokens[0].charAt(0)){
                case 'X':
                    enemy.setLife(Integer.parseInt(tokens[1]));
                    break;
                case 'Y':
                    me.setLife(Integer.parseInt(tokens[1]));
                    break;
                default:
                    weapons.add(new Weapon(tokens));
                    break;
                }
            }
        }
    }

    public static Direction suggestedMove() {
        Map<Direction, Integer> surrFields = new HashMap<Direction, Integer>();
        Random rand = new Random();

        //calculate danger for all surrounding fields
        for(Direction direction : Direction.values()) {
            Field currField = me.getPos().incPos(direction, 1);
            surrFields.put(direction, currField.calcDanger(weapons, enemy));
        }

        int currDanger = surrFields.get(Direction.STAY);
        Direction currDirection = Direction.STAY;

        for (Entry<Direction, Integer> e : surrFields.entrySet()) {
            //always move if better field found
            if (e.getValue() < currDanger) {
                currDanger = e.getValue();
                currDirection = e.getKey();
            }
            //move sometimes if equal danger field found
            else if(e.getValue() == currDanger && rand.nextInt(3) == 1) {
                if (currDanger != 0 || rand.nextInt(15) == 1) {
                    currDanger = e.getValue();
                    currDirection = e.getKey();
                }
            }
        }
        return currDirection;
    }

    public static String shootCmd() {
        WeaponType type = WeaponType.M;

        if(me.getPos().isNear(enemy.getPos(), 3)) {
            type = WeaponType.B;
        }

        return type.name() + " " + me.shootDirection(enemy);
    }
}

class Bot {
    private Field pos;
    private int life;

    public Bot(Field pos) {
        this.pos = pos;
    }

    public void setLife(int life) {
        this.life = life;
    }

    public Field getPos() {
        return pos;
    }

    public int getLife() {
        return life;
    }

    public String shootDirection(Bot other) {
        Random rand = new Random();
        Direction direction = Direction.S;
        if (getPos().getX() >= other.getPos().getX() && getPos().getY() >= other.getPos().getY()) {
            switch(rand.nextInt(5)) {
                case 0: direction =  Direction.N; break;
                case 1: direction = Direction.W; break;
                default: direction = Direction.NW; break;
            }
        }
        else if (getPos().getX() <= other.getPos().getX() && getPos().getY() >= other.getPos().getY()) {
            switch(rand.nextInt(3)) {
                case 0: direction = Direction.N; break;
                case 1: direction = Direction.E; break;
                default: direction = Direction.NE; break;
            }
        }
        if (getPos().getX() >= other.getPos().getX() && getPos().getY() <= other.getPos().getY()) {
            switch(rand.nextInt(3)) {
                case 0: direction = Direction.S; break;
                case 1: direction = Direction.W;break;
                default: direction = Direction.SW;break;
            }
        }
        if (getPos().getX() <= other.getPos().getX() && getPos().y <= other.getPos().y) {
            switch(rand.nextInt(3)) {
                case 0: direction = Direction.S; break;
                case 1: direction = Direction.E; break;
                default: direction = Direction.SE; break;
            }
        }
        return direction.name();
    }
}

enum Direction {
    N(0, -1), NE(1, -1), E(1, 0), SE(1, 1), S(0, 1), SW(-1, 1), W(-1, 0), NW(-1,-1), STAY(0,0);

    public final int offsetX;
    public final int offsetY;

    Direction(int offsetX, int offsetY) {
        this.offsetX = offsetX;
        this.offsetY = offsetY;
    }
}

enum WeaponType {
    B(1, 3), M(3, 2), L(2, 0);

    public final int dmg;
    public final int speed;

    WeaponType(int dmg, int speed) {
        this.dmg = dmg;
        this.speed = speed;
    }
}

class Weapon {
    private WeaponType type;
    private Direction direction;
    private Field pos;

    public Weapon(String[] tokens) {
        this.type = WeaponType.valueOf(tokens[0]);
        this.pos = new Field(Integer.parseInt(tokens[1]), Integer.parseInt(tokens[2]));
        if(type != WeaponType.L) {
            this.direction = Direction.valueOf(tokens[3]);
        }
    }

    public int getDanger(Field dest) {

        if (dest.isOutside()) {
            return 99;
        }

        if (type == WeaponType.L) {
            return dest.equals(pos) ? type.dmg * 3 : 0; // stepped on landmine
        }

        for (int i = 1; i <= type.speed; i++) {
            Field newPos = pos.incPos(direction, i);

            if (dest.equals(newPos)) {
                return type.dmg * 3; // direct hit with missile or bullet
            }
        }

        return 0;
    }
}

class Field extends Point{

    public Field(int x, int y) {
        super(x,y);
    }

    // as it tries to stay off walls and enemy, it doesn't need to calc splash dmg

    public int calcDanger(ArrayList<Weapon> weapons, Bot enemy) {
        int danger = 0;

        // is near wall
        if (this.getX() == 0 || this.getX() == 9)
            danger++;
        if (this.getY() == 0 || this.getY() == 9)
            danger++;

        for (Weapon weapon : weapons) {
            danger += weapon.getDanger(this);
        }

        // near bot
        if (this.isNear(enemy.getPos(), 2)) {
            danger++;
        }

        return danger;
    }

    public Boolean isOutside() {
        if (this.getX() > 9 || this.getY() > 9 || this.getX() < 0 || this.getY() < 0) {
            return true;
        }
        return false;
    }

    public Boolean isNear(Field dest, int distance) {
        int dx = (int)Math.abs(dest.getX() - this.getX());
        int dy = (int)Math.abs(dest.getY() - this.getY());

        if (dx <= distance || dy <= distance) {
            return true;
        }
        return false;
    }

    public Field incPos(Direction direction, int step) {
        return new Field((int)this.getX() + (direction.offsetX * step), 
                (int)this.getY() + (direction.offsetY * step));
    }
}

এই বটটি আঘাত করা অত্যন্ত কঠিন, তবে শত্রুদের গুলি চালানোর ক্ষেত্রে খুব ভাল নয় ... আমি এখনও এটি আমার আগের ক্যাম্পারবটের চেয়ে ভাল হওয়ার আশা করি।


কেবল এটি সংকলনের চেষ্টা করে ত্রুটিগুলির একটি বোঝা ছুঁড়ে ফেলেছি। মনে হচ্ছে এটি কিছুটা হারিয়েছে import?
গ্যারেথ

ব্যক্তিগত অ্যাক্সেস সম্পর্কেও প্রচুর ত্রুটি:UltraBot.java:...: x has private access in Point
গ্যারেথ

ওপস, আমদানিগুলি সম্পর্কে ভুলে গেছি ... এটি আমার মেশিনে কাজ করা সত্ত্বেও এক্স / ওয়াই-অ্যাক্সেসটিও ঠিক করে দিয়েছে ...
সাধারণগুয়ে

1
ঠিক আছে, ধন্যবাদ. এটি এখন আমার মেশিনে কাজ করছে।
গ্যারেথ

2

NinjaPy

পাইথনে শেষ মুহুর্তের জমা দেওয়া (অনির্ধারিত তবে আশা করি কার্যকর হবে)। ধারণাটি হ'ল এটি অন্ধের জায়গায় থাকা অবস্থায় প্রতিপক্ষের দিকে অগ্রসর হয়। যখন এটি যথেষ্ট কাছাকাছি হয় (3 কোষের দূরে) এটি প্রতিপক্ষের তির্যকটিতে নিজেকে রাখে এবং একটি ক্ষেপণাস্ত্র অঙ্কিত করে।

import sys

def position(arena, element):
    y = [i for i,j in enumerate(arena) if element in arena[i]][0]
    x = arena[y].index(element)
    return (x,y)

def distance(other):
    dM = [[0 for x in range(10)] for y in range(10)]
    for i in range(len(dM)):
        for j in range(len(dM[0])):
            dM[i][j] = max([abs(other[0]-i),abs(other[1]-j)])
    return dM

def direction(coord1, coord2):
    d0 = coord1[0]-coord2[0]
    d1 = coord1[1]-coord2[1]
    if d1!=0:
        a = ['N','S'][d1<0]
    else: a = ""
    if d0!=0:
        b = ['W','E'][d0<0]
    else: b = ""
    return a+b

def getPath(coord, aim, speed):
    d = {'N': (0,-1), 'S':(0,1), 'E':(1,0), 'W':(-1,0), 'NW':(-1,-1), 'NE':(1,-1), 'SW':(-1,1), 'SE':(1,1)}
    D = d[aim]
    path = [(coord[0]+D[0]*i, coord[1]+D[1]*i) for i in range(speed+1)]
    return path

def dangerMap(stuff,other):
    dM = [[0 for x in range(10)] for y in range(10)]
    surroundings = [(other[0]+i,other[1]+j) for i in range(-2,3) for j in range(-2,3)]
    for i in range(len(dM)):
        for j in range(len(dM[0])):
            if i == other[0] : dM[i][j] = 1
            if j == other[1] : dM[i][j] = 1
            if (i,j) in [(other[0]+k, other[1]+k) for k in range(-10,11)]: dM[i][j] = 1
            if (i,j) in [(other[0]-k, other[1]+k) for k in range(-10,11)]: dM[i][j] = 1
    for j in surroundings:
        dM[j[0]][j[1]] = 2
    if len(stuff):
        s = [i.split(" ") for i in stuff]
        for i in s:
            if i[0]=='L':
                g = [(int(i[1]),int(i[2]))]
            if i[0]=='M':
                g = getPath((int(i[1]),int(i[2])),i[3],2)
            if i[0]=='B':
                g = getPath((int(i[1]),int(i[2])),i[3],3)
            for j in g:
                dM[j[0]][j[1]] = 2
    return dM

input = sys.argv[1].splitlines()
arena = input[0:10]
stuff = input[12:]
me = position(arena, "Y")
other = position(arena,"X")
distOther = distance(other)
distMe = distance(me)
dangM = dangerMap(stuff,other)
if distOther[me[0]][me[1]] > 3:
    surroundings = [(i,j) for i in range(10) for j in range(10) if distMe[i][j]==1]
    choice = [k for k in surroundings if dangM[k[0]][k[1]] == 0]
    if len(choice)==0: choice = [k for k in surroundings if dangM[k[0]][k[1]] == 1]
    if len(choice)>1:
        K = []
        for i in choice: K += [distOther[i[0]][i[1]]]
        choice = [choice[k] for k in range(len(choice)) if K[k] == min(K)]
    action = direction(me,choice[0])
else:
    diag = [(other[0]+i, other[1]+i) for i in [-2,2]]+[(other[0]-i, other[1]+i) for i in [-2,2]]
    if me in diag:
        action = 'M '+direction(me,other)
    else:
        distDiag = []
        for i in diag:
            distDiag += [distMe[i[0]][i[1]]]
        choice = [diag[k] for k in range(len(diag)) if distDiag[k] == min(distDiag)]
        action = direction(me,choice[0])

sys.stdout.write(action)

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