बैटलबोट्स: द टूर्नामेंट


69

परिणाम सामने हैं, प्रतियोगिता समाप्त हो गई है।
विजेता अर्शजी का एविलबोट है जिसमें 14 जीत के साथ नियो-बॉट 13 जीत और सेंट्रेबोट और लास्टस्टैंड 11 जीत के साथ प्रत्येक है।

फाइनल रन से स्कोर

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)

यह एक चुनौती है। उद्देश्य एक बॉट लिखना है जो किसी भी अन्य की तुलना में अन्य बॉट्स को अधिक हरा देगा।

खेल

बॉट्स सभी को एक-दूसरे के खिलाफ 10x10 अखाड़े में एक समय में 2 के खिलाफ खड़ा किया जाएगा, जिसमें प्रतिद्वंद्वी की ऊर्जा को 10 से घटाकर 0 करने से पहले अपनी खुद की ऊर्जा को 0 तक कम करने का काम होगा।

प्रत्येक मैच में 5 मुकाबले होंगे। मैच का विजेता सबसे अधिक मुकाबलों का विजेता होता है। मैच जीत और बाउट जीत की कुल संख्या को नियंत्रण कार्यक्रम द्वारा संग्रहीत किया जाएगा और प्रतियोगिता के समग्र विजेता को निर्धारित करने के लिए उपयोग किया जाएगा। विजेता बड़े हरे रंग की टिक और जनता की प्रशंसा प्राप्त करता है।

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

हथियार

प्रत्येक बॉट के पास कई हथियार होंगे:

  • कवच-भेदी गोलियां। ये एक बार में 3 वर्गों की यात्रा करते हैं और 1 ऊर्जा बिंदु को नुकसान पहुंचाते हैं।
  • मिसाइलों। ये एक समय में 2 चौकों की यात्रा करते हैं और प्रभाव के बिंदु पर 3 ऊर्जा बिंदुओं को नुकसान पहुंचाते हैं, और तुरंत सभी वर्गों में क्षति का 1 बिंदु।
  • बारूदी सुरंगों। ये तुरंत बॉट के आसपास के चौकों में से एक में गिरा दिए जाते हैं और आगे बढ़ने पर 2 ऊर्जा बिंदुओं को नुकसान पहुंचाते हैं, और तुरंत आसपास के किसी एक वर्ग में खड़े किसी भी चीज को नुकसान के 1 ऊर्जा बिंदु।
  • इलेक्ट्रो-मैग्नेटिक पल्स। दोनों बॉट्स मूवमेंट सर्किट को 2 मोड़ों के लिए खराबी के कारण, जिसका अर्थ है कि वे स्थानांतरित नहीं कर सकते हैं। वे, हालांकि, अभी भी हथियार तैनात कर सकते हैं (हाँ मुझे पता है कि यह यथार्थवादी नहीं है, लेकिन यह एक खेल है। यह वास्तविक जीवन नहीं माना जाता है)। संपादित करें: प्रत्येक ईएमपी तैनाती बॉट का एक ऊर्जा बिंदु खर्च करेगी जो इसका उपयोग करती है।

बुलेट / मिसाइल केवल बॉट, या दीवारों के साथ प्रभाव डाल सकते हैं। वे किसी भी ऐसे बॉट को मारेंगे, जो किसी भी ऐसे वर्ग में है, जिससे वे गुजरते हैं। एक बार जब वे कुछ हिट करते हैं तो वे गायब हो जाते हैं।

सभी मामलों immediately surrounding squaresमें 8 वर्गों का मतलब है कि बॉट अपने अगले कदम - मूर पड़ोस पर जा सकता है।

आज्ञा

  • 0 कुछ मत करो।
  • N, NE, E, SE, S, SW, W, NWसभी दिशा आदेशों कर रहे हैं और दिए गए दिशा में बॉट एक वर्ग ले जाएँ। यदि बॉट उस दिशा में जाने में असमर्थ है क्योंकि चौराहे पर एक दीवार या कोई अन्य बॉट है, तो बॉट वहीं रहता है। एक वर्ग में जाना जिसमें पहले से ही एक बुलेट या मिसाइल सुरक्षित है क्योंकि बुलेट / मिसाइल को उस वर्ग से बाहर जाने के पहले से ही माना जाएगा।
  • B एक अंतरिक्ष द्वारा पीछा किया जाता है और फिर एक दिशा निर्देश उस दिशा में एक कवच भेदी गोली चलाता है।
  • M एक स्थान और उसके बाद एक दिशा निर्देश उस दिशा में एक मिसाइल फायर करता है।
  • Lएक स्थान और उसके बाद दिशा निर्देशों में से एक बॉट के बगल में उस वर्ग पर एक भूमि की खान को गिराता है। यदि वर्ग पहले से ही दीवार या बॉट द्वारा कब्जा कर लिया गया है, तो कमांड को अनदेखा किया जाता है। यदि एक बारूदी सुरंग को दूसरे बारूदी सुरंग पर गिराया जाता है, तो यह विस्फोट कर देती है। यह बॉट को ड्रोपिंग करने वाले नुकसान पहुंचाएगा, और मूल बारूदी सुरंग की सीमा के भीतर किसी भी अन्य बॉट को नुकसान पहुंचाएगा।
  • P ईएमपी फायर करता है।

चूँकि प्रति राउंड केवल एक कमांड दिया जा सकता है, एक बोट केवल एक हथियार को स्थानांतरित या आग / तैनात कर सकता है, एक ही समय में दोनों नहीं।

आदेशों का आदेश
या तो बॉट की आवाजाही हमेशा पहले आएगी, और सभी आंदोलनों को दो बार प्रयास किया जाएगा कि एक और बॉट रास्ते में हो लेकिन रास्ते से बाहर जा रहा है।

उदाहरण

  • बॉट 1 स्थानांतरित करने की कोशिश करता है Eलेकिन बॉट 2 पहले से ही उस वर्ग में है
  • नियंत्रण कार्यक्रम बॉट 2 पर आगे बढ़ता है।
  • बॉट 2 स्थानांतरित करने की कोशिश करता है Sऔर सफल होता है क्योंकि कुछ भी रास्ते में नहीं है।
  • बोट 1 को अपनी चाल में दूसरा प्रयास करने का मौका मिलता है। इस बार यह सफल हुआ और बॉट 1 आगे बढ़ा 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';
  }
}

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

intx13 ने कुछ बगफिक्स के साथ नियंत्रण कार्यक्रम का अधिक मजबूत संस्करण लिखा है, जिसे आप यहां पा सकते हैं ।

नियंत्रण कार्यक्रम में सुधार या बग-सुधार के सुझाव स्वागत योग्य हैं।

टेस्ट बॉट

स्कोरिंग रन में कोई भी टेस्ट बॉट शामिल नहीं होगा। वे सिर्फ परीक्षण के उद्देश्य के लिए हैं।

डडली डोनट (C)

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

स्थिति की परवाह किए बिना कुछ भी नहीं करता है। ज्यादा जीत की उम्मीद नहीं थी।

HuggyBot (PHP)

<?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
@ intx13 शायद बॉट 1 से संबंधित बॉट और बॉट 2 के संगत एक ही हर बॉउट को रैंडम नहीं होना चाहिए, बल्कि बेतरतीब ढंग से केवल पहले बॉउट पर चुना जाता है और प्रत्येक निम्नलिखित बाउट की शुरुआत में स्वैप किया जाता है।
अर्शजी

2
मुझे लगता है कि मुझे @ intx13 के कोड में एक बग मिला। जब दोनों बॉट एक ही समय में ईएमपी फायर करते हैं, तो मुझे लगता है कि दोनों को ऊर्जा खोनी चाहिए। मैंने उसका कोड नहीं चलाया है, लेकिन इसे देखते हुए, ऐसा प्रतीत नहीं होता है। पंक्तियों को देखें 295-304 github.com/gazrogers/CodegolfBattlebotsScorer/blob/master/…
थॉमस एडिंग

2
एक और संभावित बग। ऐसा लगता है कि बॉट ऊर्जा शून्य से नीचे जा सकती है। यह ठीक है, लेकिन अगर बॉट 1 में -1 ऊर्जा है और बॉट 2 में 0 ऊर्जा है, तो न तो जीत दर्ज करनी चाहिए।
थॉमस ईडिंग

2
इस टूर्नामेंट के लिए धन्यवाद, @ गैरेथ। यह एक अच्छी चुनौती थी और मुझे प्रोग्रामिंग के नए क्षेत्रों का पता लगाने के लिए प्रेरित किया। मेरे कुछ दोस्तों को लगता है कि मैं चुनौती दूंगा। :) सभी प्रतिभागियों को शुभकामनाएँ, अच्छा खेल!
कॉर्विन

जवाबों:


14

EvilBot

एक बॉट जो जितना संभव हो उतना बुराई करने की कोशिश करता है

अच्छी तरह से यहाँ मुझे क्या मिला है: एक जावा बॉट जो प्रतिद्वंद्वी के करीब के रूप में संभव के रूप में क्षेत्र के केंद्र के चारों ओर त्रिज्या 2.5 की एक गोलाकार पट्टी के करीब जाने की कोशिश करता है और फिर इसे जितना नुकसान हो सकता है उतना ही करता है। इसके आंदोलन पैटर्न उसके पड़ोसी वर्गों में से प्रत्येक के लिए एक "खतरे" मान निर्दिष्ट है, और इन मूल्यों पर आधारित ले करने का निर्णय लेने पर आधारित है और एक प्रवृत्ति के आधार पर क्षेत्र के केंद्र के बारे में त्रिज्या 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>

टिप्पणियाँ:

  • वर्तमान में, भूमि की खानों का उपयोग नहीं किया जा रहा है, केवल चकमा दिया गया है। मैं शायद इसे बदलने नहीं जा रहा हूँ, क्योंकि भूमि खानों का उपयोग करने से अच्छा है (कम से कम एविलबिल के लिए) कुछ परीक्षणों द्वारा निर्णय लेने से अधिक नुकसान होता है।

  • वर्तमान में, ईएमपी का उपयोग नहीं किया जा रहा है। मैंने प्रतिद्वंद्वी के साथ गठबंधन करने और मिसाइलों के बाद ईएमपी फायरिंग की रणनीति की कोशिश की, लेकिन इसके लिए कुछ प्रति-रणनीतियां हैं जो लगभग 100% जीतेंगी, इसलिए मैंने उस मार्ग को छोड़ने का फैसला किया। मैं बाद में अलग-अलग तरीकों से ईएमपी का उपयोग कर पता लगा सकता हूं।


औसत पर, एविलबोट ने सीधे निशानेबाज को 5-0 और ड्रॉडिंग बुर्ज को 2-0 से हराया। यह डोडिंग बुर्ज के साथ बहुत संबंध रखता है।
20

@ intx13 हाँ, मैंने भी देखा। ईविलबोट और ड्रॉडिंग बुर्ज दोनों किंग्स लास्ट स्टैंड के साथ टाई करते हैं; खेल एक अनंत लूप में कमी करता है।
अर्शजी

2
@ हर्षजी बधाई, आप जीत गए!
गारेथ

17

Rifter

यह बॉट किस लड़ाई को लेकर अलग-अलग कार्रवाई करता है। प्रतिद्वंद्वी को निर्धारित करने के लिए, यह अपने स्वयं के राज्य को फ़्लिप करता है और अन्य बॉट्स में फ़ीड करता है कि वे क्या करेंगे, और तुलना करते हैं कि वे वास्तव में क्या करते हैं। एक बार जब वे 'सही' चाल की दहलीज पर पहुंच जाते हैं, तो यह दूसरों का परीक्षण करना बंद कर देता है।

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

बेशक, कुछ कमियां हैं। एक यह है कि "बेतरतीब" गतिविधि वाले बॉट्स का इतनी अच्छी तरह से पता नहीं लगाया जाता है। यह प्रतिद्वंद्वी के ज्ञात नहीं होने पर किंग्स लास्ट स्टैंड लॉजिक का उपयोग करके संतुलित किया जाता है।

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

मेरे दूसरों की तरह, यह BattleBot.java का विस्तार करता है:

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

वाह ... मैं उत्सुक था कि विशेष बॉट पर प्रतिक्रिया करने वाले बॉट को प्राप्त करने में कितना समय लगेगा! यदि कुछ बहुत देर से प्रविष्टियां होती हैं तो यह कैसे चलेगा?
लोचोक

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

1
हह, मैं एक बॉट पर भी काम कर रहा हूं जो यह पहचानने की कोशिश करता है कि यह किस तरह के बॉट के खिलाफ लड़ रहा है! अब मैं इसे और अपडेट कर सकता हूं और एक बॉट की पहचान कर सकता हूं जो अन्य बॉट्स की पहचान करता है! या शायद कुछ चालों को नाकाम करके आपको धोखा दे! Muahaha!
टॉम वेरेलस्ट

1
@TomVerelst मैं पहले से ही आसानी से यह एक को विफल करने के लिए कुछ तरीके ऊपर सोचा है, तो मैं नहीं होगा भी एक नया बॉट यह नीचे ले देख कर हैरान। यह कहा जा रहा है, यह इस क्षेत्र में वर्तमान में बॉट्स के खिलाफ बहुत अच्छी तरह से करता है , जो कि मेरा लक्ष्य था। इसने मेरे आखिरी स्थानीय टेस्ट रन में 8/8 मैच जीते। यह कभी-कभी DodgingTurret को बाँध देता है, लेकिन मैं लगातार एक को हराने के लिए एक फाइट पैटर्न नहीं खोज सकता , इसलिए यह आसान है कि इसे दोनों जीत से इनकार करने दें।
Geobits

अगर यह खुद खेलता है तो क्या होगा?
PyRulez

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 पर है तो यह ईएमपी को छोड़ देता है।
ईएमपी को ट्रिगर करने पर नज़र रखने के लिए, यह फ़ाइल के अंत में एक टिप्पणी जोड़कर अपने स्रोत कोड को संशोधित करता है ( #p_fired2पहले तो, फिर इसे संशोधित करता है #p_fired1और फिर मिटा देता है)। मुझे उम्मीद है कि जब यह ईएमपी को ट्रिगर करता है तो इस तरह से नज़र रखना बहुत सीमावर्ती नहीं है।

कमांड लाइन होनी चाहिए Rscript ReadyAimShoot.R, उदाहरण के रूप में तर्क के बाद, कम से कम UNIX सिस्टम पर, लेकिन शायद खिड़कियों पर भी (मैं देखता हूं कि जब मैं वास्तव में इसे अन्य बॉट के खिलाफ परीक्षण करूँगा)।

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

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, यह ईएमपी-ब्लास्टर्स का मुकाबला करने के लिए डिज़ाइन किया गया है। ईएमपी का उपयोग करने का एकमात्र समझदार तरीका (आईएमओ) है, जब आप प्रतिद्वंद्वी के समान अक्ष पर होते हैं, तो यह फायरिंग करके होता है, फिर अटक प्रतिद्वंद्वी की ओर मिसाइलों / हथियारों की शूटिंग करता है। तो, मैं अक्ष से दूर रहता हूँ :)

यदि आपने कभी शतरंज का खेल किसी राजा + रानी के खिलाफ राजा के पास जाना है, तो आप जानते हैं कि एक रानी अकेले जाँच नहीं कर सकती , आपको राजा को शामिल करना होगा। यदि आप नहीं करते हैं, तो अकेला राजा की रणनीति आसान है: गतिशीलता को अधिकतम करने के लिए ऑफ-एक्सिस और केंद्र की ओर रहने की कोशिश करें। यदि आप फंस जाते हैं, तो गतिरोध के लिए जाएं।

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

ओह, और अगर यह पहले से ही धुरी है और प्रोजेक्टाइल से सुरक्षित है, तो यह दुश्मन की सामान्य दिशा में सिर्फ एक बर्तन लेगा।

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वर्ग बनाया । इसमें अखाड़ा पढ़ना, टकराव की जाँच, हेडिंग प्रबंधन आदि जैसे सहायक कार्य शामिल हैं। डिबगिंग में क्या हो रहा है, इसे ट्रैक करने में मदद करने के लिए एक लॉग फ़ंक्शन भी है। यदि 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
अच्छा लगा। दोनों माइनमाइन और रैंडमबोट को 5-0 से हराया।
गारेथ

@ कंक कोई संभावना नहीं। मैं वैसे भी यह करने जा रहा था; मुझे लगता है कि अगर यह किसी को शांत करने में मदद करता है। यह एक बहुत बेहतर हो सकता है, यद्यपि। यह बहुत नंगे-हड्डियों है, लेकिन यह मूल बातें मुझे मिल गया है।
जियोबिट्स

@ गैरेथ मैंने एक बग को ठीक किया BattleBots.java। क्या आप कृपया अगले रन से पहले मेरे बॉट्स को फिर से जोड़ सकते हैं?
Geobits

@Geobits ठीक है, करेंगे।
गारेथ

8

सर्पिल बॉट लिटरेट हास्केल

साक्षर हैस्केल में, टिप्पणियां डिफ़ॉल्ट हैं, इसलिए यह पूरी पोस्ट कार्यक्रम है। यह बॉट इनपुट की अनदेखी करते हुए इसके चारों ओर सर्पिल में मिसाइलों को शूट करेगा। यह एक फ़ाइल में राज्य को संग्रहीत करता है (जो उम्मीद है कि प्रतियोगी द्वारा सकारात्मक नहीं किया जा रहा है।)

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

सबसे पहले हम मिसाइल क्रियाओं को सूचीबद्ध करते हैं।

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

आगे हम सीधे IO मोनाड में जाते हैं। यदि "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
@Geobits मैंने डिस्क पर लिखने के बारे में सवाल के अंत में एक खंड जोड़ा है। मैंने अपना पहला टेस्ट रन भी किया है - परिणाम प्रश्न के अंत के पास हैं। मैं कोशिश करता हूं और अब ये नियमित रूप से करता हूं।
गारेथ

क्या मैं आपसे फाइलों को लिखने के नियमों को देखने के लिए कह सकता हूं? मुझे बस यह चाहिए कि आपकी लिखित फ़ाइल stateकिसी अन्य गैर-राज्य फ़ाइलों के साथ किसी भी आकस्मिक झड़प से बचने के लिए एक उपनिर्देशिका में हो ।
गारेथ

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

मुझे लगता है कि आपका नया संस्करण एक या दो आयात याद कर रहा है। जब मैं संकलन करने की कोशिश कर रहा हूं, तो मैं कर रहा हूं LiterateHaskell.lhs:13:5: Not in scope: 'createDirectoryIfMissing'और LiterateHaskell.lhs:14:5: Not in scope: सेट कर रहा हूं।
गारेथ

1
विडंबना यह है कि मेरा बॉट अंतिम बिंदु पर है लेकिन उसके पास सबसे अधिक वोट हैं। जीत के लिए साक्षर प्रोग्रामिंग!
21

7

DodgingTurret

एक पायथन बॉट

यहाँ एक और प्रयास है। चूंकि ReadyAimShoot थोड़ी देर के लिए मरम्मत की दुकान में है :) मुझे लगा कि मैं इस बीच पायथन का उपयोग करके इस बीच में कुछ और कोशिश करूंगा।

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()से @ गैरेथ से लाइन चुरा ली लेकिन कम से कम इस बार इसका मतलब है कि मुझे इनपुट पार्स करने में कोई समस्या नहीं होगी।

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


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

मिश्रण में जोड़ने के लिए एक और जावास्क्रिप्ट बॉट। यह एक Node.js को लक्षित करता है और 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))

विशेष रूप से चतुर कुछ भी नहीं करता है। एक खदान को गिरा देता है अगर आसपास के किसी भी हिस्से में कोई नहीं होता है तो सुरक्षित आसपास के चौकों में से एक में चला जाता है। केवल हग्बीबोट को मुश्किल से हरा सकते हैं।

कृपया naff Python कोडिंग का बहाना करें।


5

रैंडम बॉट

यह बॉट प्रत्येक चाल पर एक यादृच्छिक कार्रवाई करता है। यह ईएमपी को फायर नहीं करता है और यह मैप को बिल्कुल भी नहीं देखता है। आधे समय यह सिर्फ दीवार में फायरिंग है!

#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सही होना चाहिए ?
अर्शजी

यदि आप मुख्य को शून्य के रूप में परिभाषित करते हैं तो gcc रिटर्न कोड को 0 पर सेट करेगा
intx13

सिली gcc। void mainबीएस है।
tomsmeding

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

केंद्र-बॉट

एक जावास्क्रिप्ट बॉट

इस बॉट का लक्ष्य अखाड़ा के बीच में पहुंचना है, इससे पहले कि यह कितना करीब है, इसके आधार पर हर मोड़ पर गोलियां या मिसाइल दागे। अगर दुश्मन बीच में है, तो यह सिर्फ अस्पष्ट दिशा में गोलियां चलाएगा।

मुझे इसकी बहुत अच्छी उम्मीद नहीं है, लेकिन यह एक परीक्षण से अधिक है, और मुझे यह देखने में दिलचस्पी है कि यह वास्तव में कितना अच्छा है।

    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। यह Node.js के साथ काम करेगा, लेकिन आपको इसे किसी अन्य प्रोग्राम के लिए संशोधित करना पड़ सकता है, क्षमा करें!

मेरे परीक्षणों में:

  • बिना स्क्रैच के रेडीमशूट फेंका।
  • DodgingTurret के खिलाफ सबसे अधिक जीतता है
  • Randombot से भाग्यशाली लैंडमाइंस से कुछ खरोंच के साथ सभी जीता
  • सीधे शूटर को 9 में से 9 बार हराया, लेकिन प्रत्येक मुकाबला करीब था, भले ही मैंने उन सभी को जीता।

शीर्ष जावा बॉट में से किसी का भी परीक्षण नहीं किया गया है, और मुझे विश्वास भी नहीं है ...


मैंने स्पाइडरमैन को टेस्ट मशीन पर स्थापित किया है, इसलिए मैं putstr(...)आपके बजाय इसका उपयोग कर रहा हूं stdo.writeLine(...)और इनपुट से आ रहा है scriptArgs[0]। ऐसा करने के बाद मुझे नक्शे को लाइनों में विभाजित \\nकरने के \nलिए बदलने की आवश्यकता है । जब मैं इसे चलाने मैं कोई त्रुटि मिलती है क्योंकि FindFoe()और findCentre()परिभाषित कर रहे हैं, लेकिन नहीं बुलाया।
गारेथ

ऊप्स! बस एक त्रुटि देखा! मुझे फ़ंक्शंस मिल गए हैं, लेकिन वास्तव में उन्हें चलाएं नहीं! मेरा बुरा, मैं इसे बदल दूंगा। धन्यवाद!
कॉर्विन

मुझे एक और त्रुटि दिखाई दी है - सभी दिशाएँ वापस सामने हैं। आपके पास जहां भी आपके पास Eहोना चाहिए Wऔर आपके पास जहां भी आपके पास Sहोना चाहिए, वहां एक होना चाहिए N। यदि आप प्रश्न से उदाहरण इनपुट का उपयोग करते हैं, तो आप देख सकते हैं कि प्रोग्राम से आउटपुट वह है SEजो नीचे दाएं कोने से संभव दिशा नहीं है। मैंने इसे अगले टेस्ट रन के लिए ठीक कर लिया है।
गारेथ

अच्छा, धन्यवाद @ गैरेथ, मैंने इसे जल्दी में लिखा था इसलिए मैंने वास्तव में बहुत त्रुटि परीक्षण नहीं किया था ... अब इसे ठीक कर दूंगा।
कोर्विन

3

कनिंघप्लनबॉट (पायथन 3.3)

यह वास्तविक इंटरफ़ेस के तहत पूरी तरह से अप्रयुक्त है ... यह कम से कम नक्शे के साथ सही ढंग से काम करता है!

यह पायथन 3.3 के लिए लिखा गया है

यह क्या करता है:

यदि चरण 1 में - यदि दीवार और दिशा दीवार में या एक बारूदी सुरंग में चलती है, तो बेतरतीब ढंग से एक गैर दीवार या बारूदी सुरंग दिशा में बदल जाती है - वर्तमान दिशा में आगे बढ़ें - चरण 2 पर जाएं

यदि चरण 2 में - दुश्मन को निकटतम दिशा में गोली मारो - चरण 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बजाय निर्देशिका के भीतर एक फ़ाइल में लिखने के लिए राज्य को बदल दिया state
गारेथ

Eek! मैं क्षमाप्रार्थी हूं। यह बाद में रात में था तो मुझे इसे भेजना चाहिए था। मैं इसे कल्पना ASAP आज्ञाकारी मिल जाएगा!
21

कोई बात नहीं, मैं किसी भी टेस्ट स्कोरिंग रन के लिए अपने फिक्स का उपयोग करूंगा जब तक कि आप इस पर एक नज़र नहीं डालते।
गारेथ

मैंने एक ही सुधार लागू किया है, लेकिन मुझे 'Py_Initialise:' sys स्टैण्डर्ड स्ट्रीम्स को इनिशियलाइज़ नहीं कर सकता '। किसी भी मौका मैं स्रोत के अपने संस्करण को पकड़ सकता हूं यह देखने के लिए कि क्या यह वही करता है?
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
गैरेथ

अप्स, आयातों के बारे में भूल गए ... इसके अलावा x / y-access को भी ठीक कर दिया, भले ही यह मेरी मशीन पर काम कर रहा हो ...
CommonGuy

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)

देर से प्रवेश के लिए क्षमा करें: मैं पिछले सप्ताह के अधिकांश के लिए एक बैठक में था।
प्लेनैपस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.