Результаты подведены, конкурс окончен.
Победителем стал EvilBot от arshajii с 14 победами перед Neo-Bot с 13 победами, а также CentreBot и LastStand с 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)
Это вызов царя горы . Цель состоит в том, чтобы написать бота, который побьет больше других ботов, чем любой другой.
Игра
Все боты будут сражаться друг с другом по 2 на арене 10х10 с целью снижения энергии противника с 10 до 0, прежде чем его собственная энергия уменьшится до 0.
Каждый матч будет состоять из 5 боев. Победитель матча - победитель большинства поединков. Общее количество побед в матче и побед будет сохранено управляющей программой и будет использовано для определения общего победителя конкурса. Победитель получает большую зеленую галочку и восхищение масс.
Каждый бой будет проходить в несколько раундов. В начале каждого раунда каждому боту будет присвоено текущее состояние арены, и бот ответит командой, чтобы определить, что он хочет делать дальше. Как только обе команды получены управляющей программой, обе команды выполняются одновременно, и уровни энергии арены и бота обновляются, чтобы отразить новое состояние. Если у обоих ботов достаточно энергии для продолжения, игра переходит в следующий раунд. Будет ограничение в 1000 раундов на бой, чтобы гарантировать, что бой не будет продолжаться вечно, и в случае достижения этого лимита победителем станет бот с наибольшей энергией. Если оба бота имеют одинаковую энергию, бой - ничья, и ни один бот не получит очко за победу (это было бы так, как если бы они оба проиграли).
Оружие
Каждый бот будет иметь в своем распоряжении несколько видов оружия:
- Бронебойные пули. Они путешествуют 3 квадрата за раз и наносят 1 единицу энергии урона.
- Ракеты. Они перемещаются на 2 квадрата за раз и наносят 3 энергетических пункта урона в точке удара и 1 пункт урона во всех непосредственно окружающих квадратах.
- Наземные мины. Они выпадают в одном из квадратов, непосредственно окружающих бота, и наносят 2 энергетических очка урона при наступлении, и 1 энергетический урон всему, что стоит в одном из непосредственно окружающих квадратов.
- Электромагнитный импульс. Вызывает сбой в работе контуров движения обоих ботов на 2 оборота, что означает, что они не могут двигаться. Они могут, однако, по-прежнему использовать оружие (да, я знаю, что это нереально, но это игра. Это не должно быть в реальной жизни). Изменить: Каждое развертывание EMP будет стоить одно энергетическое очко для бота, который его использует.
Пули / ракеты могут поражать только ботов или стены. Они поразят любого бота, который находится на любом из квадратов, через которые они проходят. Они исчезают, когда они что-то ударили.
Во всех случаях immediately surrounding squares
означает 8 квадратов, к которым бот может переместиться на следующем шаге - окрестности Мура.
Команды
0
ничего не делать.N
,NE
,E
,SE
,S
,SW
,W
,NW
Все команды , направление и переместить бот один квадрат в заданном направлении. Если бот не может двигаться в этом направлении, потому что в квадрате есть стена или другой бот, бот остается там, где он есть. Перемещение в квадрат, который уже содержит пулю или ракету, является безопасным, поскольку пуля / ракета будет считаться уже выходящей из этой площади.B
затем пробел, а затем одна из команд направления запускает бронебойную пулю в этом направлении.M
затем пробел, а затем одна из команд направления запускает ракету в этом направлении.L
затем пробел, а затем одна из команд направления сбрасывает мины на этом квадрате рядом с ботом. Если квадрат уже занят стеной или ботом, команда игнорируется. Если мина сбрасывается на другую, она взрывается. Это повредит боту, выполняющему сброс, и любому другому боту в пределах досягаемости от оригинальной мины.P
запускает ПУОС.
Поскольку за раунд может быть дана только одна команда, бот может только перемещать или стрелять / использовать оружие, но не делать оба одновременно.
Порядок команд
Движение любого бота всегда будет на первом месте, и все движения будут предприниматься дважды, чтобы учесть, что другой бот находится в пути, но движется в стороне.
пример
- Bot1 пытается двигаться,
E
но Bot2 уже в этой клетке - Управляющая программа переходит к Bot2.
- Bot2 пытается двигаться
S
и добивается успеха, потому что ничто не мешает . - Bot1 получает вторую попытку сделать свой ход. На этот раз это удается, и Bot1 движется
E
.
Как только боты совершат любые движения, которые они хотят сделать, оружие будет запущено, и все снаряды (новые и ранее выпущенные) будут перемещать свое заранее определенное количество квадратов.
Арена
В начале каждого раунда бот будет получать текущее состояние игры в качестве единственного аргумента командной строки программы:
X.....LLL.
..........
..........
..........
M.........
..........
..........
..........
..........
...B.....Y
Y 10
X 7
B 3 9 W
M 0 4 S
L 6 0
B 3 9 S
L 7 0
L 8 0
Сначала идет арена, состоящая из 10 строк по 10 символов. Он окружен стенами, которые не показаны. Значения символов следующие:
.
представляет собой пустой квадратY
представляет ваш бот.X
представляет бот противника.L
представляет мины.B
представляет пулю в полете.M
представляет ракету в полете.
Затем следует оставшаяся энергия ботов, по одному боту на линию. Только один пробел отделит идентификатор бота от его уровня энергии. Как и на арене, Y
представляет вашего бота и X
представляет вашего противника. Наконец, список снарядов и наземных мин, их позиции и (при необходимости) заголовки, снова по одному на строку.
Контрольная программа
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define NUMBOTS 2
#define BOUTSPERMATCH 5
#define ROUNDSPERBOUT 1000
#define MAXFILENAMESIZE 100
#define MAXWEAPONS 100
#define DISPLAYBOUTS true
typedef struct
{
int x, y, energy;
char cmd[5];
} Bot;
int getxmove(char cmd[5]);
int getymove(char cmd[5]);
int newposinbounds(int oldx, int oldy, int dx, int dy);
int directhit(Bot bot, int landmine[2]);
int landminecollision(int landmine1[2], int landmine2[2]);
int inshrapnelrange(Bot bot, int landmine[2]);
int directiontoint(char direction[5], char directions[8][3]);
void deployweapons(Bot *bot, Bot *enemy, int bullets[MAXWEAPONS][3], int missiles[MAXWEAPONS][3], int landmines[MAXWEAPONS][2], char directions[8][3]);
void cleararena(char arena[10][11]);
int main()
{
FILE *fp;
Bot b1, b2;
int bot1, bot2, bot1bouts, bot2bouts;
int bout, round, loop, totalprojectiles, dx, dy;
char bots[NUMBOTS][MAXFILENAMESIZE]=
{
"./donowt ",
"php -f huggybot.php "
};
char directions[8][3]={"N", "NE", "E", "SE", "S", "SW", "W", "NW"};
char openstring[5000], argumentstring[4000], bot1string[6], bot2string[6];
int matcheswon[NUMBOTS],boutswon[NUMBOTS];
int missiles[MAXWEAPONS][3];
int bullets[MAXWEAPONS][3];
int landmines[MAXWEAPONS][2];
int paralyzedturnsremaining=0;
bool bot1moved;
char arena[10][11];
char projectiles[300][10];
for(loop=0;loop<NUMBOTS;loop++)
{
matcheswon[loop]=0;
boutswon[loop]=0;
}
srand(time(NULL));
for(bot1=0;bot1<NUMBOTS-1;bot1++)
{
for(bot2=bot1+1;bot2<NUMBOTS;bot2++)
{
bot1bouts=bot2bouts=0;
printf("%s vs %s ",bots[bot1],bots[bot2]);
for(bout=0;bout<BOUTSPERMATCH;bout++)
{
printf("%d ",bout);
//setup the arena for the bout
b1.x=1;b1.y=1;
b2.x=9;
//b1.y=rand()%10;
b2.y=rand()%10;
b1.energy=b2.energy=10;
//clear the previous stuff
memset(missiles, -1, sizeof(missiles));
memset(bullets, -1, sizeof(bullets));
memset(landmines, -1, sizeof(landmines));
for(round=0;round<ROUNDSPERBOUT;round++)
{
//draw the arena based on current state
cleararena(arena);
totalprojectiles=0;
for(loop=0;loop<MAXWEAPONS;loop++)
{
if(bullets[loop][0]!= -1)
{
arena[bullets[loop][1]][bullets[loop][0]]='B';
sprintf(projectiles[totalprojectiles], "%c %d %d %s\n", 'B', bullets[loop][0], bullets[loop][1], directions[bullets[loop][2]]);
totalprojectiles+=1;
}
if(missiles[loop][0]!= -1)
{
arena[missiles[loop][1]][missiles[loop][0]]='M';
sprintf(projectiles[totalprojectiles], "%c %d %d %s\n", 'M', missiles[loop][0], missiles[loop][1], directions[missiles[loop][2]]);
totalprojectiles+=1;
}
if(landmines[loop][0]!= -1)
{
arena[landmines[loop][1]][landmines[loop][0]]='L';
sprintf(projectiles[totalprojectiles], "%c %d %d\n", 'L', landmines[loop][0], landmines[loop][1]);
totalprojectiles+=1;
}
}
//send the arena to both bots to get the commands
// create bot1's input
arena[b1.y][b1.x]='Y';
arena[b2.y][b2.x]='X';
sprintf(bot1string, "Y %d\n", b1.energy);
sprintf(bot2string, "X %d\n", b2.energy);
strcpy(argumentstring, "'");
strncat(argumentstring, *arena, 10*11);
strcat(argumentstring, bot1string);
strcat(argumentstring, bot2string);
for(loop=0;loop<totalprojectiles;loop++)
{
strcat(argumentstring, projectiles[loop]);
}
strcat(argumentstring, "'");
sprintf(openstring, "%s %s", bots[bot1], argumentstring);
// send it and get the command back
fp=popen(openstring, "r");
fgets(b1.cmd, 5, fp);
fflush(NULL);
pclose(fp);
// create bot2's input
arena[b2.y][b2.x]='Y';
arena[b1.y][b1.x]='X';
sprintf(bot2string, "Y %d\n", b2.energy);
sprintf(bot1string, "X %d\n", b1.energy);
strcpy(argumentstring, "'");
strncat(argumentstring, *arena, 10*11);
strcat(argumentstring, bot2string);
strcat(argumentstring, bot1string);
for(loop=0;loop<totalprojectiles;loop++)
{
strcat(argumentstring, projectiles[loop]);
}
strcat(argumentstring, "'");
sprintf(openstring, "%s %s", bots[bot2], argumentstring);
// send it and get the command back
fp=popen(openstring, "r");
fgets(b2.cmd, 5, fp);
fflush(NULL);
pclose(fp);
if(DISPLAYBOUTS)
{
arena[b1.y][b1.x]='A';
arena[b2.y][b2.x]='B';
printf("\033c");
printf("Round: %d\n", round);
printf("%s", arena);
sprintf(bot1string, "A %d\n", b1.energy);
sprintf(bot2string, "B %d\n", b2.energy);
printf("%s%s", bot1string, bot2string);
}
//do bot movement phase
if(paralyzedturnsremaining==0)
{
// move bot 1 first
bot1moved=false;
dx=dy=0;
dx=getxmove(b1.cmd);
dy=getymove(b1.cmd);
if(newposinbounds(b1.x, b1.y, dx, dy))
{
if(!(b1.x+dx==b2.x) || !(b1.y+dy==b2.y))
{
bot1moved=true;
b1.x=b1.x+dx;
b1.y=b1.y+dy;
}
}
// move bot 2 next
dx=dy=0;
dx=getxmove(b2.cmd);
dy=getymove(b2.cmd);
if(newposinbounds(b2.x, b2.y, dx, dy))
{
if(!(b2.x+dx==b1.x) || !(b2.y+dy==b1.y))
{
b2.x=b2.x+dx;
b2.y=b2.y+dy;
}
}
if(!bot1moved) // if bot2 was in the way first time, try again
{
dx=dy=0;
dx=getxmove(b1.cmd);
dy=getymove(b1.cmd);
if(newposinbounds(b1.x, b1.y, dx, dy))
{
if(!(b1.x+dx==b2.x) || !(b1.y+dy==b2.y))
{
b1.x=b1.x+dx;
b1.y=b1.y+dy;
}
}
}
//check for landmine hits
for(loop=0;loop<MAXWEAPONS;loop++)
{
if(landmines[loop][0]!= -1)
{
if(directhit(b1, landmines[loop]))
{
b1.energy-=2;
if(inshrapnelrange(b2, landmines[loop]))
{
b2.energy-=1;
}
landmines[loop][0]= -1;
landmines[loop][1]= -1;
}
if(directhit(b2, landmines[loop]))
{
b2.energy-=2;
if(inshrapnelrange(b1, landmines[loop]))
{
b1.energy-=1;
}
landmines[loop][0]= -1;
landmines[loop][1]= -1;
}
}
}
}
else
{
paralyzedturnsremaining-=1;
}
//do weapons firing phase
if(strcmp(b1.cmd, "P")==0)
{
paralyzedturnsremaining=2;
b1.energy--;
}
else if(strcmp(b2.cmd, "P")==0)
{
paralyzedturnsremaining=2;
b2.energy--;
}
deployweapons(&b1, &b2, bullets, missiles, landmines, directions);
deployweapons(&b2, &b1, bullets, missiles, landmines, directions);
//do weapons movement phase
int moves;
for(loop=0;loop<MAXWEAPONS;loop++)
{
dx=dy=0;
if(bullets[loop][0]!= -1)
{
dx=getxmove(directions[bullets[loop][2]]);
dy=getymove(directions[bullets[loop][2]]);
for(moves=0;moves<3;moves++)
{
if(newposinbounds(bullets[loop][0], bullets[loop][1], dx, dy))
{
bullets[loop][0]+=dx;
bullets[loop][1]+=dy;
if(directhit(b1, bullets[loop]))
{
b1.energy-=1;
bullets[loop][0]= -1;
bullets[loop][1]= -1;
bullets[loop][2]= -1;
}
if(directhit(b2, bullets[loop]))
{
b2.energy-=1;
bullets[loop][0]= -1;
bullets[loop][1]= -1;
bullets[loop][2]= -1;
}
}
else
{
bullets[loop][0]= -1;
bullets[loop][1]= -1;
bullets[loop][2]= -1;
dx=dy=0;
}
}
}
};
for(loop=0;loop<MAXWEAPONS;loop++)
{
dx=dy=0;
if(missiles[loop][0]!= -1)
{
dx=getxmove(directions[missiles[loop][2]]);
dy=getymove(directions[missiles[loop][2]]);
for(moves=0;moves<2;moves++)
{
if(newposinbounds(missiles[loop][0], missiles[loop][1], dx, dy))
{
missiles[loop][0]+=dx;
missiles[loop][1]+=dy;
if(directhit(b1, missiles[loop]))
{
b1.energy-=3;
if(inshrapnelrange(b2, missiles[loop]))
{
b2.energy-=1;
}
missiles[loop][0]= -1;
missiles[loop][1]= -1;
missiles[loop][2]= -1;
}
if(directhit(b2, missiles[loop]))
{
b2.energy-=3;
if(inshrapnelrange(b1, missiles[loop]))
{
b1.energy-=1;
}
missiles[loop][0]= -1;
missiles[loop][1]= -1;
missiles[loop][2]= -1;
}
}
else
{
if(inshrapnelrange(b1, missiles[loop]))
{
b1.energy-=1;
}
if(inshrapnelrange(b2, missiles[loop]))
{
b2.energy-=1;
}
missiles[loop][0]= -1;
missiles[loop][1]= -1;
missiles[loop][2]= -1;
dx=dy=0;
}
}
}
}
//check if there's a winner
if(b1.energy<1 || b2.energy<1)
{
round=ROUNDSPERBOUT;
}
}
// who has won the bout
if(b1.energy<b2.energy)
{
bot2bouts+=1;
boutswon[bot2]+=1;
}
else if(b2.energy<b1.energy)
{
bot1bouts+=1;
boutswon[bot1]+=1;
}
}
if(bot1bouts>bot2bouts)
{
matcheswon[bot1]+=1;
}
else if(bot2bouts>bot1bouts)
{
matcheswon[bot2]+=1;
}
printf("\n");
}
}
// output final scores
printf("\nResults:\n");
printf("Bot\t\t\tMatches\tBouts\n");
for(loop=0;loop<NUMBOTS;loop++)
{
printf("%s\t%d\t%d\n", bots[loop], matcheswon[loop], boutswon[loop]);
}
}
int getxmove(char cmd[5])
{
int dx=0;
if(strcmp(cmd, "NE")==0)
dx= 1;
else if(strcmp(cmd, "E")==0)
dx= 1;
else if(strcmp(cmd, "SE")==0)
dx= 1;
else if(strcmp(cmd, "SW")==0)
dx= -1;
else if(strcmp(cmd, "W")==0)
dx= -1;
else if(strcmp(cmd, "NW")==0)
dx= -1;
return dx;
}
int getymove(char cmd[5])
{
int dy=0;
if(strcmp(cmd, "N")==0)
dy= -1;
else if(strcmp(cmd, "NE")==0)
dy= -1;
else if(strcmp(cmd, "SE")==0)
dy= 1;
else if(strcmp(cmd, "S")==0)
dy= 1;
else if(strcmp(cmd, "SW")==0)
dy= 1;
else if(strcmp(cmd, "NW")==0)
dy= -1;
return dy;
}
int newposinbounds(int oldx, int oldy, int dx, int dy)
{
return (oldx+dx>=0 && oldx+dx<10 && oldy+dy>=0 && oldy+dy<10);
}
int directhit(Bot bot, int landmine[2])
{
return (bot.x==landmine[0] && bot.y==landmine[1]);
}
int landminecollision(int landmine1[2], int landmine2[2])
{
return ((landmine1[1]==landmine2[1]) && abs(landmine1[0]==landmine2[0]));
}
int inshrapnelrange(Bot bot, int landmine[2])
{
return (abs(bot.x-landmine[0])<2 && abs(bot.y-landmine[1])<2);
}
int directiontoint(char direction[5], char directions[8][3])
{
int loop,returnval=8;
for(loop=0;loop<8;loop++)
{
if(strcmp(directions[loop], direction)==0)
returnval=loop;
}
return returnval;
}
void deployweapons(Bot *bot, Bot *enemy, int bullets[MAXWEAPONS][3], int missiles[MAXWEAPONS][3], int landmines[MAXWEAPONS][2], char directions[8][3])
{
int loop;
if(strlen(bot->cmd)>2)
{
if(bot->cmd[0]=='B')
{
int weaponslot=0;
while(bullets[weaponslot][0]!= -1)
weaponslot+=1;
bullets[weaponslot][0]=bot->x;
bullets[weaponslot][1]=bot->y;
bullets[weaponslot][2]=directiontoint(bot->cmd+2, directions);
if(bullets[weaponslot][2]>7)
{
// direction wasn't recognized so clear the weapon
bullets[weaponslot][0]= -1;
bullets[weaponslot][1]= -1;
bullets[weaponslot][2]= -1;
}
}
if(bot->cmd[0]=='M')
{
int weaponslot=0;
while(missiles[weaponslot][0]!= -1)
weaponslot+=1;
missiles[weaponslot][0]=bot->x;
missiles[weaponslot][1]=bot->y;
missiles[weaponslot][2]=directiontoint(bot->cmd+2, directions);
if(missiles[weaponslot][2]>7)
{
// direction wasn't recognized so clear the weapon
missiles[weaponslot][0]= -1;
missiles[weaponslot][1]= -1;
missiles[weaponslot][2]= -1;
}
}
if(bot->cmd[0]=='L')
{
int weaponslot=0;
while(landmines[weaponslot][0]!= -1)
weaponslot+=1;
if(newposinbounds(bot->x, bot->y, getxmove(bot->cmd+2), getymove(bot->cmd+2)))
{
landmines[weaponslot][0]=bot->x+getxmove(bot->cmd+2);
landmines[weaponslot][1]=bot->y+getymove(bot->cmd+2);
//check for landmine hits
for(loop=0;loop<MAXWEAPONS;loop++)
{
if(landmines[loop][0]!= -1)
{
if(landminecollision(landmines[weaponslot], landmines[loop]) && weaponslot!=loop)
{
if(inshrapnelrange(*bot, landmines[loop]))
{
bot->energy-=1;
}
if(inshrapnelrange(*enemy, landmines[loop]))
{
enemy->energy-=1;
}
landmines[loop][0]= -1;
landmines[loop][1]= -1;
landmines[weaponslot][0]= -1;
landmines[weaponslot][1]= -1;
}
}
}
}
}
}
}
void cleararena(char arena[10][11])
{
int loop;
memset(arena, '.', 110);
for(loop=0;loop<10;loop++)
{
arena[loop][10]='\n';
}
}
Управляющая программа вызовет вашего бота из командной строки. По этой причине программы, которые нельзя вызвать из командной строки, будут считаться недействительными . Я прошу прощения у тех, чей язык не работает таким образом, но делать каждое совпадение вручную было бы нецелесообразно.
intx13 любезно написал более надежную версию управляющей программы с некоторыми исправлениями, которые вы можете найти здесь .
Предложения по улучшению или исправлению ошибок в управляющей программе приветствуются.
Тестовые боты
Ни один из тестовых ботов не будет включен в подсчеты очков. Они только для целей тестирования.
Дадли Донат (С)
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);
}
?>
Пытается получить право рядом с противником. Уязвим к наземным минам, поскольку не ищет их. Делает запуск ракет менее эффективной тактикой для противника, когда он достигает своей цели.
Результаты, достижения
Финальный забив будет проведен после 23:59 24 марта 2014 года . Я буду регулярно проводить тестовые заезды, чтобы участники могли видеть, как их боты противостоят нынешней оппозиции.
Записи
Записи должны включать источник вашего бота и аргумент командной строки, которые мне понадобятся для его запуска. Вы можете оставлять столько разных записей, сколько хотите, но каждый ответ должен содержать только одного бота.
Важный
Кажется, что некоторые записи хотят записать на диск, чтобы сохранить некоторое состояние между запусками. Это новые правила, касающиеся записи на диск.
- Вы можете изменить источник своего собственного бота. Модификация любого другого бота является мошенничеством и приведет к дисквалификации нарушающего бота.
- Вы можете записать в файл, созданный с целью сохранения состояния. Этот файл должен храниться в подкаталоге каталога, в котором находится ваш бот. Подкаталог будет назван
state
. Запись в любую другую часть файловой системы (кроме вашего собственного источника) запрещена.
источник
Ответы:
EvilBot
бот, который пытается быть настолько злым, насколько это возможно
Хорошо, вот что у меня есть: Java-бот, который пытается приблизить
противникак круговой полосе радиуса 2.5 вокруг центра арены, а затем наносит как можно больше урона, когда может. Его модель движения основана на присвоении значения «опасности» каждому из соседних квадратов и решении двигаться на основе этих значений и на основе тенденции быть как можно ближе к круглой области радиуса 2.5 вокруг центра арены. Я использовал некоторые гайки и болты из ответа @ Geobits (например, имея рефератBattleBot
класс и техника разбора) так что спасибо! Я, вероятно, собираюсь изменить / расширить то, что у меня есть до сих пор, хотя это довольно хорошо, как и с другими ботами, опубликованными до сих пор. Код ниже. (если кто-то еще использует Java, не стесняйтесь использовать мои абстрактные / вспомогательные классы.)(
EvilBot.java
)Использование:
Примечания:
В настоящее время наземные мины не используются, только уклоняются. Я, вероятно, не собираюсь менять это, поскольку использование наземных мин, кажется, приносит больше вреда, чем пользы (по крайней мере, для EvilBot), судя по нескольким тестам, которые я провел.
В настоящее время ПУОС не используется. Я попробовал стратегию выравнивания с противником и запуска EMP, а затем ракет, но есть несколько контрстратегий, которые выиграли бы почти 100% времени, поэтому я решил отказаться от этого маршрута. Позже я мог бы изучить использование EMP по-разному.
источник
Rifter
Этот бот выполняет различные действия в зависимости от того, с каким ботом он борется. Чтобы определить противника, он переворачивает свое собственное состояние и передает его другим ботам, чтобы увидеть, что они будут делать, и сравнивает это с тем, что они на самом деле делают. Как только они достигают порога «правильных» ходов, они перестают проверять остальных.
Как только он знает, с каким ботом он сражается, он обычно знает, где он будет находиться на следующем ходу, поэтому он может стрелять туда вместо своей текущей позиции.
Конечно, есть некоторые недостатки. Во-первых, боты со «случайной» активностью не так хорошо обнаруживаются. Это уравновешивается с помощью логики «Последняя битва короля», когда противник не известен.
Однако, если бот является чисто детерминированным, у него нет проблем с выяснением, кто он. Затем его можно легко адаптировать к ситуации, добавив в его логику больше кейсов для каждого оппонента. Например, сражаясь с Last Stand, он будет загонять его в угол, стоять на расстоянии 2х1, чтобы он не мог двигаться или стрелять напрямую, а также стрелять ракетами в стену позади, убивая ее уроном от брызг.
Как и мои другие, он расширяет BattleBot.java:
источник
ReadyAimShoot
R робота
Этот бот пытается поместить себя в ту же строку или столбец, что и цель, когда он выровнен с целью, он запускает ПУЗ, затем в следующий ход он запускает ракету по направлению к цели, а затем пулю. Он также должен знать об окружающей шахте и избегать их, но совершенно не замечает пуль и ракет. Если жизнь уже на 1, она пропускает ПУОС.
Чтобы отслеживать, когда он запускает EMP, он модифицирует свой исходный код, добавляя комментарий в конец файла (
#p_fired2
сначала, затем изменяет его#p_fired1
и затем удаляет его). Я надеюсь, что отслеживание того, когда он запускает EMP таким образом, не слишком граничит.За командной строкой должен
Rscript ReadyAimShoot.R
следовать аргумент, как в примере, по крайней мере в системах UNIX, но, вероятно, также и в Windows (я проверю это, когда действительно проверю его на других ботах).Изменить : Так как версия R, кажется, имеет проблемы с синтаксическим анализом ввода, вот Python-версия того же бота с, я надеюсь, работает. Если любой другой программист R увидит пост и увидит, что не так с этим ботом, не стесняйтесь отлаживать!
источник
Последний бой короля
Расширение для меня
BattleBot
, это предназначено для борьбы с EMP-бластерами. Единственный разумный способ (IMO) использовать EMP - это стрелять по нему, находясь на одной оси с противником, а затем стрелять ракетами / оружием в направлении застрявшего противника. Итак, я остаюсь вне оси :)Если у вас когда-нибудь была шахматная игра против короля против королевы + королевы, вы знаете, что одна королева не может поставить мат , вам нужно вовлечь короля. Если вы этого не сделаете, стратегия одинокого короля проста: старайтесь оставаться вне оси и к центру, чтобы максимизировать мобильность. Если вы застряли, идите в тупик.
Конечно, здесь нет прекрасного способа навести патовую ситуацию, поэтому в конечном итоге вы застряли на стороне или в углу, если королева играет на любом уровне компетентности. Если этот бот когда-либо в этой ситуации, он стреляет. Предполагая, что противник идет в EMP, это дает преимущество в один ход урона, поэтому последняя стойка короля должна получиться в порядке, если у него уже мало жизни.
О, и если он уже вне оси и безопасен от снарядов, он просто сделает точечный выстрел в общем направлении противника.
LastStand.java
Чтобы скомпилировать прогон, поместите в папку
BattleBot.java
и запустите:источник
EvadeBot
Этот бот приоритизирует оставаться в живых. Если он обнаруживает входящие столкновения, он пытается переместиться в безопасное место, проверяя это место на наличие столкновений. Если окружающих «безопасных» пятен нет, он остается на месте и переходит к следующему шагу.
Если не было столкновений (или безопасных мест в случае столкновения), выполняется проверка атаки. Если противник выровнен по 8 осям, он стреляет 80% времени. Если он не выровнен, он срабатывает 50% времени в ближайшем заголовке. Он выбирает оружие в зависимости от расстояния. Если это близко, мины или пули (в зависимости от точного расстояния и относительного здоровья), ракеты издалека.
Если он решил не стрелять, он берет случайную прогулку (снова проверяя безопасные места).
Если ничего из вышеперечисленного не сработало, он просто сидит там до следующего хода.
Он не использует ПУОС, и у меня плохое предчувствие
ReadyAimShoot
, что я буду противостоять ему , но посмотрим, как оно пойдет.Код состоит из двух частей. Поскольку я могу создать более одного бота, я создал абстрактный
BattleBot
класс. Он включает вспомогательные функции, такие как чтение арены, проверка столкновений, управление заголовками и т. Д. Есть также функция журнала, помогающая отслеживать, что происходит во время отладки. Еслиdebug==false
, он будет печатать только фактический результат. Если кто-то хочет использовать / расширить его, не стесняйтесь. Это не красивый код, но это лучше, чем писать шаблон.BattleBot.java
Этот конкретный бот есть
EvadeBot
. Чтобы скомпилировать / запустить, поместите его в папкуBattleBot.java
и запустите:Если вы пропустите аргумент или не сможете его правильно проанализировать, по умолчанию он будет выведен
"0"
.EvadeBot.java
источник
BattleBots.java
. Не могли бы вы перекомпилировать моих ботов до следующего запуска?Спиральный бот грамотный Хаскелл
В грамотном haskell комментарии по умолчанию, поэтому весь этот пост - программа. Этот бот будет стрелять ракетами по спирали вокруг него, игнорируя входные данные. Он хранит состояние в файле (который, мы надеемся, не будет предоставлен участником).
Сначала перечислим ракетные действия.
Далее мы идем прямо в монаду IO. Если "spiral.txt" не существует, мы пишем "0" в него. Мы также проверяем каталог.
Затем мы читаем это и распечатываем действие.
И наконец мы записываем в файл текущую позицию.
источник
state
во избежание случайного столкновения с любыми другими файлами, не имеющими состояния.LiterateHaskell.lhs:13:5: Not in scope: 'createDirectoryIfMissing'
иLiterateHaskell.lhs:14:5: Not in scope:
setCurrentDirectory'`, когда я пытаюсь скомпилировать.DodgingTurret
бот питона
Вот еще одна попытка. Поскольку ReadyAimShoot некоторое время находится в ремонтной мастерской :) Я подумал, что тем временем попробую что-нибудь еще, используя Python на этот раз.
Я бесстыдно украл строку
sys.argv[1].splitlines()
из @Gareth, но по крайней мере на этот раз у меня не возникнет проблем с анализом ввода.Этот бот работает в центре в начале боя, затем остается там и стреляет ракетами в направлении противника. Он также пытается уклониться от ближайших пуль и ракет, если они находятся на их пути, но затем возвращается в центр, прежде чем снова начать стрелять.
источник
Стрелок прямо
Это еще один простой бот, который вы можете использовать для тестирования. Если у него есть прямая видимость противника, он стреляет, в противном случае он шагает случайным образом.
источник
нео-бот
CoffeeScript
Еще один JavaScript-бот для добавления в микс. Этот предназначен для Node.js и написан на CoffeeScript. Архитектура вытекает из толпы Java с базовым классом, который обрабатывает общие проблемы, и другим файлом со специализацией для бота под рукой.
Основная стратегия этого бота - не попасть под ваши снаряды. Если вы не представляете непосредственной угрозы, нео-бот просто начнет стрелять.
Базовый файл
shared.coffee
И
neo-bot.coffee
, код бота.Я настоятельно рекомендую скомпилировать файлы кофе в javascript перед запуском; это немного быстрее. В основном вы хотите сделать это:
источник
CamperBot
Этот бот просто остается там, где он есть, и стреляет. Я применил только пули, так как другое оружие могло бы повредить бот. Пожалуйста, простите мне мои ужасные C-навыки;)
Не особо ожидал, что выиграет много.
источник
Поскольку пока нет ни одной записи, я выложу одну, чтобы у вас было что побить. Я даю тебе:
Шахта! Шахта! Шахта!
Не делает ничего особенно умного. Сбрасывает мину, если ее нет ни на одном из окружающих квадратов, в противном случае перемещается в один из безопасных окружающих квадратов. Может только победить HuggyBot.
Прошу прощения за наф код Python.
источник
Случайный бот
Этот бот просто делает случайные действия при каждом движении. Он не запускает ПУОС и не смотрит на карту вообще. Половину времени это просто выстрел в стену!
Проверьте это (против себя), как показано ниже.
источник
int main
правильно?void main
это BS.Беда и страйф
Некоторые рубиновые представления в бою. Перемещается вверх и вниз по случайно назначенной стене, стреляя ракетами по противоположной стене. Слегка глючит сверху и снизу.
источник
Ядро JavaScript
Я думал, что буду добр и передам вам свой основной бот JS. В нем есть все функции, необходимые для создания бота, все, что вам нужно, - это какие-то действия, основанные на данных, которые это вам дает. Еще не закончено, так как я не могу проверить это (не могу заставить код арены скомпилировать).
Не стесняйтесь использовать это, я с нетерпением жду появления некоторых ботов JS в миксе.
Сделать:
Добавить функции для расчета местоположения оружия
Обратите внимание, что некоторые вещи здесь, возможно, придется изменить для других ОС (это работает только в Windows). Версия Rhino здесь: http://pastebin.com/FHvmHCB8
источник
Центр-Bot
JavaScript-бот
Этот бот стремится попасть в середину арены, прежде чем он будет стрелять пулями или ракетами по цели каждый ход, в зависимости от того, насколько близко он находится. Если враг окажется посередине, он просто продолжит стрелять пулями в неопределенном направлении.
Я не ожидаю, что это будет очень хорошо, но это скорее тестирование, и мне интересно посмотреть, насколько хорошо это действительно работает.
сохранить как файл .js и выполнить с
node centrebot.js
. Это будет работать с Node.js, но вам, возможно, придется изменить его для другой программы, извините!В моих тестах:
Я не проверял ни одного из лучших Java-ботов, и я не слишком уверен в этом ...
источник
putstr(...)
вместо вас,stdo.writeLine(...)
и ввод поступаетscriptArgs[0]
. Сделав , что мне нужно изменить ,\\n
чтобы\n
разделить карту на линию. Когда я запускаю его, я получаю ошибку, потому чтоFindFoe()
иfindCentre()
определены, но не вызваны.E
вы должны иметь,W
и где у вас есть,S
вы должны иметьN
. Если вы воспользуетесь примером ввода из вопроса, вы увидите, что вывод из программыSE
не является возможным направлением из нижнего правого угла. Я исправил это для следующего теста.CunningPlanBot (Python 3.3)
Это полностью не проверено в реальном интерфейсе ... Он работает правильно с картами, по крайней мере!
Это написано для Python 3.3
Что оно делает:
Если в Фазе 1 - Если у стены и направление движется в стену или движется к наземной мине, случайным образом измените направление в сторону не стены или мины - Двигайтесь в текущем направлении - Перейдите к Фазе 2
Если в фазе 2 - стрелять пулями в ближайшем к врагу направлении - перейти к фазе 3
Если в Фазе 3 - Если нет наземной мины, бросьте наземную мину - Перейти к фазе 1
Еще нужно выяснить, нужно ли стрелять ракетой. Кроме того, я не имею ни малейшего понятия о том, работает ли материал, избегающий наземных мин. Нужно больше тестировать завтра вечером.
источник
sys.argv[1].splitlines()
для подсчета очков : я использовал для получения ввода из командной строки, а затем использовалline[x][y]
в следующем блоке; добавленыend=""
команды печати, чтобы избавиться от новой строки, которая сбивает с толку счетчика; изменил состояние для записи в файл вstate
каталоге, а не вstate
себя.UltraBot
Java-бот, который вычисляет опасность для каждого окружающего поля. Если окружающее поле менее опасно, чем текущее, бот перемещается туда (или другое, не менее опасное поле). Если есть не менее опасное поле, бот стреляет (ракеты, если вражеский бот далеко, пули, если вражеский бот рядом). Я взял некоторый код из BattleBot (спасибо!).
Этот бот очень тяжело поражает, но не очень хорош в стрельбе по врагу ... Я все еще ожидаю, что он будет лучше, чем мой предыдущий CamperBot.
источник
import
с?UltraBot.java:...: x has private access in Point
NinjaPy
Последнее представление в Python (не проверено, но, надеюсь, будет работать). Идея состоит в том, что он продвигается к противнику, оставаясь в его слепой зоне. Когда он достаточно близко (на расстоянии 3 клетки), он размещается по диагонали противника и стреляет ракетой.
источник