#Red Team - The Coward var bounds = 128; var movements = [[0,0], [-1,-1],[1,-1],[-1,0],[1,0],[-1,1],[1,1]]; var distanceTo = function(x, y, pixel) { var a = x - pixel.x; var b = y - pixel.y; return Math.sqrt( a*a + b*b ); } var isDiagonallyAdjacent = function(x, y, pixel) { return (Math.abs(pixel.x - x) == 1 && Math.abs(pixel.y - y) == 1); } var canAttackMe = function(x, y, pixel) { if(x == pixel.x && Math.abs(pixel.y - y) == 1) { return true; } else { return isDiagonallyAdjacent(x, y, pixel); } } var canIAttack = function(x, y, pixel) { if(y == pixel.y && Math.abs(pixel.x - x) == 1) { return true; } else { return isDiagonallyAdjacent(x, y, pixel); } } var isPositionSafe = function(x2, y2, enemies) { var safe = true; for(var i in enemies) { if(canAttackMe(x2, y2, enemies[i])) { safe = false; break; } } return safe; } var moveTo = function(x, y, x2, y2) { if(x2 < x) { if(y2 < y) return 4; else if(y2 > y) return 5; else return 2; } else if(x2 > x) { if(y2 < y) return 3; else if(y2 > y) return 6; else return 1; } else { if(y2 < y) { if(x2 < bounds) { return 3; } return 4; } else if(y2 > y) { if(x2 >= 0) { return 5; } return 6; } } return 0; } var getMovement = function(i) { var m = [[0, 0], [1, 0], [-1, 0], [1, -1], [-1, -1], [-1, 1], [1, 1]]; return m[i]; } if(eNear.length == 0) { // Move at random //return Math.floor((Math.random() * 6) + 1); return 0; } else { var safePositions = []; var isSafePosition = function(x2, y2) { for(var i in safePositions) { if(safePositions[i][0]==x2 && safePositions[i][0]==y2) { return true; } } return false; } for(var i in movements) { var x2 = x + movements[i][0]; var y2 = y + movements[i][1]; if(x2 >= 0 && x2 < bounds && y2 >= 0 && y2 < bounds && isPositionSafe(x2, y2, eNear)) { safePositions.push([x + movements[i][0], y + movements[i][1]]); } } var dangerousPixels = []; var attackablePixels = []; var kamikazePixels = []; for(var ei in eNear) { var e = eNear[ei]; var attackable = canIAttack(x, y, e); var dangerous = canAttackMe(x, y, e); if( attackable ) { if(isSafePosition(e.x, e.y)) { attackablePixels.push(e); } else { kamikazePixels.push(e); } } else if(dangerous) { dangerousPixels.push(e); } } if(attackablePixels.length == eNear.length) { return moveTo(attackablePixels[0].x, attackablePixels[0].y); } if(attackablePixels.length > 0 && tNear.length >= eNear.length) { // Attack only if we have greater numbers // Attack one of them at random var i = Math.floor(Math.random() * attackablePixels.length); return moveTo(x, y, attackablePixels[i].x, attackablePixels[i].y); } else if(dangerousPixels.length > 0 && safePositions.length > 0) { // Flee var i = Math.floor(Math.random() * safePositions.length); return moveTo(x, y, safePositions[i][0], safePositions[i][1]); } else if(dangerousPixels.length > 0 && safePositions.length == 0 && kamikazePixels.length > 0) { var i = Math.floor(Math.random() * kamikazePixels.length); return moveTo(x, y, kamikazePixels[i].x, kamikazePixels[i].y); } else { var nearest = null; var nearestDist = Infinity; for(var ei in eNear) { var e = eNear[ei]; var d = distanceTo(x, y, e); if(nearest === null || d < nearestDist) { nearestDist = d; nearest = e; } } if(tNear.length >= eNear.length) { // Attack the nearest return moveTo(x, y, nearest.x, nearest.y); } else { // Get Away from the nearest var n = moveTo(x, y, nearest.x, nearest.y); var m = getMovement(n); var x2 = x-m[0]; var y2 = y-m[1]; if(x2 < 0 || x2 >= bounds) x2 = x + m[0]; if(y2 < 0 || y2 >= bounds) y2 = y + m[1]; return moveTo(x, y, x2, y2); } } } This bot stays still to avoid being detected as much as possible. When one or more enemies are in sight, several things can happen: - If there are more enemies than the bot and his allies in sight, he tries to get away from the nearest enemy. - If there are more friends in sight than enemies, the numeric superiority gives the bot courage and tries to go forth and attack the enemy. - If he can kill an enemy next to it, he will try to, regardless of how many friendly and enemy bots there are, always trying to end up in a cell that can't be attacked by another bot. - If all the enemies are protected by other enemies, tries to flee. - If he can not go anywhere because all positions can be attacked, enters kamikaze mode and tries to at least take someone with him to the grave. Doesn't communicate with anyone, in case someone could hear him and go after him. It may not be the most useful bot to the team, but it was fun watching him trying to get away from everyone.