Hasilnya sudah masuk, kontes sudah berakhir.
Pemenangnya adalah EvilBot arshajii dengan 14 kemenangan di depan Neo-Bot dengan 13 kemenangan dan CentreBot dan LastStand dengan 11 kemenangan masing-masing.
Skor dari putaran terakhir
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)
Ini adalah tantangan raja-dari-bukit . Tujuannya adalah untuk menulis bot yang akan mengalahkan bot lainnya lebih dari yang lain.
Permainan
Semua bot akan diadu satu sama lain 2 pada satu waktu di arena 10x10 dengan tugas mengurangi energi lawan turun dari 10 ke 0 sebelum energinya sendiri dikurangi menjadi 0.
Setiap pertandingan akan terdiri dari 5 pertarungan. Pemenang pertandingan adalah pemenang pertarungan terbanyak. Jumlah total kemenangan pertandingan dan kemenangan pertarungan akan disimpan oleh program kontrol dan akan digunakan untuk menentukan pemenang kontes secara keseluruhan. Pemenang menerima tanda centang hijau besar dan pujian dari massa.
Setiap pertarungan akan berlangsung dalam sejumlah putaran. Pada awal setiap putaran, kondisi saat ini dari arena akan diberikan kepada masing-masing bot dan bot kemudian akan merespon dengan perintah untuk menentukan apa yang ingin dilakukan selanjutnya. Setelah kedua perintah diterima oleh program kontrol, kedua perintah dieksekusi pada waktu yang sama dan level energi arena dan bot diperbarui untuk mencerminkan status baru. Jika kedua bot masih memiliki energi yang cukup untuk melanjutkan permainan, lanjutkan ke babak berikutnya. Akan ada batas 1000 putaran per pertarungan untuk memastikan tidak ada pertarungan yang berlangsung selamanya, dan jika batas ini tercapai, pemenang akan menjadi bot dengan energi terbanyak. Jika kedua bot memiliki energi yang sama, pertarungan adalah seri dan kedua bot tidak akan mendapatkan poin untuk menang (itu akan seolah-olah mereka berdua kalah).
Senjata
Setiap bot akan memiliki sejumlah senjata:
- Peluru yang menembus armor. Ini berjalan 3 kotak pada satu waktu dan menyebabkan 1 titik energi kerusakan.
- Rudal. Ini berjalan 2 kotak pada satu waktu dan menyebabkan 3 titik energi kerusakan pada titik tumbukan, dan 1 titik kerusakan di semua kotak di sekitarnya.
- Ranjau darat. Ini dijatuhkan di salah satu kotak segera mengelilingi bot dan menyebabkan 2 titik energi kerusakan ketika diinjak, dan 1 titik energi kerusakan apa pun yang berdiri di salah satu kotak langsung di sekitarnya.
- Denyut elektro-magnetik. Menyebabkan kegagalan sirkuit gerak kedua bot selama 2 putaran, artinya mereka tidak bisa bergerak. Namun, mereka masih bisa menggunakan senjata (ya saya tahu itu tidak realistis, tapi itu permainan. Seharusnya bukan kehidupan nyata). Sunting: Setiap penyebaran EMP akan dikenakan biaya satu titik energi ke bot yang menggunakannya.
Peluru / misil hanya dapat berdampak dengan bot, atau dinding. Mereka akan mengenai bot yang ada di kotak mana pun yang mereka lalui. Mereka menghilang begitu mereka menabrak sesuatu.
Dalam semua kasus immediately surrounding squares
berarti 8 kotak yang dapat dipindahkan bot pada langkah selanjutnya - lingkungan Moore.
Perintahnya
0
tidak melakukan apapun.N
,NE
,E
,SE
,S
,SW
,W
,NW
Semua perintah arah dan memindahkan bot satu persegi di arah tertentu. Jika bot tidak dapat bergerak ke arah itu karena ada dinding atau bot lain di alun-alun, bot tetap di tempatnya. Pindah ke kotak yang sudah berisi peluru atau rudal adalah aman karena peluru / rudal akan dianggap sudah dalam perjalanan keluar dari kotak itu.B
diikuti oleh spasi dan kemudian salah satu perintah arah menembakkan peluru menembus zirah ke arah itu.M
diikuti oleh spasi dan kemudian salah satu perintah arah menembakkan rudal ke arah itu.L
diikuti oleh spasi dan kemudian salah satu perintah arah menjatuhkan ranjau darat di alun-alun di sebelah bot. Jika kotak sudah ditempati oleh dinding atau bot, perintah ini diabaikan. Jika ranjau darat dijatuhkan ke ranjau darat lain, ia meledakkannya. Ini akan merusak bot yang melakukan dropping, dan bot lainnya dalam jarak ranjau darat asli.P
menembakkan EMP.
Karena hanya satu perintah yang dapat diberikan per putaran, bot hanya bisa bergerak atau menembakkan / menggunakan senjata, tidak melakukan keduanya pada saat yang sama.
Urutan perintah
. Gerakan bot baik akan selalu didahulukan, dan semua gerakan akan dicoba dua kali untuk memperhitungkan bot lain berada di jalan tetapi bergerak keluar dari jalan.
Contoh
- Bot1 mencoba bergerak
E
tetapi Bot2 sudah ada di kotak itu - Program kontrol pindah ke Bot2.
- Bot2 mencoba bergerak
S
dan berhasil karena tidak ada yang menghalangi. - Bot1 mendapat upaya kedua dalam melakukan gerakannya. Kali ini berhasil dan Bot1 bergerak
E
.
Setelah bot melakukan gerakan apa pun yang mereka inginkan, senjata akan ditembakkan dan semua proyektil (baru dan yang sebelumnya ditembakkan) akan memindahkan jumlah kotak yang telah ditentukan sebelumnya.
Arena
Pada awal setiap putaran bot akan menerima status permainan saat ini sebagai satu-satunya argumen baris perintah program:
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
Arena hadir pertama kali terdiri dari 10 baris 10 karakter. Dikelilingi dengan dinding yang tidak ditampilkan. Arti karakter adalah sebagai berikut:
.
mewakili kotak kosongY
mewakili bot Anda.X
mewakili bot lawan.L
mewakili ranjau darat.B
mewakili peluru dalam penerbangan.M
mewakili sebuah rudal dalam penerbangan.
Ini diikuti oleh sisa energi bot, satu bot per baris. Hanya satu ruang yang akan memisahkan pengidentifikasi bot dari tingkat energinya. Seperti di arena, Y
mewakili bot Anda dan X
mewakili lawan Anda. Akhirnya muncul daftar proyektil dan ranjau darat, posisi mereka dan (jika perlu) pos, sekali lagi satu per baris.
Program kontrol
#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';
}
}
Program kontrol akan memanggil bot Anda dari baris perintah. Karena alasan ini, program yang tidak dapat dipanggil dari baris perintah akan dianggap tidak valid . Saya meminta maaf kepada mereka yang bahasa pilihannya tidak bekerja seperti itu, tetapi melakukan setiap pertandingan secara manual tidak praktis.
intx13 telah menulis versi yang lebih baik dari program kontrol dengan beberapa perbaikan bug yang dapat Anda temukan di sini .
Saran untuk perbaikan atau perbaikan bug untuk program kontrol dipersilahkan.
Bot uji
Tak satu pun dari bot uji akan dimasukkan dalam penilaian berjalan. Mereka hanya untuk tujuan pengujian.
Dudley DoNowt (C)
int main(int argc, char *argv)
{
printf("0");
}
Tidak melakukan apa pun terlepas dari situasinya. Tidak diharapkan menang banyak.
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);
}
?>
Mencoba tepat di samping lawan. Rentan terhadap ranjau darat karena tidak mencari mereka. Membuat peluru kendali menjadi taktik yang kurang efektif untuk lawan saat mencapai tujuannya.
Hasil
Run skor akhir akan dilakukan setelah 23:59 pada 24 Maret 2014 . Saya akan menjalankan tes berjalan secara teratur sehingga pendatang dapat melihat bagaimana bot mereka menumpuk melawan oposisi saat ini.
Entri
Entri harus menyertakan sumber bot Anda, dan argumen baris perintah yang harus saya gunakan untuk menjalankannya. Anda boleh memposting sebanyak mungkin entri berbeda, tetapi setiap jawaban hanya boleh berisi satu bot.
Penting
Tampaknya beberapa entri ingin menulis ke disk untuk mempertahankan beberapa status di antara proses. Ini adalah aturan baru tentang penulisan ke disk.
- Anda dapat memodifikasi sumber bot Anda sendiri. Memodifikasi bot lain yang curang dan akan mengakibatkan bot menyinggung didiskualifikasi.
- Anda dapat menulis ke file yang dibuat untuk tujuan penyimpanan. File ini harus disimpan di subdirektori dari direktori tempat bot Anda berada. Subdirektori akan diberi nama
state
. Menulis ke bagian lain dari sistem file (selain dari sumber Anda sendiri) tidak diizinkan.
sumber
Jawaban:
EvilBot
bot yang mencoba untuk menjadi seburuk mungkin
Nah inilah yang saya punya: bot Java yang mencoba untuk sedekat mungkin dengan
lawanjalur melingkar jari-jari 2,5 di sekitar pusat arena mungkin dan kemudian melakukan kerusakan sebanyak mungkin ketika itu bisa. Pola pergerakannya didasarkan pada penetapan nilai "bahaya" untuk masing-masing kuadrat tetangganya, dan memutuskan untuk bergerak berdasarkan pada nilai-nilai ini dan berdasarkan kecenderungan untuk sedekat mungkin dengan wilayah melingkar dengan radius 2.5 di sekitar tengah arena. Saya menggunakan beberapa mur dan baut dari jawaban @ Geobits (misalnya memiliki abstrakBattleBot
kelas dan teknik parsing), terima kasih! Saya mungkin akan memodifikasi / memperluas apa yang saya miliki sejauh ini, meskipun harganya cukup baik seperti halnya dengan bot lain yang diposting sejauh ini. Kode di bawah ini. (jika ada orang lain yang menggunakan Java, silakan gunakan kelas abstrak / pembantu saya.)(
EvilBot.java
)Pemakaian:
Catatan:
Saat ini, ranjau darat tidak digunakan, hanya dihindari. Saya mungkin tidak akan mengubah ini, karena menggunakan ranjau darat tampaknya lebih berbahaya daripada kebaikan (setidaknya untuk EvilBot) dinilai dari beberapa tes yang saya jalankan.
Saat ini, EMP tidak digunakan. Saya mencoba strategi menyelaraskan dengan lawan dan menembakkan EMP diikuti oleh rudal, tetapi ada beberapa strategi kontra untuk ini yang akan memenangkan hampir 100% dari waktu, jadi saya memutuskan untuk meninggalkan rute itu. Saya mungkin akan mengeksplorasi menggunakan EMP dengan berbagai cara nanti.
sumber
Pemberontak
Bot ini mengambil tindakan yang berbeda berdasarkan bot apa yang diperangi. Untuk menentukan lawan, ia membalik keadaannya sendiri dan memasukkannya ke bot lain untuk melihat apa yang akan mereka lakukan, dan membandingkannya dengan apa yang sebenarnya mereka lakukan. Begitu mereka mencapai ambang gerakan 'benar', itu berhenti menguji yang lain.
Setelah mengetahui bot apa yang bertarung, umumnya tahu di mana ia akan berada di belokan berikutnya, sehingga ia bisa menembak di sana daripada posisi mereka saat ini.
Tentu saja ada beberapa kekurangannya. Salah satunya adalah bahwa bot yang memiliki aktivitas "acak" tidak terdeteksi dengan baik. Ini diseimbangkan dengan menggunakan logika King's Last Stand ketika lawan tidak dikenal.
Namun, jika bot adalah murni deterministik, ini tidak memiliki masalah untuk mencari tahu siapa itu. Ini kemudian dapat dengan mudah disesuaikan dengan situasi dengan menambahkan lebih banyak kasus ke dalam logikanya untuk setiap lawan. Misalnya, melawan Last Stand, itu akan menyudutkannya, berdiri 2x1 sehingga dia tidak bisa bergerak atau menembak secara langsung, dan menembakkan rudal ke dinding di belakang, membunuhnya dengan kerusakan akibat percikan.
Seperti yang lainnya, ia memperluas BattleBot.java:
sumber
ReadyAimShoot
a R Bot
Bot ini mencoba untuk menempatkan dirinya di baris atau kolom yang sama dengan target, ketika disejajarkan dengan target yang ditembakkan EMP, kemudian pada belokan berikut ia menembakkan rudal ke arah target, dan kemudian sebuah peluru. Itu juga harus menyadari tambang di sekitarnya dan menghindari mereka tetapi sama sekali tidak menyadari peluru dan rudal. Jika hidup sudah di 1 itu dilewati EMP.
Untuk melacak kapan ia memicu EMP, ia memodifikasi kode sumbernya dengan menambahkan komentar di akhir file (
#p_fired2
pada awalnya, kemudian mengubahnya ke#p_fired1
dan kemudian menghapusnya). Saya berharap bahwa melacak ketika memicu EMP dengan cara ini tidak terlalu terbatas.Baris perintah harus
Rscript ReadyAimShoot.R
, diikuti oleh argumen seperti dalam contoh, setidaknya pada sistem UNIX tetapi mungkin juga pada windows (saya akan memeriksa bahwa ketika saya benar-benar akan mengujinya terhadap bot lain).Sunting : Karena versi R tampaknya memiliki masalah dalam mengurai input, berikut adalah versi python dari bot yang sama dengan, saya harap, berfungsi. Jika ada programmer R lain yang melihat posting dan melihat apa yang salah dengan bot ini, jangan ragu untuk debug!
sumber
King's Last Stand
Perluasan untuk saya
BattleBot
, ini dirancang untuk memerangi EMP-blasters. Satu-satunya cara yang masuk akal (IMO) untuk menggunakan EMP adalah dengan menembakkannya saat Anda berada pada poros yang sama dengan lawan, lalu menembakkan rudal / senjata ke arah lawan yang terjebak. Jadi, saya menjauh :)Jika Anda pernah memiliki permainan catur jatuh ke raja melawan raja + ratu, Anda tahu bahwa seorang ratu saja tidak dapat skakmat , Anda harus melibatkan raja. Jika tidak, strategi raja tunggal itu mudah: cobalah untuk tetap berada di luar poros dan menuju pusat untuk memaksimalkan mobilitas. Jika Anda buntu, lakukan jalan buntu.
Tentu saja, tidak ada cara yang bagus untuk memaksakan kebuntuan di sini, jadi pada akhirnya Anda akan terjebak di sisi atau sudut jika sang ratu bermain di semua level kompetensi. Jika bot ini pernah dalam situasi itu, ia akan menembak. Dengan asumsi lawan akan menuju EMP, ini memberikan keuntungan kerusakan satu putaran, sehingga tegakan terakhir raja harus baik-baik saja kecuali dia sudah lemah dalam kehidupan.
Oh, dan jika itu sudah off-axis dan aman dari proyektil, itu hanya akan mengambil gambar di arah umum musuh.
LastStand.java
Untuk mengkompilasi run, letakkan dalam folder dengan
BattleBot.java
dan jalankan:sumber
EvadeBot
Bot ini memprioritaskan tetap hidup. Jika mendeteksi tabrakan masuk, mencoba untuk pindah ke tempat yang aman dengan memeriksa bahwa tempat untuk tabrakan. Jika tidak ada titik-titik "aman" di sekitarnya, ia tetap berada di tempatnya dan pergi ke langkah berikutnya.
Jika tidak ada tabrakan (atau tempat aman jika terjadi tabrakan), itu melakukan pemeriksaan serangan. Jika lawan diluruskan 8-sumbu, ia menembakkan 80% dari waktu. Jika tidak disejajarkan, itu akan menyala 50% dari waktu di pos terdekat. Ia memilih senjata berdasarkan jarak. Jika dekat, ranjau darat atau peluru (tergantung pada jarak yang tepat dan kesehatan relatif), rudal dari jauh.
Jika diputuskan untuk tidak menembak, dibutuhkan jalan acak (lagi-lagi memeriksa tempat aman).
Jika tidak ada di atas yang berhasil, itu hanya duduk di sana sampai belokan berikutnya.
Itu tidak menggunakan EMP, dan saya punya firasat buruk tentang mengkuadratkan
ReadyAimShoot
, tapi kita akan lihat bagaimana kelanjutannya.Kode ini terdiri dari dua bagian. Karena saya dapat membuat lebih dari satu bot, saya membuat
BattleBot
kelas abstrak . Ini termasuk fungsi pembantu seperti membaca arena, memeriksa tabrakan, manajemen pos, dll. Ada juga fungsi log untuk membantu melacak apa yang terjadi saat debugging. Jikadebug==false
, itu hanya akan mencetak hasil aktual. Jika ada yang ingin menggunakan / memperluasnya, silakan saja. Ini bukan kode yang cantik , tapi ini mengalahkan penulisan boilerplate.BattleBot.java
Ini khususnya bot adalah
EvadeBot
. Untuk mengkompilasi / menjalankan, letakkan di folder denganBattleBot.java
dan jalankan:Jika Anda menghilangkan argumen atau tidak dapat menguraikannya dengan benar, default untuk
"0"
output.EvadeBot.java
sumber
BattleBots.java
. Bisakah Anda mengkompilasi ulang bot saya sebelum menjalankan berikutnya?Spiral Bot Literate Haskell
Dalam haskell melek, komentar adalah default, jadi seluruh posting ini adalah programnya. Bot ini akan menembakkan rudal dalam spiral di sekitarnya, mengabaikan input. Ini menyimpan status dalam file (yang diharapkan tidak dimiliki oleh competer.)
Pertama-tama kita buat daftar tindakan rudal.
Selanjutnya kita langsung menuju monad IO. Jika "spiral.txt" tidak ada, kami menulis "0" untuk itu. Kami juga memeriksa direktori.
Lalu kami membacanya dan mencetak aksinya.
Dan akhirnya kami menulis ke file posisi sekarang.
sumber
state
untuk menghindari bentrokan tidak disengaja dengan file non-negara lainnya.LiterateHaskell.lhs:13:5: Not in scope: 'createDirectoryIfMissing'
danLiterateHaskell.lhs:14:5: Not in scope:
setCurrentDirectory'` ketika saya mencoba untuk mengkompilasi.DodgingTurret
Bot Python
Ini upaya lain. Karena ReadyAimShoot berada di bengkel untuk sementara waktu :) Saya pikir saya akan mencoba sesuatu yang lain sementara itu, menggunakan Python kali ini.
Saya tanpa malu-malu mencuri baris
sys.argv[1].splitlines()
dari @Gareth tapi setidaknya kali ini itu berarti saya tidak akan punya masalah mengurai input.Bot ini berjalan di tengah pada awal pertarungan, lalu tetap di sana dan menembakkan rudal ke arah lawan. Dia juga mencoba menghindari peluru dan rudal di dekatnya jika ada di jalur mereka tetapi kemudian kembali ke pusat sebelum mulai menembak lagi.
sumber
Penembak lurus
Ini adalah bot sederhana lain yang dapat Anda gunakan untuk pengujian. Jika memiliki garis pandang langsung ke lawan yang ditembakkan, jika tidak ia akan melangkah secara acak.
sumber
neo-bot
naskah kopi
Bot JavaScript lain untuk ditambahkan ke dalam campuran. Yang ini menargetkan Node.js dan ditulis dalam CoffeeScript. Arsitektur mengikuti dari kerumunan Java dengan kelas dasar menangani kemalasan umum dan file lain dengan spesialisasi untuk bot di tangan.
Strategi utama bot ini adalah untuk tidak terkena proyektil Anda. Jika Anda bukan ancaman langsung, neo-bot hanya akan mulai menembak.
File dasar
shared.coffee
Dan
neo-bot.coffee
, kode botnya.Saya sangat merekomendasikan kompilasi file kopi ke javascript sebelum menjalankan; ini sedikit lebih cepat. Pada dasarnya Anda ingin melakukan ini:
sumber
CamperBot
Bot ini hanya tinggal di mana dia berada dan menembak. Saya hanya menerapkan peluru, karena senjata lain akan merusak bot. Tolong maafkan C-skill mengerikan saya;)
Tidak terlalu berharap untuk menang banyak.
sumber
Karena tidak ada entri, saya akan meletakkannya di sana sehingga Anda memiliki sesuatu untuk dihancurkan. Saya berikan kepada Anda:
Milikku! Milikku! Milikku!
Tidak melakukan sesuatu yang sangat pintar. Menjatuhkan ranjau jika tidak ada di salah satu kotak di sekitarnya jika tidak pindah ke salah satu kotak sekitarnya yang aman. Hanya bisa mengalahkan HuggyBot.
Maafkan naff Python coding.
sumber
Bot acak
Bot ini hanya membuat tindakan acak pada setiap gerakan. Itu tidak memecat EMP dan tidak melihat peta sama sekali. Setengah waktu itu hanya menembaki tembok!
Uji (terhadap dirinya sendiri) seperti di bawah ini.
sumber
int main
benar?void main
adalah BS.Masalah dan Pemberhentian
Beberapa representasi Ruby dalam pertarungan. Bergerak naik dan turun dari rudal penembakan dinding yang ditugaskan secara acak di dinding yang berlawanan. Sedikit glitchy di bagian atas dan bawah.
sumber
Inti JavaScript
Saya pikir saya akan baik dan memberi Anda bot JS inti saya. Ia memiliki semua fungsi yang diperlukan untuk membuat bot, yang Anda butuhkan hanyalah beberapa tindakan yang harus dilakukan berdasarkan data yang diberikan kepada Anda. Belum selesai, karena saya tidak bisa mengujinya (tidak bisa mengkompilasi kode arena).
Jangan ragu untuk menggunakan ini, saya menantikan untuk melihat beberapa bot JS dalam campuran.
Melakukan:
Tambahkan fungsi untuk menghitung lokasi senjata
Harap dicatat bahwa beberapa hal di sini mungkin harus dimodifikasi untuk OS lain (ini hanya berfungsi pada Windows). Versi badak di sini: http://pastebin.com/FHvmHCB8
sumber
Center-Bot
Bot JavaScript
Bot ini bertujuan untuk masuk ke tengah arena, sebelum menembakkan peluru atau rudal ke targetnya setiap belokan bergantung pada seberapa dekat itu. Jika musuh ada di tengah, itu hanya akan terus menembakkan peluru ke arah yang tidak jelas.
Saya tidak berharap itu bekerja dengan sangat baik, tetapi ini lebih merupakan pengujian, dan saya tertarik untuk melihat seberapa bagus itu.
simpan sebagai file .js dan jalankan dengan
node centrebot.js
. Ini akan bekerja dengan Node.js, tetapi Anda mungkin harus memodifikasinya untuk program lain, maaf!Dalam tes saya:
Belum menguji salah satu bot java teratas, dan saya juga tidak terlalu percaya diri ...
sumber
putstr(...)
untuk menggantikan Andastdo.writeLine(...)
dan inputnya berasalscriptArgs[0]
. Setelah melakukan bahwa saya perlu untuk mengubah\\n
ke\n
untuk membagi peta menjadi garis. Ketika saya menjalankannya saya mendapatkan kesalahan karenaFindFoe()
danfindCentre()
didefinisikan tetapi tidak dipanggil.E
Anda harus memilikiW
dan di mana pun Anda memilikiS
Anda harus memilikiN
. Jika Anda menggunakan contoh input dari pertanyaan, Anda dapat melihat bahwa output dari program adalah arahSE
yang tidak mungkin dari sudut kanan bawah. Saya telah memperbaikinya untuk uji coba berikutnya.CunningPlanBot (Python 3.3)
Ini benar-benar belum teruji di bawah antarmuka yang sebenarnya ... Ini berfungsi dengan benar dengan peta setidaknya!
Ini ditulis untuk Python 3.3
Apa fungsinya:
Jika dalam Fase 1 - Jika di dinding dan arah bergerak ke dinding atau pindah ke ranjau darat, ubah arah secara acak ke arah non dinding atau ranjau darat - Pindahkan ke arah saat ini - Pergi ke Fase 2
Jika dalam Fase 2 - Tembak peluru ke arah yang paling dekat dengan musuh - Pergi ke Fase 3
Jika pada Tahap 3 - Jika tidak ada ranjau darat, jatuhkan ranjau darat - Lanjutkan ke fase 1
Masih perlu mencari tahu apakah akan menembakkan rudal. Juga saya tidak punya petunjuk sama sekali tentang apakah ranjau darat menghindari barang-barang bekerja. Perlu lebih banyak pengujian besok malam.
sumber
sys.argv[1].splitlines()
mengambil input dari command-line, dan kemudian digunakanline[x][y]
di blok berikut; ditambahkanend=""
ke perintah cetak untuk menghilangkan baris baru yang membingungkan pencetak gol; mengubah status untuk menulis ke file di dalamstate
direktori daripadastate
dirinya sendiri.UltraBot
Bot Java yang menghitung bahaya untuk setiap bidang di sekitarnya. Jika bidang di sekitarnya kurang berbahaya daripada yang saat ini, bot bergerak ke sana (atau bidang lain yang sama berbahaya). Jika tidak ada bidang yang kurang berbahaya, bot menembak (misil jika bot musuh jauh, peluru jika bot musuh dekat). Saya mengambil beberapa kode dari BattleBot (terima kasih!).
Bot ini sangat sulit untuk dipukul, tetapi tidak pandai menembak musuh ... Saya masih berharap ini lebih baik daripada CamperBot saya sebelumnya.
sumber
import
?UltraBot.java:...: x has private access in Point
NinjaPy
Pengajuan menit terakhir dalam python (belum diuji tetapi mudah-mudahan akan berhasil). Idenya adalah bahwa ia maju ke arah lawan sambil tetap berada di titik buta. Ketika cukup dekat (3 sel jauhnya) ia menempatkan dirinya di diagonal lawan dan menembakkan rudal.
sumber