Skip to content

Instantly share code, notes, and snippets.

@robwalch
Created December 1, 2012 02:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save robwalch/4180209 to your computer and use it in GitHub Desktop.
Save robwalch/4180209 to your computer and use it in GitHub Desktop.
minimonk
var r = 19, Robot = function(e) {
this.data = {}, this.time = 0, this.arenaTopLeft = {x: r,y: r}, this.arenaTopRight = {x: e.arenaWidth - r,y: r}, this.arenaBottomLeft = {x: r,y: e.arenaHeight - r}, this.arenaBottomRight = {x: e.arenaWidth - r,y: e.arenaHeight - r}, this.arenaCenter = {x: e.arenaWidth / 2,y: e.arenaHeight / 2}, this.target1 = null, this.target2 = null
}, p = Robot.prototype;
(function() {
var e = r, t = r * r, n = 20, i = 2, s = 50, o = 50;
p.sub = function(e, t) {
return {x: e.x - t.x,y: e.y - t.y}
}, p.add = function(e, t) {
return {x: e.x + t.x,y: e.y + t.y}
}, p.neg = function(e) {
return {x: -e.x,y: -e.y}
}, p.perp = function(e) {
return {x: -e.y,y: e.x}
}, p.rperp = function(e) {
return {x: e.y,y: -e.x}
}, p.mult = function(e, t) {
return {x: e.x * t,y: e.y * t}
}, p.dot = function(e, t) {
return e.x * t.x + e.y * t.y
}, p.len = function(e) {
return Math.sqrt(this.dot(e, e))
}, p.dist = function(e, t) {
var n = this.sub(e, t);
return this.len(n, n)
}, p.distSq = function(e, t) {
var n = this.sub(e, t);
return this.dot(n, n)
}, p.tostr = function(e) {
return e ? "(" + e.x + ", " + e.y + ")" : "(undefined)"
}, p.radian = function(e) {
return e * Math.PI / 180
}, p.forangle = function(e) {
return e = this.radian(e), {x: Math.cos(e),y: Math.sin(e)}
}, p.toangle = function(e) {
return Math.round(Math.atan2(e.y, e.x) * 180 / Math.PI + 90)
}, p.normalizeAngle = function(e) {
return (e % 360 + 360) % 360
}, p.shortest = function(e) {
return e = this.normalizeAngle(e), e > 180 ? e - 360 : e
}, p.getBearing = function(e, t) {
return this.shortest(this.toangle(this.sub(t, e.position)) - e.angle)
}, p.adjacentCorner = function(e) {
return e.x > this.arenaCenter.x ? e.y > this.arenaCenter.y ? this.arenaBottomLeft : this.arenaBottomRight : e.y > this.arenaCenter.y ? this.arenaTopLeft : this.arenaTopRight
}, p.farthestCorner = function(e) {
return e.x > this.arenaCenter.x ? e.y > this.arenaCenter.y ? this.arenaTopLeft : this.arenaBottomLeft : e.y > this.arenaCenter.y ? this.arenaTopRight : this.arenaBottomRight
}, p.gotoPos = function(e, t) {
var n = this.data[e.id], r;
n.maxDistanceBeforeIdle === 1 ? r = n.maxDistanceBeforeIdle : r = Math.min(n.maxDistanceBeforeIdle, this.dist(t, e.position));
var i, s = this.getBearing(e, t);
s < 90 || s > -90 ? i = 1 : (i = -1, s = this.shortest(s - 180));
var o;
s > 0 ? o = Math.min(n.maxTurnBeforeIdle, s) : o = Math.max(-n.maxTurnBeforeIdle, s), n.turnDir = o, n.dest = t, e.turn(o), e.move(r, i)
}, p.atDestination = function(e) {
var n = this.data[e.id];
return n.dest ? this.distSq(n.dest, e.position) < t : !0
}, p.rayray = function(t, n, r) {
n = this.sub(n, t), r = this.sub(r, t);
var i = this.dot(n, n) - 2 * this.dot(n, r) + this.dot(r, r), s = -2 * this.dot(n, n) + 2 * this.dot(n, r), o = this.dot(n, n) - e * e, u = s * s - 4 * i * o;
if (u >= 0) {
var a = (-s - Math.sqrt(u)) / (2 * i);
if (0 <= a && a <= 1)
return !0
}
return !1
}, p.aimAt = function(e, t) {
var n = this.shortest(this.getBearing(e, t) - e.cannonRelativeAngle + 90), r = this.sub(t, e.position), i = this.getSiblingData(e), s = !1;
i && !i.dead && this.rayray(i.robot.position, e.position, t) && (s = !0);
if (n === 0 && !s)
return !0;
var o = this.dist(t, e.position), u = 180 - this.toangle({x: 17,y: o}), a = n > 0 ? 2 : -2;
return e.rotateCannon(a), s || Math.abs(n - a) > Math.abs(u) ? !1 : !0
}, p.aimAtTarget = function(e, t) {
return this.aimAt(e, t.position)
}, p.fireAt = function(e, t) {
var n = this.data[e.id];
t.shotsToFire > 0 && this.aimAtTarget(e, t) && (e.fire(), t.shotsToFire--)
}, p.initData = function(e) {
var t = this.data[e.id];
return t || (t = {}, this.data[e.id] = t, t.isClone = !!e.parentId, t.isClone && (this.getSiblingData(e).cloneId = e.id), t.lastAngle = e.angle, t.lastTurn = 0, t.maxTurnBeforeIdle = 2, t.maxDistanceBeforeIdle = 19, t.robot = e), t
}, p.getSiblingData = function(e) {
return e.parentId ? this.data[e.parentId] : this.data[this.data[e.id].cloneId]
}, p.onIdle = function(n) {
var r = n.robot, i = this.initData(r);
i.robot = r, r.parentId || this.time++;
var s = this.data.enemy || this.data.enemyClone;
if (s) {
r.parentId || (s.timeSinceAquisition++, s.timeUntilCollision--);
if (s.life <= 0)
this.data.enemyClone = null;
else if (s.shotsToFire <= 0)
s.timeSinceAquisition > this.baseScanWaitTime && (i.isClone ? this.aimAt(r, this.target2 || {x: r.arenaWidth * Math.random(),y: r.arenaHeight * Math.random()}) : this.aimAt(r, this.target1 || {x: r.arenaWidth * Math.random(),y: r.arenaHeight * Math.random()}));
else {
if (r.gunCoolDownTime <= 0) {
this.fireAt(r, s);
return
}
s.timeSinceAquisition > e, s.timeSinceAquisition > this.baseScanWaitTime, this.aimAtTarget(r, s), s.timeUntilCollision <= 0 && this.gotoPos(r, this.adjacentCorner(s.position))
}
}
if (r.availableClones) {
r.clone();
return
}
if (i.dest && !this.atDestination(r)) {
var o = this.getSiblingData(r);
if (o && !o.dead) {
var u = o.dest;
u && this.distSq(u, i.dest) < t && (this.distSq(r, i.dest) > this.distSq(o.robot, u) ? i.dest = this.farthestCorner(u) : o.dest = this.farthestCorner(i.dest))
}
this.gotoPos(r, i.dest);
if (!s) {
var a = i.turnDir || i.isClone ? 1 : -1;
r.rotateCannon(a)
} else
i.isClone ? this.aimAt(r, this.target2 || {x: r.arenaWidth * Math.random(),y: r.arenaHeight * Math.random()}) : this.aimAt(r, this.target1 || {x: r.arenaWidth * Math.random(),y: r.arenaHeight * Math.random()});
return
}
this.atDestination(r) && this.gotoPos(r, this.adjacentCorner(r.position))
}, p.friendOrFoe = function(e, t) {
var n = this.initData(e);
return t.parentId == e.id ? 1 : t.id == e.parentId ? 1 : this.aquireTarget(e, t)
}, p.aquireTarget = function(e, t) {
var r = this.initData(e);
if (t.life === 0)
return 0;
var s = e.position;
return t.shotsToFire = Math.ceil(t.life / n), t.timeUntilCollision = this.dist(s, t.position) / i, t.timeSinceAquisition = 0, t.predictions = [], this.data.enemy && t.id === this.data.enemy.id || this.data.enemyClone && t.id === this.data.enemyClone.id, t.parentId ? (this.data.enemyClone = t, -1) : (this.data.enemy = t, -1)
}, p.onScannedRobot = function(e) {
var t = e.robot, n = e.scannedRobot, r = this.initData(t), i;
if (this.friendOrFoe(t, n) < 0) {
t.stop();
if (!this.atDestination(t))
return;
var s = this.data.enemy || this.data.enemyClone;
r.dest = s.position, this.fireAt(t, s);
var o = this.forangle(s.angle);
this.target1 = this.sub(s.position, this.mult(o, 50)), this.target2 = this.sub(s.position, this.mult(o, -50))
} else {
var u = this.shortest(this.getBearing(t, n.position) - t.cannonRelativeAngle + 90), a;
if (u === 0)
a = 17;
else {
var f = this.dist(n.position, t.position);
a = 180 - this.toangle({x: 17,y: f})
}
var l = a > 0 ? 1 : -1;
t.rotateCannon(l)
}
}, p.onRobotCollision = function(e) {
var t = e.robot, n = e.collidedRobot, r = this.initData(t);
if (this.friendOrFoe(t, n) < 0) {
t.stop();
var i = this.data.enemy || this.data.enemyClone;
this.fireAt(t, i);
if (!i.parentId) {
var s = this.sub(i.position, t.position);
this.target1 = this.sub(i.position, this.mult(s, 50)), this.target2 = this.sub(i.position, this.mult(s, -50))
}
} else {
var o = this.add(t.position, this.sub(t.position, n.position));
r.dest = o
}
}, p.onHitByBullet = function(e) {
var t = e.robot, n = this.initData(t);
if (t.life === 0 && t.parentId) {
n.dest = null, n.dead = !0;
return
}
var r = this.shortest(t.angle - e.bearing), i = this.forangle(r), s = this.getSiblingData(t);
if (s && !s.dead) {
var o = this.toangle(this.sub(s.robot.position, t.position));
console.log("bullet @ " + r, "sib @ " + o, this.tostr(s.robot.position), this.tostr(i)), Math.abs(r - o) > 30 && (this.target1 = this.sub(t.position, this.mult(i, 50)), this.target2 = this.sub(t.position, this.mult(i, t.arenaWidth)))
}
var u = this.data.enemy || this.data.enemyClone;
if (!u || u.timeSinceAquisition > this.baseScanWaitTime) {
var a = this.mult(this.perp(i), 100), f = this.mult(this.rperp(i), 100);
this.dist(a, this.arenaCenter) < this.dist(f, this.arenaCenter) ? this.gotoPos(t, this.add(t.position, a)) : this.gotoPos(t, this.add(t.position, f))
}
}, p.onWallCollision = function(e) {
var t = e.robot, n = this.initData(t);
if (n.dest) {
var r = this.getBearing(t, n.dest);
t.turn(r), n.turnDir = r
}
n.dest = this.arenaCenter
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment