Red vs. Blue - Pixel Team Battlebots
Blue Team - SphiNotPi3000
// Char 0: top or bottom ("T" or "B")
// Char 1, 2: x/y coords
// Char 3, move polarity
// Char 4: offset (as codepoint - 128)
var twin = 21487;
var myself = 2867;
var formpos = "T";
var tochar = String.fromCharCode;
var movestat = (move % 2).toString();
var inbox = getMsg(twin);
// Spoofing the message of a deceased partner
if (inbox == "X"){
inbox = "B" + tochar(x) + tochar(y+1) + ((move + 1) % 2).toString() + tochar(0);
}
var selfsafe = [9,10,10,10,10,10,10];
// Remove useless edge moves
if (x == 0){
selfsafe[4] = 0;
selfsafe[5] = 0;
}
if (x == 127){
selfsafe[3] = 0;
selfsafe[6] = 0;
}
if (y == 0){
selfsafe[2] = 0;
selfsafe[3] = 0;
selfsafe[4] = 0;
}
if (y == 127){
selfsafe[1] = 0;
selfsafe[6] = 0;
selfsafe[5] = 0;
}
var selfdisp = [[0,0],[0,1],[0,-1],[1,-1],[-1,-1],[-1,1],[1,1]];
if (inbox == "") {
// First move, pick anywhere safe
for (j = 0; j < 7; j++) {
for (var i = 0; i < eNear.length; i++){
var enemy = eNear[i];
var dx = enemy.x - x - selfdisp[j][0];
var dy = enemy.y - y - selfdisp[j][1];
if (dx * dx == 1 && dy >= -1 && dy <= 1) {
selfsafe[j] = 0;
}
}
if (selfsafe[j]) {
var strpos = tochar(x + selfdisp[j][0]) + tochar(y + selfdisp[j][0]);
var offset = tochar(Math.floor(Math.random() * 256));
setMsg(formpos + strpos + movestat + offset);
return j;
}
}
} else {
var twinformpos = inbox.charAt(0);
var twinx = inbox.charAt(1).charCodeAt();
var twiny = inbox.charAt(2).charCodeAt();
var twinmovestat = inbox.charAt(3);
var offset = inbox.charAt(4);
formpos = twinformpos == "T" ? "B" : "T";
var targetx = twinx;
var targety = formpos == "T" ? (twiny - 1) : (twiny + 1);
// If true, then this bot is either the second one to move or is not in position. Move into position.
if (twinmovestat == movestat || x != targetx || y != targety) {
var bestmove = 0;
for (var j = 0; j < 7; j++) {
for (var i = 0; i < eNear.length; i++){
var enemy = eNear[i];
var dx = enemy.x - x - selfdisp[j][0];
var dy = enemy.y - y - selfdisp[j][1];
if (dx * dx == 1 && dy >= -1 && dy <= 1) {
selfsafe[j] = 0;
}
if (dx == 0 && dy == 0){
selfsafe[j] *= 2;
}
}
selfsafe[j] -= Math.abs(x + selfdisp[j][0] - targetx) + Math.abs(y + selfdisp[j][1] - targety);
if (selfsafe[j] > selfsafe[bestmove]) {
bestmove = j;
}
}
var strpos = tochar(x + selfdisp[bestmove][0]) + tochar(y + selfdisp[bestmove][1]);
setMsg(formpos + strpos + movestat + offset);
return bestmove;
} else {
// In formation, and is the leader this turn
var topy = formpos == "T" ? y : (y - 1);
var topx = x;
var safe = [1,1,1,1,1,1,1,1,1];
var disp = [[0,0],[0,1],[0,-1],[1,-1],[-1,-1],[-1,1],[1,1],[1,0],[-1,0]];
var otherpos = formpos == "T" ? "B" : "T";
// Avoid dangerous squares and always kill if safe to do so
for (var j = 0; j < 9; j++){
var ntopx = topx + disp[j][0];
var ntopy = topy + disp[j][1];
if (ntopx < 0 || ntopx > 127 || ntopy < 0 || ntopy > 126){
safe[j] = 0;
continue;
}
for (var i = 0; i < eNear.length; i++){
var enemy = eNear[i];
var dx = enemy.x - ntopx;
var dy = enemy.y - ntopy;
if(dx * dx == 1 && dy >= -1 && dy <= 2){
safe[j] = 0;
continue;
}
if(dx == 0 && dy >= 0 && dy <= 1){
// Kill!
var strpos = tochar(x + disp[j][0]) + tochar(y + disp[j][1]);
if (j > 6) {
setMsg(otherpos + strpos + movestat + offset);
if (formpos == "T"){return 13 - j;}
return j - 4;
}
setMsg(formpos + strpos + movestat + offset);
return j;
}
}
}
var pref = [];
for (var i = 0; i < eNear.length; i++){
var enemy = eNear[i];
var dy = enemy.y - topy;
var dx = enemy.x - topx;
if (dy < 0 && dx == 0){ pref=[2,4,3,8,7,1,5,6,0]; }
if (dy > 0 && dx == 0){ pref=[1,5,6,7,8,2,4,3,0]; }
if (dy == 0 && dx > 0){ pref=[7,6,3,1,2,5,4,8,0]; }
if (dy == 0 && dx < 0){ pref=[8,5,4,1,2,6,3,7,0]; }
if (dy < 0 && dx < 0){ pref=[4,8,5,1,0,2,6,7,3]; }
if (dy > 0 && dx < 0){ pref=[5,8,4,2,0,1,3,7,6]; }
if (dy < 0 && dx > 0){ pref=[3,7,6,1,0,2,5,8,4]; }
if (dy > 0 && dx > 0){ pref=[6,7,3,2,0,1,4,8,5]; }
for (var k = 0; k < pref.length; k++)
{
if (safe[pref[k]]){
var strpos = tochar(x + disp[pref[k]][0]) + tochar(y + disp[pref[k]][1]);
if (pref[k] > 6) {
setMsg(otherpos + strpos + movestat + offset);
if(formpos == "T"){return 13 - pref[k];}
return pref[k] - 4;
}
setMsg(formpos + strpos + movestat + offset);
return pref[k];
}
}
}
var offsetint = offset.charCodeAt();
var offsetmove = move - 128 + offsetint;
if (offsetmove % 900 < 30) {
var targetx = 64 - (offsetmove % 30);
var targety = 64 - (offsetmove % 30);
} else if (offsetmove % 900 < 90) {
var targetx = 34 + ((offsetmove - 30) % 60);
var targety = 34;
} else if (offsetmove % 900 < 150) {
var targetx = 94;
var targety = 34 + ((offsetmove - 30) % 60);
} else if (offsetmove % 900 < 210) {
var targetx = 94 - ((offsetmove - 30) % 60);
var targety = 94;
} else if (offsetmove % 900 < 270) {
var targetx = 34;
var targety = 94 - ((offsetmove - 30) % 60);
} else if (offsetmove % 900 < 300) {
var targetx = 34 + (offsetmove % 30);
var targety = 34 + (offsetmove % 30);
} else if (offsetmove % 900 < 360) {
var targetx = 64 + (offsetmove % 60);
var targety = 64 - (offsetmove % 60);
} else if (offsetmove % 900 < 480) {
var targetx = 124;
var targety = 4 + (offsetmove % 120);
} else if (offsetmove % 900 < 600) {
var targetx = 124 - (offsetmove % 120);
var targety = 124;
} else if (offsetmove % 900 < 720) {
var targetx = 4;
var targety = 124 - (offsetmove % 120);
} else if (offsetmove % 900 < 840) {
var targetx = 4 + (offsetmove % 120);
var targety = 4;
} else {
var targetx = 124 - (offsetmove % 60);
var targety = 4 + (offsetmove % 60);
}
if (offsetint % 4 == 1) {
var temp = targetx;
var targetx = 127 - targety;
var targety = temp;
} else if (offsetint % 4 == 2) {
var targetx = 127 - targetx;
var targety = 127 - targety;
} else if (offsetint % 4 == 3) {
var temp = targetx;
var targetx = targety;
var targety = 127 - temp;
}
if ((offsetint >> 3) % 2) {
var targetx = 127 - targetx;
}
var bestmove = 0;
for (var j = 0; j < 9; j++) {
safe[j] -= Math.abs(topx + disp[j][0] - targetx) + Math.abs(topy + disp[j][1] - targety);
if (safe[j] > safe[bestmove]) {
bestmove = j;
}
}
var strpos = tochar(x + disp[bestmove][0]) + tochar(y + disp[bestmove][1]);
if (bestmove > 6) {
setMsg(otherpos + strpos + movestat + offset);
if (formpos == "T"){return 13 - bestmove;}
return bestmove - 4;
}
setMsg(formpos + strpos + movestat + offset);
return bestmove;
}
}
This bot forms a pair with Sp3000's bot.
The basic idea is that two bots, positioned adjacent to each other, help cover each other's weaknesses, so that neither bot has an exposed side. This helps protect from threats and limit the escape options of the target.
At the beginning of the game, they navigate towards each other and form a pair. This pair then moves as a single unit, with one bot leading the other. The two bots have almost identical code, allowing them to trade positions and roles when necessary.
When idle, the bots move around the board searching for enemies. Once they spot an enemy, they carefully maneuver themselves into the correct positions to attack. A very neat feature is the formation's ability to move straight horizontally, achieved by having the bots alternate places.
Blue Team - SphiNotPi3000
// Char 0: top or bottom ("T" or "B")
// Char 1, 2: x/y coords
// Char 3, move polarity
// Char 4: offset (as codepoint - 128)
var myself = 21487;
var twin = 2867;
var formpos = "B";
var tochar = String.fromCharCode;
var movestat = (move % 2).toString();
var inbox = getMsg(twin);
// Spoofing the message of a deceased partner
if (inbox == "X"){
inbox = "B" + tochar(x) + tochar(y+1) + ((move + 1) % 2).toString() + tochar(0);
}
var selfsafe = [9,10,10,10,10,10,10];
// Remove useless edge moves
if (x == 0){
selfsafe[4] = 0;
selfsafe[5] = 0;
}
if (x == 127){
selfsafe[3] = 0;
selfsafe[6] = 0;
}
if (y == 0){
selfsafe[2] = 0;
selfsafe[3] = 0;
selfsafe[4] = 0;
}
if (y == 127){
selfsafe[1] = 0;
selfsafe[6] = 0;
selfsafe[5] = 0;
}
var selfdisp = [[0,0],[0,1],[0,-1],[1,-1],[-1,-1],[-1,1],[1,1]];
if (inbox == "") {
// First move, pick anywhere safe
for (j = 0; j < 7; j++) {
for (var i = 0; i < eNear.length; i++){
var enemy = eNear[i];
var dx = enemy.x - x - selfdisp[j][0];
var dy = enemy.y - y - selfdisp[j][1];
if (dx * dx == 1 && dy >= -1 && dy <= 1) {
selfsafe[j] = 0;
}
}
if (selfsafe[j]) {
var strpos = tochar(x + selfdisp[j][0]) + tochar(y + selfdisp[j][0]);
var offset = tochar(Math.floor(Math.random() * 256));
setMsg(formpos + strpos + movestat + offset);
return j;
}
}
} else {
var twinformpos = inbox.charAt(0);
var twinx = inbox.charAt(1).charCodeAt();
var twiny = inbox.charAt(2).charCodeAt();
var twinmovestat = inbox.charAt(3);
var offset = inbox.charAt(4);
formpos = twinformpos == "T" ? "B" : "T";
var targetx = twinx;
var targety = formpos == "T" ? (twiny - 1) : (twiny + 1);
// If true, then this bot is either the second one to move or is not in position. Move into position.
if (twinmovestat == movestat || x != targetx || y != targety) {
var bestmove = 0;
for (var j = 0; j < 7; j++) {
for (var i = 0; i < eNear.length; i++){
var enemy = eNear[i];
var dx = enemy.x - x - selfdisp[j][0];
var dy = enemy.y - y - selfdisp[j][1];
if (dx * dx == 1 && dy >= -1 && dy <= 1) {
selfsafe[j] = 0;
}
if (dx == 0 && dy == 0){
selfsafe[j] *= 2;
}
}
selfsafe[j] -= Math.abs(x + selfdisp[j][0] - targetx) + Math.abs(y + selfdisp[j][1] - targety);
if (selfsafe[j] > selfsafe[bestmove]) {
bestmove = j;
}
}
var strpos = tochar(x + selfdisp[bestmove][0]) + tochar(y + selfdisp[bestmove][1]);
setMsg(formpos + strpos + movestat + offset);
return bestmove;
} else {
// In formation, and is the leader this turn
var topy = formpos == "T" ? y : (y - 1);
var topx = x;
var safe = [1,1,1,1,1,1,1,1,1];
var disp = [[0,0],[0,1],[0,-1],[1,-1],[-1,-1],[-1,1],[1,1],[1,0],[-1,0]];
var otherpos = formpos == "T" ? "B" : "T";
// Avoid dangerous squares and always kill if safe to do so
for (var j = 0; j < 9; j++){
var ntopx = topx + disp[j][0];
var ntopy = topy + disp[j][1];
if (ntopx < 0 || ntopx > 127 || ntopy < 0 || ntopy > 126){
safe[j] = 0;
continue;
}
for (var i = 0; i < eNear.length; i++){
var enemy = eNear[i];
var dx = enemy.x - ntopx;
var dy = enemy.y - ntopy;
if(dx * dx == 1 && dy >= -1 && dy <= 2){
safe[j] = 0;
continue;
}
if(dx == 0 && dy >= 0 && dy <= 1){
// Kill!
var strpos = tochar(x + disp[j][0]) + tochar(y + disp[j][1]);
if (j > 6) {
setMsg(otherpos + strpos + movestat + offset);
if (formpos == "T"){return 13 - j;}
return j - 4;
}
setMsg(formpos + strpos + movestat + offset);
return j;
}
}
}
var pref = [];
for (var i = 0; i < eNear.length; i++){
var enemy = eNear[i];
var dy = enemy.y - topy;
var dx = enemy.x - topx;
if (dy < 0 && dx == 0){ pref=[2,4,3,8,7,1,5,6,0]; }
if (dy > 0 && dx == 0){ pref=[1,5,6,7,8,2,4,3,0]; }
if (dy == 0 && dx > 0){ pref=[7,6,3,1,2,5,4,8,0]; }
if (dy == 0 && dx < 0){ pref=[8,5,4,1,2,6,3,7,0]; }
if (dy < 0 && dx < 0){ pref=[4,8,5,1,0,2,6,7,3]; }
if (dy > 0 && dx < 0){ pref=[5,8,4,2,0,1,3,7,6]; }
if (dy < 0 && dx > 0){ pref=[3,7,6,1,0,2,5,8,4]; }
if (dy > 0 && dx > 0){ pref=[6,7,3,2,0,1,4,8,5]; }
for (var k = 0; k < pref.length; k++)
{
if (safe[pref[k]]){
var strpos = tochar(x + disp[pref[k]][0]) + tochar(y + disp[pref[k]][1]);
if (pref[k] > 6) {
setMsg(otherpos + strpos + movestat + offset);
if(formpos == "T"){return 13 - pref[k];}
return pref[k] - 4;
}
setMsg(formpos + strpos + movestat + offset);
return pref[k];
}
}
}
var offsetint = offset.charCodeAt();
var offsetmove = move - 128 + offsetint;
if (offsetmove % 900 < 30) {
var targetx = 64 - (offsetmove % 30);
var targety = 64 - (offsetmove % 30);
} else if (offsetmove % 900 < 90) {
var targetx = 34 + ((offsetmove - 30) % 60);
var targety = 34;
} else if (offsetmove % 900 < 150) {
var targetx = 94;
var targety = 34 + ((offsetmove - 30) % 60);
} else if (offsetmove % 900 < 210) {
var targetx = 94 - ((offsetmove - 30) % 60);
var targety = 94;
} else if (offsetmove % 900 < 270) {
var targetx = 34;
var targety = 94 - ((offsetmove - 30) % 60);
} else if (offsetmove % 900 < 300) {
var targetx = 34 + (offsetmove % 30);
var targety = 34 + (offsetmove % 30);
} else if (offsetmove % 900 < 360) {
var targetx = 64 + (offsetmove % 60);
var targety = 64 - (offsetmove % 60);
} else if (offsetmove % 900 < 480) {
var targetx = 124;
var targety = 4 + (offsetmove % 120);
} else if (offsetmove % 900 < 600) {
var targetx = 124 - (offsetmove % 120);
var targety = 124;
} else if (offsetmove % 900 < 720) {
var targetx = 4;
var targety = 124 - (offsetmove % 120);
} else if (offsetmove % 900 < 840) {
var targetx = 4 + (offsetmove % 120);
var targety = 4;
} else {
var targetx = 124 - (offsetmove % 60);
var targety = 4 + (offsetmove % 60);
}
if (offsetint % 4 == 1) {
var temp = targetx;
var targetx = 127 - targety;
var targety = temp;
} else if (offsetint % 4 == 2) {
var targetx = 127 - targetx;
var targety = 127 - targety;
} else if (offsetint % 4 == 3) {
var temp = targetx;
var targetx = targety;
var targety = 127 - temp;
}
if ((offsetint >> 3) % 2) {
var targetx = 127 - targetx;
}
var bestmove = 0;
for (var j = 0; j < 9; j++) {
safe[j] -= Math.abs(topx + disp[j][0] - targetx) + Math.abs(topy + disp[j][1] - targety);
if (safe[j] > safe[bestmove]) {
bestmove = j;
}
}
var strpos = tochar(x + disp[bestmove][0]) + tochar(y + disp[bestmove][1]);
if (bestmove > 6) {
setMsg(otherpos + strpos + movestat + offset);
if (formpos == "T"){return 13 - bestmove;}
return bestmove - 4;
}
setMsg(formpos + strpos + movestat + offset);
return bestmove;
}
}
This bot forms a pair with PhiNotPi's bot. See Phi's post for a brief explanation of our strategy.
Red Team - SeekerBot
var myself = 38926;
var messages = getMsg(myself).split(';');
var minimalDistanceToFriend = 2;
var chosenMove = null;
var newDistanceToFriend = null;
var minimalVerticalDistanceToEnemy = null, minimalHorizontalDistanceToEnemy = null;
var closestFriend = null;
var closestEnemy = null;
var possibleVictims = [];
var possibleMoves = [
{newX: x, newY: y},
{newX: x + 1, newY: y},
{newX: x - 1, newY: y},
{newX: x + 1, newY: y - 1},
{newX: x - 1, newY: y - 1},
{newX: x - 1, newY: y + 1},
{newX: x + 1, newY: y + 1}
];
var calculateDistance = function(x1, y1, x2, y2) {
return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
};
var iAmInDanger = function(meX, meY, himX, himY) {
return (Math.abs(meY - himY) === 1 && Math.abs(meX - himX) <= 1);
};
var iCanKillHim = function(meX, meY, himX, himY) {
return (Math.abs(meX - himX) === 1 && Math.abs(meY - himY) <= 1);
};
var setMessage = function() {
messages[0] = ("000" + x).substr(-3, 3);
messages[1] = ("000" + y).substr(-3, 3);
setMsg(messages.join(';'));
}
for (i = 0; i < possibleMoves.length; i++) {
if (possibleMoves[i].newX < 0 || possibleMoves[i].newY < 0 || possibleMoves[i].newX > 127 || possibleMoves[i].newY > 127) {
possibleMoves[i] = null;
}
}
for (var i = 0; i < eNear.length; i++) {
if (closestEnemy === null || calculateDistance(x, y, closestEnemy.x, closestEnemy.y) > calculateDistance(x, y, eNear[i].x, eNear[i].y)) {
closestEnemy = eNear[i];
}
if (Math.abs(x - eNear[i].x) <= 2 && Math.abs(y - eNear[i].y) <= 2) {
possibleVictims.push(eNear[i]);
}
}
for (i = 0; i < tNear.length; i++) {
if (closestFriend === null || calculateDistance(x, y, closestFriend.x, closestFriend.y) > calculateDistance(x, y, tNear[i].x, tNear[i].y)) {
closestFriend = tNear[i];
}
}
for (i = 0; i < possibleMoves.length; i++) {
for (var j = 0; j < possibleVictims.length; j++) {
if (possibleMoves[i] !== null && iAmInDanger(possibleMoves[i].newX, possibleMoves[i].newY, possibleVictims[j].x, possibleVictims[j].y)) {
possibleMoves[i] = null;
}
}
}
for (i = 0; i < possibleMoves.length; i++) {
for (j = 0; j < possibleVictims.length; j++) {
if (possibleMoves[i] !== null && possibleMoves[i].newX === possibleVictims[j].x && possibleMoves[i].newY === possibleVictims[j].y) {
messages[2] = 0;
setMessage();
return i;
}
}
}
if (possibleVictims.length > 0) {
if (iAmInDanger(x, y, possibleVictims[0].x, possibleVictims[0].y)) {
if (closestFriend !== null) {
for (i = 0; i < possibleMoves.length; i++) {
if (possibleMoves[i] !== null) {
var distance = calculateDistance(possibleMoves[i].newX, possibleMoves[i].newY, closestFriend.x, closestFriend.y);
if (newDistanceToFriend === null || (distance < newDistanceToFriend && distance >= minimalDistanceToFriend)) {
newDistanceToFriend = distance;
chosenMove = i;
}
}
}
messages[2] = 0;
setMessage();
return chosenMove;
}
else {
var aggressiveMoves = [];
var randomMoves = [];
for (i = 0; i < possibleMoves.length; i++) {
if (possibleMoves[i] !== null) {
if (iCanKillHim(possibleMoves[i].newX, possibleMoves[i].newY, possibleVictims[0].x, possibleVictims[0].y)) {
aggressiveMoves.push(i);
}
randomMoves.push(i);
}
}
var approachCount = messages[2] || 0;
if (approachCount < 5 && aggressiveMoves.length > 0) {
messages[2] = approachCount + 1;
chosenMove = aggressiveMoves[Math.floor(Math.random() * aggressiveMoves.length)];
setMessage();
return chosenMove;
}
else {
chosenMove = randomMoves[Math.floor(Math.random() * randomMoves.length)];
setMessage();
return chosenMove;
}
}
}
}
if (closestEnemy != null) {
for (i = 1; i < possibleMoves.length; i++) {
if (possibleMoves[i] !== null) {
var verticalDistance = Math.abs(possibleMoves[i].newY - closestEnemy.y);
var horizontalDistance = Math.abs(possibleMoves[i].newX - closestEnemy.x);
if (minimalVerticalDistanceToEnemy === null || verticalDistance <= minimalVerticalDistanceToEnemy) {
if (minimalVerticalDistanceToEnemy !== null && verticalDistance === minimalVerticalDistanceToEnemy) {
if (minimalHorizontalDistanceToEnemy === null || horizontalDistance <= minimalHorizontalDistanceToEnemy) {
minimalHorizontalDistanceToEnemy = horizontalDistance;
chosenMove = i;
}
}
else {
minimalVerticalDistanceToEnemy = verticalDistance;
minimalHorizontalDistanceToEnemy = horizontalDistance;
chosenMove = i;
}
}
}
}
messages[2] = 0;
setMessage();
return chosenMove;
}
var seekStatus = messages[3] || 0;
var seekCount = messages[4] || 0;
seekStatus = parseInt(seekStatus, 10);
seekCount = parseInt(seekCount, 10);
switch (seekStatus) {
case 0:
if (x < 16) {
seekCount = 0;
if (y > 111) {
seekStatus = 4;
}
else {
seekStatus = 1;
}
}
else {
chosenMove = 2;
}
break;
case 1:
seekCount++;
if (y > 111 || seekCount > 31) {
seekStatus = 2;
}
else {
if (seekCount % 2 === 0) {
chosenMove = 5;
}
else {
chosenMove = 6;
}
}
break;
case 2:
if (x > 111) {
seekCount = 0;
if (y > 111) {
seekStatus = 4;
}
else {
seekStatus = 3;
}
}
else {
chosenMove = 1;
}
break;
case 3:
seekCount++;
if (y > 111 || seekCount > 31) {
seekStatus = 0;
}
else {
if (seekCount % 2 === 0) {
chosenMove = 5;
}
else {
chosenMove = 6;
}
}
break;
case 4:
seekCount++;
if (y < 16) {
if (x > 63) {
seekStatus = 0;
}
else {
seekStatus = 2;
}
}
else {
if (seekCount % 2 === 0) {
chosenMove = 3;
}
else {
chosenMove = 4;
}
}
break;
}
messages[2] = 0;
messages[3] = seekStatus;
messages[4] = seekCount;
setMessage();
return chosenMove;
The highest priority of SeekerBot is survival. Therefore, it will only consider moves which will not put it into jeopardy of being killed in the next turn (as long as such moves exist).
When no opponents are in view, it will move in a pattern over the battlefield, which will ensure that most of the ground will regularly be in viewing distance.
If SeekerBot spots an enemy, it will move towards it. If it can kill an enemy, it will do so as long as the move is save.
If it cannot kill an enemy but the enemy is in a position to kill it on its next turn, SeekerBot will try to lure the enemy towards a friend (if one is visible). If no team member is in view, it will try to move into a position, where it can kill the enemy in the next turn. If this does not work 5 times in a row, it will switch tactics and start moving in a random pattern, possibly closing in on the enemy again in the next round.
For what it's worth, it will use the first 7 characters of the message to shout its own position in the format "x;y" (where x and y are zero padded).
Its certainly not the cleanest code, but it seems to do what I expected of it.