Created
June 24, 2015 14:33
-
-
Save bencrowder/1fa7e5608f981951e902 to your computer and use it in GitHub Desktop.
Helm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Bot: Helm | |
// Ruleset: default | |
// -------------------------------------------------- | |
var Helm = function() {}; | |
Helm.prototype = new Bot(); | |
Helm.prototype.setup = function() { | |
this.timer = 0; | |
this.target = undefined; | |
this.stuckCounter = 0; | |
this.unstickityCommands = [ 'forward', 'strafe-left', 'strafe-right', 'backward', 'left', 'right' ]; | |
this.hitCounter = 0; | |
this.hitEvasionCommands = [ 'strafe-left', 'strafe-right', 'backward' ]; | |
this.lastCommand = undefined; | |
// Field stuff | |
this.attrStrength = 8; | |
this.safety = 9; | |
this.repStrength = 4; | |
this.lastX = undefined; | |
this.lastY = undefined; | |
}; | |
// Choose the closest bot and target it | |
// -------------------------------------------------- | |
Helm.prototype.acquireTarget = function() { | |
var target = undefined; | |
var distance = 50000; // Obscenely high number | |
for (i in this.state.bots) { | |
var bot = this.state.bots[i]; | |
// Only attack opposing bots | |
if (bot.name != this.name) { | |
// If I'm closer to this bot, make it my target | |
if (this.myDistanceToPoint(bot.x, bot.y) < distance) { | |
target = bot; | |
this.state.payload.target = bot; | |
distance = this.myDistanceToPoint(bot.x, bot.y); | |
} | |
} | |
} | |
return target; | |
} | |
// Check for collisions | |
// -------------------------------------------------- | |
Helm.prototype.checkCollisions = function(point) { | |
var collision = false; | |
var type = ''; | |
var object = undefined; | |
var obstacles = server.getObstacles(); | |
var bots = server.getBots(); | |
// Check bots | |
for (i in bots) { | |
bot = bots[i]; | |
if (server.collisionBotWeapon(bot, point)) { | |
collision = true; | |
type = 'bot'; | |
object = bot; | |
break; | |
} | |
} | |
// Check obstacles | |
if (!collision) { | |
for (i in obstacles) { | |
obstacle = obstacles[i]; | |
if (server.collisionObstacle(obstacle, point)) { | |
collision = true; | |
type = 'obstacle'; | |
object = obstacle; | |
break; | |
} | |
} | |
} | |
// Check boundaries | |
if (!collision && server.collisionBoundary(point)) { | |
collision = true; | |
type = 'boundary'; | |
object = undefined; | |
} | |
return { collision: collision, type: type, object: object }; | |
} | |
// Starting at (x, y) and moving along angle, check for collisions | |
// Returns collision type and distance to first collision | |
// -------------------------------------------------- | |
Helm.prototype.distanceToCollision = function(x, y, angle) { | |
var speed = 5; | |
var newPoint = { x: x, y: y }; | |
var response = {}; | |
response.collision = false; | |
while (!response.collision) { | |
newPoint = server.helpers.calcVector(newPoint.x, newPoint.y, angle, speed); | |
response = this.checkCollisions(newPoint); | |
} | |
distance = this.myDistanceToPoint(newPoint.x, newPoint.y); | |
return { distance: distance, type: response.type, object: response.object }; | |
} | |
// Run distanceToCollision for my bot | |
// -------------------------------------------------- | |
Helm.prototype.myDistanceToCollision = function() { | |
// Start outside the bot | |
var pos = server.helpers.calcVector(this.x, this.y, this.angle, this.radius + 1); | |
return this.distanceToCollision(pos.x, pos.y, this.angle); | |
} | |
// Standard run function | |
// -------------------------------------------------- | |
Helm.prototype.run = function() { | |
var done = false; | |
// Initialize command to return | |
var command = ''; | |
if (typeof this.state.payload.target == 'undefined') { | |
// Get the closest target | |
this.state.payload.target = {}; | |
this.target = this.acquireTarget(); | |
} else { | |
// There's already a target, so get it | |
this.target = this.state.payload.target; | |
} | |
// Find out what's on my path | |
var dtc = this.myDistanceToCollision(this.x, this.y, this.angle); | |
// Use fields to get recommended command for moving close to target | |
var dir = this.getDirection(this.target, 0.05); | |
// Distance to target | |
var dist = this.myDistanceToPoint(this.target.x, this.target.y); | |
// Boolean: are we aiming at an enemy bot? | |
var aimingAtEnemy = (dtc.type == 'bot' && dtc.object.name != this.name); | |
// Boolean: are we aiming at an obstacle and it's fairly close? | |
var aimingAtCloseObstacle = (dtc.type == 'obstacle' && dtc.distance < 150); | |
// If the bot can shoot, and if we're aiming at an enemy or a close obstacle, shoot | |
if (this.canShoot && this.weapons.bullet > 0 && (aimingAtEnemy || aimingAtCloseObstacle)) { | |
command = 'fire'; | |
} else { | |
// Turn left or right if that's what the field says | |
if (dir.command != 'forward') { | |
command = dir.command; | |
} else { | |
// If one of our team bots is in front of us, strafe right to get out from behind them | |
if (dtc.type == 'bot' && dtc.object.name == this.name) { | |
command = 'strafe-right'; | |
} else { | |
// If we're far away, move close | |
if (dist > 80) { | |
command = 'forward'; | |
} else { | |
// Otherwise strafe | |
command = (this.strafe > 50) ? "strafe-left" : "strafe-right"; | |
if (this.strafe > 0) { | |
this.strafe--; | |
} else { | |
this.strafe = 100; | |
} | |
} | |
} | |
// Every 15 ticks, check to see if we haven't moved | |
if (this.timer % 15 == 0) { | |
if ((this.lastX == this.x && this.lastY == this.y) || this.hitByBullet) { | |
// We're stuck or hit, so try something else | |
this.lastCommand = this.unstickityCommands[Math.floor(Math.random() * this.unstickityCommands.length)]; | |
this.stuckCounter = 50; | |
} | |
this.lastX = this.x; | |
this.lastY = this.y; | |
} | |
if (this.stuckCounter > 0) { | |
// If we're stuck, keep doing the last command | |
command = this.lastCommand; | |
this.stuckCounter--; | |
} | |
} | |
} | |
// Every 100th turn, lay a mine | |
if (this.timer % 100 == 0 && this.weapons.mine > 0) { | |
command = 'mine'; | |
} | |
// Check to see if we've been hit | |
if (this.hitByBullet) { | |
// We're stuck or hit, so try something else | |
this.lastCommand = this.hitEvasionCommands[Math.floor(Math.random() * this.hitEvasionCommands.length)]; | |
this.hitCounter = 20; | |
this.hitByBullet = false; | |
} | |
// We've been hit | |
if (this.hitCounter > 0) { | |
// If we're stuck, keep doing the last command | |
command = this.lastCommand; | |
this.hitCounter--; | |
} | |
this.lastCommand = command; | |
this.timer++; | |
return { 'command': command, 'team': this.state.payload }; | |
}; | |
server.registerBotScript("Helm"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment