Instantly share code, notes, and snippets.
Last active
August 29, 2015 14:01
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save diginc/ad29b017b2246d3d30c7 to your computer and use it in GitHub Desktop.
[SAI] Nav System
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
// Custom functions list: | |
// Also see var Robot for variables that tie into some of these custom functions: | |
/* | |
Robot.prototype.gridSetup = function(ev) // Ran once | |
Robot.prototype.updateCurrentCoords = function(ev) // Ran every idle | |
Robot.prototype.navigation = function(ev) { | |
Robot.prototype.navigateCorner = function(ev) { | |
Robot.prototype.navigateWall = function(ev) { | |
Robot.prototype.navigateOpenArea = function(ev) { | |
Robot.prototype.postScanned = function(ev) { | |
Robot.prototype.postHit = function(ev) { | |
Robot.prototype.postBotCollision = function(ev) { | |
Robot.prototype.postWallCollision = function(ev) { | |
// Helpers | |
Robot.prototype.isInCorner = function( x, y ) { | |
Robot.prototype.isAlongWall = function( x, y ) { | |
Robot.prototype.getWallName = function( x, y ) { | |
Robot.prototype.getClosestRightAngle = function( bearing ) { | |
Robot.prototype.idleLogging = function(ev) { | |
*/ | |
var Robot = function(robot) { | |
this.runOnce = false; | |
this.x = 0; | |
this.y = 0; | |
// slow down there idleLogging() | |
this.logCounter = 0; | |
this.logIdleEveryXLoops = 6; | |
this.logNavigation = false; | |
this.moveDirection = 1; | |
this.cannonDirection = -1; | |
// Core function flags to trigger behavior change until you say to stop | |
// rather than when the listen event function is done running | |
this.hit = 0; | |
this.scannedEnemy = 0; | |
this.botCollision = 0; | |
this.wallCollision = 0; | |
// function variables | |
this.wallName = null; | |
}; | |
Robot.prototype.gridSetup = function(ev) { | |
var r = ev.robot; | |
r.log("Setting up the grid..."); | |
this.yGridSize = r.arenaHeight/this.yGridSections; | |
this.y_grid = new Array(); | |
for (var y=0 ; y <= this.yGridSections; y++) { | |
this.y_grid[y] = this.yGridSize * (y+1); | |
r.log("Y" + y +": "+ this.y_grid[y]); | |
} | |
this.xGridSize = r.arenaWidth/this.xGridSections; | |
this.x_grid = new Array(); | |
for (var x=0 ; x <= this.xGridSections; x++) { | |
this.x_grid[x] = this.xGridSize * (x+1); | |
r.log("X" + x +": "+ this.x_grid[x]); | |
} | |
this.avgSectionSize = (this.xGridSize + this.yGridSize) / 2; | |
}; | |
Robot.prototype.updateCurrentCoords = function(ev) { | |
var r = ev.robot; | |
for ( var x = 0; x < this.x_grid.length ; x++) { | |
if (r.position.x <= this.x_grid[x]) { | |
this.x = x; | |
break; | |
} | |
} | |
for ( var y = 0; y < this.y_grid.length ; y++) { | |
if (r.position.y <= this.y_grid[y]) { | |
this.y = y; | |
break; | |
} | |
} | |
}; | |
Robot.prototype.onIdle = function(ev) { | |
var r = ev.robot; | |
if (this.runOnce == false) { | |
this.xGridSections = 8; | |
this.yGridSections = Math.round( (this.xGridSections * r.arenaHeight) / r.arenaWidth) ; | |
this.gridSetup(ev); | |
r.log("Start Position") | |
r.rotateCannon(-90); | |
this.runOnce = true; | |
} | |
// Keep the cannon pointed inward by reversing direction once parallel to wall | |
// does not always work, sometimes turrent gets stuck reversing direction repeatedly | |
if(r.cannonRelativeAngle < 270) { | |
this.reverseCannon(); | |
//r.rotateCannon( (270 - r.cannonRelativeAngle) * this.cannonDirection ); | |
} | |
if( r.cannonRelativeAngle > 90) { | |
this.reverseCannon(); | |
//r.rotateCannon( (r.cannonRelativeAngle - 90) * this.cannonDirection ); | |
} | |
//r.ignore(Robot.prototype.onScannedRobot); | |
this.idleLogging(ev); | |
this.updateCurrentCoords(ev); | |
if (this.hit == 1) { this.postHit(ev); } | |
else | |
if (this.scannedEnemy == 1) { this.postScanned(ev); } | |
else | |
if (this.botCollision == 1) { this.postBotCollision(ev); } | |
else | |
if (this.wallCollision == 1) { this.postWallCollision(ev); } | |
else { | |
this.navigation(ev); | |
} | |
}; | |
Robot.prototype.navigation = function(ev) { | |
var r = ev.robot; | |
var logNavigation = this.logNavigation; | |
this.wallName = this.getWallName(this.x, this.y); | |
//uncomment to slow bot down! | |
//r.rotateCannon(15); r.rotateCannon(-15); | |
if( this.isInCorner(this.x, this.y) ) { | |
if(logNavigation != false) { r.log("navigateCorner!"); } | |
this.navigateCorner(ev); | |
} | |
else if ( this.isAlongWall(this.x, this.y) ) { | |
if(logNavigation != false) { r.log("navigateWall!"); } | |
this.navigateWall(ev); | |
} | |
else { | |
if(logNavigation != false) { r.log("navigateOpenArea!"); } | |
this.navigateOpenArea(ev); | |
} | |
}; | |
// Core Nav functions | |
Robot.prototype.navigateCorner = function(ev) { | |
var r = ev.robot; | |
for( var i=1; i <= 10 ; i++) { | |
r.turn(9 * (-1 * this.moveDirection)); | |
r.move(this.avgSectionSize/16, this.moveDirection); | |
} | |
r.move(50, this.moveDirection); | |
}; | |
Robot.prototype.navigateWall = function(ev) { | |
var r = ev.robot; | |
this.turnParallelToWall(ev); | |
r.move(this.avgSectionSize/5, this.moveDirection); | |
r.rotateCannon(10 * this.cannonDirection); | |
}; | |
Robot.prototype.navigateOpenArea = function(ev) { | |
var r = ev.robot; | |
r.move(3, this.direction); | |
r.turn(-1 * this.moveDirection); | |
r.rotateCannon(1 * this.cannonDirection); | |
}; | |
Robot.prototype.turnParallelToWall = function(ev) { | |
var r = ev.robot; | |
var parallelAngle; | |
var parallelAngleCorrection; | |
switch ( this.getWallName( this.x, this.y ) ) { | |
case "S": parallelAngle = 90; break; | |
case "E": parallelAngle = 0; break; | |
case "N": parallelAngle = 270; break; | |
case "W": parallelAngle = 180; break; | |
} | |
if ( ! this.isRightAngle(r.angle) ) { | |
r.log("Correcting to a parallelAngle angle "+parallelAngle+" from "+ r.angle); | |
if (r.angle > parallelAngle) { | |
parallelAngleCorrection = r.angle - parallelAngle; | |
r.log("Correction = "+ r.angle +" - "+ parallelAngle + " = " + parallelAngleCorrection) | |
} else { | |
parallelAngleCorrection = parallelAngle - r.angle; | |
r.log("Correction = "+ r.angle +" - "+ parallelAngle + " = " + parallelAngleCorrection) | |
} | |
//r.turn( parallelAngleCorrection ); | |
this.absoluteTurn( ev, parallelAngleCorrection ) | |
} | |
}; | |
// Default available events + post event custom functions | |
Robot.prototype.onScannedRobot = function(ev) { | |
var r = ev.robot; | |
var scanned = ev.scannedRobot; | |
this.enemyAngle = ev.cannonRelativeAngle; | |
if(scanned.id !== r.parentId && scanned.parentId !== r.id) { | |
this.scannedEnemy = 1; | |
//r.fire(); | |
} | |
}; | |
Robot.prototype.postScanned = function(ev) { | |
var r = ev.robot; | |
this.cannonDirectionReversed = (this.cannonDirection * -1); | |
r.rotateCannon(7 * this.cannonDirectionReversed); | |
this.scannedEnemy = 0; | |
this.reverseCannon(); | |
}; | |
Robot.prototype.onHitByBullet = function(ev) { | |
var r = ev.robot; | |
this.hit++; | |
r.log("Hit: " + this.hit); | |
}; | |
Robot.prototype.postHit = function(ev) { | |
var r = ev.robot; | |
this.hit = 0; | |
}; | |
Robot.prototype.onRobotCollision = function(ev) { | |
var r = ev.robot; | |
this.botCollision++; | |
r.disappear(); | |
//r.back(2); | |
//r.turn(9 * this.moveDirection); | |
this.moveDirection = this.moveDirection * -1; | |
}; | |
Robot.prototype.postBotCollision = function(ev) { | |
var r = ev.robot; | |
this.botCollision = 0; | |
}; | |
Robot.prototype.onWallCollision = function(ev) { | |
var r = ev.robot; | |
this.wallCollision++; | |
// Calculate the exact amount to turn parallel to the wall | |
r.back(2); | |
r.turn(-9 * this.moveDirection); | |
}; | |
Robot.prototype.postWallCollision = function(ev) { | |
var r = ev.robot; | |
this.wallCollision = 0; | |
}; | |
// Other helper functions | |
Robot.prototype.isInCorner = function( x, y ) { | |
if ( x == 0 && y == 0 | |
|| x == 0 && y == (this.yGridSections - 1) | |
|| x == (this.xGridSections - 1) && y == 0 | |
|| x == (this.xGridSections - 1) && y == (this.yGridSections - 1) | |
) { | |
return true; | |
} | |
return false; | |
}; | |
Robot.prototype.isAlongWall = function( x, y ) { | |
if ( x == 0 | |
|| y == 0 | |
|| x == (this.xGridSections - 1) | |
|| y == (this.yGridSections - 1) | |
) { | |
return true; | |
} | |
return false; | |
}; | |
Robot.prototype.getWallName = function( x, y ) { | |
if ( x == 0 && y == 0 ) | |
{ return "NW"; } | |
if ( x == 0 && y == (this.yGridSections - 1) ) | |
{ return "SW"; } | |
if ( x == (this.xGridSections - 1) && y == 0 ) | |
{ return "NE"; } | |
if ( x == (this.xGridSections - 1) && y == (this.yGridSections - 1) ) | |
{ return "SE"; } | |
if ( x == 0 ) | |
{ return "W"; } | |
if ( y == 0 ) | |
{ return "N"; } | |
if ( x == (this.xGridSections - 1) ) | |
{ return "E"; } | |
if ( y == (this.yGridSections - 1) ) | |
{ return "S"; } | |
return "Mid"; | |
}; | |
Robot.prototype.getClosestRightAngle = function( angle ) { | |
// Front of tank = 0 | |
if (angle < 45 || angle > 315) { return 0; } | |
if (angle > 45 && angle < 135) { return 90; } | |
if (angle > 135 && angle < 225) { return 180; } | |
if (angle > 225 && angle < 315) { return 270; } | |
return 0; | |
}; | |
Robot.prototype.isRightAngle = function( angle ) { | |
// Front of tank = 0 | |
switch (angle) { | |
case 0: return true; | |
case 90: return true; | |
case 180: return true; | |
case 270: return true; | |
} | |
return false; | |
}; | |
Robot.prototype.radian = function( angle ) { | |
if (angle < 0) { | |
return Math.absolute(angle) | |
} | |
if (angle > 360) { | |
var multiplier = angle % 360 | |
return angle - 360 * multiplier; | |
} | |
}; | |
Robot.prototype.absoluteTurn = function( ev, angle ) { | |
var r = ev.robot; | |
var angleDiff = (r.bearing > angle ? r.bearing - angle : angle - r.bearing); | |
var turnDegrees = 0; | |
if (r.bearing > angle) { | |
if(angleDiff > 180) { | |
r.log('aTurn case1'); | |
turnDegrees = -1 * (angle - 180); | |
} else { | |
r.log('aTurn case2'); | |
turnDegrees = angle; | |
} | |
} else { | |
if(angleDiff > 180) { | |
r.log('aTurn case3'); | |
turnDegrees = (angle - 180); | |
} else { | |
r.log('aTurn case4'); | |
turnDegrees = -1 * angle; // works for S but not N? | |
} | |
} | |
r.log("turnDegrees: "+turnDegrees); | |
r.turn(turnDegrees); | |
// Examples of bad turns go below | |
/* | |
NORTH WALL: | |
ROBOT player: Correction = 40 - 270 = 23 | |
ROBOT player: aTurn case4 | |
ROBOT player: turnDegrees: -230 | |
*/ | |
}; | |
Robot.prototype.idleLogging = function(ev) { | |
var r = ev.robot; | |
this.logCounter++; | |
// Idle repeats/ticks very fast, slow down! | |
if ( this.logCounter == this.logIdleEveryXLoops ) { | |
r.log( "ID="+ r.id | |
+ " X=" + this.x + "/" + this.xGridSections | |
+ " Y=" + this.y + "/" + this.yGridSections | |
+ " ("+ this.wallName + ")" | |
+ " angle=" + r.angle | |
+ " rightAngle=" + this.getClosestRightAngle(r.angle) | |
+ " CannonAbs=" + r.cannonAbsoluteAngle | |
+ " cannonRel=" + r.cannonRelativeAngle | |
); | |
this.logCounter = 0; | |
} | |
}; | |
Robot.prototype.reverseCannon = function() { | |
this.cannonDirection = this.cannonDirection * -1; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment