Bot for Spacewar PPCG KotH I wrote a bot for a Programming Puzzles &amp; Code Gold King of the Hill type of challenge called "Spacewar!". The challenge was written by @El'endiaStarman. The bot is called "Spy". 

The controller is hosted here, so take a look for the feel. The API is a bit long, so here's a link.

The bot's logic:


  It runs away from the other bot with a 70% chance of firing a missile and hyperspaces when it's close to the sun. 


It's not online yet at a seperate bot; so you can copy-paste the code here into the KotH controller's text area at the bottom to test it out. 

I sorta just monkey-patched this bot together without an IDE, so the code isn't that great. Seriously, there's even an extra function I didn't use.

The code

function Spy_setup(team) {
  // Typical setup. Nothing to see here. ;)
  var botVars = {};
  botVars["color"] = team;
  return botVars;
}


function Spy_getActions(gameInfo, botVars) {
    var actions = [];
    var us, them, red = {
            rotation: gameInfo.red_rot,
            x: gameInfo.red_x,
            y: gameInfo.red_y,
            alive: gameInfo.blue_alive
        },
        blue = {
            rotation: gameInfo.blue_rot,
            x: gameInfo.blue_x,
            y: gameInfo.blue_y,
            alive: gameInfo.blue_alive
        };
    if (botVars.color == "red") {
        us = red;
        them = blue;
    } else if (botVars.color == "blue") {
        us = blue;
        them = red;
    }

    function distance(x1, y1, x2, y2) {
        return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
    }

    // Get our ship's position
    var rotation, x, y, opponentAlive;
    if (botVars.color == "red") {
        rotation = gameInfo.red_rot;
        x = gameInfo.red_x;
        y = gameInfo.red_y;
        opponentAlive = gameInfo.blue_alive;
    } else if (botVars.color == "blue") {
        rotation = gameInfo.blue_rot;
        x = gameInfo.blue_x;
        y = gameInfo.blue_y;
        opponentAlive = gameInfo.red_alive;
    }

    // Calculate our rotation compared to the sun in degrees
    var sunX = gameInfo.sun_x,
        sunY = gameInfo.sun_y,
        angle = Math.atan2(sunY - y, sunX - x) * 180 / Math.PI,
        rotationToSun = (rotation - angle + 360) % 360;

    // Check if we need to hyperspace to avoid the sun
    var rX = x - sunX,
        rY = y - sunY,
        distanceFromSun = Math.sqrt(rX * rX + rY * rY) - gameInfo.sun_r;
    if (distanceFromSun &lt; 30) {
        actions.push("hyperspace");
        console.log("Command Module is Hyperspacing.")
    }
    if (gameInfo[botVars["color"] + "_alive"]) {
        var angle = Math.degrees(Math.atan2(them.y - us.y, them.x - us.x)),
            rotationToOpponent = (us.rotation - angle + 360) % 360;
        if (rotationToOpponent &gt; 90 &amp;&amp; rotationToOpponent &lt; 270) {
            actions.push("turn right");
        } else {
            actions.push("turn left");
        };
        actions.push("fire engine");
        if (Math.random() &gt; 0.3) {
            actions.push("fire missile")
        }
    }
}
Bugs

var us, them, red = {
        rotation: gameInfo.red_rot,
        x: gameInfo.red_x,
        y: gameInfo.red_y,
        alive: gameInfo.blue_alive
    },
    blue = {
        rotation: gameInfo.blue_rot,
        x: gameInfo.blue_x,
        y: gameInfo.blue_y,
        alive: gameInfo.blue_alive
    };


Red and blue are using the same alive variable.

Also...

if (distanceFromSun &lt; 30) {
    actions.push("hyperspace");
    console.log("Command Module is Hyperspacing.")
}
if (gameInfo[botVars["color"] + "_alive"]) {


I don't think dead ships are supposed to hyperspace.

Licensing

When you use code from StackExchange, like from this answer to the PPCG challenge, you should at the very least add a comment referencing the original source. 

Duplication

Without looking at the code in detail, I spot this bit of duplication:

var rotation, x, y, opponentAlive;
if (botVars.color == "red") {
    rotation = gameInfo.red_rot;
    x = gameInfo.red_x;
    y = gameInfo.red_y;
    opponentAlive = gameInfo.blue_alive;
} else if (botVars.color == "blue") {
    rotation = gameInfo.blue_rot;
    x = gameInfo.blue_x;
    y = gameInfo.blue_y;
    opponentAlive = gameInfo.red_alive;
}




if (gameInfo[botVars["color"] + "_alive"]) {


You should pick one style and stick with it. I think you could get rid of a lot of the duplication by using the second style:

var rotation, x, y, opponentAlive;
rotation = gameInfo[botVars.color + "_rot"];
x = gameInfo[botVars.color + "_x"];
y = gameInfo[botVars.color + "_y"];


Leaves us with the opponentAlive variable, though.

For that, I'd just go with a function getOppositeColor: 

function getOppositeColor(ownColor){
    return ownColor === "blue" ? "red" : "blue";
}


And then we can get opponentAlive via

opponentAlive = gameInfo[getOppositeColor(botVars.color) + "_alive"];




Other weird things in your code are that you explicitly declare a distance function... and then you don't use it. You make objects for red and blue, but you don't use them and then extract values from gameInfo a second time...

You should get the variables once. Then use them. Make a single flow like that.

var actions = [];
var us, them, red = {
        rotation: gameInfo.red_rot,
        x: gameInfo.red_x,
        y: gameInfo.red_y,
        alive: gameInfo.red_alive
    },
    blue = {
        rotation: gameInfo.blue_rot,
        x: gameInfo.blue_x,
        y: gameInfo.blue_y,
        alive: gameInfo.blue_alive
    };
if (botVars.color == "red") {
    us = red;
    them = blue;
} else if (botVars.color == "blue") {
    us = blue;
    them = red;
}


This part, in that regard, is perfectly fine.

var rotation, x, y, opponentAlive;
if (botVars.color == "red") {
    rotation = gameInfo.red_rot;
    x = gameInfo.red_x;
    y = gameInfo.red_y;
    opponentAlive = gameInfo.blue_alive;
} else if (botVars.color == "blue") {
    rotation = gameInfo.blue_rot;
    x = gameInfo.blue_x;
    y = gameInfo.blue_y;
    opponentAlive = gameInfo.red_alive;
}


This entire part can go. It's not needed. You already have all of these variables as us.rotation, us.x, us.y, and them.alive.



    if (rotationToOpponent &gt; 90 &amp;&amp; rotationToOpponent &lt; 270) {
        actions.push("turn right");
    } else {
        actions.push("turn left");
    };


Also, you don't need a semicolon to end this if-statement here.