Skip to content

Instantly share code, notes, and snippets.

@bencrowder
Created June 24, 2015 14:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bencrowder/1fa7e5608f981951e902 to your computer and use it in GitHub Desktop.
Save bencrowder/1fa7e5608f981951e902 to your computer and use it in GitHub Desktop.
Helm
// 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