Created
April 1, 2016 16:23
-
-
Save rfotino/39b104fd61bc6c4d8cc24282c1f10444 to your computer and use it in GitHub Desktop.
A solution for the Obstacle level on Spaceship.codes.
This file contains 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
/** | |
* Turns your ship to the given angle. Returns true when it is within | |
* epsilon radians of the target angle and the angular velocity is zero. | |
* | |
* @param {Number} angle | |
* @param {Number} [epsilon] Defaults to 0.001 | |
* @return {Boolean} True if the operation is complete | |
*/ | |
var servo = function(angle, epsilon) { | |
// Set a default value for epsilon | |
if (!epsilon) { | |
epsilon = 0.001; | |
} | |
// Get the maximum angular acceleration | |
var prevTurn = turn(); | |
turn(1); | |
var maxAngularAccel = accel().angular; | |
turn(prevTurn); | |
// Get the smallest angle we need to move from our current angle | |
// to reach the target angle | |
var diff = (pos().angular - angle) % (Math.PI * 2); | |
if (Math.abs(diff - (Math.PI * 2)) < Math.abs(diff)) { | |
diff -= Math.PI * 2; | |
} else if (Math.abs(diff + (Math.PI * 2)) < Math.abs(diff)) { | |
diff += Math.PI * 2; | |
} | |
// Get the angular distance needed to travel and the angular | |
// distance needed to decelerate from the current angular velocity | |
var dist = Math.abs(diff); | |
var decelDist = Math.pow(vel().angular, 2) / maxAngularAccel; | |
// If we are within epsilon of the target angle and we no longer | |
// have any angular velocity, we are done | |
if (Math.max(dist, Math.abs(vel().angular)) < epsilon) { | |
turn(0); | |
return true; | |
} | |
// Calculate and set the new acceleration; if we don't have enough | |
// distance to decelerate, slow down - otherwise speed up | |
var a = 0; | |
if (dist < decelDist) { | |
a = -vel().angular; | |
} else { | |
a = vel().angular - diff; | |
} | |
turn(a / maxAngularAccel); | |
return false; | |
} | |
// State machine to go up, right, and then into the target | |
var state = load('state', 0); | |
if (0 === state) { | |
if (servo(Math.PI / 2)) { | |
state++; | |
} | |
} else if (state < 6) { | |
thrust(1); | |
state++; | |
} else if (6 === state) { | |
thrust(0); | |
if (servo(-Math.PI / 2)) { | |
state++; | |
} | |
} else if (state < 12) { | |
thrust(1); | |
state++; | |
} else if (12 === state) { | |
thrust(0); | |
if (servo(0)) { | |
state++; | |
} | |
} else if (state < 22) { | |
thrust(1); | |
state++; | |
} else if (22 === state) { | |
thrust(0); | |
if (servo(Math.PI)) { | |
state++; | |
} | |
} else if (state < 32) { | |
thrust(1); | |
state++; | |
} else { | |
thrust(0); | |
var target = radar('target')[0]; | |
if (servo(Math.atan2(target.pos.y - pos().y, | |
target.pos.x - pos().x))) { | |
thrust(1); | |
} | |
} | |
store('state', state); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment