Stack Exchange Network

Stack Exchange network consists of 175 Q&A communities including Stack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.

Visit Stack Exchange
39 added 132 characters in body
source | link
//console.log(JSON.stringify(view))
var TRAIL = 6;
var SPAWN = 3;
var IDLE = 4;
var FOOD_THRESHOLD = 150;
var SPAWN_MIN = 3;
var HIGHWAY_COLORS = [7,6,4,2,3];
var HIGHWAY_THRESHOLD = 70;
var ret = {cell:4};
if(isOnHighway()) {
    var cont = true;
    //== Make best guess to if in a glider formation ==//
    if(view[4].ant.type == 5) {
        if((findWorker(1) >= 0 && findWorker(4) >= 0) || view[4].ant.food < HIGHWAY_THRESHOLD) {
            cont = false;
        }
    }
    else if(view[4].ant.type == 4) {
        if(findWorker(1) >= 0 && findWorker(5) >= 0) {
            cont = false;
        }
    }
    else if(view[4].ant.type == 3) {
        if(findWorker(2) >= 0 && findWorker(5) >= 0) {
            cont = false;
        }
    }
    else if(view[4].ant.type == 2) {
        if(findWorker(5) < 0) {
            var pos3 = findWorker(3);
            if(pos3 >= 0 && view[pos3].ant.food == 0) {
                cont = false;
            }
        }
        else if(findWorker(3) >= 0 || (findWorker(1) >= 0 && view[findWorker(5)].color == SPAWN))
            cont = false;
    }
    else if(view[4].ant.type == 1) {
        if(findWorker(5) < 0) {
            var pos4 = findWorker(4);
            if(pos4 >= 0 && view[pos4].ant.food == 0) {
                cont = false;
            }
        }
        else if(!isHighwayCenter())
            cont = false;
    }
    if(findWorker(5) >= 0) {
        for(var i=0;i<9;i++) {
            if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                if(view[i].ant.food > 10 || view[i].ant.food == 0)
                    cont = true;
                else
                    cont = false;
            }
        }
    }
    //== End guesswork ==//
    if(cont) {
        ret = highwayRobbery();
        if(view[4].ant.type == 1) {
            //try to repair
            var curIndex = HIGHWAY_COLORS.indexOf(view[4].color);
            var prvCol = HIGHWAY_COLORS[(curIndex+1)%HIGHWAY_COLORS.length];
            var nxtCol1 = HIGHWAY_COLORS[(curIndex+HIGHWAY_COLORS.length-1)%HIGHWAY_COLORS.length];
            var nxtCol2 = HIGHWAY_COLORS[(curIndex+HIGHWAY_COLORS.length-2)%HIGHWAY_COLORS.length];
            var nxtCol3 = HIGHWAY_COLORS[(curIndex+HIGHWAY_COLORS.length-3)%HIGHWAY_COLORS.length];
            var prevAt = -1;
            for(var i=0;i<9;i++) {
                if(i%2 == 1 && view[i].color == prvCol && view[deRotate(i,1)].color == nxtCol1 && view[deRotate(i,-1)].color == nxtCol1) prevAt = i;
            }
            if(prevAt >= 0) {
                // yep, brute force it. Because I'm lazy.
                var goNxt = 8-prevAt;
                if(view[deRotate(goNxt,1)].color == nxtCol3 && view[deRotate(goNxt,-1)].color == prvCol) ret = {cell:goNxt};
                else if(view[deRotate(goNxt,1)].color == prvCol && view[deRotate(goNxt,-1)].color == nxtCol3) ret = {cell:goNxt};
                else if(view[goNxt].color != nxtCol1) ret = {cell:goNxt,color:nxtCol1};
                else if(view[deRotate(goNxt,2)].color != nxtCol2) ret = {cell:deRotate(goNxt,2),color:nxtCol2};
                else if(view[deRotate(goNxt,-2)].color != nxtCol2) ret = {cell:deRotate(goNxt,-2),color:nxtCol2};
                else if(view[deRotate(goNxt,1)].color != nxtCol3) ret = {cell:deRotate(goNxt,1),color:nxtCol3};
                else if(view[deRotate(goNxt,-1)].color != nxtCol3) ret = {cell:deRotate(goNxt,-1),color:nxtCol3};
                else ret = {cell:goNxt};
                ret = sanityCheck(ret);
                return ret;
            }
        }
        if(view[4].ant.type == 5 && isHighwayCenter()) {
            if(ret.cell >= 0) {
                ret = {cell:8-ret.cell};
                if(view[4].color == SPAWN && (view[4].ant.food > 90 || view[4].ant.food % 7 == 0) && getHighestWorker() == 0 && (view[4].ant.food < 140 || view[4].ant.food % 9 == 0) && view[0].color == 2 && view[4].ant.food > 50 && view[4].ant.food < 200) {
            //fine
                    if(view[4].ant.food % 10 < 5)
                        ret = {cell:deRotate(ret.cell,3),type:3};
                }
                if(view[ret.cell].ant != null && !view[ret.cell].ant.friend && view[ret.cell].ant.food == 0 && view[4].ant.food > 0) {
                    if(view[deRotate(ret.cell,1)].ant == null)
                        ret = {cell:deRotate(ret.cell,1),type:3};
                    if(view[deRotate(ret.cell,-1)].ant == null)
                        ret = {cell:deRotate(ret.cell,1),type:3};
                }
            }
            for(var i=0;i<9;i++) {
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                    ret = {cell:8-i};
                }
            }
        }
        if(ret.cell >= 0) {
            for(var i=0;i<9;i++) {
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                    var rr = basicHighwayMove();
                    if(rr.cell >= 0 && view[4].ant.type != 5)
                        ret = {cell:deRotate(rr.cell,-2)};
                }
            }
            if(view[ret.cell].ant != null) {
                var n = HIGHWAY_COLORS.indexOf(view[4].color) + 1;
                var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
                for(var i=0;i<9;i++) {
                    if(view[i].color == nextMove) {
                        if(view[i].ant == null) {
                            ret = {cell:i};
                            break;
                        }
                    }
                }
                if(view[4].ant.type == 5) ret = {cell:8-ret.cell};
            }
        }
        if(view[4].ant.type == 5) {
            var foodedEnemy = false;
            for(var i=0;i<9;i++) {
                if(getNumWorkers(3) >= 2) break;
                if(i != 4 && view[i].ant != null && view[i].ant.type == 5 && view[i].ant.food > 25) {
                    if(view[deRotate(i,1)].ant == null) {
                        ret = {cell:deRotate(i,1),type:3};
                    }
                    else if(view[deRotate(i,-1)].ant == null) {
                        ret = {cell:deRotate(i,-1),type:3};
                    }
                    else if(i%2 == 1 && view[deRotate(i,2)].ant == null) {
                        ret = {cell:deRotate(i,2),type:3};
                    }
                    else if(i%2 == 1 && view[deRotate(i,-2)].ant == null) {
                        ret = {cell:deRotate(i,-2),type:3};
                    }
                }
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 3 && view[8-i].ant == null) {
                    if(i == ret.cell) {
                        ret = {cell:deRotate(i,1)}
                    }
                    else {
                        return {cell:8-i};
                    }
                }
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.food == 0) {
                    foodedEnemy = true;
                }
            }
        }
        var numAnts = 0;
        for(var i=0;i<9;i++) {
            if(view[i].ant != null)
                numAnts++;
        }
        if(numAnts > 2 && sanityCheck(ret).cell == 4) {
            ret = {cell:findOpenSpace(0,1)};
        }
        if(view[4].ant.type == 3) {
            if(getNumWorkers(5) > 0) {
                for(var i=0;i<9;i++) {
                    if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                        ret = {cell:4};
                    }
                }
            }
        }
        if(view[4].ant.type == 4 && getNumWorkers(1) && isHighwayCenter()) {
            var workerPos = findWorker(1);
            for(var i=0;i<9;i++) {
                if(!areAdjacent(i,workerPos)) ret = {cell:i};
            }
        }
        if(ret.cell == -1) {
            if(isHighwayCenter()) {
                for(var i=0;i<9;i++) {
                    var p1 = deRotate(i,3);
                    var p2 = deRotate(i,-3);
                    if(view[i].color == view[p1].color && view[i].color == view[p2].color) {
                        ret = {cell:8-i};
                    }
                }
                if(view[4].ant.type == 1 || view[4].ant.type == 5) {
                    ret = {cell:8-ret.cell};
                }
            }
        }
        if(ret.cell >= 0)
            return sanityCheck(ret);
    }
}

switch(view[4].ant.type) {
    case 5:
        ret = doQueen();
        break;
    case 1:
    case 2:
        ret = doSweep();
        break;
    case 3:
    case 4:
        ret = doGuide();
        break;
    default:
        break;
}
//basic sanity check
ret = sanityCheck(ret);
return ret;

function sanityCheck(ret) {
    if(!ret || ret.cell < 0 || ret.cell > 8) {
        return {cell:4};
    }
    if(ret.color) {
        return ret;
    }
    if((ret.cell != 4 && view[ret.cell].ant != null) || (view[ret.cell].food > 0 && (view[4].ant.food > 0 && view[4].ant.type < 5))) {
        return {cell:4};
    }
    if(ret.type && (view[ret.cell].ant != null || view[ret.cell].food > 0 || view[4].ant.food == 0 || view[4].ant.type < 5)) {
        return {cell:4};
    }
    return ret;
}

function doQueen() {
    if((view[4].ant.food == SPAWN_MIN || (view[4].ant.food >= SPAWN_MIN && view[4].ant.food < FOOD_THRESHOLD && (view[4].ant.food % 3 == 1 || isOnHighway()))) && getHighestWorker() <= 1 ) {
        //prep for first ant
        var s0 = view[0].ant;
        var s1 = view[1].ant;
        var s2 = view[2].ant;
        var s3 = view[3].ant;
        var s5 = view[5].ant;
        var s6 = view[6].ant;
        var s7 = view[7].ant;
        var s8 = view[8].ant;
        var nullCount = 0 + (s0 == null?1:0) + (s1 == null?1:0) + (s2 == null?1:0) + (s3 == null?1:0) + (s5 == null?1:0) + (s6 == null?1:0) + (s7 == null?1:0) + (s8 == null?1:0);
        var nullCount2 = 0 + (s0 == null || s0.friend?1:0) + (s1 == null || s1.friend?1:0) + (s2 == null || s2.friend?1:0) + (s3 == null || s3.friend?1:0) + (s5 == null || s5.friend?1:0) + (s6 == null || s6.friend?1:0) + (s7 == null || s7.friend?1:0) + (s8 == null || s8.friend?1:0);
        if(nullCount >= 7 && nullCount2 >= 8 && view[1].food == 0 && view[3].food == 0 && view[5].food == 0 && view[7].food == 0) {
            var high = getHighestWorker();
            if (high <= 1 && view[4].color != SPAWN && !isOnHighway()) {
                // 50% chance of delaying the respawn by 1 additional move away from where we exploded
                // reduces the chance of a second, immediate explosion
                if(findFirstTrail() < 2 && view[4].ant.food > SPAWN_MIN+1) return foreverAlone();
                var pos1 = findWorker(1);
                if(findFirstTrail() < 2 && view[4].ant.food > SPAWN_MIN+1 && pos1 < 0) return foreverAlone();
                if(pos1 >= 0) {
                    var space = deRotate(pos1,2);
                    if(view[space].ant != null) return {cell:findOpenSpace(0,1)};
                }
                return {cell:4,color:SPAWN};
            }
            //spawn first ant
            else if(view[4].color == SPAWN) {
                var pos1 = findWorker(1);
                if(pos1 < 0)  {
                    pos1 = findFirstTrail();
                    if(pos1 % 2 == 0) pos1 = deRotate(pos1,1);
                    else pos1 = deRotate(pos1,4);
                }
                var space = findOpenSpace(pos1,2);
                var high = getHighestWorker();
                if(space < 0) return {cell:4,color:TRAIL}
                if(high == 0) { //no workers
                    return {cell:space,type:1};
                }
                else if(high < 4) { //1 worker of type:high
                    return {cell:space,type:high+1};
                }
                else { //1 worker of type 4
                    //we have all workers, skip!
                }
            }
        }
        else {
            return foreverAlone();
        }
    }
    else if(view[4].ant.food == 1 && getHighestWorker() == 0 ) {
        var space = findOpenSpace(1,2);
        return {cell:space,type:1};
    }
    else if(view[4].ant.food >= 1 && getHighestWorker() < 4 && findWorker(1) >= 0) {
        //spawn remaining ants
        if(view[4].color == SPAWN && !isHighwayCenter()) {
            var pos1 = findWorker(getHighestWorker());
            var space = deRotate(pos1,2);
            var high = getHighestWorker();
            if(space < 0 || view[space].ant != null) return {cell:findOpenSpace(0,1)};
            if(high == 0) { //no workers
                return {cell:space,type:1};
            }
            else if(high < 4) { //1 worker of type:high
                return {cell:space,type:high+1};
            }
            else { //1 worker of type 4
                //we have all workers, skip!
            }
        }
    }
    if(view[4].color == SPAWN && getNumWorkers(3) == 1 && getNumWorkers(4) == 1) {
        var one = getNumWorkers(1);
        var two = getNumWorkers(2);
        if((one ^ two) == 1 && (findWorker(1) % 2 == 0 || findWorker(2) % 2 == 0))
            return {cell:4,color:1};
    }
    if(getNumWorkers(1) == 0 && getNumWorkers(2) == 0) {
        if(getNumWorkers(4) == 1 && getNumWorkers(3) == 0) {
            var pos4 = findWorker(4);
            if(view[deRotate(pos4,1)].ant == null && view[deRotate(pos4,2)].ant == null && findWorker(4) % 2 == 1) {
                //finish rotate with only one glider arm
                return {cell:4};
            }
        }
        return foreverAlone();
    }
    else if(getNumWorkers(1) >= 1 && getNumWorkers(2) >= 1 && getNumWorkers(3) >= 1 && getNumWorkers(4) >= 1) {
        if(view[4].color != 2 && findWorker(1)%2 == 1 && findWorker(2)%2 == 1) {
            return {cell:4,color:TRAIL};
        }
        //move diagonally
        var pos = findWorker(4);
        pos = deRotate(pos,1);
        var checkpos = view[deRotate(pos,4)];
        if(checkpos.ant != null && checkpos.ant.friend) {
            if(checkpos.ant.type == 2)
                return {cell:4};
            if(checkpos.ant.type == 1)
                return {cell:4};
        }
        if(view[pos].ant) return {cell:4,color:1};
        return {cell:pos};
    }
    else {
        var pos = findWorker(4);
        if(pos < 0) {
            //if gliding along with only a buddy
            pos = findWorker(1);
            if(pos >= 0 && view[deRotate(pos,2)].food > 0 && view[deRotate(pos,1)].food == 0) {
                return {cell:4};
            }
        }
        if(pos < 0) {
            var s1 = view[1].ant;
            var s3 = view[3].ant;
            var s5 = view[5].ant;
            var s7 = view[7].ant;
            //return {cell:999}
            if(s1 == null) {
                if(s3 == null) {
                    return {cell:0};
                }
                if(s5 == null) {
                    return {cell:2};
                }
            }
            if(s7 == null) {
                if(s3 == null) {
                    return {cell:6};
                }
                if(s5 == null) {
                    return {cell:8};
                }
            }
            return {cell:4};
        }
        pos = deRotate(pos,1);
        var checkpos1 = view[pos];
        for(var i=0;i<9;i++) {
            if(i != 4 && view[i].ant != null && view[i].ant.type == 5 && view[i].ant.food > 2) {
                if(i%2==0) {
                    if(view[deRotate(i,1)].ant == null) return {cell:deRotate(i,1),type:3};
                    if(view[deRotate(i,-1)].ant == null) return {cell:deRotate(i,-1),type:3};
                }
                else {
                    if(view[deRotate(i,1)].ant == null) return {cell:deRotate(i,1),type:3};
                    if(view[deRotate(i,-1)].ant == null) return {cell:deRotate(i,-1),type:3};
                    if(view[deRotate(i,2)].ant == null) return {cell:deRotate(i,2),type:3};
                    if(view[deRotate(i,-2)].ant == null) return {cell:deRotate(i,-2),type:3};
                }
                return {cell:4};
            }
        }
        if(checkpos1.ant != null && view[deRotate(pos,1)].ant != null && !view[deRotate(pos,1)].ant.friend) {
            return foreverAlone();
        }

        var checkpos2 = view[deRotate(pos,4)];
        var checkpos3 = view[deRotate(checkpos,1)];
        if(checkpos1.ant != null && checkpos1.ant.friend && checkpos1.ant.type == 1 && checkpos2.ant != null && checkpos2.ant.friend && checkpos2.ant.type == 2 && checkpos3.ant != null && checkpos3.ant.friend && checkpos3.ant.type == 3) {
            //move out of spawn orientation
            return {cell:4};
        }
        if(view[pos].ant != null) {
            if(checkpos2.ant == null && checkpos1.ant == null) {
                return {cell:8-pos};
            }
            if(!view[pos].ant.friend) {
                return foreverAlone();
            }
            if(view[4].color == TRAIL) return foreverAlone();
            return {cell:4,color:TRAIL};
        }
        if(8 - findWorker(3) == findWorker(4)) {
            //finish rotate to the right
            return {cell:4};
        }
        if((view[deRotate(pos,1)].food > 0 || view[deRotate(pos,2)].food > 0) && view[deRotate(pos,1)].ant == null && view[4].color != TRAIL) {
            if(findWorker(1) < 0 || view[deRotate(findWorker(1),1)].food == 0) {
                return {cell:4};
            }
        }
        return {cell:pos};
    }
    return {cell:100+view[4].ant.type}; //oh god
}

//guides sit next to the queen
function doGuide() {
    var queenPos = findWorker(5);
    var ty = view[4].ant.type==3?2:1;
    var dir = view[4].ant.type==3?1:-1;
    if(queenPos >= 0 && queenPos%2 == 1 && view[queenPos].color == SPAWN) {
        if(view[deRotate(queenPos,dir*2)].ant == null) {
            return {cell:4};
        }
    }
    if(queenPos < 0 || findWorker(ty) < 0) {
        if(findWorker(ty) >= 0 && view[0].color != IDLE) return {cell:0,color:IDLE}
        return firebreak();
    }
    var checkpos = view[deRotate(queenPos,-2*dir)];
    if(view[4].ant.type==4 && checkpos.ant != null && checkpos.ant.friend && checkpos.ant.type == 1) {
        //attempt rotate
        return {cell:deRotate(queenPos,-dir)};
    }
    checkpos = view[deRotate(queenPos,4)];
    if(checkpos.ant != null && checkpos.ant.friend && checkpos.ant.type == ty) {
        //attempt rotate
        if(getNumWorkers(ty) == 1) {
            return {cell:4};
        }
    }
    var pos = deRotate(queenPos,dir);
    if(pos >= 0 && view[4].ant.type==3 && findWorker(4) < 0) {
        //wait for rotate
        if(view[4].color == TRAIL) {
            return {cell:4};
        }
    }
    if(pos >= 0 && findWorker(2) >= 0 && view[deRotate(findWorker(2),1)].ant != null) {
        //rotate
        return {cell:4,color:TRAIL};
    }
    if(pos < 0) pos = 4;
    else if(view[pos].ant != null) return {cell:deRotate(queenPos,4)};
    if(pos == 4 && view[queenPos].color == TRAIL) return {cell:queenPos,color:1};
    return {cell:pos};
}

//sweepers sit next to guides
function doSweep() {
    var queenPos = findWorker(5);
    var followType = view[4].ant.type==1?4:3;
    var pos = findWorker(followType);
    if(pos % 2 == 0 && getNumWorkers(followType) > 1) {
        //if there's more than one worker #4, we want to use the best one
        for(var i=pos+1;i<9;i++) {
            if(i != 4 && view[i].ant != null) {
                if(view[i].ant.friend && view[i].ant.type == followType) {
                    pos = i;
                    break;
                }
            }
        }
    }
    if(queenPos >= 0 && queenPos%2 == 1 && view[queenPos].color == SPAWN) {
        var p = findWorker(view[4].ant.type);
        if(p >= 0 && (deRotate(p,1) == queenPos || deRotate(p,-1) == queenPos)) {
            return {cell:8-queenPos};
        }
        return {cell:4};
    }
    if(queenPos >= 0 && pos < 0) {
        //if Worker #1 is the only ant besides the queen:
        //TODO
    //good
        if(view[queenPos].ant.food <= SPAWN_MIN || !(view[queenPos].ant.food < FOOD_THRESHOLD && view[queenPos].ant.food % 3 == 1 && !isOnHighway())) {
            var go = deRotate(queenPos,-1);
            if((view[deRotate(queenPos,-2)].food > 0 || view[deRotate(queenPos,-3)].food > 0 || (queenPos %2 == 1 && view[deRotate(queenPos,-3)].food > 0)) && view[go].food == 0) {
                go = deRotate(queenPos,2);
                //return {cell:4};
            }
            return {cell:go};
        }
        else if(view[queenPos].ant.food < FOOD_THRESHOLD && view[queenPos].ant.food % 3 == 1) {
            return {cell:4};
        }
    }
    if(queenPos >= 0) {
        var dir = view[4].ant.type==1?1:-1;
        //var checkpos = view[deRotate(pos,-dir)];
        var moveTo = deRotate(pos,dir);
        if(moveTo >= 0 && view[moveTo].ant != null && view[moveTo].ant.friend && view[moveTo].ant.type == 5) {
            moveTo = deRotate(pos,-dir);
        }
        if(view[4].ant.type == 2 && findWorker(1) < 0 && view[queenPos].color != TRAIL) {
            moveTo = 4;
        }
        return {cell:moveTo};
    }
    else {
        if(pos < 0) return {cell:4}; //firebreak();
        var dir = view[4].ant.type==1?-1:1;
        var moveTo = deRotate(pos,dir);
        if(view[4].ant.food > 0 && view[moveTo].food > 0) {
            //have food, attempt to give to queen
            moveTo = deRotate(pos,-dir);
        }
        if(view[4].ant.type==1 && pos >= 0 && (view[deRotate(pos,dir*2)].food > 0 || view[deRotate(pos,dir*3)].food > 0)) {
            //attempt rotate
            moveTo = deRotate(pos,-dir);
        }
        if(view[4].ant.type==2 && pos >= 0 && (view[deRotate(pos,dir*2)].food > 0 || view[deRotate(pos,dir*3)].food > 0)) {
            //attempt rotate
            moveTo = deRotate(pos,-dir);
        }
        if(moveTo >= 0 && view[moveTo].ant != null && view[moveTo].ant.type == 5) {
            if(view[moveTo].ant.friend)
                moveTo = deRotate(moveTo,dir*2);
            else
                moveTo = deRotate(pos,-dir);
        }
        return {cell:moveTo};
    }
    return {cell:100+view[4].ant.type};//oh god
}

function foreverAlone() {
    var s0 = view[0].ant;
    var s1 = view[1].ant;
    var s2 = view[2].ant;
    var s3 = view[3].ant;
    var s5 = view[5].ant;
    var s6 = view[6].ant;
    var s7 = view[7].ant;
    var s8 = view[8].ant;
    //good
    if(!(s0 == null && s1 == null && s2 == null && s3 == null && s5 == null && s6 == null && s7 == null && s8 == null) && view[4].color == TRAIL) {
        if (view[0].color == TRAIL && !view[8].ant && view[8].color != TRAIL) return {cell: 8};
        else if (view[2].color == TRAIL && !view[6].ant && view[6].color != TRAIL) return {cell: 6};
        else if (view[6].color == TRAIL && !view[2].ant && view[2].color != TRAIL) return {cell: 2};
        else if (view[8].color == TRAIL && !view[0].ant && view[0].color != TRAIL) return {cell: 0};
        //Can't find color, or path is blocked? try diagonals regardless of color
        else if (!view[0].ant) return {cell: 0};
        else if (!view[2].ant) return {cell: 2};
        else if (!view[6].ant) return {cell: 6};
        else if (!view[8].ant) return {cell: 8};
        //Everything else failed? Stay put.
        else return {cell: 4};
    }
    //good
    if (view[4].color == TRAIL) { //If on colored square, try to move
        var totGreen = 0;
        for (var i = 0; i < 9; i++) { //Look for food
            if (view[i].food) {
                return {cell: i};
            }
            if(view[i].color == TRAIL) totGreen++;
        }
        var ret = getTrailMove();
        if(view[deRotate(ret.cell,1)].color == TRAIL && totGreen <= 4) ret.cell = deRotate(ret.cell,-1);
        else if(view[deRotate(ret.cell,-1)].color == TRAIL && totGreen <= 4) ret.cell = deRotate(ret.cell,1);
        return ret;
    } else { //If not on colored square, look for food, or set current color to 2.
        for (var i = 0; i < 9; i++) { //Look for enemies
            if (i != 4 && view[i].ant != null && !view[i].ant.friend) {
                var r = findOpenSpace(8-i,1);
                if(view[r].color == TRAIL) r = deRotate(r,1);
                return {cell: r};
            }
        }
        return {cell: 4, color:TRAIL};
    }
}

function getTrailMove() {
    if (view[0].color == TRAIL && !view[8].ant && view[8].color != TRAIL) return {cell: 8};
    else if (view[2].color == TRAIL && !view[6].ant && view[6].color != TRAIL) return {cell: 6};
    else if (view[6].color == TRAIL && !view[2].ant && view[2].color != TRAIL) return {cell: 2};
    else if (view[8].color == TRAIL && !view[0].ant && view[0].color != TRAIL) return {cell: 0};
    //Can't find color, or path is blocked? try diagonals regardless of color
    else if (!view[0].ant) return {cell: 0};
    else if (!view[2].ant) return {cell: 2};
    else if (!view[6].ant) return {cell: 6};
    else if (!view[8].ant) return {cell: 8};
    //Everything else failed? Stay put.
    else return {cell: 4};
}

function firebreak() {
    var ret = -1;
    if(findWorker(5) >= 0) {
        return {cell:8-findWorker(5)};
    }
    if(view[4].color != 5) {
        var myView = [0,0,0,0,0,0,0,0,0]
        for(var i=0; i < 9; i++) {
            myView[i] = view[i].color
            if(view[4].ant.food > 0 && view[i].food > 0) {
                myView[i] = 8;
            }
            if(view[i].ant != null && !view[i].ant.friend) return {cell:findOpenSpace(deRotate(i,2),1)};
        }
        var ret = clearAhead(myView);
        if(ret == null)
            return {cell:4,color:5};
        else {
            if(!(view[ret.cell].ant != null && view[ret.cell].ant.friend == false) && (view[4].ant.food == 0 || view[ret.cell].food == 0))
                return ret;
            return {cell:4,color:5};
        }
    }
    if(view[1].color == 5 && view[3].color == 5 && view[5].color == 5 && view[7].color == 5) {
        if(view[0].color != 8) return {cell:0,color:8};
        if(view[1].color != 8) return {cell:1,color:8};
    }
    if(view[1].color == 5 && view[7].color != 5) ret = {cell:7};
    if(view[3].color == 5 && view[5].color != 5) ret = {cell:5};
    if(view[5].color == 5 && view[3].color != 5) ret = {cell:3};
    if(view[7].color == 5 && view[1].color != 5) ret = {cell:1};
    if(view[1].color != 5 && view[3].color != 5 && view[5].color != 5 && view[7].color != 5) ret = {cell:1};
    if((view[1].color == 5 && view[7].color == 5) || (view[3].color == 5 && view[5].color == 5)) ret = {cell:0};
    var loop = 0;
    while(ret.cell >= 0 && ((view[ret.cell].food > 0 && view[4].ant.food > 0) || view[ret.cell].ant != null) && loop < 9) {
        loop++;
        ret.cell = (ret.cell + 2) % 9;
    }
    if(loop < 9 && ret.cell >= 0) return ret;
    return {cell:4};
}

//7,6,4,2,3
//O7,D2

function highwayRobbery() {
    var move = basicHighwayMove();
    if(move.cell >= 0 && view[move.cell].ant != null) {
        var n = HIGHWAY_COLORS.indexOf(view[4].color) + (view[4].color%2==0?1:HIGHWAY_COLORS.length);
        var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
        for(var i=0;i<9;i++) {
            if(view[i].color == nextMove) {
                return {cell:i};
            }
        }
    }
    return move;
}

function basicHighwayMove() {
    var isQueen = view[4].ant.type == 5;
    if(isHighwayCenter()) {
        var n = HIGHWAY_COLORS.indexOf(view[4].color) + 1;
        var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
        for(var i=0;i<9;i++) {
            if(view[i].color == nextMove) {
                if(view[i].ant == null)
                    return {cell:i};
                else {
                    return {cell:deRotate(i,1)};
                }
            }
        }
    }
    else {
        if(view[4].color == 7) {
            //move diagonal to yellow (2)
            for(var i=0;i<9;i++) {
                if(i != 4 && i % 2 == 0 && view[i].color == 2) {
                    return {cell:i};
                }
            }
        }
        else {
            //move orthogonal to blue (7)
            for(var i=0;i<9;i++) {
                if(i % 2 == 1 && view[i].color == 7) {
                    //try ortho yellow first
                    for(var j=0;j<9;j++) {
                        if(j % 2 == 1 && view[j].color == 2 && areAdjacent(i,j))
                            return {cell:j};
                    }
                    return {cell:i};
                }
            }
            //if orthogonal blue doens't exist...
            //...try diagonal to magenta
            for(var i=0;i<9;i++) {
                if(i != 4 && i % 2 == 0 && view[i].color == 3) {
                    return {cell:i};
                }
            }
            if(view[4].color != 2) {
                //...try diagonal blue
                for(var i=0;i<9;i++) {
                    if(i % 2 == 0 && view[i].color == 7)
                        return {cell:i};
                }
            }
            //...and orthogonal yellow
            for(var i=0;i<9;i++) {
                if(i % 2 == 1 && view[i].color == 2)
                    return {cell:i};
            }
        }
        var n = HIGHWAY_COLORS.indexOf(view[4].color) + 1;
        var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
        for(var i=0;i<9;i++) {
            if(view[i].color == nextMove) {
                return {cell:i};
            }
        }
    }
    return {cell:-1};
}

function isOnHighway() {
    var match = 0;
    var nxt = HIGHWAY_COLORS[(HIGHWAY_COLORS.indexOf(view[4].color)+1) % HIGHWAY_COLORS.length];//4
    var prv = HIGHWAY_COLORS[(HIGHWAY_COLORS.indexOf(view[4].color)+HIGHWAY_COLORS.length-2) % HIGHWAY_COLORS.length];//6
    for(var i=0;i<9;i++) {
        if(HIGHWAY_COLORS.indexOf(view[i].color) >=0 && (i == 4 || view[i].color != view[4].color))
            match++;
    }
    if(match >= 5) {
        //7,6,4,2,3


        if((view[1].color == nxt && view[7].color == prv)||(view[1].color == prv && view[7].color == nxt) || 
            (view[3].color == nxt && view[5].color == prv)||(view[3].color == prv && view[5].color == nxt)) {
            return true;
        }
        if((view[1].color == view[8].color && (view[1].color == nxt || view[1].color == prv))||(view[1].color == view[6].color && (view[1].color == nxt || view[1].color == prv)) || 
            (view[3].color == view[2].color && (view[3].color == nxt || view[3].color == prv))||(view[3].color == view[8].color && (view[3].color == nxt || view[3].color == prv))) {
            return true;
        }
        if((view[0].color == view[7].color && (view[0].color == nxt || view[0].color == prv))||(view[2].color == view[7].color && (view[2].color == nxt || view[2].color == prv)) || 
            (view[0].color == view[5].color && (view[0].color == nxt || view[0].color == prv))||(view[6].color == view[5].color && (view[6].color == nxt || view[6].color == prv))) {
            return true;
        }
        if(isHighwayCenter()) {
            return true;
        }
    }
    return false;
}

function isHighwayCenter() {
    if(HIGHWAY_COLORS.indexOf(view[4].color) >=0 && (((view[0].color != view[8].color || view[2].color != view[6].color) && view[4].ant.type == 1) || (view[0].color != view[8].color && view[2].color != view[6].color))){
        var m1 = view[1].color == view[7].color;
        var m2 = view[2].color == view[8].color;
        var m3 = view[0].color == view[6].color;
        var m4 = view[0].color != 1 && view[2].color != 1;
        if((m1?1:0)+(m2?1:0)+(m3?1:0) >= 2 && m4) {
            if(view[3].color != view[5].color && ((view[2].color != view[5].color && view[8].color != view[5].color) || view[4].ant.type == 1) && ((view[3].color != view[0].color && view[3].color != view[6].color) || view[4].ant.type == 1)) {
                return true;
            }
        }
        m1 = view[3].color == view[5].color;
        m2 = view[0].color == view[2].color;
        m3 = view[6].color == view[8].color;
        m4 = view[0].color != 1 && view[6].color != 1;
    //good
        if((m1?1:0)+(m2?1:0)+(m3?1:0) >= 2 && m4) {
            m1 = view[1].color != view[7].color;
            m2 = (view[0].color != view[1].color && view[1].color != view[2].color);
            m3 = (view[6].color != view[7].color && view[7].color != view[8].color);
            if(m1 && m2 && m3) {
                return true;
            }
            if(view[4].ant.type == 1 && ((m1?1:0)+(m2?1:0)+(m3?1:0)) >= 2) {
                return true;
            }
        }
    }
    return false;
}

function deRotateSide(m, amt) {
    return deRotate(m,amt*2);
}

/**Positive amount is clockwise**/
function deRotate(m, amt) {
    var rotationsCW = [1,2,5,8,7,6,3,0];
    var rotationsCCW = [3,6,7,8,5,2,1,0];
    if(m == 4 || m < 0 || m > 8 || amt == 0) return m;
    if(amt > 0)
        return rotationsCW[(rotationsCW.indexOf(m)+amt)%8];
    amt = -amt;
    return rotationsCCW[(rotationsCCW.indexOf(m)+amt)%8];
}

function areAdjacent(A, B) {
    if(A == 4 || B == 4 || A == B) return true;
    if(A % 2 == 0 && B % 2 == 0) return false;
    if(A % 2 == 1 && B % 2 == 0) return areAdjacent(B,A);
    if(A % 2 == 1 && B % 2 == 1) return !(8-A == B || 8-B == A);
    if(A == 0 && (B == 1 || B == 3)) return true;
    if(A == 2 && (B == 1 || B == 5)) return true;
    if(A == 6 && (B == 3 || B == 7)) return true;
    if(A == 8 && (B == 5 || B == 7)) return true;
    return false;
}

function findFirstTrail() {
    var pos = 0;
    var b = 0;
    while(view[pos].color != TRAIL && b < 8) {
        pos=deRotate(pos,1);
        b++;
    }
    return pos;
}

function clearAhead(sides) {
    var c=0;
    for(var i=0;i<9;i++) {
        if(view[i].color == 5) c++;
        if(view[i].color == 5 && i%2 == 0) c+=10;
    }
    if(c == 2) {
        if(view[0].color == 5 || view[2].color == 5 || view[6].color == 5 || view[8].color == 5) {
            return {cell:4,color:5};
        }
        if(view[0].ant == null)
            return {cell:0};
        if(view[2].ant == null)
            return {cell:2};
        if(view[6].ant == null)
            return {cell:6};
        if(view[8].ant == null)
            return {cell:8};
    }
    c = 0;
    sides[4] = 0;
    var toMatch =[{state:[1,1,1,
                          2,0,2,
                          0,1,0]},
                 {state:[0,2,1,
                         1,0,1,
                         0,2,1]},
                 {state:[0,1,0,
                         2,0,2,
                         1,1,1]},
                 {state:[1,2,0,
                         1,0,1,
                         1,2,0]}];
    for(var m=0;m<4;m++) {
        var score=0;
        for(var j=0;j<9;j++) {
            if(j!=4) {
                if(sides[j] == 5 && toMatch[m].state[j] == 1) {
                    score++;
                }
                if(sides[j] != 5 && (toMatch[m].state[j] == 0 || toMatch[m].state[j] == 2)) {
                    score++;
                }
                if(sides[j] == 5 && toMatch[m].state[j] == 2) {
                    score--;
                }
            }
        }
        if(score >= 6) {
            var clearOrder=[1,0,2];
            for(var r=0;r<clearOrder.length;r++) {
                var s = deRotateSide(clearOrder[r],m);
                if(view[s].color == 5) {
                    if(view[s].ant == null)
                        return {cell:s,color:8};
                    else
                        return {cell:4};
                }
            }
        }
    }
    return null;
}

function findOpenSpace(pos, dir) {
    if(pos > 8 || pos < 0) return pos;
    var b = 0;
    while(view[pos].ant != null && b < 8) {
        pos=deRotate(pos,dir);
        b++;
    }
    return pos;
}

function getHighestWorker() {
    var r=0;
    for(var i=0;i<9;i++) {
        if(i != 4 && view[i].ant != null) {
            if(view[i].ant.friend && view[i].ant.type > r) r = view[i].ant.type;
        }
    }
    return r;
}

function getNumWorkers(type) {
    var r=0;
    for(var i=0;i<9;i++) {
        if(i != 4 && view[i].ant != null) {
            if(view[i].ant.friend && view[i].ant.type == type) r++;
        }
    }
    return r;
}

function findWorker(type) {
    for(var i=0;i<9;i++) {
        if(i != 4 && view[i].ant != null) {
            if(view[i].ant.friend && view[i].ant.type == type) return i;
        }
    }
    return -1;
}

326%422% Complete
326%422% because the update was on 34/1622This joke has gone on too long

Update 4/21

Minor fixes.

var TRAIL = 6;
var SPAWN = 3;
var IDLE = 4;
var FOOD_THRESHOLD = 150;
var SPAWN_MIN = 3;
var HIGHWAY_COLORS = [7,6,4,2,3];
var HIGHWAY_THRESHOLD = 70;
var ret = {cell:4};
if(isOnHighway()) {
    var cont = true;
    //== Make best guess to if in a glider formation ==//
    if(view[4].ant.type == 5) {
        if((findWorker(1) >= 0 && findWorker(4) >= 0) || view[4].ant.food < HIGHWAY_THRESHOLD) {
            cont = false;
        }
    }
    else if(view[4].ant.type == 4) {
        if(findWorker(1) >= 0 && findWorker(5) >= 0) {
            cont = false;
        }
    }
    else if(view[4].ant.type == 3) {
        if(findWorker(2) >= 0 && findWorker(5) >= 0) {
            cont = false;
        }
    }
    else if(view[4].ant.type == 2) {
        if(findWorker(5) < 0) {
            var pos3 = findWorker(3);
            if(pos3 >= 0 && view[pos3].ant.food == 0) {
                cont = false;
            }
        }
        else if(findWorker(3) >= 0 || (findWorker(1) >= 0 && view[findWorker(5)].color == SPAWN))
            cont = false;
    }
    else if(view[4].ant.type == 1) {
        if(findWorker(5) < 0) {
            var pos4 = findWorker(4);
            if(pos4 >= 0 && view[pos4].ant.food == 0) {
                cont = false;
            }
        }
        else if(!isHighwayCenter())
            cont = false;
    }
    if(findWorker(5) >= 0) {
        for(var i=0;i<9;i++) {
            if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                if(view[i].ant.food > 10 || view[i].ant.food == 0)
                    cont = true;
                else
                    cont = false;
            }
        }
    }
    //== End guesswork ==//
    if(cont) {
        ret = highwayRobbery();
        if(view[4].ant.type == 1) {
            //try to repair
            var curIndex = HIGHWAY_COLORS.indexOf(view[4].color);
            var prvCol = HIGHWAY_COLORS[(curIndex+1)%HIGHWAY_COLORS.length];
            var nxtCol1 = HIGHWAY_COLORS[(curIndex+HIGHWAY_COLORS.length-1)%HIGHWAY_COLORS.length];
            var nxtCol2 = HIGHWAY_COLORS[(curIndex+HIGHWAY_COLORS.length-2)%HIGHWAY_COLORS.length];
            var nxtCol3 = HIGHWAY_COLORS[(curIndex+HIGHWAY_COLORS.length-3)%HIGHWAY_COLORS.length];
            var prevAt = -1;
            for(var i=0;i<9;i++) {
                if(i%2 == 1 && view[i].color == prvCol && view[deRotate(i,1)].color == nxtCol1 && view[deRotate(i,-1)].color == nxtCol1) prevAt = i;
            }
            if(prevAt >= 0) {
                // yep, brute force it. Because I'm lazy.
                var goNxt = 8-prevAt;
                if(view[deRotate(goNxt,1)].color == nxtCol3 && view[deRotate(goNxt,-1)].color == prvCol) ret = {cell:goNxt};
                else if(view[deRotate(goNxt,1)].color == prvCol && view[deRotate(goNxt,-1)].color == nxtCol3) ret = {cell:goNxt};
                else if(view[goNxt].color != nxtCol1) ret = {cell:goNxt,color:nxtCol1};
                else if(view[deRotate(goNxt,2)].color != nxtCol2) ret = {cell:deRotate(goNxt,2),color:nxtCol2};
                else if(view[deRotate(goNxt,-2)].color != nxtCol2) ret = {cell:deRotate(goNxt,-2),color:nxtCol2};
                else if(view[deRotate(goNxt,1)].color != nxtCol3) ret = {cell:deRotate(goNxt,1),color:nxtCol3};
                else if(view[deRotate(goNxt,-1)].color != nxtCol3) ret = {cell:deRotate(goNxt,-1),color:nxtCol3};
                else ret = {cell:goNxt};
                ret = sanityCheck(ret);
                return ret;
            }
        }
        if(view[4].ant.type == 5 && isHighwayCenter()) {
            if(ret.cell >= 0) {
                ret = {cell:8-ret.cell};
                if(view[4].color == SPAWN && (view[4].ant.food > 90 || view[4].ant.food % 7 == 0) && getHighestWorker() == 0 && (view[4].ant.food < 140 || view[4].ant.food % 9 == 0) && view[0].color == 2 && view[4].ant.food > 50 && view[4].ant.food < 200) {
            //fine
                    if(view[4].ant.food % 10 < 5)
                        ret = {cell:deRotate(ret.cell,3),type:3};
                }
                if(view[ret.cell].ant != null && !view[ret.cell].ant.friend && view[ret.cell].ant.food == 0 && view[4].ant.food > 0) {
                    if(view[deRotate(ret.cell,1)].ant == null)
                        ret = {cell:deRotate(ret.cell,1),type:3};
                    if(view[deRotate(ret.cell,-1)].ant == null)
                        ret = {cell:deRotate(ret.cell,1),type:3};
                }
            }
            for(var i=0;i<9;i++) {
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                    ret = {cell:8-i};
                }
            }
        }
        if(ret.cell >= 0) {
            for(var i=0;i<9;i++) {
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                    var rr = basicHighwayMove();
                    if(rr.cell >= 0 && view[4].ant.type != 5)
                        ret = {cell:deRotate(rr.cell,-2)};
                }
            }
            if(view[ret.cell].ant != null) {
                var n = HIGHWAY_COLORS.indexOf(view[4].color) + 1;
                var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
                for(var i=0;i<9;i++) {
                    if(view[i].color == nextMove) {
                        if(view[i].ant == null) {
                            ret = {cell:i};
                            break;
                        }
                    }
                }
                if(view[4].ant.type == 5) ret = {cell:8-ret.cell};
            }
        }
        if(view[4].ant.type == 5) {
            var foodedEnemy = false;
            for(var i=0;i<9;i++) {
                if(getNumWorkers(3) >= 2) break;
                if(i != 4 && view[i].ant != null && view[i].ant.type == 5 && view[i].ant.food > 25) {
                    if(view[deRotate(i,1)].ant == null) {
                        ret = {cell:deRotate(i,1),type:3};
                    }
                    else if(view[deRotate(i,-1)].ant == null) {
                        ret = {cell:deRotate(i,-1),type:3};
                    }
                    else if(i%2 == 1 && view[deRotate(i,2)].ant == null) {
                        ret = {cell:deRotate(i,2),type:3};
                    }
                    else if(i%2 == 1 && view[deRotate(i,-2)].ant == null) {
                        ret = {cell:deRotate(i,-2),type:3};
                    }
                }
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 3 && view[8-i].ant == null) {
                    if(i == ret.cell) {
                        ret = {cell:deRotate(i,1)}
                    }
                    else {
                        return {cell:8-i};
                    }
                }
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.food == 0) {
                    foodedEnemy = true;
                }
            }
        }
        var numAnts = 0;
        for(var i=0;i<9;i++) {
            if(view[i].ant != null)
                numAnts++;
        }
        if(numAnts > 2 && sanityCheck(ret).cell == 4) {
            ret = {cell:findOpenSpace(0,1)};
        }
        if(view[4].ant.type == 3) {
            if(getNumWorkers(5) > 0) {
                for(var i=0;i<9;i++) {
                    if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                        ret = {cell:4};
                    }
                }
            }
        }
        if(view[4].ant.type == 4 && getNumWorkers(1) && isHighwayCenter()) {
            var workerPos = findWorker(1);
            for(var i=0;i<9;i++) {
                if(!areAdjacent(i,workerPos)) ret = {cell:i};
            }
        }
        if(ret.cell == -1) {
            if(isHighwayCenter()) {
                for(var i=0;i<9;i++) {
                    var p1 = deRotate(i,3);
                    var p2 = deRotate(i,-3);
                    if(view[i].color == view[p1].color && view[i].color == view[p2].color) {
                        ret = {cell:8-i};
                    }
                }
                if(view[4].ant.type == 1 || view[4].ant.type == 5) {
                    ret = {cell:8-ret.cell};
                }
            }
        }
        if(ret.cell >= 0)
            return sanityCheck(ret);
    }
}

switch(view[4].ant.type) {
    case 5:
        ret = doQueen();
        break;
    case 1:
    case 2:
        ret = doSweep();
        break;
    case 3:
    case 4:
        ret = doGuide();
        break;
    default:
        break;
}
//basic sanity check
ret = sanityCheck(ret);
return ret;

function sanityCheck(ret) {
    if(!ret || ret.cell < 0 || ret.cell > 8) {
        return {cell:4};
    }
    if(ret.color) {
        return ret;
    }
    if((ret.cell != 4 && view[ret.cell].ant != null) || (view[ret.cell].food > 0 && (view[4].ant.food > 0 && view[4].ant.type < 5))) {
        return {cell:4};
    }
    if(ret.type && (view[ret.cell].ant != null || view[ret.cell].food > 0 || view[4].ant.food == 0 || view[4].ant.type < 5)) {
        return {cell:4};
    }
    return ret;
}

function doQueen() {
    if((view[4].ant.food == SPAWN_MIN || (view[4].ant.food >= SPAWN_MIN && view[4].ant.food < FOOD_THRESHOLD && (view[4].ant.food % 3 == 1 || isOnHighway()))) && getHighestWorker() <= 1 ) {
        //prep for first ant
        var s0 = view[0].ant;
        var s1 = view[1].ant;
        var s2 = view[2].ant;
        var s3 = view[3].ant;
        var s5 = view[5].ant;
        var s6 = view[6].ant;
        var s7 = view[7].ant;
        var s8 = view[8].ant;
        var nullCount = 0 + (s0 == null?1:0) + (s1 == null?1:0) + (s2 == null?1:0) + (s3 == null?1:0) + (s5 == null?1:0) + (s6 == null?1:0) + (s7 == null?1:0) + (s8 == null?1:0);
        var nullCount2 = 0 + (s0 == null || s0.friend?1:0) + (s1 == null || s1.friend?1:0) + (s2 == null || s2.friend?1:0) + (s3 == null || s3.friend?1:0) + (s5 == null || s5.friend?1:0) + (s6 == null || s6.friend?1:0) + (s7 == null || s7.friend?1:0) + (s8 == null || s8.friend?1:0);
        if(nullCount >= 7 && nullCount2 >= 8 && view[1].food == 0 && view[3].food == 0 && view[5].food == 0 && view[7].food == 0) {
            var high = getHighestWorker();
            if (high <= 1 && view[4].color != SPAWN && !isOnHighway()) {
                // 50% chance of delaying the respawn by 1 additional move away from where we exploded
                // reduces the chance of a second, immediate explosion
                if(findFirstTrail() < 2 && view[4].ant.food > SPAWN_MIN+1) return foreverAlone();
                var pos1 = findWorker(1);
                if(pos1 >= 0) {
                    var space = deRotate(pos1,2);
                    if(view[space].ant != null) return {cell:findOpenSpace(0,1)};
                }
                return {cell:4,color:SPAWN};
            }
            //spawn first ant
            else if(view[4].color == SPAWN) {
                var pos1 = findWorker(1);
                if(pos1 < 0)  {
                    pos1 = findFirstTrail();
                    if(pos1 % 2 == 0) pos1 = deRotate(pos1,1);
                    else pos1 = deRotate(pos1,4);
                }
                var space = findOpenSpace(pos1,2);
                var high = getHighestWorker();
                if(space < 0) return {cell:4,color:TRAIL}
                if(high == 0) { //no workers
                    return {cell:space,type:1};
                }
                else if(high < 4) { //1 worker of type:high
                    return {cell:space,type:high+1};
                }
                else { //1 worker of type 4
                    //we have all workers, skip!
                }
            }
        }
        else {
            return foreverAlone();
        }
    }
    else if(view[4].ant.food == 1 && getHighestWorker() == 0 ) {
        var space = findOpenSpace(1,2);
        return {cell:space,type:1};
    }
    else if(view[4].ant.food >= 1 && getHighestWorker() < 4 && findWorker(1) >= 0) {
        //spawn remaining ants
        if(view[4].color == SPAWN && !isHighwayCenter()) {
            var pos1 = findWorker(getHighestWorker());
            var space = deRotate(pos1,2);
            var high = getHighestWorker();
            if(space < 0 || view[space].ant != null) return {cell:findOpenSpace(0,1)};
            if(high == 0) { //no workers
                return {cell:space,type:1};
            }
            else if(high < 4) { //1 worker of type:high
                return {cell:space,type:high+1};
            }
            else { //1 worker of type 4
                //we have all workers, skip!
            }
        }
    }
    if(view[4].color == SPAWN && getNumWorkers(3) == 1 && getNumWorkers(4) == 1) {
        var one = getNumWorkers(1);
        var two = getNumWorkers(2);
        if((one ^ two) == 1 && (findWorker(1) % 2 == 0 || findWorker(2) % 2 == 0))
            return {cell:4,color:1};
    }
    if(getNumWorkers(1) == 0 && getNumWorkers(2) == 0) {
        if(getNumWorkers(4) == 1 && getNumWorkers(3) == 0) {
            var pos4 = findWorker(4);
            if(view[deRotate(pos4,1)].ant == null && view[deRotate(pos4,2)].ant == null && findWorker(4) % 2 == 1) {
                //finish rotate with only one glider arm
                return {cell:4};
            }
        }
        return foreverAlone();
    }
    else if(getNumWorkers(1) >= 1 && getNumWorkers(2) >= 1 && getNumWorkers(3) >= 1 && getNumWorkers(4) >= 1) {
        if(view[4].color != 2 && findWorker(1)%2 == 1 && findWorker(2)%2 == 1) {
            return {cell:4,color:TRAIL};
        }
        //move diagonally
        var pos = findWorker(4);
        pos = deRotate(pos,1);
        var checkpos = view[deRotate(pos,4)];
        if(checkpos.ant != null && checkpos.ant.friend) {
            if(checkpos.ant.type == 2)
                return {cell:4};
            if(checkpos.ant.type == 1)
                return {cell:4};
        }
        return {cell:pos};
    }
    else {
        var pos = findWorker(4);
        if(pos < 0) {
            //if gliding along with only a buddy
            pos = findWorker(1);
            if(pos >= 0 && view[deRotate(pos,2)].food > 0 && view[deRotate(pos,1)].food == 0) {
                return {cell:4};
            }
        }
        if(pos < 0) {
            var s1 = view[1].ant;
            var s3 = view[3].ant;
            var s5 = view[5].ant;
            var s7 = view[7].ant;
            //return {cell:999}
            if(s1 == null) {
                if(s3 == null) {
                    return {cell:0};
                }
                if(s5 == null) {
                    return {cell:2};
                }
            }
            if(s7 == null) {
                if(s3 == null) {
                    return {cell:6};
                }
                if(s5 == null) {
                    return {cell:8};
                }
            }
            return {cell:4};
        }
        pos = deRotate(pos,1);
        var checkpos1 = view[pos];
        for(var i=0;i<9;i++) {
            if(i != 4 && view[i].ant != null && view[i].ant.type == 5 && view[i].ant.food > 2) {
                if(i%2==0) {
                    if(view[deRotate(i,1)].ant == null) return {cell:deRotate(i,1),type:3};
                    if(view[deRotate(i,-1)].ant == null) return {cell:deRotate(i,-1),type:3};
                }
                else {
                    if(view[deRotate(i,1)].ant == null) return {cell:deRotate(i,1),type:3};
                    if(view[deRotate(i,-1)].ant == null) return {cell:deRotate(i,-1),type:3};
                    if(view[deRotate(i,2)].ant == null) return {cell:deRotate(i,2),type:3};
                    if(view[deRotate(i,-2)].ant == null) return {cell:deRotate(i,-2),type:3};
                }
                return {cell:4};
            }
        }
        if(checkpos1.ant != null && view[deRotate(pos,1)].ant != null && !view[deRotate(pos,1)].ant.friend) {
            return foreverAlone();
        }

        var checkpos2 = view[deRotate(pos,4)];
        var checkpos3 = view[deRotate(checkpos,1)];
        if(checkpos1.ant != null && checkpos1.ant.friend && checkpos1.ant.type == 1 && checkpos2.ant != null && checkpos2.ant.friend && checkpos2.ant.type == 2 && checkpos3.ant != null && checkpos3.ant.friend && checkpos3.ant.type == 3) {
            //move out of spawn orientation
            return {cell:4};
        }
        if(view[pos].ant != null) {
            if(checkpos2.ant == null && checkpos1.ant == null) {
                return {cell:8-pos};
            }
            if(!view[pos].ant.friend) {
                return foreverAlone();
            }
            if(view[4].color == TRAIL) return foreverAlone();
            return {cell:4,color:TRAIL};
        }
        if(8 - findWorker(3) == findWorker(4)) {
            //finish rotate to the right
            return {cell:4};
        }
        if((view[deRotate(pos,1)].food > 0 || view[deRotate(pos,2)].food > 0) && view[deRotate(pos,1)].ant == null && view[4].color != TRAIL) {
            if(findWorker(1) < 0 || view[deRotate(findWorker(1),1)].food == 0) {
                return {cell:4};
            }
        }
        return {cell:pos};
    }
    return {cell:100+view[4].ant.type}; //oh god
}

//guides sit next to the queen
function doGuide() {
    var queenPos = findWorker(5);
    var ty = view[4].ant.type==3?2:1;
    var dir = view[4].ant.type==3?1:-1;
    if(queenPos >= 0 && queenPos%2 == 1 && view[queenPos].color == SPAWN) {
        if(view[deRotate(queenPos,dir*2)].ant == null) {
            return {cell:4};
        }
    }
    if(queenPos < 0 || findWorker(ty) < 0) {
        if(findWorker(ty) >= 0 && view[0].color != IDLE) return {cell:0,color:IDLE}
        return firebreak();
    }
    var checkpos = view[deRotate(queenPos,-2*dir)];
    if(view[4].ant.type==4 && checkpos.ant != null && checkpos.ant.friend && checkpos.ant.type == 1) {
        //attempt rotate
        return {cell:deRotate(queenPos,-dir)};
    }
    checkpos = view[deRotate(queenPos,4)];
    if(checkpos.ant != null && checkpos.ant.friend && checkpos.ant.type == ty) {
        //attempt rotate
        if(getNumWorkers(ty) == 1) {
            return {cell:4};
        }
    }
    var pos = deRotate(queenPos,dir);
    if(pos >= 0 && view[4].ant.type==3 && findWorker(4) < 0) {
        //wait for rotate
        if(view[4].color == TRAIL) {
            return {cell:4};
        }
    }
    if(pos >= 0 && findWorker(2) >= 0 && view[deRotate(findWorker(2),1)].ant != null) {
        //rotate
        return {cell:4,color:TRAIL};
    }
    if(pos < 0) pos = 4;
    else if(view[pos].ant != null) return {cell:deRotate(queenPos,4)};
    if(pos == 4 && view[queenPos].color == TRAIL) return {cell:queenPos,color:1};
    return {cell:pos};
}

//sweepers sit next to guides
function doSweep() {
    var queenPos = findWorker(5);
    var followType = view[4].ant.type==1?4:3;
    var pos = findWorker(followType);
    if(pos % 2 == 0 && getNumWorkers(followType) > 1) {
        //if there's more than one worker #4, we want to use the best one
        for(var i=pos+1;i<9;i++) {
            if(i != 4 && view[i].ant != null) {
                if(view[i].ant.friend && view[i].ant.type == followType) {
                    pos = i;
                    break;
                }
            }
        }
    }
    if(queenPos >= 0 && queenPos%2 == 1 && view[queenPos].color == SPAWN) {
        var p = findWorker(view[4].ant.type);
        if(p >= 0 && (deRotate(p,1) == queenPos || deRotate(p,-1) == queenPos)) {
            return {cell:8-queenPos};
        }
        return {cell:4};
    }
    if(queenPos >= 0 && pos < 0) {
        //if Worker #1 is the only ant besides the queen:
        //TODO
    //good
        if(view[queenPos].ant.food <= SPAWN_MIN || !(view[queenPos].ant.food < FOOD_THRESHOLD && view[queenPos].ant.food % 3 == 1 && !isOnHighway())) {
            var go = deRotate(queenPos,-1);
            if((view[deRotate(queenPos,-2)].food > 0 || view[deRotate(queenPos,-3)].food > 0 || (queenPos %2 == 1 && view[deRotate(queenPos,-3)].food > 0)) && view[go].food == 0) {
                go = deRotate(queenPos,2);
                //return {cell:4};
            }
            return {cell:go};
        }
        else if(view[queenPos].ant.food < FOOD_THRESHOLD && view[queenPos].ant.food % 3 == 1) {
            return {cell:4};
        }
    }
    if(queenPos >= 0) {
        var dir = view[4].ant.type==1?1:-1;
        //var checkpos = view[deRotate(pos,-dir)];
        var moveTo = deRotate(pos,dir);
        if(moveTo >= 0 && view[moveTo].ant != null && view[moveTo].ant.friend && view[moveTo].ant.type == 5) {
            moveTo = deRotate(pos,-dir);
        }
        if(view[4].ant.type == 2 && findWorker(1) < 0 && view[queenPos].color != TRAIL) {
            moveTo = 4;
        }
        return {cell:moveTo};
    }
    else {
        if(pos < 0) return {cell:4}; //firebreak();
        var dir = view[4].ant.type==1?-1:1;
        var moveTo = deRotate(pos,dir);
        if(view[4].ant.food > 0 && view[moveTo].food > 0) {
            //have food, attempt to give to queen
            moveTo = deRotate(pos,-dir);
        }
        if(view[4].ant.type==1 && pos >= 0 && (view[deRotate(pos,dir*2)].food > 0 || view[deRotate(pos,dir*3)].food > 0)) {
            //attempt rotate
            moveTo = deRotate(pos,-dir);
        }
        if(view[4].ant.type==2 && pos >= 0 && (view[deRotate(pos,dir*2)].food > 0 || view[deRotate(pos,dir*3)].food > 0)) {
            //attempt rotate
            moveTo = deRotate(pos,-dir);
        }
        if(moveTo >= 0 && view[moveTo].ant != null && view[moveTo].ant.type == 5) {
            if(view[moveTo].ant.friend)
                moveTo = deRotate(moveTo,dir*2);
            else
                moveTo = deRotate(pos,-dir);
        }
        return {cell:moveTo};
    }
    return {cell:100+view[4].ant.type};//oh god
}

function foreverAlone() {
    var s0 = view[0].ant;
    var s1 = view[1].ant;
    var s2 = view[2].ant;
    var s3 = view[3].ant;
    var s5 = view[5].ant;
    var s6 = view[6].ant;
    var s7 = view[7].ant;
    var s8 = view[8].ant;
    //good
    if(!(s0 == null && s1 == null && s2 == null && s3 == null && s5 == null && s6 == null && s7 == null && s8 == null) && view[4].color == TRAIL) {
        if (view[0].color == TRAIL && !view[8].ant && view[8].color != TRAIL) return {cell: 8};
        else if (view[2].color == TRAIL && !view[6].ant && view[6].color != TRAIL) return {cell: 6};
        else if (view[6].color == TRAIL && !view[2].ant && view[2].color != TRAIL) return {cell: 2};
        else if (view[8].color == TRAIL && !view[0].ant && view[0].color != TRAIL) return {cell: 0};
        //Can't find color, or path is blocked? try diagonals regardless of color
        else if (!view[0].ant) return {cell: 0};
        else if (!view[2].ant) return {cell: 2};
        else if (!view[6].ant) return {cell: 6};
        else if (!view[8].ant) return {cell: 8};
        //Everything else failed? Stay put.
        else return {cell: 4};
    }
    //good
    if (view[4].color == TRAIL) { //If on colored square, try to move
        var totGreen = 0;
        for (var i = 0; i < 9; i++) { //Look for food
            if (view[i].food) {
                return {cell: i};
            }
            if(view[i].color == TRAIL) totGreen++;
        }
        var ret = getTrailMove();
        if(view[deRotate(ret.cell,1)].color == TRAIL && totGreen <= 4) ret.cell = deRotate(ret.cell,-1);
        else if(view[deRotate(ret.cell,-1)].color == TRAIL && totGreen <= 4) ret.cell = deRotate(ret.cell,1);
        return ret;
    } else { //If not on colored square, look for food, or set current color to 2.
        for (var i = 0; i < 9; i++) { //Look for enemies
            if (i != 4 && view[i].ant != null && !view[i].ant.friend) {
                var r = findOpenSpace(8-i,1);
                if(view[r].color == TRAIL) r = deRotate(r,1);
                return {cell: r};
            }
        }
        return {cell: 4, color:TRAIL};
    }
}

function getTrailMove() {
    if (view[0].color == TRAIL && !view[8].ant && view[8].color != TRAIL) return {cell: 8};
    else if (view[2].color == TRAIL && !view[6].ant && view[6].color != TRAIL) return {cell: 6};
    else if (view[6].color == TRAIL && !view[2].ant && view[2].color != TRAIL) return {cell: 2};
    else if (view[8].color == TRAIL && !view[0].ant && view[0].color != TRAIL) return {cell: 0};
    //Can't find color, or path is blocked? try diagonals regardless of color
    else if (!view[0].ant) return {cell: 0};
    else if (!view[2].ant) return {cell: 2};
    else if (!view[6].ant) return {cell: 6};
    else if (!view[8].ant) return {cell: 8};
    //Everything else failed? Stay put.
    else return {cell: 4};
}

function firebreak() {
    var ret = -1;
    if(findWorker(5) >= 0) {
        return {cell:8-findWorker(5)};
    }
    if(view[4].color != 5) {
        var myView = [0,0,0,0,0,0,0,0,0]
        for(var i=0; i < 9; i++) {
            myView[i] = view[i].color
            if(view[4].ant.food > 0 && view[i].food > 0) {
                myView[i] = 8;
            }
            if(view[i].ant != null && !view[i].ant.friend) return {cell:findOpenSpace(deRotate(i,2),1)};
        }
        var ret = clearAhead(myView);
        if(ret == null)
            return {cell:4,color:5};
        else {
            if(!(view[ret.cell].ant != null && view[ret.cell].ant.friend == false) && (view[4].ant.food == 0 || view[ret.cell].food == 0))
                return ret;
            return {cell:4,color:5};
        }
    }
    if(view[1].color == 5 && view[3].color == 5 && view[5].color == 5 && view[7].color == 5) {
        if(view[0].color != 8) return {cell:0,color:8};
        if(view[1].color != 8) return {cell:1,color:8};
    }
    if(view[1].color == 5 && view[7].color != 5) ret = {cell:7};
    if(view[3].color == 5 && view[5].color != 5) ret = {cell:5};
    if(view[5].color == 5 && view[3].color != 5) ret = {cell:3};
    if(view[7].color == 5 && view[1].color != 5) ret = {cell:1};
    if(view[1].color != 5 && view[3].color != 5 && view[5].color != 5 && view[7].color != 5) ret = {cell:1};
    if((view[1].color == 5 && view[7].color == 5) || (view[3].color == 5 && view[5].color == 5)) ret = {cell:0};
    var loop = 0;
    while(ret.cell >= 0 && ((view[ret.cell].food > 0 && view[4].ant.food > 0) || view[ret.cell].ant != null) && loop < 9) {
        loop++;
        ret.cell = (ret.cell + 2) % 9;
    }
    if(loop < 9 && ret.cell >= 0) return ret;
    return {cell:4};
}

//7,6,4,2,3
//O7,D2

function highwayRobbery() {
    var move = basicHighwayMove();
    if(move.cell >= 0 && view[move.cell].ant != null) {
        var n = HIGHWAY_COLORS.indexOf(view[4].color) + (view[4].color%2==0?1:HIGHWAY_COLORS.length);
        var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
        for(var i=0;i<9;i++) {
            if(view[i].color == nextMove) {
                return {cell:i};
            }
        }
    }
    return move;
}

function basicHighwayMove() {
    var isQueen = view[4].ant.type == 5;
    if(isHighwayCenter()) {
        var n = HIGHWAY_COLORS.indexOf(view[4].color) + 1;
        var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
        for(var i=0;i<9;i++) {
            if(view[i].color == nextMove) {
                if(view[i].ant == null)
                    return {cell:i};
                else {
                    return {cell:deRotate(i,1)};
                }
            }
        }
    }
    else {
        if(view[4].color == 7) {
            //move diagonal to yellow (2)
            for(var i=0;i<9;i++) {
                if(i != 4 && i % 2 == 0 && view[i].color == 2) {
                    return {cell:i};
                }
            }
        }
        else {
            //move orthogonal to blue (7)
            for(var i=0;i<9;i++) {
                if(i % 2 == 1 && view[i].color == 7) {
                    //try ortho yellow first
                    for(var j=0;j<9;j++) {
                        if(j % 2 == 1 && view[j].color == 2 && areAdjacent(i,j))
                            return {cell:j};
                    }
                    return {cell:i};
                }
            }
            //if orthogonal blue doens't exist...
            //...try diagonal to magenta
            for(var i=0;i<9;i++) {
                if(i != 4 && i % 2 == 0 && view[i].color == 3) {
                    return {cell:i};
                }
            }
            if(view[4].color != 2) {
                //...try diagonal blue
                for(var i=0;i<9;i++) {
                    if(i % 2 == 0 && view[i].color == 7)
                        return {cell:i};
                }
            }
            //...and orthogonal yellow
            for(var i=0;i<9;i++) {
                if(i % 2 == 1 && view[i].color == 2)
                    return {cell:i};
            }
        }
        var n = HIGHWAY_COLORS.indexOf(view[4].color) + 1;
        var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
        for(var i=0;i<9;i++) {
            if(view[i].color == nextMove) {
                return {cell:i};
            }
        }
    }
    return {cell:-1};
}

function isOnHighway() {
    var match = 0;
    var nxt = HIGHWAY_COLORS[(HIGHWAY_COLORS.indexOf(view[4].color)+1) % HIGHWAY_COLORS.length];//4
    var prv = HIGHWAY_COLORS[(HIGHWAY_COLORS.indexOf(view[4].color)+HIGHWAY_COLORS.length-2) % HIGHWAY_COLORS.length];//6
    for(var i=0;i<9;i++) {
        if(HIGHWAY_COLORS.indexOf(view[i].color) >=0 && (i == 4 || view[i].color != view[4].color))
            match++;
    }
    if(match >= 5) {
        //7,6,4,2,3


        if((view[1].color == nxt && view[7].color == prv)||(view[1].color == prv && view[7].color == nxt) || 
            (view[3].color == nxt && view[5].color == prv)||(view[3].color == prv && view[5].color == nxt)) {
            return true;
        }
        if((view[1].color == view[8].color && (view[1].color == nxt || view[1].color == prv))||(view[1].color == view[6].color && (view[1].color == nxt || view[1].color == prv)) || 
            (view[3].color == view[2].color && (view[3].color == nxt || view[3].color == prv))||(view[3].color == view[8].color && (view[3].color == nxt || view[3].color == prv))) {
            return true;
        }
        if((view[0].color == view[7].color && (view[0].color == nxt || view[0].color == prv))||(view[2].color == view[7].color && (view[2].color == nxt || view[2].color == prv)) || 
            (view[0].color == view[5].color && (view[0].color == nxt || view[0].color == prv))||(view[6].color == view[5].color && (view[6].color == nxt || view[6].color == prv))) {
            return true;
        }
        if(isHighwayCenter()) {
            return true;
        }
    }
    return false;
}

function isHighwayCenter() {
    if(HIGHWAY_COLORS.indexOf(view[4].color) >=0 && (((view[0].color != view[8].color || view[2].color != view[6].color) && view[4].ant.type == 1) || (view[0].color != view[8].color && view[2].color != view[6].color))){
        var m1 = view[1].color == view[7].color;
        var m2 = view[2].color == view[8].color;
        var m3 = view[0].color == view[6].color;
        var m4 = view[0].color != 1 && view[2].color != 1;
        if((m1?1:0)+(m2?1:0)+(m3?1:0) >= 2 && m4) {
            if(view[3].color != view[5].color && ((view[2].color != view[5].color && view[8].color != view[5].color) || view[4].ant.type == 1) && ((view[3].color != view[0].color && view[3].color != view[6].color) || view[4].ant.type == 1)) {
                return true;
            }
        }
        m1 = view[3].color == view[5].color;
        m2 = view[0].color == view[2].color;
        m3 = view[6].color == view[8].color;
        m4 = view[0].color != 1 && view[6].color != 1;
    //good
        if((m1?1:0)+(m2?1:0)+(m3?1:0) >= 2 && m4) {
            m1 = view[1].color != view[7].color;
            m2 = (view[0].color != view[1].color && view[1].color != view[2].color);
            m3 = (view[6].color != view[7].color && view[7].color != view[8].color);
            if(m1 && m2 && m3) {
                return true;
            }
            if(view[4].ant.type == 1 && ((m1?1:0)+(m2?1:0)+(m3?1:0)) >= 2) {
                return true;
            }
        }
    }
    return false;
}

function deRotateSide(m, amt) {
    return deRotate(m,amt*2);
}

/**Positive amount is clockwise**/
function deRotate(m, amt) {
    var rotationsCW = [1,2,5,8,7,6,3,0];
    var rotationsCCW = [3,6,7,8,5,2,1,0];
    if(m == 4 || m < 0 || m > 8 || amt == 0) return m;
    if(amt > 0)
        return rotationsCW[(rotationsCW.indexOf(m)+amt)%8];
    amt = -amt;
    return rotationsCCW[(rotationsCCW.indexOf(m)+amt)%8];
}

function areAdjacent(A, B) {
    if(A == 4 || B == 4 || A == B) return true;
    if(A % 2 == 0 && B % 2 == 0) return false;
    if(A % 2 == 1 && B % 2 == 0) return areAdjacent(B,A);
    if(A % 2 == 1 && B % 2 == 1) return !(8-A == B || 8-B == A);
    if(A == 0 && (B == 1 || B == 3)) return true;
    if(A == 2 && (B == 1 || B == 5)) return true;
    if(A == 6 && (B == 3 || B == 7)) return true;
    if(A == 8 && (B == 5 || B == 7)) return true;
    return false;
}

function findFirstTrail() {
    var pos = 0;
    var b = 0;
    while(view[pos].color != TRAIL && b < 8) {
        pos=deRotate(pos,1);
        b++;
    }
    return pos;
}

function clearAhead(sides) {
    var c=0;
    for(var i=0;i<9;i++) {
        if(view[i].color == 5) c++;
        if(view[i].color == 5 && i%2 == 0) c+=10;
    }
    if(c == 2) {
        if(view[0].color == 5 || view[2].color == 5 || view[6].color == 5 || view[8].color == 5) {
            return {cell:4,color:5};
        }
        if(view[0].ant == null)
            return {cell:0};
        if(view[2].ant == null)
            return {cell:2};
        if(view[6].ant == null)
            return {cell:6};
        if(view[8].ant == null)
            return {cell:8};
    }
    c = 0;
    sides[4] = 0;
    var toMatch =[{state:[1,1,1,
                          2,0,2,
                          0,1,0]},
                 {state:[0,2,1,
                         1,0,1,
                         0,2,1]},
                 {state:[0,1,0,
                         2,0,2,
                         1,1,1]},
                 {state:[1,2,0,
                         1,0,1,
                         1,2,0]}];
    for(var m=0;m<4;m++) {
        var score=0;
        for(var j=0;j<9;j++) {
            if(j!=4) {
                if(sides[j] == 5 && toMatch[m].state[j] == 1) {
                    score++;
                }
                if(sides[j] != 5 && (toMatch[m].state[j] == 0 || toMatch[m].state[j] == 2)) {
                    score++;
                }
                if(sides[j] == 5 && toMatch[m].state[j] == 2) {
                    score--;
                }
            }
        }
        if(score >= 6) {
            var clearOrder=[1,0,2];
            for(var r=0;r<clearOrder.length;r++) {
                var s = deRotateSide(clearOrder[r],m);
                if(view[s].color == 5) {
                    if(view[s].ant == null)
                        return {cell:s,color:8};
                    else
                        return {cell:4};
                }
            }
        }
    }
    return null;
}

function findOpenSpace(pos, dir) {
    if(pos > 8 || pos < 0) return pos;
    var b = 0;
    while(view[pos].ant != null && b < 8) {
        pos=deRotate(pos,dir);
        b++;
    }
    return pos;
}

function getHighestWorker() {
    var r=0;
    for(var i=0;i<9;i++) {
        if(i != 4 && view[i].ant != null) {
            if(view[i].ant.friend && view[i].ant.type > r) r = view[i].ant.type;
        }
    }
    return r;
}

function getNumWorkers(type) {
    var r=0;
    for(var i=0;i<9;i++) {
        if(i != 4 && view[i].ant != null) {
            if(view[i].ant.friend && view[i].ant.type == type) r++;
        }
    }
    return r;
}

function findWorker(type) {
    for(var i=0;i<9;i++) {
        if(i != 4 && view[i].ant != null) {
            if(view[i].ant.friend && view[i].ant.type == type) return i;
        }
    }
    return -1;
}

326% Complete
326% because the update was on 3/16This joke has gone on too long

//console.log(JSON.stringify(view))
var TRAIL = 6;
var SPAWN = 3;
var IDLE = 4;
var FOOD_THRESHOLD = 150;
var SPAWN_MIN = 3;
var HIGHWAY_COLORS = [7,6,4,2,3];
var HIGHWAY_THRESHOLD = 70;
var ret = {cell:4};
if(isOnHighway()) {
    var cont = true;
    //== Make best guess to if in a glider formation ==//
    if(view[4].ant.type == 5) {
        if((findWorker(1) >= 0 && findWorker(4) >= 0) || view[4].ant.food < HIGHWAY_THRESHOLD) {
            cont = false;
        }
    }
    else if(view[4].ant.type == 4) {
        if(findWorker(1) >= 0 && findWorker(5) >= 0) {
            cont = false;
        }
    }
    else if(view[4].ant.type == 3) {
        if(findWorker(2) >= 0 && findWorker(5) >= 0) {
            cont = false;
        }
    }
    else if(view[4].ant.type == 2) {
        if(findWorker(5) < 0) {
            var pos3 = findWorker(3);
            if(pos3 >= 0 && view[pos3].ant.food == 0) {
                cont = false;
            }
        }
        else if(findWorker(3) >= 0 || (findWorker(1) >= 0 && view[findWorker(5)].color == SPAWN))
            cont = false;
    }
    else if(view[4].ant.type == 1) {
        if(findWorker(5) < 0) {
            var pos4 = findWorker(4);
            if(pos4 >= 0 && view[pos4].ant.food == 0) {
                cont = false;
            }
        }
        else if(!isHighwayCenter())
            cont = false;
    }
    if(findWorker(5) >= 0) {
        for(var i=0;i<9;i++) {
            if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                if(view[i].ant.food > 10 || view[i].ant.food == 0)
                    cont = true;
                else
                    cont = false;
            }
        }
    }
    //== End guesswork ==//
    if(cont) {
        ret = highwayRobbery();
        if(view[4].ant.type == 1) {
            //try to repair
            var curIndex = HIGHWAY_COLORS.indexOf(view[4].color);
            var prvCol = HIGHWAY_COLORS[(curIndex+1)%HIGHWAY_COLORS.length];
            var nxtCol1 = HIGHWAY_COLORS[(curIndex+HIGHWAY_COLORS.length-1)%HIGHWAY_COLORS.length];
            var nxtCol2 = HIGHWAY_COLORS[(curIndex+HIGHWAY_COLORS.length-2)%HIGHWAY_COLORS.length];
            var nxtCol3 = HIGHWAY_COLORS[(curIndex+HIGHWAY_COLORS.length-3)%HIGHWAY_COLORS.length];
            var prevAt = -1;
            for(var i=0;i<9;i++) {
                if(i%2 == 1 && view[i].color == prvCol && view[deRotate(i,1)].color == nxtCol1 && view[deRotate(i,-1)].color == nxtCol1) prevAt = i;
            }
            if(prevAt >= 0) {
                // yep, brute force it. Because I'm lazy.
                var goNxt = 8-prevAt;
                if(view[deRotate(goNxt,1)].color == nxtCol3 && view[deRotate(goNxt,-1)].color == prvCol) ret = {cell:goNxt};
                else if(view[deRotate(goNxt,1)].color == prvCol && view[deRotate(goNxt,-1)].color == nxtCol3) ret = {cell:goNxt};
                else if(view[goNxt].color != nxtCol1) ret = {cell:goNxt,color:nxtCol1};
                else if(view[deRotate(goNxt,2)].color != nxtCol2) ret = {cell:deRotate(goNxt,2),color:nxtCol2};
                else if(view[deRotate(goNxt,-2)].color != nxtCol2) ret = {cell:deRotate(goNxt,-2),color:nxtCol2};
                else if(view[deRotate(goNxt,1)].color != nxtCol3) ret = {cell:deRotate(goNxt,1),color:nxtCol3};
                else if(view[deRotate(goNxt,-1)].color != nxtCol3) ret = {cell:deRotate(goNxt,-1),color:nxtCol3};
                else ret = {cell:goNxt};
                ret = sanityCheck(ret);
                return ret;
            }
        }
        if(view[4].ant.type == 5 && isHighwayCenter()) {
            if(ret.cell >= 0) {
                ret = {cell:8-ret.cell};
                if(view[4].color == SPAWN && (view[4].ant.food > 90 || view[4].ant.food % 7 == 0) && getHighestWorker() == 0 && (view[4].ant.food < 140 || view[4].ant.food % 9 == 0) && view[0].color == 2 && view[4].ant.food > 50 && view[4].ant.food < 200) {
            //fine
                    if(view[4].ant.food % 10 < 5)
                        ret = {cell:deRotate(ret.cell,3),type:3};
                }
                if(view[ret.cell].ant != null && !view[ret.cell].ant.friend && view[ret.cell].ant.food == 0 && view[4].ant.food > 0) {
                    if(view[deRotate(ret.cell,1)].ant == null)
                        ret = {cell:deRotate(ret.cell,1),type:3};
                    if(view[deRotate(ret.cell,-1)].ant == null)
                        ret = {cell:deRotate(ret.cell,1),type:3};
                }
            }
            for(var i=0;i<9;i++) {
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                    ret = {cell:8-i};
                }
            }
        }
        if(ret.cell >= 0) {
            for(var i=0;i<9;i++) {
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                    var rr = basicHighwayMove();
                    if(rr.cell >= 0 && view[4].ant.type != 5)
                        ret = {cell:deRotate(rr.cell,-2)};
                }
            }
            if(view[ret.cell].ant != null) {
                var n = HIGHWAY_COLORS.indexOf(view[4].color) + 1;
                var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
                for(var i=0;i<9;i++) {
                    if(view[i].color == nextMove) {
                        if(view[i].ant == null) {
                            ret = {cell:i};
                            break;
                        }
                    }
                }
                if(view[4].ant.type == 5) ret = {cell:8-ret.cell};
            }
        }
        if(view[4].ant.type == 5) {
            var foodedEnemy = false;
            for(var i=0;i<9;i++) {
                if(getNumWorkers(3) >= 2) break;
                if(i != 4 && view[i].ant != null && view[i].ant.type == 5 && view[i].ant.food > 25) {
                    if(view[deRotate(i,1)].ant == null) {
                        ret = {cell:deRotate(i,1),type:3};
                    }
                    else if(view[deRotate(i,-1)].ant == null) {
                        ret = {cell:deRotate(i,-1),type:3};
                    }
                    else if(i%2 == 1 && view[deRotate(i,2)].ant == null) {
                        ret = {cell:deRotate(i,2),type:3};
                    }
                    else if(i%2 == 1 && view[deRotate(i,-2)].ant == null) {
                        ret = {cell:deRotate(i,-2),type:3};
                    }
                }
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 3 && view[8-i].ant == null) {
                    if(i == ret.cell) {
                        ret = {cell:deRotate(i,1)}
                    }
                    else {
                        return {cell:8-i};
                    }
                }
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.food == 0) {
                    foodedEnemy = true;
                }
            }
        }
        var numAnts = 0;
        for(var i=0;i<9;i++) {
            if(view[i].ant != null)
                numAnts++;
        }
        if(numAnts > 2 && sanityCheck(ret).cell == 4) {
            ret = {cell:findOpenSpace(0,1)};
        }
        if(view[4].ant.type == 3) {
            if(getNumWorkers(5) > 0) {
                for(var i=0;i<9;i++) {
                    if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                        ret = {cell:4};
                    }
                }
            }
        }
        if(view[4].ant.type == 4 && getNumWorkers(1) && isHighwayCenter()) {
            var workerPos = findWorker(1);
            for(var i=0;i<9;i++) {
                if(!areAdjacent(i,workerPos)) ret = {cell:i};
            }
        }
        if(ret.cell == -1) {
            if(isHighwayCenter()) {
                for(var i=0;i<9;i++) {
                    var p1 = deRotate(i,3);
                    var p2 = deRotate(i,-3);
                    if(view[i].color == view[p1].color && view[i].color == view[p2].color) {
                        ret = {cell:8-i};
                    }
                }
                if(view[4].ant.type == 1 || view[4].ant.type == 5) {
                    ret = {cell:8-ret.cell};
                }
            }
        }
        if(ret.cell >= 0)
            return sanityCheck(ret);
    }
}

switch(view[4].ant.type) {
    case 5:
        ret = doQueen();
        break;
    case 1:
    case 2:
        ret = doSweep();
        break;
    case 3:
    case 4:
        ret = doGuide();
        break;
    default:
        break;
}
//basic sanity check
ret = sanityCheck(ret);
return ret;

function sanityCheck(ret) {
    if(!ret || ret.cell < 0 || ret.cell > 8) {
        return {cell:4};
    }
    if(ret.color) {
        return ret;
    }
    if((ret.cell != 4 && view[ret.cell].ant != null) || (view[ret.cell].food > 0 && (view[4].ant.food > 0 && view[4].ant.type < 5))) {
        return {cell:4};
    }
    if(ret.type && (view[ret.cell].ant != null || view[ret.cell].food > 0 || view[4].ant.food == 0 || view[4].ant.type < 5)) {
        return {cell:4};
    }
    return ret;
}

function doQueen() {
    if((view[4].ant.food == SPAWN_MIN || (view[4].ant.food >= SPAWN_MIN && view[4].ant.food < FOOD_THRESHOLD && (view[4].ant.food % 3 == 1 || isOnHighway()))) && getHighestWorker() <= 1 ) {
        //prep for first ant
        var s0 = view[0].ant;
        var s1 = view[1].ant;
        var s2 = view[2].ant;
        var s3 = view[3].ant;
        var s5 = view[5].ant;
        var s6 = view[6].ant;
        var s7 = view[7].ant;
        var s8 = view[8].ant;
        var nullCount = 0 + (s0 == null?1:0) + (s1 == null?1:0) + (s2 == null?1:0) + (s3 == null?1:0) + (s5 == null?1:0) + (s6 == null?1:0) + (s7 == null?1:0) + (s8 == null?1:0);
        var nullCount2 = 0 + (s0 == null || s0.friend?1:0) + (s1 == null || s1.friend?1:0) + (s2 == null || s2.friend?1:0) + (s3 == null || s3.friend?1:0) + (s5 == null || s5.friend?1:0) + (s6 == null || s6.friend?1:0) + (s7 == null || s7.friend?1:0) + (s8 == null || s8.friend?1:0);
        if(nullCount >= 7 && nullCount2 >= 8 && view[1].food == 0 && view[3].food == 0 && view[5].food == 0 && view[7].food == 0) {
            var high = getHighestWorker();
            if (high <= 1 && view[4].color != SPAWN && !isOnHighway()) {
                // 50% chance of delaying the respawn by 1 additional move away from where we exploded
                // reduces the chance of a second, immediate explosion
                var pos1 = findWorker(1);
                if(findFirstTrail() < 2 && view[4].ant.food > SPAWN_MIN+1 && pos1 < 0) return foreverAlone();
                if(pos1 >= 0) {
                    var space = deRotate(pos1,2);
                    if(view[space].ant != null) return {cell:findOpenSpace(0,1)};
                }
                return {cell:4,color:SPAWN};
            }
            //spawn first ant
            else if(view[4].color == SPAWN) {
                var pos1 = findWorker(1);
                if(pos1 < 0)  {
                    pos1 = findFirstTrail();
                    if(pos1 % 2 == 0) pos1 = deRotate(pos1,1);
                    else pos1 = deRotate(pos1,4);
                }
                var space = findOpenSpace(pos1,2);
                var high = getHighestWorker();
                if(space < 0) return {cell:4,color:TRAIL}
                if(high == 0) { //no workers
                    return {cell:space,type:1};
                }
                else if(high < 4) { //1 worker of type:high
                    return {cell:space,type:high+1};
                }
                else { //1 worker of type 4
                    //we have all workers, skip!
                }
            }
        }
        else {
            return foreverAlone();
        }
    }
    else if(view[4].ant.food == 1 && getHighestWorker() == 0 ) {
        var space = findOpenSpace(1,2);
        return {cell:space,type:1};
    }
    else if(view[4].ant.food >= 1 && getHighestWorker() < 4 && findWorker(1) >= 0) {
        //spawn remaining ants
        if(view[4].color == SPAWN && !isHighwayCenter()) {
            var pos1 = findWorker(getHighestWorker());
            var space = deRotate(pos1,2);
            var high = getHighestWorker();
            if(space < 0 || view[space].ant != null) return {cell:findOpenSpace(0,1)};
            if(high == 0) { //no workers
                return {cell:space,type:1};
            }
            else if(high < 4) { //1 worker of type:high
                return {cell:space,type:high+1};
            }
            else { //1 worker of type 4
                //we have all workers, skip!
            }
        }
    }
    if(view[4].color == SPAWN && getNumWorkers(3) == 1 && getNumWorkers(4) == 1) {
        var one = getNumWorkers(1);
        var two = getNumWorkers(2);
        if((one ^ two) == 1 && (findWorker(1) % 2 == 0 || findWorker(2) % 2 == 0))
            return {cell:4,color:1};
    }
    if(getNumWorkers(1) == 0 && getNumWorkers(2) == 0) {
        if(getNumWorkers(4) == 1 && getNumWorkers(3) == 0) {
            var pos4 = findWorker(4);
            if(view[deRotate(pos4,1)].ant == null && view[deRotate(pos4,2)].ant == null && findWorker(4) % 2 == 1) {
                //finish rotate with only one glider arm
                return {cell:4};
            }
        }
        return foreverAlone();
    }
    else if(getNumWorkers(1) >= 1 && getNumWorkers(2) >= 1 && getNumWorkers(3) >= 1 && getNumWorkers(4) >= 1) {
        if(view[4].color != 2 && findWorker(1)%2 == 1 && findWorker(2)%2 == 1) {
            return {cell:4,color:TRAIL};
        }
        //move diagonally
        var pos = findWorker(4);
        pos = deRotate(pos,1);
        var checkpos = view[deRotate(pos,4)];
        if(checkpos.ant != null && checkpos.ant.friend) {
            if(checkpos.ant.type == 2)
                return {cell:4};
            if(checkpos.ant.type == 1)
                return {cell:4};
        }
        if(view[pos].ant) return {cell:4,color:1};
        return {cell:pos};
    }
    else {
        var pos = findWorker(4);
        if(pos < 0) {
            //if gliding along with only a buddy
            pos = findWorker(1);
            if(pos >= 0 && view[deRotate(pos,2)].food > 0 && view[deRotate(pos,1)].food == 0) {
                return {cell:4};
            }
        }
        if(pos < 0) {
            var s1 = view[1].ant;
            var s3 = view[3].ant;
            var s5 = view[5].ant;
            var s7 = view[7].ant;
            //return {cell:999}
            if(s1 == null) {
                if(s3 == null) {
                    return {cell:0};
                }
                if(s5 == null) {
                    return {cell:2};
                }
            }
            if(s7 == null) {
                if(s3 == null) {
                    return {cell:6};
                }
                if(s5 == null) {
                    return {cell:8};
                }
            }
            return {cell:4};
        }
        pos = deRotate(pos,1);
        var checkpos1 = view[pos];
        for(var i=0;i<9;i++) {
            if(i != 4 && view[i].ant != null && view[i].ant.type == 5 && view[i].ant.food > 2) {
                if(i%2==0) {
                    if(view[deRotate(i,1)].ant == null) return {cell:deRotate(i,1),type:3};
                    if(view[deRotate(i,-1)].ant == null) return {cell:deRotate(i,-1),type:3};
                }
                else {
                    if(view[deRotate(i,1)].ant == null) return {cell:deRotate(i,1),type:3};
                    if(view[deRotate(i,-1)].ant == null) return {cell:deRotate(i,-1),type:3};
                    if(view[deRotate(i,2)].ant == null) return {cell:deRotate(i,2),type:3};
                    if(view[deRotate(i,-2)].ant == null) return {cell:deRotate(i,-2),type:3};
                }
                return {cell:4};
            }
        }
        if(checkpos1.ant != null && view[deRotate(pos,1)].ant != null && !view[deRotate(pos,1)].ant.friend) {
            return foreverAlone();
        }

        var checkpos2 = view[deRotate(pos,4)];
        var checkpos3 = view[deRotate(checkpos,1)];
        if(checkpos1.ant != null && checkpos1.ant.friend && checkpos1.ant.type == 1 && checkpos2.ant != null && checkpos2.ant.friend && checkpos2.ant.type == 2 && checkpos3.ant != null && checkpos3.ant.friend && checkpos3.ant.type == 3) {
            //move out of spawn orientation
            return {cell:4};
        }
        if(view[pos].ant != null) {
            if(checkpos2.ant == null && checkpos1.ant == null) {
                return {cell:8-pos};
            }
            if(!view[pos].ant.friend) {
                return foreverAlone();
            }
            if(view[4].color == TRAIL) return foreverAlone();
            return {cell:4,color:TRAIL};
        }
        if(8 - findWorker(3) == findWorker(4)) {
            //finish rotate to the right
            return {cell:4};
        }
        if((view[deRotate(pos,1)].food > 0 || view[deRotate(pos,2)].food > 0) && view[deRotate(pos,1)].ant == null && view[4].color != TRAIL) {
            if(findWorker(1) < 0 || view[deRotate(findWorker(1),1)].food == 0) {
                return {cell:4};
            }
        }
        return {cell:pos};
    }
    return {cell:100+view[4].ant.type}; //oh god
}

//guides sit next to the queen
function doGuide() {
    var queenPos = findWorker(5);
    var ty = view[4].ant.type==3?2:1;
    var dir = view[4].ant.type==3?1:-1;
    if(queenPos >= 0 && queenPos%2 == 1 && view[queenPos].color == SPAWN) {
        if(view[deRotate(queenPos,dir*2)].ant == null) {
            return {cell:4};
        }
    }
    if(queenPos < 0 || findWorker(ty) < 0) {
        if(findWorker(ty) >= 0 && view[0].color != IDLE) return {cell:0,color:IDLE}
        return firebreak();
    }
    var checkpos = view[deRotate(queenPos,-2*dir)];
    if(view[4].ant.type==4 && checkpos.ant != null && checkpos.ant.friend && checkpos.ant.type == 1) {
        //attempt rotate
        return {cell:deRotate(queenPos,-dir)};
    }
    checkpos = view[deRotate(queenPos,4)];
    if(checkpos.ant != null && checkpos.ant.friend && checkpos.ant.type == ty) {
        //attempt rotate
        if(getNumWorkers(ty) == 1) {
            return {cell:4};
        }
    }
    var pos = deRotate(queenPos,dir);
    if(pos >= 0 && view[4].ant.type==3 && findWorker(4) < 0) {
        //wait for rotate
        if(view[4].color == TRAIL) {
            return {cell:4};
        }
    }
    if(pos >= 0 && findWorker(2) >= 0 && view[deRotate(findWorker(2),1)].ant != null) {
        //rotate
        return {cell:4,color:TRAIL};
    }
    if(pos < 0) pos = 4;
    else if(view[pos].ant != null) return {cell:deRotate(queenPos,4)};
    if(pos == 4 && view[queenPos].color == TRAIL) return {cell:queenPos,color:1};
    return {cell:pos};
}

//sweepers sit next to guides
function doSweep() {
    var queenPos = findWorker(5);
    var followType = view[4].ant.type==1?4:3;
    var pos = findWorker(followType);
    if(pos % 2 == 0 && getNumWorkers(followType) > 1) {
        //if there's more than one worker #4, we want to use the best one
        for(var i=pos+1;i<9;i++) {
            if(i != 4 && view[i].ant != null) {
                if(view[i].ant.friend && view[i].ant.type == followType) {
                    pos = i;
                    break;
                }
            }
        }
    }
    if(queenPos >= 0 && queenPos%2 == 1 && view[queenPos].color == SPAWN) {
        var p = findWorker(view[4].ant.type);
        if(p >= 0 && (deRotate(p,1) == queenPos || deRotate(p,-1) == queenPos)) {
            return {cell:8-queenPos};
        }
        return {cell:4};
    }
    if(queenPos >= 0 && pos < 0) {
        //if Worker #1 is the only ant besides the queen:
        //TODO
    //good
        if(view[queenPos].ant.food <= SPAWN_MIN || !(view[queenPos].ant.food < FOOD_THRESHOLD && view[queenPos].ant.food % 3 == 1 && !isOnHighway())) {
            var go = deRotate(queenPos,-1);
            if((view[deRotate(queenPos,-2)].food > 0 || view[deRotate(queenPos,-3)].food > 0 || (queenPos %2 == 1 && view[deRotate(queenPos,-3)].food > 0)) && view[go].food == 0) {
                go = deRotate(queenPos,2);
                //return {cell:4};
            }
            return {cell:go};
        }
        else if(view[queenPos].ant.food < FOOD_THRESHOLD && view[queenPos].ant.food % 3 == 1) {
            return {cell:4};
        }
    }
    if(queenPos >= 0) {
        var dir = view[4].ant.type==1?1:-1;
        //var checkpos = view[deRotate(pos,-dir)];
        var moveTo = deRotate(pos,dir);
        if(moveTo >= 0 && view[moveTo].ant != null && view[moveTo].ant.friend && view[moveTo].ant.type == 5) {
            moveTo = deRotate(pos,-dir);
        }
        if(view[4].ant.type == 2 && findWorker(1) < 0 && view[queenPos].color != TRAIL) {
            moveTo = 4;
        }
        return {cell:moveTo};
    }
    else {
        if(pos < 0) return {cell:4}; //firebreak();
        var dir = view[4].ant.type==1?-1:1;
        var moveTo = deRotate(pos,dir);
        if(view[4].ant.food > 0 && view[moveTo].food > 0) {
            //have food, attempt to give to queen
            moveTo = deRotate(pos,-dir);
        }
        if(view[4].ant.type==1 && pos >= 0 && (view[deRotate(pos,dir*2)].food > 0 || view[deRotate(pos,dir*3)].food > 0)) {
            //attempt rotate
            moveTo = deRotate(pos,-dir);
        }
        if(view[4].ant.type==2 && pos >= 0 && (view[deRotate(pos,dir*2)].food > 0 || view[deRotate(pos,dir*3)].food > 0)) {
            //attempt rotate
            moveTo = deRotate(pos,-dir);
        }
        if(moveTo >= 0 && view[moveTo].ant != null && view[moveTo].ant.type == 5) {
            if(view[moveTo].ant.friend)
                moveTo = deRotate(moveTo,dir*2);
            else
                moveTo = deRotate(pos,-dir);
        }
        return {cell:moveTo};
    }
    return {cell:100+view[4].ant.type};//oh god
}

function foreverAlone() {
    var s0 = view[0].ant;
    var s1 = view[1].ant;
    var s2 = view[2].ant;
    var s3 = view[3].ant;
    var s5 = view[5].ant;
    var s6 = view[6].ant;
    var s7 = view[7].ant;
    var s8 = view[8].ant;
    //good
    if(!(s0 == null && s1 == null && s2 == null && s3 == null && s5 == null && s6 == null && s7 == null && s8 == null) && view[4].color == TRAIL) {
        if (view[0].color == TRAIL && !view[8].ant && view[8].color != TRAIL) return {cell: 8};
        else if (view[2].color == TRAIL && !view[6].ant && view[6].color != TRAIL) return {cell: 6};
        else if (view[6].color == TRAIL && !view[2].ant && view[2].color != TRAIL) return {cell: 2};
        else if (view[8].color == TRAIL && !view[0].ant && view[0].color != TRAIL) return {cell: 0};
        //Can't find color, or path is blocked? try diagonals regardless of color
        else if (!view[0].ant) return {cell: 0};
        else if (!view[2].ant) return {cell: 2};
        else if (!view[6].ant) return {cell: 6};
        else if (!view[8].ant) return {cell: 8};
        //Everything else failed? Stay put.
        else return {cell: 4};
    }
    //good
    if (view[4].color == TRAIL) { //If on colored square, try to move
        var totGreen = 0;
        for (var i = 0; i < 9; i++) { //Look for food
            if (view[i].food) {
                return {cell: i};
            }
            if(view[i].color == TRAIL) totGreen++;
        }
        var ret = getTrailMove();
        if(view[deRotate(ret.cell,1)].color == TRAIL && totGreen <= 4) ret.cell = deRotate(ret.cell,-1);
        else if(view[deRotate(ret.cell,-1)].color == TRAIL && totGreen <= 4) ret.cell = deRotate(ret.cell,1);
        return ret;
    } else { //If not on colored square, look for food, or set current color to 2.
        for (var i = 0; i < 9; i++) { //Look for enemies
            if (i != 4 && view[i].ant != null && !view[i].ant.friend) {
                var r = findOpenSpace(8-i,1);
                if(view[r].color == TRAIL) r = deRotate(r,1);
                return {cell: r};
            }
        }
        return {cell: 4, color:TRAIL};
    }
}

function getTrailMove() {
    if (view[0].color == TRAIL && !view[8].ant && view[8].color != TRAIL) return {cell: 8};
    else if (view[2].color == TRAIL && !view[6].ant && view[6].color != TRAIL) return {cell: 6};
    else if (view[6].color == TRAIL && !view[2].ant && view[2].color != TRAIL) return {cell: 2};
    else if (view[8].color == TRAIL && !view[0].ant && view[0].color != TRAIL) return {cell: 0};
    //Can't find color, or path is blocked? try diagonals regardless of color
    else if (!view[0].ant) return {cell: 0};
    else if (!view[2].ant) return {cell: 2};
    else if (!view[6].ant) return {cell: 6};
    else if (!view[8].ant) return {cell: 8};
    //Everything else failed? Stay put.
    else return {cell: 4};
}

function firebreak() {
    var ret = -1;
    if(findWorker(5) >= 0) {
        return {cell:8-findWorker(5)};
    }
    if(view[4].color != 5) {
        var myView = [0,0,0,0,0,0,0,0,0]
        for(var i=0; i < 9; i++) {
            myView[i] = view[i].color
            if(view[4].ant.food > 0 && view[i].food > 0) {
                myView[i] = 8;
            }
            if(view[i].ant != null && !view[i].ant.friend) return {cell:findOpenSpace(deRotate(i,2),1)};
        }
        var ret = clearAhead(myView);
        if(ret == null)
            return {cell:4,color:5};
        else {
            if(!(view[ret.cell].ant != null && view[ret.cell].ant.friend == false) && (view[4].ant.food == 0 || view[ret.cell].food == 0))
                return ret;
            return {cell:4,color:5};
        }
    }
    if(view[1].color == 5 && view[3].color == 5 && view[5].color == 5 && view[7].color == 5) {
        if(view[0].color != 8) return {cell:0,color:8};
        if(view[1].color != 8) return {cell:1,color:8};
    }
    if(view[1].color == 5 && view[7].color != 5) ret = {cell:7};
    if(view[3].color == 5 && view[5].color != 5) ret = {cell:5};
    if(view[5].color == 5 && view[3].color != 5) ret = {cell:3};
    if(view[7].color == 5 && view[1].color != 5) ret = {cell:1};
    if(view[1].color != 5 && view[3].color != 5 && view[5].color != 5 && view[7].color != 5) ret = {cell:1};
    if((view[1].color == 5 && view[7].color == 5) || (view[3].color == 5 && view[5].color == 5)) ret = {cell:0};
    var loop = 0;
    while(ret.cell >= 0 && ((view[ret.cell].food > 0 && view[4].ant.food > 0) || view[ret.cell].ant != null) && loop < 9) {
        loop++;
        ret.cell = (ret.cell + 2) % 9;
    }
    if(loop < 9 && ret.cell >= 0) return ret;
    return {cell:4};
}

//7,6,4,2,3
//O7,D2

function highwayRobbery() {
    var move = basicHighwayMove();
    if(move.cell >= 0 && view[move.cell].ant != null) {
        var n = HIGHWAY_COLORS.indexOf(view[4].color) + (view[4].color%2==0?1:HIGHWAY_COLORS.length);
        var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
        for(var i=0;i<9;i++) {
            if(view[i].color == nextMove) {
                return {cell:i};
            }
        }
    }
    return move;
}

function basicHighwayMove() {
    var isQueen = view[4].ant.type == 5;
    if(isHighwayCenter()) {
        var n = HIGHWAY_COLORS.indexOf(view[4].color) + 1;
        var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
        for(var i=0;i<9;i++) {
            if(view[i].color == nextMove) {
                if(view[i].ant == null)
                    return {cell:i};
                else {
                    return {cell:deRotate(i,1)};
                }
            }
        }
    }
    else {
        if(view[4].color == 7) {
            //move diagonal to yellow (2)
            for(var i=0;i<9;i++) {
                if(i != 4 && i % 2 == 0 && view[i].color == 2) {
                    return {cell:i};
                }
            }
        }
        else {
            //move orthogonal to blue (7)
            for(var i=0;i<9;i++) {
                if(i % 2 == 1 && view[i].color == 7) {
                    //try ortho yellow first
                    for(var j=0;j<9;j++) {
                        if(j % 2 == 1 && view[j].color == 2 && areAdjacent(i,j))
                            return {cell:j};
                    }
                    return {cell:i};
                }
            }
            //if orthogonal blue doens't exist...
            //...try diagonal to magenta
            for(var i=0;i<9;i++) {
                if(i != 4 && i % 2 == 0 && view[i].color == 3) {
                    return {cell:i};
                }
            }
            if(view[4].color != 2) {
                //...try diagonal blue
                for(var i=0;i<9;i++) {
                    if(i % 2 == 0 && view[i].color == 7)
                        return {cell:i};
                }
            }
            //...and orthogonal yellow
            for(var i=0;i<9;i++) {
                if(i % 2 == 1 && view[i].color == 2)
                    return {cell:i};
            }
        }
        var n = HIGHWAY_COLORS.indexOf(view[4].color) + 1;
        var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
        for(var i=0;i<9;i++) {
            if(view[i].color == nextMove) {
                return {cell:i};
            }
        }
    }
    return {cell:-1};
}

function isOnHighway() {
    var match = 0;
    var nxt = HIGHWAY_COLORS[(HIGHWAY_COLORS.indexOf(view[4].color)+1) % HIGHWAY_COLORS.length];//4
    var prv = HIGHWAY_COLORS[(HIGHWAY_COLORS.indexOf(view[4].color)+HIGHWAY_COLORS.length-2) % HIGHWAY_COLORS.length];//6
    for(var i=0;i<9;i++) {
        if(HIGHWAY_COLORS.indexOf(view[i].color) >=0 && (i == 4 || view[i].color != view[4].color))
            match++;
    }
    if(match >= 5) {
        //7,6,4,2,3


        if((view[1].color == nxt && view[7].color == prv)||(view[1].color == prv && view[7].color == nxt) || 
            (view[3].color == nxt && view[5].color == prv)||(view[3].color == prv && view[5].color == nxt)) {
            return true;
        }
        if((view[1].color == view[8].color && (view[1].color == nxt || view[1].color == prv))||(view[1].color == view[6].color && (view[1].color == nxt || view[1].color == prv)) || 
            (view[3].color == view[2].color && (view[3].color == nxt || view[3].color == prv))||(view[3].color == view[8].color && (view[3].color == nxt || view[3].color == prv))) {
            return true;
        }
        if((view[0].color == view[7].color && (view[0].color == nxt || view[0].color == prv))||(view[2].color == view[7].color && (view[2].color == nxt || view[2].color == prv)) || 
            (view[0].color == view[5].color && (view[0].color == nxt || view[0].color == prv))||(view[6].color == view[5].color && (view[6].color == nxt || view[6].color == prv))) {
            return true;
        }
        if(isHighwayCenter()) {
            return true;
        }
    }
    return false;
}

function isHighwayCenter() {
    if(HIGHWAY_COLORS.indexOf(view[4].color) >=0 && (((view[0].color != view[8].color || view[2].color != view[6].color) && view[4].ant.type == 1) || (view[0].color != view[8].color && view[2].color != view[6].color))){
        var m1 = view[1].color == view[7].color;
        var m2 = view[2].color == view[8].color;
        var m3 = view[0].color == view[6].color;
        var m4 = view[0].color != 1 && view[2].color != 1;
        if((m1?1:0)+(m2?1:0)+(m3?1:0) >= 2 && m4) {
            if(view[3].color != view[5].color && ((view[2].color != view[5].color && view[8].color != view[5].color) || view[4].ant.type == 1) && ((view[3].color != view[0].color && view[3].color != view[6].color) || view[4].ant.type == 1)) {
                return true;
            }
        }
        m1 = view[3].color == view[5].color;
        m2 = view[0].color == view[2].color;
        m3 = view[6].color == view[8].color;
        m4 = view[0].color != 1 && view[6].color != 1;
    //good
        if((m1?1:0)+(m2?1:0)+(m3?1:0) >= 2 && m4) {
            m1 = view[1].color != view[7].color;
            m2 = (view[0].color != view[1].color && view[1].color != view[2].color);
            m3 = (view[6].color != view[7].color && view[7].color != view[8].color);
            if(m1 && m2 && m3) {
                return true;
            }
            if(view[4].ant.type == 1 && ((m1?1:0)+(m2?1:0)+(m3?1:0)) >= 2) {
                return true;
            }
        }
    }
    return false;
}

function deRotateSide(m, amt) {
    return deRotate(m,amt*2);
}

/**Positive amount is clockwise**/
function deRotate(m, amt) {
    var rotationsCW = [1,2,5,8,7,6,3,0];
    var rotationsCCW = [3,6,7,8,5,2,1,0];
    if(m == 4 || m < 0 || m > 8 || amt == 0) return m;
    if(amt > 0)
        return rotationsCW[(rotationsCW.indexOf(m)+amt)%8];
    amt = -amt;
    return rotationsCCW[(rotationsCCW.indexOf(m)+amt)%8];
}

function areAdjacent(A, B) {
    if(A == 4 || B == 4 || A == B) return true;
    if(A % 2 == 0 && B % 2 == 0) return false;
    if(A % 2 == 1 && B % 2 == 0) return areAdjacent(B,A);
    if(A % 2 == 1 && B % 2 == 1) return !(8-A == B || 8-B == A);
    if(A == 0 && (B == 1 || B == 3)) return true;
    if(A == 2 && (B == 1 || B == 5)) return true;
    if(A == 6 && (B == 3 || B == 7)) return true;
    if(A == 8 && (B == 5 || B == 7)) return true;
    return false;
}

function findFirstTrail() {
    var pos = 0;
    var b = 0;
    while(view[pos].color != TRAIL && b < 8) {
        pos=deRotate(pos,1);
        b++;
    }
    return pos;
}

function clearAhead(sides) {
    var c=0;
    for(var i=0;i<9;i++) {
        if(view[i].color == 5) c++;
        if(view[i].color == 5 && i%2 == 0) c+=10;
    }
    if(c == 2) {
        if(view[0].color == 5 || view[2].color == 5 || view[6].color == 5 || view[8].color == 5) {
            return {cell:4,color:5};
        }
        if(view[0].ant == null)
            return {cell:0};
        if(view[2].ant == null)
            return {cell:2};
        if(view[6].ant == null)
            return {cell:6};
        if(view[8].ant == null)
            return {cell:8};
    }
    c = 0;
    sides[4] = 0;
    var toMatch =[{state:[1,1,1,
                          2,0,2,
                          0,1,0]},
                 {state:[0,2,1,
                         1,0,1,
                         0,2,1]},
                 {state:[0,1,0,
                         2,0,2,
                         1,1,1]},
                 {state:[1,2,0,
                         1,0,1,
                         1,2,0]}];
    for(var m=0;m<4;m++) {
        var score=0;
        for(var j=0;j<9;j++) {
            if(j!=4) {
                if(sides[j] == 5 && toMatch[m].state[j] == 1) {
                    score++;
                }
                if(sides[j] != 5 && (toMatch[m].state[j] == 0 || toMatch[m].state[j] == 2)) {
                    score++;
                }
                if(sides[j] == 5 && toMatch[m].state[j] == 2) {
                    score--;
                }
            }
        }
        if(score >= 6) {
            var clearOrder=[1,0,2];
            for(var r=0;r<clearOrder.length;r++) {
                var s = deRotateSide(clearOrder[r],m);
                if(view[s].color == 5) {
                    if(view[s].ant == null)
                        return {cell:s,color:8};
                    else
                        return {cell:4};
                }
            }
        }
    }
    return null;
}

function findOpenSpace(pos, dir) {
    if(pos > 8 || pos < 0) return pos;
    var b = 0;
    while(view[pos].ant != null && b < 8) {
        pos=deRotate(pos,dir);
        b++;
    }
    return pos;
}

function getHighestWorker() {
    var r=0;
    for(var i=0;i<9;i++) {
        if(i != 4 && view[i].ant != null) {
            if(view[i].ant.friend && view[i].ant.type > r) r = view[i].ant.type;
        }
    }
    return r;
}

function getNumWorkers(type) {
    var r=0;
    for(var i=0;i<9;i++) {
        if(i != 4 && view[i].ant != null) {
            if(view[i].ant.friend && view[i].ant.type == type) r++;
        }
    }
    return r;
}

function findWorker(type) {
    for(var i=0;i<9;i++) {
        if(i != 4 && view[i].ant != null) {
            if(view[i].ant.friend && view[i].ant.type == type) return i;
        }
    }
    return -1;
}

422% Complete
422% because the update was on 4/22This joke has gone on too long

Update 4/21

Minor fixes.

38 added 370 characters in body
source | link
var TRAIL = 6;
var SPAWN = 3;
var IDLE = 4;
var FOOD_THRESHOLD = 150;
var SPAWN_MIN = 3;
var HIGHWAY_COLORS = [7,6,4,2,3];
var HIGHWAY_THRESHOLD = 70;
var ret = {cell:4};
if(isOnHighway()) {
    var cont = true;
    //== Make best guess to if in a glider formation ==//
    if(view[4].ant.type == 5) {
        if((findWorker(1) >= 0 && findWorker(4) >= 0) || view[4].ant.food < 80HIGHWAY_THRESHOLD) {
            cont = false;
        }
    }
    else if(view[4].ant.type == 4) {
        if(findWorker(1) >= 0 && findWorker(5) >= 0) {
            cont = false;
        }
    }
    else if(view[4].ant.type == 3) {
        if(findWorker(2) >= 0 && findWorker(5) >= 0) {
            cont = false;
        }
    }
    else if(view[4].ant.type == 2) {
        if(findWorker(5) < 0) {
            var pos3 = findWorker(3);
            if(pos3 >= 0 && view[pos3].ant.food == 0) {
                cont = false;
            }
        }
        else if(findWorker(3) >= 0 || (findWorker(1) >= 0 && view[findWorker(5)].color == SPAWN))
            cont = false;
    }
    else if(view[4].ant.type == 1) {
        if(findWorker(5) < 0) {
            var pos4 = findWorker(4);
            if(pos4 >= 0 && view[pos4].ant.food == 0) {
                cont = false;
            }
        }
        else if(!isHighwayCenter())
            cont = false;
    }
    if(findWorker(5) >= 0) {
        for(var i=0;i<9;i++) {
            if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                if(view[i].ant.food > 10 || view[i].ant.food == 0)
                    cont = true;
                else
                    cont = false;
            }
        }
    }
    //== End guesswork ==//
    if(cont) {
        ret = highwayRobbery();
        if(view[4].ant.type == 1) {
            //try to repair
            var curIndex = HIGHWAY_COLORS.indexOf(view[4].color);
            var prvCol = HIGHWAY_COLORS[(curIndex+1)%HIGHWAY_COLORS.length];
            var nxtCol1 = HIGHWAY_COLORS[(curIndex+HIGHWAY_COLORS.length-1)%HIGHWAY_COLORS.length];
            var nxtCol2 = HIGHWAY_COLORS[(curIndex+HIGHWAY_COLORS.length-2)%HIGHWAY_COLORS.length];
            var nxtCol3 = HIGHWAY_COLORS[(curIndex+HIGHWAY_COLORS.length-3)%HIGHWAY_COLORS.length];
            var prevAt = -1;
            for(var i=0;i<9;i++) {
                if(i%2 == 1 && view[i].color == prvCol && view[deRotate(i,1)].color == nxtCol1 && view[deRotate(i,-1)].color == nxtCol1) prevAt = i;
            }
            if(prevAt >= 0) {
                // yep, brute force it. Because I'm lazy.
                var goNxt = 8-prevAt;
                if(view[deRotate(goNxt,1)].color == nxtCol3 && view[deRotate(goNxt,-1)].color == prvCol) ret = {cell:goNxt};
                else if(view[deRotate(goNxt,1)].color == prvCol && view[deRotate(goNxt,-1)].color == nxtCol3) ret = {cell:goNxt};
                else if(view[goNxt].color != nxtCol1) ret = {cell:goNxt,color:nxtCol1};
                else if(view[deRotate(goNxt,2)].color != nxtCol2) ret = {cell:deRotate(goNxt,2),color:nxtCol2};
                else if(view[deRotate(goNxt,-2)].color != nxtCol2) ret = {cell:deRotate(goNxt,-2),color:nxtCol2};
                else if(view[deRotate(goNxt,1)].color != nxtCol3) ret = {cell:deRotate(goNxt,1),color:nxtCol3};
                else if(view[deRotate(goNxt,-1)].color != nxtCol3) ret = {cell:deRotate(goNxt,-1),color:nxtCol3};
                else ret = {cell:goNxt};
                ret = sanityCheck(ret);
                return ret;
            }
        }
        if(view[4].ant.type == 5 && isHighwayCenter()) {
            if(ret.cell >= 0) {
                ret = {cell:8-ret.cell};
                if(view[4].color == SPAWN && (view[4].ant.food > 90 || view[4].ant.food % 7 == 0) && getHighestWorker() == 0 && (view[4].ant.food < 140 || view[4].ant.food % 9 == 0) && view[0].color == 2 && view[4].ant.food > 50 && view[4].ant.food < 200) {
            //fine
                    if(view[4].ant.food % 10 < 5)
                        ret = {cell:deRotate(ret.cell,3),type:3};
                }
                if(view[ret.cell].ant != null && !view[ret.cell].ant.friend && view[ret.cell].ant.food == 0 && view[4].ant.food > 0) {
                    if(view[deRotate(ret.cell,1)].ant == null)
                        ret = {cell:deRotate(ret.cell,1),type:3};
                    if(view[deRotate(ret.cell,-1)].ant == null)
                        ret = {cell:deRotate(ret.cell,1),type:3};
                }
            }
            for(var i=0;i<9;i++) {
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                    ret = {cell:8-i};
                }
            }
        }
        if(ret.cell >= 0) {
            for(var i=0;i<9;i++) {
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                    var rr = basicHighwayMove();
                    if(rr.cell >= 0 && view[4].ant.type != 5)
                        ret = {cell:deRotate(rr.cell,-2)};
                }
            }
            if(view[ret.cell].ant != null) {
                var n = HIGHWAY_COLORS.indexOf(view[4].color) + 1;
                var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
                for(var i=0;i<9;i++) {
                    if(view[i].color == nextMove) {
                        if(view[i].ant == null) {
                            ret = {cell:i};
                            break;
                        }
                    }
                }
                if(view[4].ant.type == 5) ret = {cell:8-ret.cell};
            }
        }
        if(view[4].ant.type == 5) {
            var foodedEnemy = false;
            for(var i=0;i<9;i++) {
                if(getNumWorkers(3) >= 2) break;
                if(i != 4 && view[i].ant != null && view[i].ant.type == 5 && view[i].ant.food > 25) {
                    if(view[deRotate(i,1)].ant == null) {
                        ret = {cell:deRotate(i,1),type:3};
                    }
                    else if(view[deRotate(i,-1)].ant == null) {
                        ret = {cell:deRotate(i,-1),type:3};
                    }
                    else if(i%2 == 1 && view[deRotate(i,2)].ant == null) {
                        ret = {cell:deRotate(i,2),type:3};
                    }
                    else if(i%2 == 1 && view[deRotate(i,-2)].ant == null) {
                        ret = {cell:deRotate(i,-2),type:3};
                    }
                }
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 3 && view[8-i].ant == null) {
                    if(i == ret.cell) {
                        ret = {cell:deRotate(i,1)}
                    }
                    else {
                        return {cell:8-i};
                    }
                }
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.food == 0) {
                    foodedEnemy = true;
                }
            }
        }
        var numAnts = 0;
        for(var i=0;i<9;i++) {
            if(view[i].ant != null)
                numAnts++;
        }
        if(numAnts > 2 && sanityCheck(ret).cell == 4) {
            ret = {cell:findOpenSpace(0,1)};
        }
        if(view[4].ant.type == 3) {
            if(getNumWorkers(5) > 0) {
                for(var i=0;i<9;i++) {
                    if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                        ret = {cell:4};
                    }
                }
            }
        }
        if(view[4].ant.type == 4 && getNumWorkers(1) && isHighwayCenter()) {
            var workerPos = findWorker(1);
            for(var i=0;i<9;i++) {
                if(!areAdjacent(i,workerPos)) ret = {cell:i};
            }
        }
        if(ret.cell == -1) {
            if(isHighwayCenter()) {
                for(var i=0;i<9;i++) {
                    var p1 = deRotate(i,3);
                    var p2 = deRotate(i,-3);
                    if(view[i].color == view[p1].color && view[i].color == view[p2].color) {
                        ret = {cell:8-i};
                    }
                }
                if(view[4].ant.type == 1 || view[4].ant.type == 5) {
                    ret = {cell:8-ret.cell};
                }
            }
        }
        if(ret.cell >= 0)
            return sanityCheck(ret);
    }
}

switch(view[4].ant.type) {
    case 5:
        ret = doQueen();
        break;
    case 1:
    case 2:
        ret = doSweep();
        break;
    case 3:
    case 4:
        ret = doGuide();
        break;
    default:
        break;
}
//basic sanity check
ret = sanityCheck(ret);
return ret;

function sanityCheck(ret) {
    if(!ret || ret.cell < 0 || ret.cell > 8) {
        return {cell:4};
    }
    if(ret.color) {
        return ret;
    }
    if((ret.cell != 4 && view[ret.cell].ant != null) || (view[ret.cell].food > 0 && (view[4].ant.food > 0 && view[4].ant.type < 5))) {
        return {cell:4};
    }
    if(ret.type && (view[ret.cell].ant != null || view[ret.cell].food > 0 || view[4].ant.food == 0 || view[4].ant.type < 5)) {
        return {cell:4};
    }
    return ret;
}

function doQueen() {
    if((view[4].ant.food == SPAWN_MIN || (view[4].ant.food >= SPAWN_MIN && view[4].ant.food < FOOD_THRESHOLD && (view[4].ant.food % 3 == 1 || isOnHighway()))) && getHighestWorker() <= 1 ) {
        //prep for first ant
        var s0 = view[0].ant;
        var s1 = view[1].ant;
        var s2 = view[2].ant;
        var s3 = view[3].ant;
        var s5 = view[5].ant;
        var s6 = view[6].ant;
        var s7 = view[7].ant;
        var s8 = view[8].ant;
        var nullCount = 0 + (s0 == null?1:0) + (s1 == null?1:0) + (s2 == null?1:0) + (s3 == null?1:0) + (s5 == null?1:0) + (s6 == null?1:0) + (s7 == null?1:0) + (s8 == null?1:0);
        var nullCount2 = 0 + (s0 == null || s0.friend?1:0) + (s1 == null || s1.friend?1:0) + (s2 == null || s2.friend?1:0) + (s3 == null || s3.friend?1:0) + (s5 == null || s5.friend?1:0) + (s6 == null || s6.friend?1:0) + (s7 == null || s7.friend?1:0) + (s8 == null || s8.friend?1:0);
        if(nullCount >= 7 && nullCount2 >= 8 && view[1].food == 0 && view[3].food == 0 && view[5].food == 0 && view[7].food == 0) {
            var high = getHighestWorker();
            if (high <= 1 && view[4].color != SPAWN && !isOnHighway()) {
                // 50% chance of delaying the respawn by 1 additional move away from where we exploded
                // reduces the chance of a second, immediate explosion
                if(findFirstTrail() < 2 && view[4].ant.food > SPAWN_MIN+1) return foreverAlone();
                var pos1 = findWorker(1);
                if(pos1 >= 0) {
                    var space = deRotate(pos1,2);
                    if(view[space].ant != null) return {cell:findOpenSpace(0,1)};
                }
                return {cell:4,color:SPAWN};
            }
            //spawn first ant
            else if(view[4].color == SPAWN) {
                var pos1 = findWorker(1);
                if(pos1 < 0)  {
                    pos1 = findFirstTrail();
                    if(pos1 % 2 == 0) pos1 = deRotate(pos1,1);
                    else pos1 = deRotate(pos1,4);
                }
                var space = findOpenSpace(pos1,2);
                var high = getHighestWorker();
                if(space < 0) return {cell:4,color:TRAIL}
                if(high == 0) { //no workers
                    return {cell:space,type:1};
                }
                else if(high < 4) { //1 worker of type:high
                    return {cell:space,type:high+1};
                }
                else { //1 worker of type 4
                    //we have all workers, skip!
                }
            }
        }
        else {
            return foreverAlone();
        }
    }
    else if(view[4].ant.food == 1 && getHighestWorker() == 0 ) {
        var space = findOpenSpace(1,2);
        return {cell:space,type:1};
    }
    else if(view[4].ant.food >= 1 && getHighestWorker() < 4 && findWorker(1) >= 0) {
        //spawn remaining ants
        if(view[4].color == SPAWN && !isHighwayCenter()) {
            var pos1 = findWorker(getHighestWorker());
            var space = deRotate(pos1,2);
            var high = getHighestWorker();
            if(space < 0 || view[space].ant != null) return {cell:findOpenSpace(0,1)};
            if(high == 0) { //no workers
                return {cell:space,type:1};
            }
            else if(high < 4) { //1 worker of type:high
                return {cell:space,type:high+1};
            }
            else { //1 worker of type 4
                //we have all workers, skip!
            }
        }
    }
    if(view[4].color == SPAWN && getNumWorkers(3) == 1 && getNumWorkers(4) == 1) {
        var one = getNumWorkers(1);
        var two = getNumWorkers(2);
        if((one ^ two) == 1 && (findWorker(1) % 2 == 0 || findWorker(2) % 2 == 0))
            return {cell:4,color:1};
    }
    if(getNumWorkers(1) == 0 && getNumWorkers(2) == 0) {
        if(getNumWorkers(4) == 1 && getNumWorkers(3) == 0) {
            var pos4 = findWorker(4);
            if(view[deRotate(pos4,1)].ant == null && view[deRotate(pos4,2)].ant == null && findWorker(4) % 2 == 1) {
                //finish rotate with only one glider arm
                return {cell:4};
            }
        }
        return foreverAlone();
    }
    else if(getNumWorkers(1) >= 1 && getNumWorkers(2) >= 1 && getNumWorkers(3) >= 1 && getNumWorkers(4) >= 1) {
        if(view[4].color != 2 && findWorker(1)%2 == 1 && findWorker(2)%2 == 1) {
            return {cell:4,color:TRAIL};
        }
        //move diagonally
        var pos = findWorker(4);
        pos = deRotate(pos,1);
        var checkpos = view[deRotate(pos,4)];
        if(checkpos.ant != null && checkpos.ant.friend) {
            if(checkpos.ant.type == 2)
                return {cell:4};
            if(checkpos.ant.type == 1)
                return {cell:4};
        }
        return {cell:pos};
    }
    else {
        var pos = findWorker(4);
        if(pos < 0) {
            //if gliding along with only a buddy
            pos = findWorker(1);
            if(pos >= 0 && view[deRotate(pos,2)].food > 0 && view[deRotate(pos,1)].food == 0) {
                return {cell:4};
            }
        }
        if(pos < 0) {
            var s1 = view[1].ant;
            var s3 = view[3].ant;
            var s5 = view[5].ant;
            var s7 = view[7].ant;
            //return {cell:999}
            if(s1 == null) {
                if(s3 == null) {
                    return {cell:0};
                }
                if(s5 == null) {
                    return {cell:2};
                }
            }
            if(s7 == null) {
                if(s3 == null) {
                    return {cell:6};
                }
                if(s5 == null) {
                    return {cell:8};
                }
            }
            return {cell:4};
        }
        pos = deRotate(pos,1);
        var checkpos1 = view[pos];
        for(var i=0;i<9;i++) {
            if(i != 4 && view[i].ant != null && view[i].ant.type == 5 && view[i].ant.food > 2) {
                if(i%2==0) {
                    if(view[deRotate(i,1)].ant == null) return {cell:deRotate(i,1),type:3};
                    if(view[deRotate(i,-1)].ant == null) return {cell:deRotate(i,-1),type:3};
                }
                else {
                    if(view[deRotate(i,1)].ant == null) return {cell:deRotate(i,1),type:3};
                    if(view[deRotate(i,-1)].ant == null) return {cell:deRotate(i,-1),type:3};
                    if(view[deRotate(i,2)].ant == null) return {cell:deRotate(i,2),type:3};
                    if(view[deRotate(i,-2)].ant == null) return {cell:deRotate(i,-2),type:3};
                }
                return {cell:4};
            }
        }
        if(checkpos1.ant != null && view[deRotate(pos,1)].ant != null && !view[deRotate(pos,1)].ant.friend) {
            return foreverAlone();
        }

        var checkpos2 = view[deRotate(pos,4)];
        var checkpos3 = view[deRotate(checkpos,1)];
        if(checkpos1.ant != null && checkpos1.ant.friend && checkpos1.ant.type == 1 && checkpos2.ant != null && checkpos2.ant.friend && checkpos2.ant.type == 2 && checkpos3.ant != null && checkpos3.ant.friend && checkpos3.ant.type == 3) {
            //move out of spawn orientation
            return {cell:4};
        }
        if(view[pos].ant != null) {
            if(checkpos2.ant == null && checkpos1.ant == null) {
                return {cell:8-pos};
            }
            if(!view[pos].ant.friend) {
                return foreverAlone();
            }
            if(view[4].color == TRAIL) return foreverAlone();
            return {cell:4,color:TRAIL};
        }
        if(8 - findWorker(3) == findWorker(4)) {
            //finish rotate to the right
            return {cell:4};
        }
        if((view[deRotate(pos,1)].food > 0 || view[deRotate(pos,2)].food > 0) && view[deRotate(pos,1)].ant == null && view[4].color != TRAIL) {
            if(findWorker(1) < 0 || view[deRotate(findWorker(1),1)].food == 0) {
                return {cell:4};
            }
        }
        return {cell:pos};
    }
    return {cell:100+view[4].ant.type}; //oh god
}

//guides sit next to the queen
function doGuide() {
    var queenPos = findWorker(5);
    var ty = view[4].ant.type==3?2:1;
    var dir = view[4].ant.type==3?1:-1;
    if(queenPos >= 0 && queenPos%2 == 1 && view[queenPos].color == SPAWN) {
        if(view[deRotate(queenPos,dir*2)].ant == null) {
            return {cell:4};
        }
    }
    if(queenPos < 0 || findWorker(ty) < 0) {
        if(findWorker(ty) >= 0 && view[0].color != IDLE) return {cell:0,color:IDLE}
        return firebreak();
    }
    var checkpos = view[deRotate(queenPos,-2*dir)];
    if(view[4].ant.type==4 && checkpos.ant != null && checkpos.ant.friend && checkpos.ant.type == 1) {
        //attempt rotate
        return {cell:deRotate(queenPos,-dir)};
    }
    checkpos = view[deRotate(queenPos,4)];
    if(checkpos.ant != null && checkpos.ant.friend && checkpos.ant.type == ty) {
        //attempt rotate
        if(getNumWorkers(ty) == 1) {
            return {cell:4};
        }
    }
    var pos = deRotate(queenPos,dir);
    if(pos >= 0 && view[4].ant.type==3 && findWorker(4) < 0) {
        //wait for rotate
        if(view[4].color == TRAIL) {
            return {cell:4};
        }
    }
    if(pos >= 0 && findWorker(2) >= 0 && view[deRotate(findWorker(2),1)].ant != null) {
        //rotate
        return {cell:4,color:TRAIL};
    }
    if(pos < 0) pos = 4;
    else if(view[pos].ant != null) return {cell:deRotate(queenPos,4)};
    if(pos == 4 && view[queenPos].color == TRAIL) return {cell:queenPos,color:1};
    return {cell:pos};
}

//sweepers sit next to guides
function doSweep() {
    var queenPos = findWorker(5);
    var followType = view[4].ant.type==1?4:3;
    var pos = findWorker(followType);
    if(pos % 2 == 0 && getNumWorkers(followType) > 1) {
        //if there's more than one worker #4, we want to use the best one
        for(var i=pos+1;i<9;i++) {
            if(i != 4 && view[i].ant != null) {
                if(view[i].ant.friend && view[i].ant.type == followType) {
                    pos = i;
                    break;
                }
            }
        }
    }
    if(queenPos >= 0 && queenPos%2 == 1 && view[queenPos].color == SPAWN) {
        var p = findWorker(view[4].ant.type);
        if(p >= 0 && (deRotate(p,1) == queenPos || deRotate(p,-1) == queenPos)) {
            return {cell:8-queenPos};
        }
        return {cell:4};
    }
    if(queenPos >= 0 && pos < 0) {
        //if Worker #1 is the only ant besides the queen:
        //TODO
    //good
        if(view[queenPos].ant.food <= SPAWN_MIN || !(view[queenPos].ant.food < FOOD_THRESHOLD && view[queenPos].ant.food % 3 == 1 && !isOnHighway())) {
            var go = deRotate(queenPos,-1);
            if((view[deRotate(queenPos,-2)].food > 0 || view[deRotate(queenPos,-3)].food > 0 || (queenPos %2 == 1 && view[deRotate(queenPos,-3)].food > 0)) && view[go].food == 0) {
                go = deRotate(queenPos,2);
                //return {cell:4};
            }
            return {cell:go};
        }
        else if(view[queenPos].ant.food < FOOD_THRESHOLD && view[queenPos].ant.food % 3 == 1) {
            return {cell:4};
        }
    }
    if(queenPos >= 0) {
        var dir = view[4].ant.type==1?1:-1;
        //var checkpos = view[deRotate(pos,-dir)];
        var moveTo = deRotate(pos,dir);
        if(moveTo >= 0 && view[moveTo].ant != null && view[moveTo].ant.friend && view[moveTo].ant.type == 5) {
            moveTo = deRotate(pos,-dir);
        }
        if(view[4].ant.type == 2 && findWorker(1) < 0 && view[queenPos].color != TRAIL) {
            moveTo = 4;
        }
        return {cell:moveTo};
    }
    else {
        if(pos < 0) return {cell:4}; //firebreak();
        var dir = view[4].ant.type==1?-1:1;
        var moveTo = deRotate(pos,dir);
        if(view[4].ant.food > 0 && view[moveTo].food > 0) {
            //have food, attempt to give to queen
            moveTo = deRotate(pos,-dir);
        }
        if(view[4].ant.type==1 && pos >= 0 && (view[deRotate(pos,dir*2)].food > 0 || view[deRotate(pos,dir*3)].food > 0)) {
            //attempt rotate
            moveTo = deRotate(pos,-dir);
        }
        if(view[4].ant.type==2 && pos >= 0 && (view[deRotate(pos,dir*2)].food > 0 || view[deRotate(pos,dir*3)].food > 0)) {
            //attempt rotate
            moveTo = deRotate(pos,-dir);
        }
        if(moveTo >= 0 && view[moveTo].ant != null && view[moveTo].ant.type == 5) {
            if(view[moveTo].ant.friend)
                moveTo = deRotate(moveTo,dir*2);
            else
                moveTo = deRotate(pos,-dir);
        }
        return {cell:moveTo};
    }
    return {cell:100+view[4].ant.type};//oh god
}

function foreverAlone() {
    var s0 = view[0].ant;
    var s1 = view[1].ant;
    var s2 = view[2].ant;
    var s3 = view[3].ant;
    var s5 = view[5].ant;
    var s6 = view[6].ant;
    var s7 = view[7].ant;
    var s8 = view[8].ant;
    //good
    if(!(s0 == null && s1 == null && s2 == null && s3 == null && s5 == null && s6 == null && s7 == null && s8 == null) && view[4].color == SPAWNTRAIL) {
        if (view[0].color == TRAIL && !view[8].ant && view[8].color != TRAIL) return {cell: 8};
        else if (view[2].color == TRAIL && !view[6].ant && view[6].color != TRAIL) return {cell: 6};
        else if (view[6].color == TRAIL && !view[2].ant && view[2].color != TRAIL) return {cell: 2};
        else if (view[8].color == TRAIL && !view[0].ant && view[0].color != TRAIL) return {cell: 0};
        //Can't find color, or path is blocked? try diagonals regardless of color
        else if (!view[0].ant) return {cell: 0};
        else if (!view[2].ant) return {cell: 2};
        else if (!view[6].ant) return {cell: 6};
        else if (!view[8].ant) return {cell: 8};
        //Everything else failed? Stay put.
        else return {cell: 4};
    }
    if//good
 (view[4].color == TRAIL ||if (view[4].color == SPAWNTRAIL) { //If on colored square, try to move
        var totGreen = 0;
        for (var i = 0; i < 9; i++) { //Look for food
            if (view[i].food) {
                return {cell: i};
            }
            if(view[i].color == TRAIL) totGreen++;
        }
        var ret = getTrailMove();
        if(view[deRotate(ret.cell,1)].color == TRAIL && totGreen <= 4) ret.cell = deRotate(ret.cell,-1);
        else if(view[deRotate(ret.cell,-1)].color == TRAIL && totGreen <= 4) ret.cell = deRotate(ret.cell,1);
        return ret;
    } else { //If not on colored square, look for food, or set current color to 2.
        for (var i = 0; i < 9; i++) { //Look for enemies
            if (i != 4 && view[i].ant != null && !view[i].ant.friend) {
                var r = findOpenSpace(8-i,1);
                if(view[r].color == TRAIL) r = deRotate(r,1);
                return {cell: r};
            }
        }
        return {cell: 4, color:TRAIL};
    }
}

function getTrailMove() {
    if (view[0].color == TRAIL && !view[8].ant && view[8].color != TRAIL) return {cell: 8};
    else if (view[2].color == TRAIL && !view[6].ant && view[6].color != TRAIL) return {cell: 6};
    else if (view[6].color == TRAIL && !view[2].ant && view[2].color != TRAIL) return {cell: 2};
    else if (view[8].color == TRAIL && !view[0].ant && view[0].color != TRAIL) return {cell: 0};
    //Can't find color, or path is blocked? try diagonals regardless of color
    else if (!view[0].ant) return {cell: 0};
    else if (!view[2].ant) return {cell: 2};
    else if (!view[6].ant) return {cell: 6};
    else if (!view[8].ant) return {cell: 8};
    //Everything else failed? Stay put.
    else return {cell: 4};
}

function firebreak() {
    var ret = -1;
    if(findWorker(5) >= 0) {
        return {cell:8-findWorker(5)};
    }
    if(view[4].color != 5) {
        var myView = [0,0,0,0,0,0,0,0,0]
        for(var i=0; i < 9; i++) {
            myView[i] = view[i].color
            if(view[4].ant.food > 0 && view[i].food > 0) {
                myView[i] = 8;
            }
            if(view[i].ant != null && !view[i].ant.friend) return {cell:findOpenSpace(deRotate(i,2),1)};
        }
        var ret = clearAhead(myView);
        if(ret == null)
            return {cell:4,color:5};
        else {
            if(!(view[ret.cell].ant != null && view[ret.cell].ant.friend == false) && (view[4].ant.food == 0 || view[ret.cell].food == 0))
                return ret;
            return {cell:4,color:5};
        }
    }
    if(view[1].color == 5 && view[3].color == 5 && view[5].color == 5 && view[7].color == 5) {
        if(view[0].color != 8) return {cell:0,color:8};
        if(view[1].color != 8) return {cell:1,color:8};
    }
    if(view[1].color == 5 && view[7].color != 5) ret = {cell:7};
    if(view[3].color == 5 && view[5].color != 5) ret = {cell:5};
    if(view[5].color == 5 && view[3].color != 5) ret = {cell:3};
    if(view[7].color == 5 && view[1].color != 5) ret = {cell:1};
    if(view[1].color != 5 && view[3].color != 5 && view[5].color != 5 && view[7].color != 5) ret = {cell:1};
    if((view[1].color == 5 && view[7].color == 5) || (view[3].color == 5 && view[5].color == 5)) ret = {cell:0};
    var loop = 0;
    while(ret.cell >= 0 && ((view[ret.cell].food > 0 && view[4].ant.food > 0) || view[ret.cell].ant != null) && loop < 9) {
        loop++;
        ret.cell = (ret.cell + 2) % 9;
    }
    if(loop < 9 && ret.cell >= 0) return ret;
    return {cell:4};
}

//7,6,4,2,3
//O7,D2

function highwayRobbery() {
    var move = basicHighwayMove();
    if(move.cell >= 0 && view[move.cell].ant != null) {
        var n = HIGHWAY_COLORS.indexOf(view[4].color) + (view[4].color%2==0?1:HIGHWAY_COLORS.length);
        var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
        for(var i=0;i<9;i++) {
            if(view[i].color == nextMove) {
                return {cell:i};
            }
        }
    }
    return move;
}

function basicHighwayMove() {
    var isQueen = view[4].ant.type == 5;
    if(isHighwayCenter()) {
        var n = HIGHWAY_COLORS.indexOf(view[4].color) + 1;
        var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
        for(var i=0;i<9;i++) {
            if(view[i].color == nextMove) {
                if(view[i].ant == null)
                    return {cell:i};
                else {
                    return {cell:deRotate(i,1)};
                }
            }
        }
    }
    else {
        if(view[4].color == 7) {
            //move diagonal to yellow (2)
            for(var i=0;i<9;i++) {
                if(i != 4 && i % 2 == 0 && view[i].color == 2) {
                    return {cell:i};
                }
            }
        }
        else {
            //move orthogonal to blue (7)
            for(var i=0;i<9;i++) {
                if(i % 2 == 1 && view[i].color == 7) {
                    //try ortho yellow first
                    for(var j=0;j<9;j++) {
                        if(j % 2 == 1 && view[j].color == 2 && areAdjacent(i,j))
                            return {cell:j};
                    }
                    return {cell:i};
                }
            }
            //if orthogonal blue doens't exist...
            //...try diagonal to magenta
            for(var i=0;i<9;i++) {
                if(i != 4 && i % 2 == 0 && view[i].color == 3) {
                    return {cell:i};
                }
            }
            if(view[4].color != 2) {
                //...try diagonal blue
                for(var i=0;i<9;i++) {
                    if(i % 2 == 0 && view[i].color == 7)
                        return {cell:i};
                }
            }
            //...and orthogonal yellow
            for(var i=0;i<9;i++) {
                if(i % 2 == 1 && view[i].color == 2)
                    return {cell:i};
            }
        }
        var n = HIGHWAY_COLORS.indexOf(view[4].color) + 1;
        var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
        for(var i=0;i<9;i++) {
            if(view[i].color == nextMove) {
                return {cell:i};
            }
        }
    }
    return {cell:-1};
}

function isOnHighway() {
    var match = 0;
    var nxt = HIGHWAY_COLORS[(HIGHWAY_COLORS.indexOf(view[4].color)+1) % HIGHWAY_COLORS.length];//4
    var prv = HIGHWAY_COLORS[(HIGHWAY_COLORS.indexOf(view[4].color)+HIGHWAY_COLORS.length-2) % HIGHWAY_COLORS.length];//6
    for(var i=0;i<9;i++) {
        if(HIGHWAY_COLORS.indexOf(view[i].color) >=0 && (i == 4 || view[i].color != view[4].color))
            match++;
    }
    if(match >= 5) {
        //7,6,4,2,3


        if((view[1].color == nxt && view[7].color == prv)||(view[1].color == prv && view[7].color == nxt) || 
            (view[3].color == nxt && view[5].color == prv)||(view[3].color == prv && view[5].color == nxt)) {
            return true;
        }
        if((view[1].color == view[8].color && (view[1].color == nxt || view[1].color == prv))||(view[1].color == view[6].color && (view[1].color == nxt || view[1].color == prv)) || 
            (view[3].color == view[2].color && (view[3].color == nxt || view[3].color == prv))||(view[3].color == view[8].color && (view[3].color == nxt || view[3].color == prv))) {
            return true;
        }
        if((view[0].color == view[7].color && (view[0].color == nxt || view[0].color == prv))||(view[2].color == view[7].color && (view[2].color == nxt || view[2].color == prv)) || 
            (view[0].color == view[5].color && (view[0].color == nxt || view[0].color == prv))||(view[6].color == view[5].color && (view[6].color == nxt || view[6].color == prv))) {
            return true;
        }
        if(isHighwayCenter()) {
            return true;
        }
    }
    return false;
}

function isHighwayCenter() {
    if(HIGHWAY_COLORS.indexOf(view[4].color) >=0 && (((view[0].color != view[8].color || view[2].color != view[6].color) && view[4].ant.type == 1) || (view[0].color != view[8].color && view[2].color != view[6].color))){
        var m1 = view[1].color == view[7].color;
        var m2 = view[2].color == view[8].color;
        var m3 = view[0].color == view[6].color;
        var m4 = view[0].color != 1 && view[2].color != 1;
        if((m1?1:0)+(m2?1:0)+(m3?1:0) >= 2 && m4) {
            if(view[3].color != view[5].color && ((view[2].color != view[5].color && view[8].color != view[5].color) || view[4].ant.type == 1) && ((view[3].color != view[0].color && view[3].color != view[6].color) || view[4].ant.type == 1)) {
                return true;
            }
        }
        m1 = view[3].color == view[5].color;
        m2 = view[0].color == view[2].color;
        m3 = view[6].color == view[8].color;
        m4 = view[0].color != 1 && view[6].color != 1;
    //good
        if((m1?1:0)+(m2?1:0)+(m3?1:0) >= 2 && m4) {
            if(m1 = view[1].color != view[7].colorcolor;
 && (          m2 = (view[0].color != view[1].color && view[1].color != view[2].color);
 || view[4].ant.type == 1) && (      m3 = (view[6].color != view[7].color && view[7].color != view[8].color);
 ||           if(m1 && m2 && m3) {
                return true;
            }
            if(view[4].ant.type == 1 && ((m1?1:0)+(m2?1:0)+(m3?1:0)) >= 2) {
                return true;
            }
        }
    }
    return false;
}

function deRotateSide(m, amt) {
    return deRotate(m,amt*2);
}

/**Positive amount is clockwise**/
function deRotate(m, amt) {
    var rotationsCW = [1,2,5,8,7,6,3,0];
    var rotationsCCW = [3,6,7,8,5,2,1,0];
    if(m == 4 || m < 0 || m > 8 || amt == 0) return m;
    if(amt > 0)
        return rotationsCW[(rotationsCW.indexOf(m)+amt)%8];
    amt = -amt;
    return rotationsCCW[(rotationsCCW.indexOf(m)+amt)%8];
}

function areAdjacent(A, B) {
    if(A == 4 || B == 4 || A == B) return true;
    if(A % 2 == 0 && B % 2 == 0) return false;
    if(A % 2 == 1 && B % 2 == 0) return areAdjacent(B,A);
    if(A % 2 == 1 && B % 2 == 1) return !(8-A == B || 8-B == A);
    if(A == 0 && (B == 1 || B == 3)) return true;
    if(A == 2 && (B == 1 || B == 5)) return true;
    if(A == 6 && (B == 3 || B == 7)) return true;
    if(A == 8 && (B == 5 || B == 7)) return true;
    return false;
}

function findFirstTrail() {
    var pos = 0;
    var b = 0;
    while(view[pos].color != TRAIL && b < 8) {
        pos=deRotate(pos,1);
        b++;
    }
    return pos;
}

function clearAhead(sides) {
    var c=0;
    for(var i=0;i<9;i++) {
        if(view[i].color == 5) c++;
        if(view[i].color == 5 && i%2 == 0) c+=10;
    }
    if(c == 2) {
        if(view[0].color == 5 || view[2].color == 5 || view[6].color == 5 || view[8].color == 5) {
            return {cell:4,color:5};
        }
        if(view[0].ant == null)
            return {cell:0};
        if(view[2].ant == null)
            return {cell:2};
        if(view[6].ant == null)
            return {cell:6};
        if(view[8].ant == null)
            return {cell:8};
    }
    c = 0;
    sides[4] = 0;
    var toMatch =[{state:[1,1,1,
                          2,0,2,
                          0,1,0]},
                 {state:[0,2,1,
                         1,0,1,
                         0,2,1]},
                 {state:[0,1,0,
                         2,0,2,
                         1,1,1]},
                 {state:[1,2,0,
                         1,0,1,
                         1,2,0]}];
    for(var m=0;m<4;m++) {
        var score=0;
        for(var j=0;j<9;j++) {
            if(j!=4) {
                if(sides[j] == 5 && toMatch[m].state[j] == 1) {
                    score++;
                }
                if(sides[j] != 5 && (toMatch[m].state[j] == 0 || toMatch[m].state[j] == 2)) {
                    score++;
                }
                if(sides[j] == 5 && toMatch[m].state[j] == 2) {
                    score--;
                }
            }
        }
        if(score >= 6) {
            var clearOrder=[1,0,2];
            for(var r=0;r<clearOrder.length;r++) {
                var s = deRotateSide(clearOrder[r],m);
                if(view[s].color == 5) {
                    if(view[s].ant == null)
                        return {cell:s,color:8};
                    else
                        return {cell:4};
                }
            }
        }
    }
    return null;
}

function findOpenSpace(pos, dir) {
    if(pos > 8 || pos < 0) return pos;
    var b = 0;
    while(view[pos].ant != null && b < 8) {
        pos=deRotate(pos,dir);
        b++;
    }
    return pos;
}

function getHighestWorker() {
    var r=0;
    for(var i=0;i<9;i++) {
        if(i != 4 && view[i].ant != null) {
            if(view[i].ant.friend && view[i].ant.type > r) r = view[i].ant.type;
        }
    }
    return r;
}

function getNumWorkers(type) {
    var r=0;
    for(var i=0;i<9;i++) {
        if(i != 4 && view[i].ant != null) {
            if(view[i].ant.friend && view[i].ant.type == type) r++;
        }
    }
    return r;
}

function findWorker(type) {
    for(var i=0;i<9;i++) {
        if(i != 4 && view[i].ant != null) {
            if(view[i].ant.friend && view[i].ant.type == type) return i;
        }
    }
    return -1;
}

316%326% Complete
316%326% because the update was on 3/16This joke has gone on too long

Update 3/26

More minor tweaks.

var TRAIL = 6;
var SPAWN = 3;
var IDLE = 4;
var FOOD_THRESHOLD = 150;
var SPAWN_MIN = 3;
var HIGHWAY_COLORS = [7,6,4,2,3];
var ret = {cell:4};
if(isOnHighway()) {
    var cont = true;
    //== Make best guess to if in a glider formation ==//
    if(view[4].ant.type == 5) {
        if((findWorker(1) >= 0 && findWorker(4) >= 0) || view[4].ant.food < 80) {
            cont = false;
        }
    }
    else if(view[4].ant.type == 4) {
        if(findWorker(1) >= 0 && findWorker(5) >= 0) {
            cont = false;
        }
    }
    else if(view[4].ant.type == 3) {
        if(findWorker(2) >= 0 && findWorker(5) >= 0) {
            cont = false;
        }
    }
    else if(view[4].ant.type == 2) {
        if(findWorker(5) < 0) {
            var pos3 = findWorker(3);
            if(pos3 >= 0 && view[pos3].ant.food == 0) {
                cont = false;
            }
        }
        else if(findWorker(3) >= 0 || (findWorker(1) >= 0 && view[findWorker(5)].color == SPAWN))
            cont = false;
    }
    else if(view[4].ant.type == 1) {
        if(findWorker(5) < 0) {
            var pos4 = findWorker(4);
            if(pos4 >= 0 && view[pos4].ant.food == 0) {
                cont = false;
            }
        }
        else if(!isHighwayCenter())
            cont = false;
    }
    if(findWorker(5) >= 0) {
        for(var i=0;i<9;i++) {
            if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                if(view[i].ant.food > 10 || view[i].ant.food == 0)
                    cont = true;
                else
                    cont = false;
            }
        }
    }
    //== End guesswork ==//
    if(cont) {
        ret = highwayRobbery();
        if(view[4].ant.type == 1) {
            //try to repair
            var curIndex = HIGHWAY_COLORS.indexOf(view[4].color);
            var prvCol = HIGHWAY_COLORS[(curIndex+1)%HIGHWAY_COLORS.length];
            var nxtCol1 = HIGHWAY_COLORS[(curIndex+HIGHWAY_COLORS.length-1)%HIGHWAY_COLORS.length];
            var nxtCol2 = HIGHWAY_COLORS[(curIndex+HIGHWAY_COLORS.length-2)%HIGHWAY_COLORS.length];
            var nxtCol3 = HIGHWAY_COLORS[(curIndex+HIGHWAY_COLORS.length-3)%HIGHWAY_COLORS.length];
            var prevAt = -1;
            for(var i=0;i<9;i++) {
                if(i%2 == 1 && view[i].color == prvCol && view[deRotate(i,1)].color == nxtCol1 && view[deRotate(i,-1)].color == nxtCol1) prevAt = i;
            }
            if(prevAt >= 0) {
                // yep, brute force it. Because I'm lazy.
                var goNxt = 8-prevAt;
                if(view[deRotate(goNxt,1)].color == nxtCol3 && view[deRotate(goNxt,-1)].color == prvCol) ret = {cell:goNxt};
                else if(view[deRotate(goNxt,1)].color == prvCol && view[deRotate(goNxt,-1)].color == nxtCol3) ret = {cell:goNxt};
                else if(view[goNxt].color != nxtCol1) ret = {cell:goNxt,color:nxtCol1};
                else if(view[deRotate(goNxt,2)].color != nxtCol2) ret = {cell:deRotate(goNxt,2),color:nxtCol2};
                else if(view[deRotate(goNxt,-2)].color != nxtCol2) ret = {cell:deRotate(goNxt,-2),color:nxtCol2};
                else if(view[deRotate(goNxt,1)].color != nxtCol3) ret = {cell:deRotate(goNxt,1),color:nxtCol3};
                else if(view[deRotate(goNxt,-1)].color != nxtCol3) ret = {cell:deRotate(goNxt,-1),color:nxtCol3};
                else ret = {cell:goNxt};
                ret = sanityCheck(ret);
                return ret;
            }
        }
        if(view[4].ant.type == 5 && isHighwayCenter()) {
            if(ret.cell >= 0) {
                ret = {cell:8-ret.cell};
                if(view[4].color == SPAWN && (view[4].ant.food > 90 || view[4].ant.food % 7 == 0) && getHighestWorker() == 0 && (view[4].ant.food < 140 || view[4].ant.food % 9 == 0) && view[0].color == 2 && view[4].ant.food > 50 && view[4].ant.food < 200) {
                    ret = {cell:deRotate(ret.cell,3),type:3};
                }
                if(view[ret.cell].ant != null && !view[ret.cell].ant.friend && view[ret.cell].ant.food == 0 && view[4].ant.food > 0) {
                    if(view[deRotate(ret.cell,1)].ant == null)
                        ret = {cell:deRotate(ret.cell,1),type:3};
                    if(view[deRotate(ret.cell,-1)].ant == null)
                        ret = {cell:deRotate(ret.cell,1),type:3};
                }
            }
            for(var i=0;i<9;i++) {
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                    ret = {cell:8-i};
                }
            }
        }
        if(ret.cell >= 0) {
            for(var i=0;i<9;i++) {
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                    var rr = basicHighwayMove();
                    if(rr.cell >= 0 && view[4].ant.type != 5)
                        ret = {cell:deRotate(rr.cell,-2)};
                }
            }
            if(view[ret.cell].ant != null) {
                var n = HIGHWAY_COLORS.indexOf(view[4].color) + 1;
                var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
                for(var i=0;i<9;i++) {
                    if(view[i].color == nextMove) {
                        if(view[i].ant == null) {
                            ret = {cell:i};
                            break;
                        }
                    }
                }
                if(view[4].ant.type == 5) ret = {cell:8-ret.cell};
            }
        }
        if(view[4].ant.type == 5) {
            var foodedEnemy = false;
            for(var i=0;i<9;i++) {
                if(getNumWorkers(3) >= 2) break;
                if(i != 4 && view[i].ant != null && view[i].ant.type == 5 && view[i].ant.food > 25) {
                    if(view[deRotate(i,1)].ant == null) {
                        ret = {cell:deRotate(i,1),type:3};
                    }
                    else if(view[deRotate(i,-1)].ant == null) {
                        ret = {cell:deRotate(i,-1),type:3};
                    }
                    else if(i%2 == 1 && view[deRotate(i,2)].ant == null) {
                        ret = {cell:deRotate(i,2),type:3};
                    }
                    else if(i%2 == 1 && view[deRotate(i,-2)].ant == null) {
                        ret = {cell:deRotate(i,-2),type:3};
                    }
                }
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 3 && view[8-i].ant == null) {
                    if(i == ret.cell) {
                        ret = {cell:deRotate(i,1)}
                    }
                    else {
                        return {cell:8-i};
                    }
                }
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.food == 0) {
                    foodedEnemy = true;
                }
            }
        }
        var numAnts = 0;
        for(var i=0;i<9;i++) {
            if(view[i].ant != null)
                numAnts++;
        }
        if(numAnts > 2 && sanityCheck(ret).cell == 4) {
            ret = {cell:findOpenSpace(0,1)};
        }
        if(view[4].ant.type == 3) {
            if(getNumWorkers(5) > 0) {
                for(var i=0;i<9;i++) {
                    if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                        ret = {cell:4};
                    }
                }
            }
        }
        if(view[4].ant.type == 4 && getNumWorkers(1) && isHighwayCenter()) {
            var workerPos = findWorker(1);
            for(var i=0;i<9;i++) {
                if(!areAdjacent(i,workerPos)) ret = {cell:i};
            }
        }
        if(ret.cell == -1) {
            if(isHighwayCenter()) {
                for(var i=0;i<9;i++) {
                    var p1 = deRotate(i,3);
                    var p2 = deRotate(i,-3);
                    if(view[i].color == view[p1].color && view[i].color == view[p2].color) {
                        ret = {cell:8-i};
                    }
                }
                if(view[4].ant.type == 1 || view[4].ant.type == 5) {
                    ret = {cell:8-ret.cell};
                }
            }
        }
        if(ret.cell >= 0)
            return sanityCheck(ret);
    }
}

switch(view[4].ant.type) {
    case 5:
        ret = doQueen();
        break;
    case 1:
    case 2:
        ret = doSweep();
        break;
    case 3:
    case 4:
        ret = doGuide();
        break;
    default:
        break;
}
//basic sanity check
ret = sanityCheck(ret);
return ret;

function sanityCheck(ret) {
    if(!ret || ret.cell < 0 || ret.cell > 8) {
        return {cell:4};
    }
    if(ret.color) {
        return ret;
    }
    if((ret.cell != 4 && view[ret.cell].ant != null) || (view[ret.cell].food > 0 && (view[4].ant.food > 0 && view[4].ant.type < 5))) {
        return {cell:4};
    }
    if(ret.type && (view[ret.cell].ant != null || view[ret.cell].food > 0 || view[4].ant.food == 0 || view[4].ant.type < 5)) {
        return {cell:4};
    }
    return ret;
}

function doQueen() {
    if((view[4].ant.food == SPAWN_MIN || (view[4].ant.food >= SPAWN_MIN && view[4].ant.food < FOOD_THRESHOLD && (view[4].ant.food % 3 == 1 || isOnHighway()))) && getHighestWorker() <= 1 ) {
        //prep for first ant
        var s0 = view[0].ant;
        var s1 = view[1].ant;
        var s2 = view[2].ant;
        var s3 = view[3].ant;
        var s5 = view[5].ant;
        var s6 = view[6].ant;
        var s7 = view[7].ant;
        var s8 = view[8].ant;
        var nullCount = 0 + (s0 == null?1:0) + (s1 == null?1:0) + (s2 == null?1:0) + (s3 == null?1:0) + (s5 == null?1:0) + (s6 == null?1:0) + (s7 == null?1:0) + (s8 == null?1:0);
        var nullCount2 = 0 + (s0 == null || s0.friend?1:0) + (s1 == null || s1.friend?1:0) + (s2 == null || s2.friend?1:0) + (s3 == null || s3.friend?1:0) + (s5 == null || s5.friend?1:0) + (s6 == null || s6.friend?1:0) + (s7 == null || s7.friend?1:0) + (s8 == null || s8.friend?1:0);
        if(nullCount >= 7 && nullCount2 >= 8 && view[1].food == 0 && view[3].food == 0 && view[5].food == 0 && view[7].food == 0) {
            var high = getHighestWorker();
            if (high <= 1 && view[4].color != SPAWN && !isOnHighway()) {
                // 50% chance of delaying the respawn by 1 additional move away from where we exploded
                // reduces the chance of a second, immediate explosion
                if(findFirstTrail() < 2 && view[4].ant.food > SPAWN_MIN+1) return foreverAlone();
                var pos1 = findWorker(1);
                if(pos1 >= 0) {
                    var space = deRotate(pos1,2);
                    if(view[space].ant != null) return {cell:findOpenSpace(0,1)};
                }
                return {cell:4,color:SPAWN};
            }
            //spawn first ant
            else if(view[4].color == SPAWN) {
                var pos1 = findWorker(1);
                if(pos1 < 0)  {
                    pos1 = findFirstTrail();
                    if(pos1 % 2 == 0) pos1 = deRotate(pos1,1);
                    else pos1 = deRotate(pos1,4);
                }
                var space = findOpenSpace(pos1,2);
                var high = getHighestWorker();
                if(space < 0) return {cell:4,color:TRAIL}
                if(high == 0) { //no workers
                    return {cell:space,type:1};
                }
                else if(high < 4) { //1 worker of type:high
                    return {cell:space,type:high+1};
                }
                else { //1 worker of type 4
                    //we have all workers, skip!
                }
            }
        }
        else {
            return foreverAlone();
        }
    }
    else if(view[4].ant.food == 1 && getHighestWorker() == 0 ) {
        var space = findOpenSpace(1,2);
        return {cell:space,type:1};
    }
    else if(view[4].ant.food >= 1 && getHighestWorker() < 4 && findWorker(1) >= 0) {
        //spawn remaining ants
        if(view[4].color == SPAWN && !isHighwayCenter()) {
            var pos1 = findWorker(getHighestWorker());
            var space = deRotate(pos1,2);
            var high = getHighestWorker();
            if(space < 0 || view[space].ant != null) return {cell:findOpenSpace(0,1)};
            if(high == 0) { //no workers
                return {cell:space,type:1};
            }
            else if(high < 4) { //1 worker of type:high
                return {cell:space,type:high+1};
            }
            else { //1 worker of type 4
                //we have all workers, skip!
            }
        }
    }
    if(view[4].color == SPAWN && getNumWorkers(3) == 1 && getNumWorkers(4) == 1) {
        var one = getNumWorkers(1);
        var two = getNumWorkers(2);
        if((one ^ two) == 1 && (findWorker(1) % 2 == 0 || findWorker(2) % 2 == 0))
            return {cell:4,color:1};
    }
    if(getNumWorkers(1) == 0 && getNumWorkers(2) == 0) {
        if(getNumWorkers(4) == 1 && getNumWorkers(3) == 0) {
            var pos4 = findWorker(4);
            if(view[deRotate(pos4,1)].ant == null && view[deRotate(pos4,2)].ant == null && findWorker(4) % 2 == 1) {
                //finish rotate with only one glider arm
                return {cell:4};
            }
        }
        return foreverAlone();
    }
    else if(getNumWorkers(1) >= 1 && getNumWorkers(2) >= 1 && getNumWorkers(3) >= 1 && getNumWorkers(4) >= 1) {
        if(view[4].color != 2 && findWorker(1)%2 == 1 && findWorker(2)%2 == 1) {
            return {cell:4,color:TRAIL};
        }
        //move diagonally
        var pos = findWorker(4);
        pos = deRotate(pos,1);
        var checkpos = view[deRotate(pos,4)];
        if(checkpos.ant != null && checkpos.ant.friend) {
            if(checkpos.ant.type == 2)
                return {cell:4};
            if(checkpos.ant.type == 1)
                return {cell:4};
        }
        return {cell:pos};
    }
    else {
        var pos = findWorker(4);
        if(pos < 0) {
            //if gliding along with only a buddy
            pos = findWorker(1);
            if(pos >= 0 && view[deRotate(pos,2)].food > 0 && view[deRotate(pos,1)].food == 0) {
                return {cell:4};
            }
        }
        if(pos < 0) {
            var s1 = view[1].ant;
            var s3 = view[3].ant;
            var s5 = view[5].ant;
            var s7 = view[7].ant;
            //return {cell:999}
            if(s1 == null) {
                if(s3 == null) {
                    return {cell:0};
                }
                if(s5 == null) {
                    return {cell:2};
                }
            }
            if(s7 == null) {
                if(s3 == null) {
                    return {cell:6};
                }
                if(s5 == null) {
                    return {cell:8};
                }
            }
            return {cell:4};
        }
        pos = deRotate(pos,1);
        var checkpos1 = view[pos];
        for(var i=0;i<9;i++) {
            if(i != 4 && view[i].ant != null && view[i].ant.type == 5 && view[i].ant.food > 2) {
                if(i%2==0) {
                    if(view[deRotate(i,1)].ant == null) return {cell:deRotate(i,1),type:3};
                    if(view[deRotate(i,-1)].ant == null) return {cell:deRotate(i,-1),type:3};
                }
                else {
                    if(view[deRotate(i,1)].ant == null) return {cell:deRotate(i,1),type:3};
                    if(view[deRotate(i,-1)].ant == null) return {cell:deRotate(i,-1),type:3};
                    if(view[deRotate(i,2)].ant == null) return {cell:deRotate(i,2),type:3};
                    if(view[deRotate(i,-2)].ant == null) return {cell:deRotate(i,-2),type:3};
                }
                return {cell:4};
            }
        }
        if(checkpos1.ant != null && view[deRotate(pos,1)].ant != null && !view[deRotate(pos,1)].ant.friend) {
            return foreverAlone();
        }

        var checkpos2 = view[deRotate(pos,4)];
        var checkpos3 = view[deRotate(checkpos,1)];
        if(checkpos1.ant != null && checkpos1.ant.friend && checkpos1.ant.type == 1 && checkpos2.ant != null && checkpos2.ant.friend && checkpos2.ant.type == 2 && checkpos3.ant != null && checkpos3.ant.friend && checkpos3.ant.type == 3) {
            //move out of spawn orientation
            return {cell:4};
        }
        if(view[pos].ant != null) {
            if(checkpos2.ant == null && checkpos1.ant == null) {
                return {cell:8-pos};
            }
            if(!view[pos].ant.friend) {
                return foreverAlone();
            }
            if(view[4].color == TRAIL) return foreverAlone();
            return {cell:4,color:TRAIL};
        }
        if(8 - findWorker(3) == findWorker(4)) {
            //finish rotate to the right
            return {cell:4};
        }
        if((view[deRotate(pos,1)].food > 0 || view[deRotate(pos,2)].food > 0) && view[deRotate(pos,1)].ant == null && view[4].color != TRAIL) {
            if(findWorker(1) < 0 || view[deRotate(findWorker(1),1)].food == 0) {
                return {cell:4};
            }
        }
        return {cell:pos};
    }
    return {cell:100+view[4].ant.type}; //oh god
}

//guides sit next to the queen
function doGuide() {
    var queenPos = findWorker(5);
    var ty = view[4].ant.type==3?2:1;
    var dir = view[4].ant.type==3?1:-1;
    if(queenPos >= 0 && queenPos%2 == 1 && view[queenPos].color == SPAWN) {
        if(view[deRotate(queenPos,dir*2)].ant == null) {
            return {cell:4};
        }
    }
    if(queenPos < 0 || findWorker(ty) < 0) {
        if(findWorker(ty) >= 0 && view[0].color != IDLE) return {cell:0,color:IDLE}
        return firebreak();
    }
    var checkpos = view[deRotate(queenPos,-2*dir)];
    if(view[4].ant.type==4 && checkpos.ant != null && checkpos.ant.friend && checkpos.ant.type == 1) {
        //attempt rotate
        return {cell:deRotate(queenPos,-dir)};
    }
    checkpos = view[deRotate(queenPos,4)];
    if(checkpos.ant != null && checkpos.ant.friend && checkpos.ant.type == ty) {
        //attempt rotate
        if(getNumWorkers(ty) == 1) {
            return {cell:4};
        }
    }
    var pos = deRotate(queenPos,dir);
    if(pos >= 0 && view[4].ant.type==3 && findWorker(4) < 0) {
        //wait for rotate
        if(view[4].color == TRAIL) {
            return {cell:4};
        }
    }
    if(pos >= 0 && findWorker(2) >= 0 && view[deRotate(findWorker(2),1)].ant != null) {
        //rotate
        return {cell:4,color:TRAIL};
    }
    if(pos < 0) pos = 4;
    else if(view[pos].ant != null) return {cell:deRotate(queenPos,4)};
    if(pos == 4 && view[queenPos].color == TRAIL) return {cell:queenPos,color:1};
    return {cell:pos};
}

//sweepers sit next to guides
function doSweep() {
    var queenPos = findWorker(5);
    var followType = view[4].ant.type==1?4:3;
    var pos = findWorker(followType);
    if(pos % 2 == 0 && getNumWorkers(followType) > 1) {
        //if there's more than one worker #4, we want to use the best one
        for(var i=pos+1;i<9;i++) {
            if(i != 4 && view[i].ant != null) {
                if(view[i].ant.friend && view[i].ant.type == followType) {
                    pos = i;
                    break;
                }
            }
        }
    }
    if(queenPos >= 0 && queenPos%2 == 1 && view[queenPos].color == SPAWN) {
        var p = findWorker(view[4].ant.type);
        if(p >= 0 && (deRotate(p,1) == queenPos || deRotate(p,-1) == queenPos)) {
            return {cell:8-queenPos};
        }
        return {cell:4};
    }
    if(queenPos >= 0 && pos < 0) {
        //if Worker #1 is the only ant besides the queen:
        //TODO
        if(view[queenPos].ant.food <= SPAWN_MIN || !(view[queenPos].ant.food < FOOD_THRESHOLD && view[queenPos].ant.food % 3 == 1)) {
            var go = deRotate(queenPos,-1);
            if((view[deRotate(queenPos,-2)].food > 0 || view[deRotate(queenPos,-3)].food > 0 || (queenPos %2 == 1 && view[deRotate(queenPos,-3)].food > 0)) && view[go].food == 0) {
                go = deRotate(queenPos,2);
                //return {cell:4};
            }
            return {cell:go};
        }
        else if(view[queenPos].ant.food < FOOD_THRESHOLD && view[queenPos].ant.food % 3 == 1) {
            return {cell:4};
        }
    }
    if(queenPos >= 0) {
        var dir = view[4].ant.type==1?1:-1;
        //var checkpos = view[deRotate(pos,-dir)];
        var moveTo = deRotate(pos,dir);
        if(moveTo >= 0 && view[moveTo].ant != null && view[moveTo].ant.friend && view[moveTo].ant.type == 5) {
            moveTo = deRotate(pos,-dir);
        }
        if(view[4].ant.type == 2 && findWorker(1) < 0 && view[queenPos].color != TRAIL) {
            moveTo = 4;
        }
        return {cell:moveTo};
    }
    else {
        if(pos < 0) return {cell:4}; //firebreak();
        var dir = view[4].ant.type==1?-1:1;
        var moveTo = deRotate(pos,dir);
        if(view[4].ant.food > 0 && view[moveTo].food > 0) {
            //have food, attempt to give to queen
            moveTo = deRotate(pos,-dir);
        }
        if(view[4].ant.type==1 && pos >= 0 && (view[deRotate(pos,dir*2)].food > 0 || view[deRotate(pos,dir*3)].food > 0)) {
            //attempt rotate
            moveTo = deRotate(pos,-dir);
        }
        if(view[4].ant.type==2 && pos >= 0 && (view[deRotate(pos,dir*2)].food > 0 || view[deRotate(pos,dir*3)].food > 0)) {
            //attempt rotate
            moveTo = deRotate(pos,-dir);
        }
        if(moveTo >= 0 && view[moveTo].ant != null && view[moveTo].ant.type == 5) {
            if(view[moveTo].ant.friend)
                moveTo = deRotate(moveTo,dir*2);
            else
                moveTo = deRotate(pos,-dir);
        }
        return {cell:moveTo};
    }
    return {cell:100+view[4].ant.type};//oh god
}

function foreverAlone() {
    var s0 = view[0].ant;
    var s1 = view[1].ant;
    var s2 = view[2].ant;
    var s3 = view[3].ant;
    var s5 = view[5].ant;
    var s6 = view[6].ant;
    var s7 = view[7].ant;
    var s8 = view[8].ant;
    if(!(s0 == null && s1 == null && s2 == null && s3 == null && s5 == null && s6 == null && s7 == null && s8 == null) && view[4].color == SPAWN) {
        if (view[0].color == TRAIL && !view[8].ant && view[8].color != TRAIL) return {cell: 8};
        else if (view[2].color == TRAIL && !view[6].ant && view[6].color != TRAIL) return {cell: 6};
        else if (view[6].color == TRAIL && !view[2].ant && view[2].color != TRAIL) return {cell: 2};
        else if (view[8].color == TRAIL && !view[0].ant && view[0].color != TRAIL) return {cell: 0};
        //Can't find color, or path is blocked? try diagonals regardless of color
        else if (!view[0].ant) return {cell: 0};
        else if (!view[2].ant) return {cell: 2};
        else if (!view[6].ant) return {cell: 6};
        else if (!view[8].ant) return {cell: 8};
        //Everything else failed? Stay put.
        else return {cell: 4};
    }
    if (view[4].color == TRAIL || view[4].color == SPAWN) { //If on colored square, try to move
        var totGreen = 0;
        for (var i = 0; i < 9; i++) { //Look for food
            if (view[i].food) {
                return {cell: i};
            }
            if(view[i].color == TRAIL) totGreen++;
        }
        var ret = getTrailMove();
        if(view[deRotate(ret.cell,1)].color == TRAIL && totGreen <= 4) ret.cell = deRotate(ret.cell,-1);
        else if(view[deRotate(ret.cell,-1)].color == TRAIL && totGreen <= 4) ret.cell = deRotate(ret.cell,1);
        return ret;
    } else { //If not on colored square, look for food, or set current color to 2.
        for (var i = 0; i < 9; i++) { //Look for enemies
            if (i != 4 && view[i].ant != null && !view[i].ant.friend) {
                var r = findOpenSpace(8-i,1);
                if(view[r].color == TRAIL) r = deRotate(r,1);
                return {cell: r};
            }
        }
        return {cell: 4, color:TRAIL};
    }
}

function getTrailMove() {
    if (view[0].color == TRAIL && !view[8].ant && view[8].color != TRAIL) return {cell: 8};
    else if (view[2].color == TRAIL && !view[6].ant && view[6].color != TRAIL) return {cell: 6};
    else if (view[6].color == TRAIL && !view[2].ant && view[2].color != TRAIL) return {cell: 2};
    else if (view[8].color == TRAIL && !view[0].ant && view[0].color != TRAIL) return {cell: 0};
    //Can't find color, or path is blocked? try diagonals regardless of color
    else if (!view[0].ant) return {cell: 0};
    else if (!view[2].ant) return {cell: 2};
    else if (!view[6].ant) return {cell: 6};
    else if (!view[8].ant) return {cell: 8};
    //Everything else failed? Stay put.
    else return {cell: 4};
}

function firebreak() {
    var ret = -1;
    if(findWorker(5) >= 0) {
        return {cell:8-findWorker(5)};
    }
    if(view[4].color != 5) {
        var myView = [0,0,0,0,0,0,0,0,0]
        for(var i=0; i < 9; i++) {
            myView[i] = view[i].color
            if(view[4].ant.food > 0 && view[i].food > 0) {
                myView[i] = 8;
            }
            if(view[i].ant != null && !view[i].ant.friend) return {cell:findOpenSpace(deRotate(i,2),1)};
        }
        var ret = clearAhead(myView);
        if(ret == null)
            return {cell:4,color:5};
        else {
            if(!(view[ret.cell].ant != null && view[ret.cell].ant.friend == false) && (view[4].ant.food == 0 || view[ret.cell].food == 0))
                return ret;
            return {cell:4,color:5};
        }
    }
    if(view[1].color == 5 && view[3].color == 5 && view[5].color == 5 && view[7].color == 5) {
        if(view[0].color != 8) return {cell:0,color:8};
        if(view[1].color != 8) return {cell:1,color:8};
    }
    if(view[1].color == 5 && view[7].color != 5) ret = {cell:7};
    if(view[3].color == 5 && view[5].color != 5) ret = {cell:5};
    if(view[5].color == 5 && view[3].color != 5) ret = {cell:3};
    if(view[7].color == 5 && view[1].color != 5) ret = {cell:1};
    if(view[1].color != 5 && view[3].color != 5 && view[5].color != 5 && view[7].color != 5) ret = {cell:1};
    if((view[1].color == 5 && view[7].color == 5) || (view[3].color == 5 && view[5].color == 5)) ret = {cell:0};
    var loop = 0;
    while(ret.cell >= 0 && ((view[ret.cell].food > 0 && view[4].ant.food > 0) || view[ret.cell].ant != null) && loop < 9) {
        loop++;
        ret.cell = (ret.cell + 2) % 9;
    }
    if(loop < 9 && ret.cell >= 0) return ret;
    return {cell:4};
}

//7,6,4,2,3
//O7,D2

function highwayRobbery() {
    var move = basicHighwayMove();
    if(move.cell >= 0 && view[move.cell].ant != null) {
        var n = HIGHWAY_COLORS.indexOf(view[4].color) + (view[4].color%2==0?1:HIGHWAY_COLORS.length);
        var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
        for(var i=0;i<9;i++) {
            if(view[i].color == nextMove) {
                return {cell:i};
            }
        }
    }
    return move;
}

function basicHighwayMove() {
    var isQueen = view[4].ant.type == 5;
    if(isHighwayCenter()) {
        var n = HIGHWAY_COLORS.indexOf(view[4].color) + 1;
        var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
        for(var i=0;i<9;i++) {
            if(view[i].color == nextMove) {
                if(view[i].ant == null)
                    return {cell:i};
                else {
                    return {cell:deRotate(i,1)};
                }
            }
        }
    }
    else {
        if(view[4].color == 7) {
            //move diagonal to yellow (2)
            for(var i=0;i<9;i++) {
                if(i != 4 && i % 2 == 0 && view[i].color == 2) {
                    return {cell:i};
                }
            }
        }
        else {
            //move orthogonal to blue (7)
            for(var i=0;i<9;i++) {
                if(i % 2 == 1 && view[i].color == 7) {
                    //try ortho yellow first
                    for(var j=0;j<9;j++) {
                        if(j % 2 == 1 && view[j].color == 2 && areAdjacent(i,j))
                            return {cell:j};
                    }
                    return {cell:i};
                }
            }
            //if orthogonal blue doens't exist...
            //...try diagonal to magenta
            for(var i=0;i<9;i++) {
                if(i != 4 && i % 2 == 0 && view[i].color == 3) {
                    return {cell:i};
                }
            }
            if(view[4].color != 2) {
                //...try diagonal blue
                for(var i=0;i<9;i++) {
                    if(i % 2 == 0 && view[i].color == 7)
                        return {cell:i};
                }
            }
            //...and orthogonal yellow
            for(var i=0;i<9;i++) {
                if(i % 2 == 1 && view[i].color == 2)
                    return {cell:i};
            }
        }
        var n = HIGHWAY_COLORS.indexOf(view[4].color) + 1;
        var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
        for(var i=0;i<9;i++) {
            if(view[i].color == nextMove) {
                return {cell:i};
            }
        }
    }
    return {cell:-1};
}

function isOnHighway() {
    var match = 0;
    var nxt = HIGHWAY_COLORS[(HIGHWAY_COLORS.indexOf(view[4].color)+1) % HIGHWAY_COLORS.length];//4
    var prv = HIGHWAY_COLORS[(HIGHWAY_COLORS.indexOf(view[4].color)+HIGHWAY_COLORS.length-2) % HIGHWAY_COLORS.length];//6
    for(var i=0;i<9;i++) {
        if(HIGHWAY_COLORS.indexOf(view[i].color) >=0 && (i == 4 || view[i].color != view[4].color))
            match++;
    }
    if(match >= 5) {
        //7,6,4,2,3


        if((view[1].color == nxt && view[7].color == prv)||(view[1].color == prv && view[7].color == nxt) || 
            (view[3].color == nxt && view[5].color == prv)||(view[3].color == prv && view[5].color == nxt)) {
            return true;
        }
        if((view[1].color == view[8].color && (view[1].color == nxt || view[1].color == prv))||(view[1].color == view[6].color && (view[1].color == nxt || view[1].color == prv)) || 
            (view[3].color == view[2].color && (view[3].color == nxt || view[3].color == prv))||(view[3].color == view[8].color && (view[3].color == nxt || view[3].color == prv))) {
            return true;
        }
        if((view[0].color == view[7].color && (view[0].color == nxt || view[0].color == prv))||(view[2].color == view[7].color && (view[2].color == nxt || view[2].color == prv)) || 
            (view[0].color == view[5].color && (view[0].color == nxt || view[0].color == prv))||(view[6].color == view[5].color && (view[6].color == nxt || view[6].color == prv))) {
            return true;
        }
        if(isHighwayCenter()) {
            return true;
        }
    }
    return false;
}

function isHighwayCenter() {
    if(HIGHWAY_COLORS.indexOf(view[4].color) >=0 && (((view[0].color != view[8].color || view[2].color != view[6].color) && view[4].ant.type == 1) || (view[0].color != view[8].color && view[2].color != view[6].color))){
        var m1 = view[1].color == view[7].color;
        var m2 = view[2].color == view[8].color;
        var m3 = view[0].color == view[6].color;
        if((m1?1:0)+(m2?1:0)+(m3?1:0) >= 2) {
            if(view[3].color != view[5].color && ((view[2].color != view[5].color && view[8].color != view[5].color) || view[4].ant.type == 1) && ((view[3].color != view[0].color && view[3].color != view[6].color) || view[4].ant.type == 1)) {
                return true;
            }
        }
        m1 = view[3].color == view[5].color;
        m2 = view[0].color == view[2].color;
        m3 = view[6].color == view[8].color;
        if((m1?1:0)+(m2?1:0)+(m3?1:0) >= 2) {
            if(view[1].color != view[7].color && ((view[0].color != view[1].color && view[1].color != view[2].color) || view[4].ant.type == 1) && ((view[6].color != view[7].color && view[7].color != view[8].color) || view[4].ant.type == 1)) {
                return true;
            }
        }
    }
    return false;
}

function deRotateSide(m, amt) {
    return deRotate(m,amt*2);
}

/**Positive amount is clockwise**/
function deRotate(m, amt) {
    var rotationsCW = [1,2,5,8,7,6,3,0];
    var rotationsCCW = [3,6,7,8,5,2,1,0];
    if(m == 4 || m < 0 || m > 8 || amt == 0) return m;
    if(amt > 0)
        return rotationsCW[(rotationsCW.indexOf(m)+amt)%8];
    amt = -amt;
    return rotationsCCW[(rotationsCCW.indexOf(m)+amt)%8];
}

function areAdjacent(A, B) {
    if(A == 4 || B == 4 || A == B) return true;
    if(A % 2 == 0 && B % 2 == 0) return false;
    if(A % 2 == 1 && B % 2 == 0) return areAdjacent(B,A);
    if(A % 2 == 1 && B % 2 == 1) return !(8-A == B || 8-B == A);
    if(A == 0 && (B == 1 || B == 3)) return true;
    if(A == 2 && (B == 1 || B == 5)) return true;
    if(A == 6 && (B == 3 || B == 7)) return true;
    if(A == 8 && (B == 5 || B == 7)) return true;
    return false;
}

function findFirstTrail() {
    var pos = 0;
    var b = 0;
    while(view[pos].color != TRAIL && b < 8) {
        pos=deRotate(pos,1);
        b++;
    }
    return pos;
}

function clearAhead(sides) {
    var c=0;
    for(var i=0;i<9;i++) {
        if(view[i].color == 5) c++;
        if(view[i].color == 5 && i%2 == 0) c+=10;
    }
    if(c == 2) {
        if(view[0].color == 5 || view[2].color == 5 || view[6].color == 5 || view[8].color == 5) {
            return {cell:4,color:5};
        }
        if(view[0].ant == null)
            return {cell:0};
        if(view[2].ant == null)
            return {cell:2};
        if(view[6].ant == null)
            return {cell:6};
        if(view[8].ant == null)
            return {cell:8};
    }
    c = 0;
    sides[4] = 0;
    var toMatch =[{state:[1,1,1,
                          2,0,2,
                          0,1,0]},
                 {state:[0,2,1,
                         1,0,1,
                         0,2,1]},
                 {state:[0,1,0,
                         2,0,2,
                         1,1,1]},
                 {state:[1,2,0,
                         1,0,1,
                         1,2,0]}];
    for(var m=0;m<4;m++) {
        var score=0;
        for(var j=0;j<9;j++) {
            if(j!=4) {
                if(sides[j] == 5 && toMatch[m].state[j] == 1) {
                    score++;
                }
                if(sides[j] != 5 && (toMatch[m].state[j] == 0 || toMatch[m].state[j] == 2)) {
                    score++;
                }
                if(sides[j] == 5 && toMatch[m].state[j] == 2) {
                    score--;
                }
            }
        }
        if(score >= 6) {
            var clearOrder=[1,0,2];
            for(var r=0;r<clearOrder.length;r++) {
                var s = deRotateSide(clearOrder[r],m);
                if(view[s].color == 5) {
                    if(view[s].ant == null)
                        return {cell:s,color:8};
                    else
                        return {cell:4};
                }
            }
        }
    }
    return null;
}

function findOpenSpace(pos, dir) {
    if(pos > 8 || pos < 0) return pos;
    var b = 0;
    while(view[pos].ant != null && b < 8) {
        pos=deRotate(pos,dir);
        b++;
    }
    return pos;
}

function getHighestWorker() {
    var r=0;
    for(var i=0;i<9;i++) {
        if(i != 4 && view[i].ant != null) {
            if(view[i].ant.friend && view[i].ant.type > r) r = view[i].ant.type;
        }
    }
    return r;
}

function getNumWorkers(type) {
    var r=0;
    for(var i=0;i<9;i++) {
        if(i != 4 && view[i].ant != null) {
            if(view[i].ant.friend && view[i].ant.type == type) r++;
        }
    }
    return r;
}

function findWorker(type) {
    for(var i=0;i<9;i++) {
        if(i != 4 && view[i].ant != null) {
            if(view[i].ant.friend && view[i].ant.type == type) return i;
        }
    }
    return -1;
}

316% Complete
316% because the update was on 3/16This joke has gone on too long

var TRAIL = 6;
var SPAWN = 3;
var IDLE = 4;
var FOOD_THRESHOLD = 150;
var SPAWN_MIN = 3;
var HIGHWAY_COLORS = [7,6,4,2,3];
var HIGHWAY_THRESHOLD = 70;
var ret = {cell:4};
if(isOnHighway()) {
    var cont = true;
    //== Make best guess to if in a glider formation ==//
    if(view[4].ant.type == 5) {
        if((findWorker(1) >= 0 && findWorker(4) >= 0) || view[4].ant.food < HIGHWAY_THRESHOLD) {
            cont = false;
        }
    }
    else if(view[4].ant.type == 4) {
        if(findWorker(1) >= 0 && findWorker(5) >= 0) {
            cont = false;
        }
    }
    else if(view[4].ant.type == 3) {
        if(findWorker(2) >= 0 && findWorker(5) >= 0) {
            cont = false;
        }
    }
    else if(view[4].ant.type == 2) {
        if(findWorker(5) < 0) {
            var pos3 = findWorker(3);
            if(pos3 >= 0 && view[pos3].ant.food == 0) {
                cont = false;
            }
        }
        else if(findWorker(3) >= 0 || (findWorker(1) >= 0 && view[findWorker(5)].color == SPAWN))
            cont = false;
    }
    else if(view[4].ant.type == 1) {
        if(findWorker(5) < 0) {
            var pos4 = findWorker(4);
            if(pos4 >= 0 && view[pos4].ant.food == 0) {
                cont = false;
            }
        }
        else if(!isHighwayCenter())
            cont = false;
    }
    if(findWorker(5) >= 0) {
        for(var i=0;i<9;i++) {
            if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                if(view[i].ant.food > 10 || view[i].ant.food == 0)
                    cont = true;
                else
                    cont = false;
            }
        }
    }
    //== End guesswork ==//
    if(cont) {
        ret = highwayRobbery();
        if(view[4].ant.type == 1) {
            //try to repair
            var curIndex = HIGHWAY_COLORS.indexOf(view[4].color);
            var prvCol = HIGHWAY_COLORS[(curIndex+1)%HIGHWAY_COLORS.length];
            var nxtCol1 = HIGHWAY_COLORS[(curIndex+HIGHWAY_COLORS.length-1)%HIGHWAY_COLORS.length];
            var nxtCol2 = HIGHWAY_COLORS[(curIndex+HIGHWAY_COLORS.length-2)%HIGHWAY_COLORS.length];
            var nxtCol3 = HIGHWAY_COLORS[(curIndex+HIGHWAY_COLORS.length-3)%HIGHWAY_COLORS.length];
            var prevAt = -1;
            for(var i=0;i<9;i++) {
                if(i%2 == 1 && view[i].color == prvCol && view[deRotate(i,1)].color == nxtCol1 && view[deRotate(i,-1)].color == nxtCol1) prevAt = i;
            }
            if(prevAt >= 0) {
                // yep, brute force it. Because I'm lazy.
                var goNxt = 8-prevAt;
                if(view[deRotate(goNxt,1)].color == nxtCol3 && view[deRotate(goNxt,-1)].color == prvCol) ret = {cell:goNxt};
                else if(view[deRotate(goNxt,1)].color == prvCol && view[deRotate(goNxt,-1)].color == nxtCol3) ret = {cell:goNxt};
                else if(view[goNxt].color != nxtCol1) ret = {cell:goNxt,color:nxtCol1};
                else if(view[deRotate(goNxt,2)].color != nxtCol2) ret = {cell:deRotate(goNxt,2),color:nxtCol2};
                else if(view[deRotate(goNxt,-2)].color != nxtCol2) ret = {cell:deRotate(goNxt,-2),color:nxtCol2};
                else if(view[deRotate(goNxt,1)].color != nxtCol3) ret = {cell:deRotate(goNxt,1),color:nxtCol3};
                else if(view[deRotate(goNxt,-1)].color != nxtCol3) ret = {cell:deRotate(goNxt,-1),color:nxtCol3};
                else ret = {cell:goNxt};
                ret = sanityCheck(ret);
                return ret;
            }
        }
        if(view[4].ant.type == 5 && isHighwayCenter()) {
            if(ret.cell >= 0) {
                ret = {cell:8-ret.cell};
                if(view[4].color == SPAWN && (view[4].ant.food > 90 || view[4].ant.food % 7 == 0) && getHighestWorker() == 0 && (view[4].ant.food < 140 || view[4].ant.food % 9 == 0) && view[0].color == 2 && view[4].ant.food > 50 && view[4].ant.food < 200) {
            //fine
                    if(view[4].ant.food % 10 < 5)
                        ret = {cell:deRotate(ret.cell,3),type:3};
                }
                if(view[ret.cell].ant != null && !view[ret.cell].ant.friend && view[ret.cell].ant.food == 0 && view[4].ant.food > 0) {
                    if(view[deRotate(ret.cell,1)].ant == null)
                        ret = {cell:deRotate(ret.cell,1),type:3};
                    if(view[deRotate(ret.cell,-1)].ant == null)
                        ret = {cell:deRotate(ret.cell,1),type:3};
                }
            }
            for(var i=0;i<9;i++) {
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                    ret = {cell:8-i};
                }
            }
        }
        if(ret.cell >= 0) {
            for(var i=0;i<9;i++) {
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                    var rr = basicHighwayMove();
                    if(rr.cell >= 0 && view[4].ant.type != 5)
                        ret = {cell:deRotate(rr.cell,-2)};
                }
            }
            if(view[ret.cell].ant != null) {
                var n = HIGHWAY_COLORS.indexOf(view[4].color) + 1;
                var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
                for(var i=0;i<9;i++) {
                    if(view[i].color == nextMove) {
                        if(view[i].ant == null) {
                            ret = {cell:i};
                            break;
                        }
                    }
                }
                if(view[4].ant.type == 5) ret = {cell:8-ret.cell};
            }
        }
        if(view[4].ant.type == 5) {
            var foodedEnemy = false;
            for(var i=0;i<9;i++) {
                if(getNumWorkers(3) >= 2) break;
                if(i != 4 && view[i].ant != null && view[i].ant.type == 5 && view[i].ant.food > 25) {
                    if(view[deRotate(i,1)].ant == null) {
                        ret = {cell:deRotate(i,1),type:3};
                    }
                    else if(view[deRotate(i,-1)].ant == null) {
                        ret = {cell:deRotate(i,-1),type:3};
                    }
                    else if(i%2 == 1 && view[deRotate(i,2)].ant == null) {
                        ret = {cell:deRotate(i,2),type:3};
                    }
                    else if(i%2 == 1 && view[deRotate(i,-2)].ant == null) {
                        ret = {cell:deRotate(i,-2),type:3};
                    }
                }
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 3 && view[8-i].ant == null) {
                    if(i == ret.cell) {
                        ret = {cell:deRotate(i,1)}
                    }
                    else {
                        return {cell:8-i};
                    }
                }
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.food == 0) {
                    foodedEnemy = true;
                }
            }
        }
        var numAnts = 0;
        for(var i=0;i<9;i++) {
            if(view[i].ant != null)
                numAnts++;
        }
        if(numAnts > 2 && sanityCheck(ret).cell == 4) {
            ret = {cell:findOpenSpace(0,1)};
        }
        if(view[4].ant.type == 3) {
            if(getNumWorkers(5) > 0) {
                for(var i=0;i<9;i++) {
                    if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                        ret = {cell:4};
                    }
                }
            }
        }
        if(view[4].ant.type == 4 && getNumWorkers(1) && isHighwayCenter()) {
            var workerPos = findWorker(1);
            for(var i=0;i<9;i++) {
                if(!areAdjacent(i,workerPos)) ret = {cell:i};
            }
        }
        if(ret.cell == -1) {
            if(isHighwayCenter()) {
                for(var i=0;i<9;i++) {
                    var p1 = deRotate(i,3);
                    var p2 = deRotate(i,-3);
                    if(view[i].color == view[p1].color && view[i].color == view[p2].color) {
                        ret = {cell:8-i};
                    }
                }
                if(view[4].ant.type == 1 || view[4].ant.type == 5) {
                    ret = {cell:8-ret.cell};
                }
            }
        }
        if(ret.cell >= 0)
            return sanityCheck(ret);
    }
}

switch(view[4].ant.type) {
    case 5:
        ret = doQueen();
        break;
    case 1:
    case 2:
        ret = doSweep();
        break;
    case 3:
    case 4:
        ret = doGuide();
        break;
    default:
        break;
}
//basic sanity check
ret = sanityCheck(ret);
return ret;

function sanityCheck(ret) {
    if(!ret || ret.cell < 0 || ret.cell > 8) {
        return {cell:4};
    }
    if(ret.color) {
        return ret;
    }
    if((ret.cell != 4 && view[ret.cell].ant != null) || (view[ret.cell].food > 0 && (view[4].ant.food > 0 && view[4].ant.type < 5))) {
        return {cell:4};
    }
    if(ret.type && (view[ret.cell].ant != null || view[ret.cell].food > 0 || view[4].ant.food == 0 || view[4].ant.type < 5)) {
        return {cell:4};
    }
    return ret;
}

function doQueen() {
    if((view[4].ant.food == SPAWN_MIN || (view[4].ant.food >= SPAWN_MIN && view[4].ant.food < FOOD_THRESHOLD && (view[4].ant.food % 3 == 1 || isOnHighway()))) && getHighestWorker() <= 1 ) {
        //prep for first ant
        var s0 = view[0].ant;
        var s1 = view[1].ant;
        var s2 = view[2].ant;
        var s3 = view[3].ant;
        var s5 = view[5].ant;
        var s6 = view[6].ant;
        var s7 = view[7].ant;
        var s8 = view[8].ant;
        var nullCount = 0 + (s0 == null?1:0) + (s1 == null?1:0) + (s2 == null?1:0) + (s3 == null?1:0) + (s5 == null?1:0) + (s6 == null?1:0) + (s7 == null?1:0) + (s8 == null?1:0);
        var nullCount2 = 0 + (s0 == null || s0.friend?1:0) + (s1 == null || s1.friend?1:0) + (s2 == null || s2.friend?1:0) + (s3 == null || s3.friend?1:0) + (s5 == null || s5.friend?1:0) + (s6 == null || s6.friend?1:0) + (s7 == null || s7.friend?1:0) + (s8 == null || s8.friend?1:0);
        if(nullCount >= 7 && nullCount2 >= 8 && view[1].food == 0 && view[3].food == 0 && view[5].food == 0 && view[7].food == 0) {
            var high = getHighestWorker();
            if (high <= 1 && view[4].color != SPAWN && !isOnHighway()) {
                // 50% chance of delaying the respawn by 1 additional move away from where we exploded
                // reduces the chance of a second, immediate explosion
                if(findFirstTrail() < 2 && view[4].ant.food > SPAWN_MIN+1) return foreverAlone();
                var pos1 = findWorker(1);
                if(pos1 >= 0) {
                    var space = deRotate(pos1,2);
                    if(view[space].ant != null) return {cell:findOpenSpace(0,1)};
                }
                return {cell:4,color:SPAWN};
            }
            //spawn first ant
            else if(view[4].color == SPAWN) {
                var pos1 = findWorker(1);
                if(pos1 < 0)  {
                    pos1 = findFirstTrail();
                    if(pos1 % 2 == 0) pos1 = deRotate(pos1,1);
                    else pos1 = deRotate(pos1,4);
                }
                var space = findOpenSpace(pos1,2);
                var high = getHighestWorker();
                if(space < 0) return {cell:4,color:TRAIL}
                if(high == 0) { //no workers
                    return {cell:space,type:1};
                }
                else if(high < 4) { //1 worker of type:high
                    return {cell:space,type:high+1};
                }
                else { //1 worker of type 4
                    //we have all workers, skip!
                }
            }
        }
        else {
            return foreverAlone();
        }
    }
    else if(view[4].ant.food == 1 && getHighestWorker() == 0 ) {
        var space = findOpenSpace(1,2);
        return {cell:space,type:1};
    }
    else if(view[4].ant.food >= 1 && getHighestWorker() < 4 && findWorker(1) >= 0) {
        //spawn remaining ants
        if(view[4].color == SPAWN && !isHighwayCenter()) {
            var pos1 = findWorker(getHighestWorker());
            var space = deRotate(pos1,2);
            var high = getHighestWorker();
            if(space < 0 || view[space].ant != null) return {cell:findOpenSpace(0,1)};
            if(high == 0) { //no workers
                return {cell:space,type:1};
            }
            else if(high < 4) { //1 worker of type:high
                return {cell:space,type:high+1};
            }
            else { //1 worker of type 4
                //we have all workers, skip!
            }
        }
    }
    if(view[4].color == SPAWN && getNumWorkers(3) == 1 && getNumWorkers(4) == 1) {
        var one = getNumWorkers(1);
        var two = getNumWorkers(2);
        if((one ^ two) == 1 && (findWorker(1) % 2 == 0 || findWorker(2) % 2 == 0))
            return {cell:4,color:1};
    }
    if(getNumWorkers(1) == 0 && getNumWorkers(2) == 0) {
        if(getNumWorkers(4) == 1 && getNumWorkers(3) == 0) {
            var pos4 = findWorker(4);
            if(view[deRotate(pos4,1)].ant == null && view[deRotate(pos4,2)].ant == null && findWorker(4) % 2 == 1) {
                //finish rotate with only one glider arm
                return {cell:4};
            }
        }
        return foreverAlone();
    }
    else if(getNumWorkers(1) >= 1 && getNumWorkers(2) >= 1 && getNumWorkers(3) >= 1 && getNumWorkers(4) >= 1) {
        if(view[4].color != 2 && findWorker(1)%2 == 1 && findWorker(2)%2 == 1) {
            return {cell:4,color:TRAIL};
        }
        //move diagonally
        var pos = findWorker(4);
        pos = deRotate(pos,1);
        var checkpos = view[deRotate(pos,4)];
        if(checkpos.ant != null && checkpos.ant.friend) {
            if(checkpos.ant.type == 2)
                return {cell:4};
            if(checkpos.ant.type == 1)
                return {cell:4};
        }
        return {cell:pos};
    }
    else {
        var pos = findWorker(4);
        if(pos < 0) {
            //if gliding along with only a buddy
            pos = findWorker(1);
            if(pos >= 0 && view[deRotate(pos,2)].food > 0 && view[deRotate(pos,1)].food == 0) {
                return {cell:4};
            }
        }
        if(pos < 0) {
            var s1 = view[1].ant;
            var s3 = view[3].ant;
            var s5 = view[5].ant;
            var s7 = view[7].ant;
            //return {cell:999}
            if(s1 == null) {
                if(s3 == null) {
                    return {cell:0};
                }
                if(s5 == null) {
                    return {cell:2};
                }
            }
            if(s7 == null) {
                if(s3 == null) {
                    return {cell:6};
                }
                if(s5 == null) {
                    return {cell:8};
                }
            }
            return {cell:4};
        }
        pos = deRotate(pos,1);
        var checkpos1 = view[pos];
        for(var i=0;i<9;i++) {
            if(i != 4 && view[i].ant != null && view[i].ant.type == 5 && view[i].ant.food > 2) {
                if(i%2==0) {
                    if(view[deRotate(i,1)].ant == null) return {cell:deRotate(i,1),type:3};
                    if(view[deRotate(i,-1)].ant == null) return {cell:deRotate(i,-1),type:3};
                }
                else {
                    if(view[deRotate(i,1)].ant == null) return {cell:deRotate(i,1),type:3};
                    if(view[deRotate(i,-1)].ant == null) return {cell:deRotate(i,-1),type:3};
                    if(view[deRotate(i,2)].ant == null) return {cell:deRotate(i,2),type:3};
                    if(view[deRotate(i,-2)].ant == null) return {cell:deRotate(i,-2),type:3};
                }
                return {cell:4};
            }
        }
        if(checkpos1.ant != null && view[deRotate(pos,1)].ant != null && !view[deRotate(pos,1)].ant.friend) {
            return foreverAlone();
        }

        var checkpos2 = view[deRotate(pos,4)];
        var checkpos3 = view[deRotate(checkpos,1)];
        if(checkpos1.ant != null && checkpos1.ant.friend && checkpos1.ant.type == 1 && checkpos2.ant != null && checkpos2.ant.friend && checkpos2.ant.type == 2 && checkpos3.ant != null && checkpos3.ant.friend && checkpos3.ant.type == 3) {
            //move out of spawn orientation
            return {cell:4};
        }
        if(view[pos].ant != null) {
            if(checkpos2.ant == null && checkpos1.ant == null) {
                return {cell:8-pos};
            }
            if(!view[pos].ant.friend) {
                return foreverAlone();
            }
            if(view[4].color == TRAIL) return foreverAlone();
            return {cell:4,color:TRAIL};
        }
        if(8 - findWorker(3) == findWorker(4)) {
            //finish rotate to the right
            return {cell:4};
        }
        if((view[deRotate(pos,1)].food > 0 || view[deRotate(pos,2)].food > 0) && view[deRotate(pos,1)].ant == null && view[4].color != TRAIL) {
            if(findWorker(1) < 0 || view[deRotate(findWorker(1),1)].food == 0) {
                return {cell:4};
            }
        }
        return {cell:pos};
    }
    return {cell:100+view[4].ant.type}; //oh god
}

//guides sit next to the queen
function doGuide() {
    var queenPos = findWorker(5);
    var ty = view[4].ant.type==3?2:1;
    var dir = view[4].ant.type==3?1:-1;
    if(queenPos >= 0 && queenPos%2 == 1 && view[queenPos].color == SPAWN) {
        if(view[deRotate(queenPos,dir*2)].ant == null) {
            return {cell:4};
        }
    }
    if(queenPos < 0 || findWorker(ty) < 0) {
        if(findWorker(ty) >= 0 && view[0].color != IDLE) return {cell:0,color:IDLE}
        return firebreak();
    }
    var checkpos = view[deRotate(queenPos,-2*dir)];
    if(view[4].ant.type==4 && checkpos.ant != null && checkpos.ant.friend && checkpos.ant.type == 1) {
        //attempt rotate
        return {cell:deRotate(queenPos,-dir)};
    }
    checkpos = view[deRotate(queenPos,4)];
    if(checkpos.ant != null && checkpos.ant.friend && checkpos.ant.type == ty) {
        //attempt rotate
        if(getNumWorkers(ty) == 1) {
            return {cell:4};
        }
    }
    var pos = deRotate(queenPos,dir);
    if(pos >= 0 && view[4].ant.type==3 && findWorker(4) < 0) {
        //wait for rotate
        if(view[4].color == TRAIL) {
            return {cell:4};
        }
    }
    if(pos >= 0 && findWorker(2) >= 0 && view[deRotate(findWorker(2),1)].ant != null) {
        //rotate
        return {cell:4,color:TRAIL};
    }
    if(pos < 0) pos = 4;
    else if(view[pos].ant != null) return {cell:deRotate(queenPos,4)};
    if(pos == 4 && view[queenPos].color == TRAIL) return {cell:queenPos,color:1};
    return {cell:pos};
}

//sweepers sit next to guides
function doSweep() {
    var queenPos = findWorker(5);
    var followType = view[4].ant.type==1?4:3;
    var pos = findWorker(followType);
    if(pos % 2 == 0 && getNumWorkers(followType) > 1) {
        //if there's more than one worker #4, we want to use the best one
        for(var i=pos+1;i<9;i++) {
            if(i != 4 && view[i].ant != null) {
                if(view[i].ant.friend && view[i].ant.type == followType) {
                    pos = i;
                    break;
                }
            }
        }
    }
    if(queenPos >= 0 && queenPos%2 == 1 && view[queenPos].color == SPAWN) {
        var p = findWorker(view[4].ant.type);
        if(p >= 0 && (deRotate(p,1) == queenPos || deRotate(p,-1) == queenPos)) {
            return {cell:8-queenPos};
        }
        return {cell:4};
    }
    if(queenPos >= 0 && pos < 0) {
        //if Worker #1 is the only ant besides the queen:
        //TODO
    //good
        if(view[queenPos].ant.food <= SPAWN_MIN || !(view[queenPos].ant.food < FOOD_THRESHOLD && view[queenPos].ant.food % 3 == 1 && !isOnHighway())) {
            var go = deRotate(queenPos,-1);
            if((view[deRotate(queenPos,-2)].food > 0 || view[deRotate(queenPos,-3)].food > 0 || (queenPos %2 == 1 && view[deRotate(queenPos,-3)].food > 0)) && view[go].food == 0) {
                go = deRotate(queenPos,2);
                //return {cell:4};
            }
            return {cell:go};
        }
        else if(view[queenPos].ant.food < FOOD_THRESHOLD && view[queenPos].ant.food % 3 == 1) {
            return {cell:4};
        }
    }
    if(queenPos >= 0) {
        var dir = view[4].ant.type==1?1:-1;
        //var checkpos = view[deRotate(pos,-dir)];
        var moveTo = deRotate(pos,dir);
        if(moveTo >= 0 && view[moveTo].ant != null && view[moveTo].ant.friend && view[moveTo].ant.type == 5) {
            moveTo = deRotate(pos,-dir);
        }
        if(view[4].ant.type == 2 && findWorker(1) < 0 && view[queenPos].color != TRAIL) {
            moveTo = 4;
        }
        return {cell:moveTo};
    }
    else {
        if(pos < 0) return {cell:4}; //firebreak();
        var dir = view[4].ant.type==1?-1:1;
        var moveTo = deRotate(pos,dir);
        if(view[4].ant.food > 0 && view[moveTo].food > 0) {
            //have food, attempt to give to queen
            moveTo = deRotate(pos,-dir);
        }
        if(view[4].ant.type==1 && pos >= 0 && (view[deRotate(pos,dir*2)].food > 0 || view[deRotate(pos,dir*3)].food > 0)) {
            //attempt rotate
            moveTo = deRotate(pos,-dir);
        }
        if(view[4].ant.type==2 && pos >= 0 && (view[deRotate(pos,dir*2)].food > 0 || view[deRotate(pos,dir*3)].food > 0)) {
            //attempt rotate
            moveTo = deRotate(pos,-dir);
        }
        if(moveTo >= 0 && view[moveTo].ant != null && view[moveTo].ant.type == 5) {
            if(view[moveTo].ant.friend)
                moveTo = deRotate(moveTo,dir*2);
            else
                moveTo = deRotate(pos,-dir);
        }
        return {cell:moveTo};
    }
    return {cell:100+view[4].ant.type};//oh god
}

function foreverAlone() {
    var s0 = view[0].ant;
    var s1 = view[1].ant;
    var s2 = view[2].ant;
    var s3 = view[3].ant;
    var s5 = view[5].ant;
    var s6 = view[6].ant;
    var s7 = view[7].ant;
    var s8 = view[8].ant;
    //good
    if(!(s0 == null && s1 == null && s2 == null && s3 == null && s5 == null && s6 == null && s7 == null && s8 == null) && view[4].color == TRAIL) {
        if (view[0].color == TRAIL && !view[8].ant && view[8].color != TRAIL) return {cell: 8};
        else if (view[2].color == TRAIL && !view[6].ant && view[6].color != TRAIL) return {cell: 6};
        else if (view[6].color == TRAIL && !view[2].ant && view[2].color != TRAIL) return {cell: 2};
        else if (view[8].color == TRAIL && !view[0].ant && view[0].color != TRAIL) return {cell: 0};
        //Can't find color, or path is blocked? try diagonals regardless of color
        else if (!view[0].ant) return {cell: 0};
        else if (!view[2].ant) return {cell: 2};
        else if (!view[6].ant) return {cell: 6};
        else if (!view[8].ant) return {cell: 8};
        //Everything else failed? Stay put.
        else return {cell: 4};
    }
    //good
    if (view[4].color == TRAIL) { //If on colored square, try to move
        var totGreen = 0;
        for (var i = 0; i < 9; i++) { //Look for food
            if (view[i].food) {
                return {cell: i};
            }
            if(view[i].color == TRAIL) totGreen++;
        }
        var ret = getTrailMove();
        if(view[deRotate(ret.cell,1)].color == TRAIL && totGreen <= 4) ret.cell = deRotate(ret.cell,-1);
        else if(view[deRotate(ret.cell,-1)].color == TRAIL && totGreen <= 4) ret.cell = deRotate(ret.cell,1);
        return ret;
    } else { //If not on colored square, look for food, or set current color to 2.
        for (var i = 0; i < 9; i++) { //Look for enemies
            if (i != 4 && view[i].ant != null && !view[i].ant.friend) {
                var r = findOpenSpace(8-i,1);
                if(view[r].color == TRAIL) r = deRotate(r,1);
                return {cell: r};
            }
        }
        return {cell: 4, color:TRAIL};
    }
}

function getTrailMove() {
    if (view[0].color == TRAIL && !view[8].ant && view[8].color != TRAIL) return {cell: 8};
    else if (view[2].color == TRAIL && !view[6].ant && view[6].color != TRAIL) return {cell: 6};
    else if (view[6].color == TRAIL && !view[2].ant && view[2].color != TRAIL) return {cell: 2};
    else if (view[8].color == TRAIL && !view[0].ant && view[0].color != TRAIL) return {cell: 0};
    //Can't find color, or path is blocked? try diagonals regardless of color
    else if (!view[0].ant) return {cell: 0};
    else if (!view[2].ant) return {cell: 2};
    else if (!view[6].ant) return {cell: 6};
    else if (!view[8].ant) return {cell: 8};
    //Everything else failed? Stay put.
    else return {cell: 4};
}

function firebreak() {
    var ret = -1;
    if(findWorker(5) >= 0) {
        return {cell:8-findWorker(5)};
    }
    if(view[4].color != 5) {
        var myView = [0,0,0,0,0,0,0,0,0]
        for(var i=0; i < 9; i++) {
            myView[i] = view[i].color
            if(view[4].ant.food > 0 && view[i].food > 0) {
                myView[i] = 8;
            }
            if(view[i].ant != null && !view[i].ant.friend) return {cell:findOpenSpace(deRotate(i,2),1)};
        }
        var ret = clearAhead(myView);
        if(ret == null)
            return {cell:4,color:5};
        else {
            if(!(view[ret.cell].ant != null && view[ret.cell].ant.friend == false) && (view[4].ant.food == 0 || view[ret.cell].food == 0))
                return ret;
            return {cell:4,color:5};
        }
    }
    if(view[1].color == 5 && view[3].color == 5 && view[5].color == 5 && view[7].color == 5) {
        if(view[0].color != 8) return {cell:0,color:8};
        if(view[1].color != 8) return {cell:1,color:8};
    }
    if(view[1].color == 5 && view[7].color != 5) ret = {cell:7};
    if(view[3].color == 5 && view[5].color != 5) ret = {cell:5};
    if(view[5].color == 5 && view[3].color != 5) ret = {cell:3};
    if(view[7].color == 5 && view[1].color != 5) ret = {cell:1};
    if(view[1].color != 5 && view[3].color != 5 && view[5].color != 5 && view[7].color != 5) ret = {cell:1};
    if((view[1].color == 5 && view[7].color == 5) || (view[3].color == 5 && view[5].color == 5)) ret = {cell:0};
    var loop = 0;
    while(ret.cell >= 0 && ((view[ret.cell].food > 0 && view[4].ant.food > 0) || view[ret.cell].ant != null) && loop < 9) {
        loop++;
        ret.cell = (ret.cell + 2) % 9;
    }
    if(loop < 9 && ret.cell >= 0) return ret;
    return {cell:4};
}

//7,6,4,2,3
//O7,D2

function highwayRobbery() {
    var move = basicHighwayMove();
    if(move.cell >= 0 && view[move.cell].ant != null) {
        var n = HIGHWAY_COLORS.indexOf(view[4].color) + (view[4].color%2==0?1:HIGHWAY_COLORS.length);
        var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
        for(var i=0;i<9;i++) {
            if(view[i].color == nextMove) {
                return {cell:i};
            }
        }
    }
    return move;
}

function basicHighwayMove() {
    var isQueen = view[4].ant.type == 5;
    if(isHighwayCenter()) {
        var n = HIGHWAY_COLORS.indexOf(view[4].color) + 1;
        var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
        for(var i=0;i<9;i++) {
            if(view[i].color == nextMove) {
                if(view[i].ant == null)
                    return {cell:i};
                else {
                    return {cell:deRotate(i,1)};
                }
            }
        }
    }
    else {
        if(view[4].color == 7) {
            //move diagonal to yellow (2)
            for(var i=0;i<9;i++) {
                if(i != 4 && i % 2 == 0 && view[i].color == 2) {
                    return {cell:i};
                }
            }
        }
        else {
            //move orthogonal to blue (7)
            for(var i=0;i<9;i++) {
                if(i % 2 == 1 && view[i].color == 7) {
                    //try ortho yellow first
                    for(var j=0;j<9;j++) {
                        if(j % 2 == 1 && view[j].color == 2 && areAdjacent(i,j))
                            return {cell:j};
                    }
                    return {cell:i};
                }
            }
            //if orthogonal blue doens't exist...
            //...try diagonal to magenta
            for(var i=0;i<9;i++) {
                if(i != 4 && i % 2 == 0 && view[i].color == 3) {
                    return {cell:i};
                }
            }
            if(view[4].color != 2) {
                //...try diagonal blue
                for(var i=0;i<9;i++) {
                    if(i % 2 == 0 && view[i].color == 7)
                        return {cell:i};
                }
            }
            //...and orthogonal yellow
            for(var i=0;i<9;i++) {
                if(i % 2 == 1 && view[i].color == 2)
                    return {cell:i};
            }
        }
        var n = HIGHWAY_COLORS.indexOf(view[4].color) + 1;
        var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
        for(var i=0;i<9;i++) {
            if(view[i].color == nextMove) {
                return {cell:i};
            }
        }
    }
    return {cell:-1};
}

function isOnHighway() {
    var match = 0;
    var nxt = HIGHWAY_COLORS[(HIGHWAY_COLORS.indexOf(view[4].color)+1) % HIGHWAY_COLORS.length];//4
    var prv = HIGHWAY_COLORS[(HIGHWAY_COLORS.indexOf(view[4].color)+HIGHWAY_COLORS.length-2) % HIGHWAY_COLORS.length];//6
    for(var i=0;i<9;i++) {
        if(HIGHWAY_COLORS.indexOf(view[i].color) >=0 && (i == 4 || view[i].color != view[4].color))
            match++;
    }
    if(match >= 5) {
        //7,6,4,2,3


        if((view[1].color == nxt && view[7].color == prv)||(view[1].color == prv && view[7].color == nxt) || 
            (view[3].color == nxt && view[5].color == prv)||(view[3].color == prv && view[5].color == nxt)) {
            return true;
        }
        if((view[1].color == view[8].color && (view[1].color == nxt || view[1].color == prv))||(view[1].color == view[6].color && (view[1].color == nxt || view[1].color == prv)) || 
            (view[3].color == view[2].color && (view[3].color == nxt || view[3].color == prv))||(view[3].color == view[8].color && (view[3].color == nxt || view[3].color == prv))) {
            return true;
        }
        if((view[0].color == view[7].color && (view[0].color == nxt || view[0].color == prv))||(view[2].color == view[7].color && (view[2].color == nxt || view[2].color == prv)) || 
            (view[0].color == view[5].color && (view[0].color == nxt || view[0].color == prv))||(view[6].color == view[5].color && (view[6].color == nxt || view[6].color == prv))) {
            return true;
        }
        if(isHighwayCenter()) {
            return true;
        }
    }
    return false;
}

function isHighwayCenter() {
    if(HIGHWAY_COLORS.indexOf(view[4].color) >=0 && (((view[0].color != view[8].color || view[2].color != view[6].color) && view[4].ant.type == 1) || (view[0].color != view[8].color && view[2].color != view[6].color))){
        var m1 = view[1].color == view[7].color;
        var m2 = view[2].color == view[8].color;
        var m3 = view[0].color == view[6].color;
        var m4 = view[0].color != 1 && view[2].color != 1;
        if((m1?1:0)+(m2?1:0)+(m3?1:0) >= 2 && m4) {
            if(view[3].color != view[5].color && ((view[2].color != view[5].color && view[8].color != view[5].color) || view[4].ant.type == 1) && ((view[3].color != view[0].color && view[3].color != view[6].color) || view[4].ant.type == 1)) {
                return true;
            }
        }
        m1 = view[3].color == view[5].color;
        m2 = view[0].color == view[2].color;
        m3 = view[6].color == view[8].color;
        m4 = view[0].color != 1 && view[6].color != 1;
    //good
        if((m1?1:0)+(m2?1:0)+(m3?1:0) >= 2 && m4) {
            m1 = view[1].color != view[7].color;
            m2 = (view[0].color != view[1].color && view[1].color != view[2].color);
            m3 = (view[6].color != view[7].color && view[7].color != view[8].color);
            if(m1 && m2 && m3) {
                return true;
            }
            if(view[4].ant.type == 1 && ((m1?1:0)+(m2?1:0)+(m3?1:0)) >= 2) {
                return true;
            }
        }
    }
    return false;
}

function deRotateSide(m, amt) {
    return deRotate(m,amt*2);
}

/**Positive amount is clockwise**/
function deRotate(m, amt) {
    var rotationsCW = [1,2,5,8,7,6,3,0];
    var rotationsCCW = [3,6,7,8,5,2,1,0];
    if(m == 4 || m < 0 || m > 8 || amt == 0) return m;
    if(amt > 0)
        return rotationsCW[(rotationsCW.indexOf(m)+amt)%8];
    amt = -amt;
    return rotationsCCW[(rotationsCCW.indexOf(m)+amt)%8];
}

function areAdjacent(A, B) {
    if(A == 4 || B == 4 || A == B) return true;
    if(A % 2 == 0 && B % 2 == 0) return false;
    if(A % 2 == 1 && B % 2 == 0) return areAdjacent(B,A);
    if(A % 2 == 1 && B % 2 == 1) return !(8-A == B || 8-B == A);
    if(A == 0 && (B == 1 || B == 3)) return true;
    if(A == 2 && (B == 1 || B == 5)) return true;
    if(A == 6 && (B == 3 || B == 7)) return true;
    if(A == 8 && (B == 5 || B == 7)) return true;
    return false;
}

function findFirstTrail() {
    var pos = 0;
    var b = 0;
    while(view[pos].color != TRAIL && b < 8) {
        pos=deRotate(pos,1);
        b++;
    }
    return pos;
}

function clearAhead(sides) {
    var c=0;
    for(var i=0;i<9;i++) {
        if(view[i].color == 5) c++;
        if(view[i].color == 5 && i%2 == 0) c+=10;
    }
    if(c == 2) {
        if(view[0].color == 5 || view[2].color == 5 || view[6].color == 5 || view[8].color == 5) {
            return {cell:4,color:5};
        }
        if(view[0].ant == null)
            return {cell:0};
        if(view[2].ant == null)
            return {cell:2};
        if(view[6].ant == null)
            return {cell:6};
        if(view[8].ant == null)
            return {cell:8};
    }
    c = 0;
    sides[4] = 0;
    var toMatch =[{state:[1,1,1,
                          2,0,2,
                          0,1,0]},
                 {state:[0,2,1,
                         1,0,1,
                         0,2,1]},
                 {state:[0,1,0,
                         2,0,2,
                         1,1,1]},
                 {state:[1,2,0,
                         1,0,1,
                         1,2,0]}];
    for(var m=0;m<4;m++) {
        var score=0;
        for(var j=0;j<9;j++) {
            if(j!=4) {
                if(sides[j] == 5 && toMatch[m].state[j] == 1) {
                    score++;
                }
                if(sides[j] != 5 && (toMatch[m].state[j] == 0 || toMatch[m].state[j] == 2)) {
                    score++;
                }
                if(sides[j] == 5 && toMatch[m].state[j] == 2) {
                    score--;
                }
            }
        }
        if(score >= 6) {
            var clearOrder=[1,0,2];
            for(var r=0;r<clearOrder.length;r++) {
                var s = deRotateSide(clearOrder[r],m);
                if(view[s].color == 5) {
                    if(view[s].ant == null)
                        return {cell:s,color:8};
                    else
                        return {cell:4};
                }
            }
        }
    }
    return null;
}

function findOpenSpace(pos, dir) {
    if(pos > 8 || pos < 0) return pos;
    var b = 0;
    while(view[pos].ant != null && b < 8) {
        pos=deRotate(pos,dir);
        b++;
    }
    return pos;
}

function getHighestWorker() {
    var r=0;
    for(var i=0;i<9;i++) {
        if(i != 4 && view[i].ant != null) {
            if(view[i].ant.friend && view[i].ant.type > r) r = view[i].ant.type;
        }
    }
    return r;
}

function getNumWorkers(type) {
    var r=0;
    for(var i=0;i<9;i++) {
        if(i != 4 && view[i].ant != null) {
            if(view[i].ant.friend && view[i].ant.type == type) r++;
        }
    }
    return r;
}

function findWorker(type) {
    for(var i=0;i<9;i++) {
        if(i != 4 && view[i].ant != null) {
            if(view[i].ant.friend && view[i].ant.type == type) return i;
        }
    }
    return -1;
}

326% Complete
326% because the update was on 3/16This joke has gone on too long

Update 3/26

More minor tweaks.

37 Minor fix
source | link
var TRAIL = 6;
var SPAWN = 3;
var IDLE = 4;
var FOOD_THRESHOLD = 150;
var SPAWN_MIN = 3;
var HIGHWAY_COLORS = [7,6,4,2,3];
var ret = {cell:4};
if(isOnHighway()) {
    var cont = true;
    //== Make best guess to if in a glider formation ==//
    if(view[4].ant.type == 5) {
        if((findWorker(1) >= 0 && findWorker(4) >= 0) || view[4].ant.food < 80) {
            cont = false;
        }
    }
    else if(view[4].ant.type == 4) {
        if(findWorker(1) >= 0 && findWorker(5) >= 0) {
            cont = false;
        }
    }
    else if(view[4].ant.type == 3) {
        if(findWorker(2) >= 0 && findWorker(5) >= 0) {
            cont = false;
        }
    }
    else if(view[4].ant.type == 2) {
        if(findWorker(5) < 0) {
            var pos3 = findWorker(3);
            if(pos3 >= 0 && view[pos3].ant.food == 0) {
                cont = false;
            }
        }
        else if(findWorker(3) >= 0 || (findWorker(1) >= 0 && view[findWorker(5)].color == SPAWN))
            cont = false;
    }
    else if(view[4].ant.type == 1) {
        if(findWorker(5) < 0) {
            var pos4 = findWorker(4);
            if(pos4 >= 0 && view[pos4].ant.food == 0) {
                cont = false;
            }
        }
        else if(!isHighwayCenter())
            cont = false;
    }
    if(findWorker(5) >= 0) {
        for(var i=0;i<9;i++) {
            if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                if(view[i].ant.food > 10 || view[i].ant.food == 0)
                    cont = true;
                else
                    cont = false;
            }
        }
    }
    //== End guesswork ==//
    if(cont) {
        ret = highwayRobbery();
        if(view[4].ant.type == 1) {
            //try to repair
            var curIndex = HIGHWAY_COLORS.indexOf(view[4].color);
            var prvCol = HIGHWAY_COLORS[(curIndex+1)%HIGHWAY_COLORS.length];
            var nxtCol1 = HIGHWAY_COLORS[(curIndex+HIGHWAY_COLORS.length-1)%HIGHWAY_COLORS.length];
            var nxtCol2 = HIGHWAY_COLORS[(curIndex+HIGHWAY_COLORS.length-2)%HIGHWAY_COLORS.length];
            var nxtCol3 = HIGHWAY_COLORS[(curIndex+HIGHWAY_COLORS.length-3)%HIGHWAY_COLORS.length];
            var prevAt = -1;
            for(var i=0;i<9;i++) {
                if(i%2 == 1 && view[i].color == prvCol && view[deRotate(i,1)].color == nxtCol1 && view[deRotate(i,-1)].color == nxtCol1) prevAt = i;
            }
            if(prevAt >= 0) {
                // yep, brute force it. Because I'm lazy.
                var goNxt = 8-prevAt;
                if(view[deRotate(goNxt,1)].color == nxtCol3 && view[deRotate(goNxt,-1)].color == prvCol) ret = {cell:goNxt};
                else if(view[deRotate(goNxt,1)].color == prvCol && view[deRotate(goNxt,-1)].color == nxtCol3) ret = {cell:goNxt};
                else if(view[goNxt].color != nxtCol1) ret = {cell:goNxt,color:nxtCol1};
                else if(view[deRotate(goNxt,2)].color != nxtCol2) ret = {cell:deRotate(goNxt,2),color:nxtCol2};
                else if(view[deRotate(goNxt,-2)].color != nxtCol2) ret = {cell:deRotate(goNxt,-2),color:nxtCol2};
                else if(view[deRotate(goNxt,1)].color != nxtCol3) ret = {cell:deRotate(goNxt,1),color:nxtCol3};
                else if(view[deRotate(goNxt,-1)].color != nxtCol3) ret = {cell:deRotate(goNxt,-1),color:nxtCol3};
                else ret = {cell:goNxt};
                ret = sanityCheck(ret);
                return ret;
            }
        }
        if(view[4].ant.type == 5 && isHighwayCenter()) {
            if(ret.cell >= 0) {
                ret = {cell:8-ret.cell};
                if(view[4].color == SPAWN && (view[4].ant.food > 90 || view[4].ant.food % 7 == 0) && getHighestWorker() == 0 && (view[4].ant.food < 140 || view[4].ant.food % 9 == 0) && view[0].color == 2 && view[4].ant.food > 50 && view[4].ant.food < 200) {
                    ret = {cell:deRotate(ret.cell,3),type:3};
                }
                if(view[ret.cell].ant != null && !view[ret.cell].ant.friend && view[ret.cell].ant.food == 0 && view[4].ant.food > 0) {
                    if(view[deRotate(ret.cell,1)].ant == null)
                        ret = {cell:deRotate(ret.cell,1),type:3};
                    if(view[deRotate(ret.cell,-1)].ant == null)
                        ret = {cell:deRotate(ret.cell,1),type:3};
                }
            }
            for(var i=0;i<9;i++) {
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                    ret = {cell:8-i};
                }
            }
        }
        if(ret.cell >= 0) {
            for(var i=0;i<9;i++) {
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                    var rr = basicHighwayMove();
                    if(rr.cell >= 0 && view[4].ant.type != 5)
                        ret = {cell:deRotate(rr.cell,-2)};
                }
            }
            if(view[ret.cell].ant != null) {
                var n = HIGHWAY_COLORS.indexOf(view[4].color) + 1;
                var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
                for(var i=0;i<9;i++) {
                    if(view[i].color == nextMove) {
                        if(view[i].ant == null) {
                            ret = {cell:i};
                            break;
                        }
                    }
                }
                if(view[4].ant.type == 5) ret = {cell:8-ret.cell};
            }
        }
        if(view[4].ant.type == 5) {
            var foodedEnemy = false;
            for(var i=0;i<9;i++) {
                if(getNumWorkers(3) >= 2) break;
                if(i != 4 && view[i].ant != null && view[i].ant.type == 5 && view[i].ant.food > 25) {
                    if(view[deRotate(i,1)].ant == null) {
                        ret = {cell:deRotate(i,1),type:3};
                    }
                    else if(view[deRotate(i,-1)].ant == null) {
                        ret = {cell:deRotate(i,-1),type:3};
                    }
                    else if(i%2 == 1 && view[deRotate(i,2)].ant == null) {
                        ret = {cell:deRotate(i,2),type:3};
                    }
                    else if(i%2 == 1 && view[deRotate(i,-2)].ant == null) {
                        ret = {cell:deRotate(i,-2),type:3};
                    }
                }
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 3 && view[8-i].ant == null) {
                    if(i == ret.cell) {
                        ret = {cell:deRotate(i,1)}
                    }
                    else {
                        return {cell:8-i};
                    }
                }
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.food == 0) {
                    foodedEnemy = true;
                }
            }
        }
        var numAnts = 0;
        for(var i=0;i<9;i++) {
            if(view[i].ant != null)
                numAnts++;
        }
        if(numAnts > 2 && sanityCheck(ret).cell == 4) {
            ret = {cell:findOpenSpace(0,1)};
        }
        if(view[4].ant.type == 3) {
            if(getNumWorkers(5) > 0) {
                for(var i=0;i<9;i++) {
                    if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                        ret = {cell:4};
                    }
                }
            }
        }
        if(view[4].ant.type == 4 && getNumWorkers(1) && isHighwayCenter()) {
            var workerPos = findWorker(1);
            for(var i=0;i<9;i++) {
                if(!areAdjacent(i,workerPos)) ret = {cell:i};
            }
        }
        if(ret.cell == -1) {
            if(isHighwayCenter()) {
                for(var i=0;i<9;i++) {
                    var p1 = deRotate(i,3);
                    var p2 = deRotate(i,-3);
                    if(view[i].color == view[p1].color && view[i].color == view[p2].color) {
                        ret = {cell:8-i};
                    }
                }
                if(view[4].ant.type == 1 || view[4].ant.type == 5) {
                    ret = {cell:8-ret.cell};
                }
            }
        }
        if(ret.cell >= 0)
            return sanityCheck(ret);
    }
}

switch(view[4].ant.type) {
    case 5:
        ret = doQueen();
        break;
    case 1:
    case 2:
        ret = doSweep();
        break;
    case 3:
    case 4:
        ret = doGuide();
        break;
    default:
        break;
}
//basic sanity check
ret = sanityCheck(ret);
return ret;

function sanityCheck(ret) {
    if(!ret || ret.cell < 0 || ret.cell > 8) {
        return {cell:4};
    }
    if(ret.color) {
        return ret;
    }
    if((ret.cell != 4 && view[ret.cell].ant != null) || (view[ret.cell].food > 0 && (view[4].ant.food > 0 && view[4].ant.type < 5))) {
        return {cell:4};
    }
    if(ret.type && (view[ret.cell].ant != null || view[ret.cell].food > 0 || view[4].ant.food == 0 || view[4].ant.type < 5)) {
        return {cell:4};
    }
    return ret;
}

function doQueen() {
    if((view[4].ant.food == SPAWN_MIN || (view[4].ant.food >= SPAWN_MIN && view[4].ant.food < FOOD_THRESHOLD && (view[4].ant.food % 3 == 1 || isOnHighway()))) && getHighestWorker() <= 1 ) {
        //prep for first ant
        var s0 = view[0].ant;
        var s1 = view[1].ant;
        var s2 = view[2].ant;
        var s3 = view[3].ant;
        var s5 = view[5].ant;
        var s6 = view[6].ant;
        var s7 = view[7].ant;
        var s8 = view[8].ant;
        var nullCount = 0 + (s0 == null?1:0) + (s1 == null?1:0) + (s2 == null?1:0) + (s3 == null?1:0) + (s5 == null?1:0) + (s6 == null?1:0) + (s7 == null?1:0) + (s8 == null?1:0);
        var nullCount2 = 0 + (s0 == null || s0.friend?1:0) + (s1 == null || s1.friend?1:0) + (s2 == null || s2.friend?1:0) + (s3 == null || s3.friend?1:0) + (s5 == null || s5.friend?1:0) + (s6 == null || s6.friend?1:0) + (s7 == null || s7.friend?1:0) + (s8 == null || s8.friend?1:0);
        if(nullCount >= 7 && nullCount2 >= 8 && view[1].food == 0 && view[3].food == 0 && view[5].food == 0 && view[7].food == 0) {
            var high = getHighestWorker();
            if (high <= 1 && view[4].color != SPAWN && !isOnHighway()) {
                // 50% chance of delaying the respawn by 1 additional move away from where we exploded
                // reduces the chance of a second, immediate explosion
                if(findFirstTrail() < 2 && view[4].ant.food > SPAWN_MIN+1) return foreverAlone();
                var pos1 = findWorker(1);
                if(pos1 >= 0) {
                    var space = deRotate(pos1,2);
                    if(view[space].ant != null) return {cell:findOpenSpace(0,1)};
                }
                return {cell:4,color:SPAWN};
            }
            //spawn first ant
            else if(view[4].color == SPAWN) {
                var pos1 = findWorker(1);
                if(pos1 < 0)  {
                    pos1 = findFirstTrail();
                    if(pos1 % 2 == 0) pos1 = deRotate(pos1,1);
                    else pos1 = deRotate(pos1,4);
                }
                var space = findOpenSpace(pos1,2);
                var high = getHighestWorker();
                if(space < 0) return {cell:4,color:TRAIL}
                if(high == 0) { //no workers
                    return {cell:space,type:1};
                }
                else if(high < 4) { //1 worker of type:high
                    return {cell:space,type:high+1};
                }
                else { //1 worker of type 4
                    //we have all workers, skip!
                }
            }
        }
        else {
            return foreverAlone();
        }
    }
    else if(view[4].ant.food == 1 && getHighestWorker() == 0 ) {
        var space = findOpenSpace(1,2);
        return {cell:space,type:1};
    }
    else if(view[4].ant.food >= 1 && getHighestWorker() < 4 && findWorker(1) >= 0) {
        //spawn remaining ants
        if(view[4].color == SPAWN && !isHighwayCenter()) {
            var pos1 = findWorker(getHighestWorker());
            var space = deRotate(pos1,2);
            var high = getHighestWorker();
            if(space < 0 || view[space].ant != null) return {cell:findOpenSpace(0,1)};
            if(high == 0) { //no workers
                return {cell:space,type:1};
            }
            else if(high < 4) { //1 worker of type:high
                return {cell:space,type:high+1};
            }
            else { //1 worker of type 4
                //we have all workers, skip!
            }
        }
    }
    if(view[4].color == SPAWN && getNumWorkers(3) == 1 && getNumWorkers(4) == 1) {
        var one = getNumWorkers(1);
        var two = getNumWorkers(2);
        if((one ^ two) == 1 && (findWorker(1) % 2 == 0 || findWorker(2) % 2 == 0))
            return {cell:4,color:1};
    }
    if(getNumWorkers(1) == 0 && getNumWorkers(2) == 0) {
        if(getNumWorkers(4) == 1 && getNumWorkers(3) == 0) {
            var pos4 = findWorker(4);
            if(view[deRotate(pos4,1)].ant == null && view[deRotate(pos4,2)].ant == null && findWorker(4) % 2 == 1) {
                //finish rotate with only one glider arm
                return {cell:4};
            }
        }
        return foreverAlone();
    }
    else if(getNumWorkers(1) >= 1 && getNumWorkers(2) >= 1 && getNumWorkers(3) >= 1 && getNumWorkers(4) >= 1) {
        if(view[4].color != 2 && findWorker(1)%2 == 1 && findWorker(2)%2 == 1) {
            return {cell:4,color:TRAIL};
        }
        //move diagonally
        var pos = findWorker(4);
        pos = deRotate(pos,1);
        var checkpos = view[deRotate(pos,4)];
        if(checkpos.ant != null && checkpos.ant.friend) {
            if(checkpos.ant.type == 2)
                return {cell:4};
            if(checkpos.ant.type == 1)
                return {cell:4};
        }
        return {cell:pos};
    }
    else {
        var pos = findWorker(4);
        if(pos < 0) {
            //if gliding along with only a buddy
            pos = findWorker(1);
            if(pos >= 0 && view[deRotate(pos,2)].food > 0 && view[deRotate(pos,1)].food == 0) {
                return {cell:4};
            }
        }
        if(pos < 0) {
            var s1 = view[1].ant;
            var s3 = view[3].ant;
            var s5 = view[5].ant;
            var s7 = view[7].ant;
            //return {cell:999}
            if(s1 == null) {
                if(s3 == null) {
                    return {cell:0};
                }
                if(s5 == null) {
                    return {cell:2};
                }
            }
            if(s7 == null) {
                if(s3 == null) {
                    return {cell:6};
                }
                if(s5 == null) {
                    return {cell:8};
                }
            }
            return {cell:4};
        }
        pos = deRotate(pos,1);
        var checkpos1 = view[pos];
        for(var i=0;i<9;i++) {
            if(i != 4 && view[i].ant != null && view[i].ant.type == 5 && view[i].ant.food > 2) {
                if(i%2==0) {
                    if(view[deRotate(i,1)].ant == null) return {cell:deRotate(i,1),type:3};
                    if(view[deRotate(i,-1)].ant == null) return {cell:deRotate(i,-1),type:3};
                }
                else {
                    if(view[deRotate(i,1)].ant == null) return {cell:deRotate(i,1),type:3};
                    if(view[deRotate(i,-1)].ant == null) return {cell:deRotate(i,-1),type:3};
                    if(view[deRotate(i,2)].ant == null) return {cell:deRotate(i,2),type:3};
                    if(view[deRotate(i,-2)].ant == null) return {cell:deRotate(i,-2),type:3};
                }
                return {cell:4};
            }
        }
        if(checkpos1.ant != null && view[deRotate(pos,1)].ant != null && !view[deRotate(pos,1)].ant.friend) {
            return foreverAlone();
        }

        var checkpos2 = view[deRotate(pos,4)];
        var checkpos3 = view[deRotate(checkpos,1)];
        if(checkpos1.ant != null && checkpos1.ant.friend && checkpos1.ant.type == 1 && checkpos2.ant != null && checkpos2.ant.friend && checkpos2.ant.type == 2 && checkpos3.ant != null && checkpos3.ant.friend && checkpos3.ant.type == 3) {
            //move out of spawn orientation
            return {cell:4};
        }
        if(view[pos].ant != null) {
            if(checkpos2.ant == null && checkpos1.ant == null) {
                return {cell:8-pos};
            }
            if(!view[pos].ant.friend) {
                return foreverAlone();
            }
            if(view[4].color == TRAIL) return foreverAlone();
            return {cell:4,color:TRAIL};
        }
        if(8 - findWorker(3) == findWorker(4)) {
            //finish rotate to the right
            return {cell:4};
        }
        if((view[deRotate(pos,1)].food > 0 || view[deRotate(pos,2)].food > 0) && view[deRotate(pos,1)].ant == null && view[4].color != TRAIL) {
            if(findWorker(1) < 0 || view[deRotate(findWorker(1),1)].food == 0) {
                return {cell:4};
            }
        }
        return {cell:pos};
    }
    return {cell:100+view[4].ant.type}; //oh god
}

//guides sit next to the queen
function doGuide() {
    var queenPos = findWorker(5);
    var ty = view[4].ant.type==3?2:1;
    var dir = view[4].ant.type==3?1:-1;
    if(queenPos >= 0 && queenPos%2 == 1 && view[queenPos].color == SPAWN) {
        if(view[deRotate(queenPos,dir*2)].ant == null) {
            return {cell:4};
        }
    }
    if(queenPos < 0 || findWorker(ty) < 0) {
        if(findWorker(ty) >= 0 && view[0].color != IDLE) return {cell:0,color:IDLE}
        return firebreak();
    }
    var checkpos = view[deRotate(queenPos,-2*dir)];
    if(view[4].ant.type==4 && checkpos.ant != null && checkpos.ant.friend && checkpos.ant.type == 1) {
        //attempt rotate
        return {cell:deRotate(queenPos,-dir)};
    }
    checkpos = view[deRotate(queenPos,4)];
    if(checkpos.ant != null && checkpos.ant.friend && checkpos.ant.type == ty) {
        //attempt rotate
        if(getNumWorkers(ty) == 1) {
            return {cell:4};
        }
    }
    var pos = deRotate(queenPos,dir);
    if(pos >= 0 && view[4].ant.type==3 && findWorker(4) < 0) {
        //wait for rotate
        if(view[4].color == TRAIL) {
            return {cell:4};
        }
    }
    if(pos >= 0 && findWorker(2) >= 0 && view[deRotate(findWorker(2),1)].ant != null) {
        //rotate
        return {cell:4,color:TRAIL};
    }
    if(pos < 0) pos = 4;
    else if(view[pos].ant != null) return {cell:deRotate(queenPos,4)};
    if(pos == 4 && view[queenPos].color == TRAIL) return {cell:queenPos,color:1};
    return {cell:pos};
}

//sweepers sit next to guides
function doSweep() {
    var queenPos = findWorker(5);
    var followType = view[4].ant.type==1?4:3;
    var pos = findWorker(followType);
    if(pos % 2 == 0 && getNumWorkers(followType) > 1) {
        //if there's more than one worker #4, we want to use the best one
        for(var i=pos+1;i<9;i++) {
            if(i != 4 && view[i].ant != null) {
                if(view[i].ant.friend && view[i].ant.type == followType) {
                    pos = i;
                    break;
                }
            }
        }
    }
    if(queenPos >= 0 && queenPos%2 == 1 && view[queenPos].color == SPAWN) {
        var p = findWorker(view[4].ant.type);
        if(p >= 0 && (deRotate(p,1) == queenPos || deRotate(p,-1) == queenPos)) {
            return {cell:8-queenPos};
        }
        return {cell:4};
    }
    if(queenPos >= 0 && pos < 0) {
        //if Worker #1 is the only ant besides the queen:
        //TODO
        if(view[queenPos].ant.food <= SPAWN_MIN || !(view[queenPos].ant.food < FOOD_THRESHOLD && view[queenPos].ant.food % 3 == 1)) {
            var go = deRotate(queenPos,-1);
            if((view[deRotate(queenPos,-2)].food > 0 || view[deRotate(queenPos,-3)].food > 0 || (queenPos %2 == 1 && view[deRotate(queenPos,-3)].food > 0)) && view[go].food == 0) {
                go = deRotate(queenPos,2);
                //return {cell:4};
            }
            return {cell:go};
        }
        else if(view[queenPos].ant.food < FOOD_THRESHOLD && view[queenPos].ant.food % 3 == 1) {
            return {cell:4};
        }
    }
    if(queenPos >= 0) {
        var dir = view[4].ant.type==1?1:-1;
        //var checkpos = view[deRotate(pos,-dir)];
        var moveTo = deRotate(pos,dir);
        if(moveTo >= 0 && view[moveTo].ant != null && view[moveTo].ant.friend && view[moveTo].ant.type == 5) {
            moveTo = deRotate(pos,-dir);
        }
        if(view[4].ant.type == 2 && findWorker(1) < 0 && view[queenPos].color != TRAIL) {
            moveTo = 4;
        }
        return {cell:moveTo};
    }
    else {
        if(pos < 0) return {cell:4}; //firebreak();
        var dir = view[4].ant.type==1?-1:1;
        var moveTo = deRotate(pos,dir);
        if(view[4].ant.food > 0 && view[moveTo].food > 0) {
            //have food, attempt to give to queen
            moveTo = deRotate(pos,-dir);
        }
        if(view[4].ant.type==1 && pos >= 0 && (view[deRotate(pos,dir*2)].food > 0 || view[deRotate(pos,dir*3)].food > 0)) {
            //attempt rotate
            moveTo = deRotate(pos,-dir);
        }
        if(view[4].ant.type==2 && pos >= 0 && (view[deRotate(pos,dir*2)].food > 0 || view[deRotate(pos,dir*3)].food > 0)) {
            //attempt rotate
            moveTo = deRotate(pos,-dir);
        }
        if(moveTo >= 0 && view[moveTo].ant != null && view[moveTo].ant.type == 5) {
            if(view[moveTo].ant.friend)
                moveTo = deRotate(moveTo,dir*2);
            else
                moveTo = deRotate(pos,-dir);
        }
        return {cell:moveTo};
    }
    return {cell:100+view[4].ant.type};//oh god
}

function foreverAlone() {
    var s0 = view[0].ant;
    var s1 = view[1].ant;
    var s2 = view[2].ant;
    var s3 = view[3].ant;
    var s5 = view[5].ant;
    var s6 = view[6].ant;
    var s7 = view[7].ant;
    var s8 = view[8].ant;
    if(!(s0 == null && s1 == null && s2 == null && s3 == null && s5 == null && s6 == null && s7 == null && s8 == null) && view[4].color == SPAWN) {
        if (view[0].color == TRAIL && !view[8].ant && view[8].color != TRAIL) return {cell: 8};
        else if (view[2].color == TRAIL && !view[6].ant && view[6].color != TRAIL) return {cell: 6};
        else if (view[6].color == TRAIL && !view[2].ant && view[2].color != TRAIL) return {cell: 2};
        else if (view[8].color == TRAIL && !view[0].ant && view[0].color != TRAIL) return {cell: 0};
        //Can't find color, or path is blocked? try diagonals regardless of color
        else if (!view[0].ant) return {cell: 0};
        else if (!view[2].ant) return {cell: 2};
        else if (!view[6].ant) return {cell: 6};
        else if (!view[8].ant) return {cell: 8};
        //Everything else failed? Stay put.
        else return {cell: 4};
    }
    if (view[4].color == TRAIL || view[4].color == SPAWN) { //If on colored square, try to move
        var totGreen = 0;
        for (var i = 0; i < 9; i++) { //Look for food
            if (view[i].food) {
                return {cell: i};
            }
            if(view[i].color == TRAIL) totGreen++;
        }
        var ret = getTrailMove();
        if(view[deRotate(ret.cell,1)].color == TRAIL && totGreen <= 4) ret.cell = deRotate(ret.cell,-1);
        else if(view[deRotate(ret.cell,-1)].color == TRAIL && totGreen <= 4) ret.cell = deRotate(ret.cell,1);
        return ret;
    } else { //If not on colored square, look for food, or set current color to 2.
        for (var i = 0; i < 9; i++) { //Look for enemies
            if (i != 4 && view[i].ant != null && !view[i].ant.friend) {
                var r = findOpenSpace(8-i,1);
                if(view[r].color == TRAIL) r = deRotate(r,1);
                return {cell: r};
            }
        }
        return {cell: 4, color:TRAIL};
    }
}

function getTrailMove() {
    if (view[0].color == TRAIL && !view[8].ant && view[8].color != TRAIL) return {cell: 8};
    else if (view[2].color == TRAIL && !view[6].ant && view[6].color != TRAIL) return {cell: 6};
    else if (view[6].color == TRAIL && !view[2].ant && view[2].color != TRAIL) return {cell: 2};
    else if (view[8].color == TRAIL && !view[0].ant && view[0].color != TRAIL) return {cell: 0};
    //Can't find color, or path is blocked? try diagonals regardless of color
    else if (!view[0].ant) return {cell: 0};
    else if (!view[2].ant) return {cell: 2};
    else if (!view[6].ant) return {cell: 6};
    else if (!view[8].ant) return {cell: 8};
    //Everything else failed? Stay put.
    else return {cell: 4};
}

function firebreak() {
    var ret = -1;
    if(findWorker(5) >= 0) {
        return {cell:8-findWorker(5)};
    }
    if(view[4].color != 5) {
        var myView = [0,0,0,0,0,0,0,0,0]
        for(var i=0; i < 9; i++) {
            myView[i] = view[i].color
            if(view[4].ant.food > 0 && view[i].food > 0) {
                myView[i] = 8;
            }
            if(view[i].ant != null && !view[i].ant.friend) return {cell:findOpenSpace(deRotate(i,2),1)};
        }
        var ret = clearAhead(myView);
        if(ret == null)
            return {cell:4,color:5};
        else {
            if(!(view[ret.cell].ant != null && view[ret.cell].ant.friend == false) && (view[4].ant.food == 0 || view[ret.cell].food == 0))
                return ret;
            return {cell:4,color:5};
        }
    }
    if(view[1].color == 5 && view[3].color == 5 && view[5].color == 5 && view[7].color == 5) {
        if(view[0].color != 8) return {cell:0,color:8};
        if(view[1].color != 8) return {cell:1,color:8};
    }
    if(view[1].color == 5 && view[7].color != 5) ret = {cell:7};
    if(view[3].color == 5 && view[5].color != 5) ret = {cell:5};
    if(view[5].color == 5 && view[3].color != 5) ret = {cell:3};
    if(view[7].color == 5 && view[1].color != 5) ret = {cell:1};
    if(view[1].color != 5 && view[3].color != 5 && view[5].color != 5 && view[7].color != 5) ret = {cell:1};
    if((view[1].color == 5 && view[7].color == 5) || (view[3].color == 5 && view[5].color == 5)) ret = {cell:0};
    var loop = 0;
    while(ret.cell >= 0 && ((view[ret.cell].food > 0 && view[4].ant.food > 0) || view[ret.cell].ant != null) && loop < 9) {
        loop++;
        ret.cell = (ret.cell + 2) % 9;
    }
    if(loop < 9 && ret.cell >= 0) return ret;
    return {cell:4};
}

//7,6,4,2,3
//O7,D2

function highwayRobbery() {
    var move = basicHighwayMove();
    if(move.cell >= 0 && view[move.cell].ant != null) {
        var n = HIGHWAY_COLORS.indexOf(view[4].color) + (view[4].color%2==0?1:HIGHWAY_COLORS.length);
        var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
        for(var i=0;i<9;i++) {
            if(view[i].color == nextMove) {
                return {cell:i};
            }
        }
    }
    return move;
}

function basicHighwayMove() {
    var isQueen = view[4].ant.type == 5;
    if(isHighwayCenter()) {
        var n = HIGHWAY_COLORS.indexOf(view[4].color) + 1;
        var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
        for(var i=0;i<9;i++) {
            if(view[i].color == nextMove) {
                if(view[i].ant == null)
                    return {cell:i};
                else {
                    return {cell:deRotate(i,1)};
                }
            }
        }
    }
    else {
        if(view[4].color == 7) {
            //move diagonal to yellow (2)
            for(var i=0;i<9;i++) {
                if(i != 4 && i % 2 == 0 && view[i].color == 2) {
                    return {cell:i};
                }
            }
        }
        else {
            //move orthogonal to blue (7)
            for(var i=0;i<9;i++) {
                if(i % 2 == 1 && view[i].color == 7) {
                    //try ortho yellow first
                    for(var j=0;j<9;j++) {
                        if(j % 2 == 1 && view[j].color == 2 && areAdjacent(i,j))
                            return {cell:j};
                    }
                    return {cell:i};
                }
            }
            //if orthogonal blue doens't exist...
            //...try diagonal to magenta
            for(var i=0;i<9;i++) {
                if(i != 4 && i % 2 == 0 && view[i].color == 3) {
                    return {cell:i};
                }
            }
            if(view[4].color != 2) {
                //...try diagonal blue
                for(var i=0;i<9;i++) {
                    if(i % 2 == 0 && view[i].color == 7)
                        return {cell:i};
                }
            }
            //...and orthogonal yellow
            for(var i=0;i<9;i++) {
                if(i % 2 == 1 && view[i].color == 2)
                    return {cell:i};
            }
        }
        var n = HIGHWAY_COLORS.indexOf(view[4].color) + 1;
        var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
        for(var i=0;i<9;i++) {
            if(view[i].color == nextMove) {
                return {cell:i};
            }
        }
    }
    return {cell:-1};
}

function isOnHighway() {
    var match = 0;
    var nxt = HIGHWAY_COLORS[(HIGHWAY_COLORS.indexOf(view[4].color)+1) % HIGHWAY_COLORS.length];//4
    var prv = HIGHWAY_COLORS[(HIGHWAY_COLORS.indexOf(view[4].color)+HIGHWAY_COLORS.length-2) % HIGHWAY_COLORS.length];//6
    for(var i=0;i<9;i++) {
        if(HIGHWAY_COLORS.indexOf(view[i].color) >=0 && (i == 4 || view[i].color != view[4].color))
            match++;
    }
    if(match >= 5) {
        //7,6,4,2,3


        if((view[1].color == nxt && view[7].color == prv)||(view[1].color == prv && view[7].color == nxt) || 
            (view[3].color == nxt && view[5].color == prv)||(view[3].color == prv && view[5].color == nxt)) {
            return true;
        }
        if((view[1].color == view[8].color && (view[1].color == nxt || view[1].color == prv))||(view[1].color == view[6].color && (view[1].color == nxt || view[1].color == prv)) || 
            (view[3].color == view[2].color && (view[3].color == nxt || view[3].color == prv))||(view[3].color == view[8].color && (view[3].color == nxt || view[3].color == prv))) {
            return true;
        }
        if((view[0].color == view[7].color && (view[0].color == nxt || view[0].color == prv))||(view[2].color == view[7].color && (view[2].color == nxt || view[2].color == prv)) || 
            (view[0].color == view[5].color && (view[0].color == nxt || view[0].color == prv))||(view[6].color == view[5].color && (view[6].color == nxt || view[6].color == prv))) {
            return true;
        }
        if(isHighwayCenter()) {
            return true;
        }
    }
    return false;
}

function isHighwayCenter() {
    if(HIGHWAY_COLORS.indexOf(view[4].color) >=0 && (((view[0].color != view[8].color || view[2].color != view[6].color) && view[4].ant.type == 1) || (view[0].color != view[8].color && view[2].color != view[6].color))){
        var m1 = view[1].color == view[7].color;
        var m2 = view[2].color == view[8].color;
        var m3 = view[0].color == view[6].color;
        if((m1?1:0)+(m2?1:0)+(m3?1:0) >= 2) {
            if(view[3].color != view[5].color && ((view[2].color != view[5].color && view[8].color != view[5].color) || view[4].ant.type == 1) && ((view[3].color != view[0].color && view[3].color != view[6].color) || view[4].ant.type == 1)) {
                return true;
            }
        }
        m1 = view[3].color == view[5].color;
        m2 = view[0].color == view[2].color;
        m3 = view[6].color == view[8].color;
        if((m1?1:0)+(m2?1:0)+(m3?1:0) >= 2) {
            if(view[1].color != view[7].color && ((view[0].color != view[1].color && view[1].color != view[2].color) || view[4].ant.type == 1) && ((view[6].color != view[7].color && view[7].color != view[8].color) || view[4].ant.type == 1)) {
                return true;
            }
        }
    }
    return false;
}

function deRotateSide(m, amt) {
    return deRotate(m,amt*2);
}

/**Positive amount is clockwise**/
function deRotate(m, amt) {
    var rotationsCW = [1,2,5,8,7,6,3,0];
    var rotationsCCW = [3,6,7,8,5,2,1,0];
    if(m == 4 || m < 0 || m > 8 || amt == 0) return m;
    if(amt > 0)
        return rotationsCW[(rotationsCW.indexOf(m)+amt)%8];
    amt = -amt;
    return rotationsCCW[(rotationsCCW.indexOf(m)+amt)%8];
}

function areAdjacent(A, B) {
    if(A == 4 || B == 4 || A == B) return true;
    if(A % 2 == 0 && B % 2 == 0) return false;
    if(A % 2 == 1 && B % 2 == 0) return areAdjacent(B,A);
    if(A % 2 == 1 && B % 2 == 1) return !(8-A == B || 8-B == A);
    if(A == 0 && (B == 1 || B == 3)) return true;
    if(A == 2 && (B == 1 || B == 5)) return true;
    if(A == 6 && (B == 3 || B == 7)) return true;
    if(A == 8 && (B == 5 || B == 7)) return true;
    return false;
}

function findFirstTrail() {
    var pos = 0;
    var b = 0;
    while(view[pos].color != TRAIL && b < 8) {
        pos=deRotate(pos,1);
        b++;
    }
    return pos;
}

function clearAhead(sides) {
    var c=0;
    for(var i=0;i<9;i++) {
        if(view[i].color == 5) c++;
        if(view[i].color == 5 && i%2 == 0) c+=10;
    }
    if(c == 2) {
        if(view[0].color == 5 || view[2].color == 5 || view[6].color == 5 || view[8].color == 5) {
            return {cell:4,color:5};
        }
        if(view[0].ant == null)
            return {cell:0};
        if(view[2].ant == null)
            return {cell:2};
        if(view[6].ant == null)
            return {cell:6};
        if(view[8].ant == null)
            return {cell:8};
    }
    c = 0;
    sides[4] = 0;
    var toMatch =[{state:[1,1,1,
                          2,0,2,
                          0,1,0]},
                 {state:[0,2,1,
                         1,0,1,
                         0,2,1]},
                 {state:[0,1,0,
                         2,0,2,
                         1,1,1]},
                 {state:[1,2,0,
                         1,0,1,
                         1,2,0]}];
    for(var m=0;m<4;m++) {
        var score=0;
        for(var j=0;j<9;j++) {
            if(j!=4) {
                if(sides[j] == 5 && toMatch[m].state[j] == 1) {
                    score++;
                }
                if(sides[j] != 5 && (toMatch[m].state[j] == 0 || toMatch[m].state[j] == 2)) {
                    score++;
                }
                if(sides[j] == 5 && toMatch[m].state[j] == 2) {
                    score--;
                }
            }
        }
        if(score >= 6) {
            var clearOrder=[1,0,2];
            for(var r=0;r<clearOrder.length;r++) {
                var s = deRotateSide(clearOrder[r],m);
                if(view[s].color == 5) {
                    if(view[s].ant == null)
                        return {cell:s,color:8};
                    else
                        return {cell:4};
                }
            }
        }
    }
    return null;
}

function findOpenSpace(pos, dir) {
    if(pos > 8 || pos < 0) return pos;
    var b = 0;
    while(view[pos].ant != null && b < 8) {
        pos=deRotate(pos,dir);
        b++;
    }
    return pos;
}

function getHighestWorker() {
    var r=0;
    for(var i=0;i<9;i++) {
        if(i != 4 && view[i].ant != null) {
            if(view[i].ant.friend && view[i].ant.type > r) r = view[i].ant.type;
        }
    }
    return r;
}

function getNumWorkers(type) {
    var r=0;
    for(var i=0;i<9;i++) {
        if(i != 4 && view[i].ant != null) {
            if(view[i].ant.friend && view[i].ant.type == type) r++;
        }
    }
    return r;
}

function findWorker(type) {
    for(var i=0;i<9;i++) {
        if(i != 4 && view[i].ant != null) {
            if(view[i].ant.friend && view[i].ant.type == type) return i;
        }
    }
    return -1;
}
var TRAIL = 6;
var SPAWN = 3;
var IDLE = 4;
var FOOD_THRESHOLD = 150;
var SPAWN_MIN = 3;
var HIGHWAY_COLORS = [7,6,4,2,3];
var ret = {cell:4};
if(isOnHighway()) {
    var cont = true;
    //== Make best guess to if in a glider formation ==//
    if(view[4].ant.type == 5) {
        if((findWorker(1) >= 0 && findWorker(4) >= 0) || view[4].ant.food < 80) {
            cont = false;
        }
    }
    else if(view[4].ant.type == 4) {
        if(findWorker(1) >= 0 && findWorker(5) >= 0) {
            cont = false;
        }
    }
    else if(view[4].ant.type == 3) {
        if(findWorker(2) >= 0 && findWorker(5) >= 0) {
            cont = false;
        }
    }
    else if(view[4].ant.type == 2) {
        if(findWorker(5) < 0) {
            var pos3 = findWorker(3);
            if(pos3 >= 0 && view[pos3].ant.food == 0) {
                cont = false;
            }
        }
        else if(findWorker(3) >= 0 || (findWorker(1) >= 0 && view[findWorker(5)].color == SPAWN))
            cont = false;
    }
    else if(view[4].ant.type == 1) {
        if(findWorker(5) < 0) {
            var pos4 = findWorker(4);
            if(pos4 >= 0 && view[pos4].ant.food == 0) {
                cont = false;
            }
        }
        else if(!isHighwayCenter())
            cont = false;
    }
    if(findWorker(5) >= 0) {
        for(var i=0;i<9;i++) {
            if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                if(view[i].ant.food > 10 || view[i].ant.food == 0)
                    cont = true;
                else
                    cont = false;
            }
        }
    }
    //== End guesswork ==//
    if(cont) {
        ret = highwayRobbery();
        if(view[4].ant.type == 1) {
            //try to repair
            var curIndex = HIGHWAY_COLORS.indexOf(view[4].color);
            var prvCol = HIGHWAY_COLORS[(curIndex+1)%HIGHWAY_COLORS.length];
            var nxtCol1 = HIGHWAY_COLORS[(curIndex+HIGHWAY_COLORS.length-1)%HIGHWAY_COLORS.length];
            var nxtCol2 = HIGHWAY_COLORS[(curIndex+HIGHWAY_COLORS.length-2)%HIGHWAY_COLORS.length];
            var nxtCol3 = HIGHWAY_COLORS[(curIndex+HIGHWAY_COLORS.length-3)%HIGHWAY_COLORS.length];
            var prevAt = -1;
            for(var i=0;i<9;i++) {
                if(i%2 == 1 && view[i].color == prvCol && view[deRotate(i,1)].color == nxtCol1 && view[deRotate(i,-1)].color == nxtCol1) prevAt = i;
            }
            if(prevAt >= 0) {
                // yep, brute force it. Because I'm lazy.
                var goNxt = 8-prevAt;
                if(view[deRotate(goNxt,1)].color == nxtCol3 && view[deRotate(goNxt,-1)].color == prvCol) ret = {cell:goNxt};
                else if(view[deRotate(goNxt,1)].color == prvCol && view[deRotate(goNxt,-1)].color == nxtCol3) ret = {cell:goNxt};
                else if(view[goNxt].color != nxtCol1) ret = {cell:goNxt,color:nxtCol1};
                else if(view[deRotate(goNxt,2)].color != nxtCol2) ret = {cell:deRotate(goNxt,2),color:nxtCol2};
                else if(view[deRotate(goNxt,-2)].color != nxtCol2) ret = {cell:deRotate(goNxt,-2),color:nxtCol2};
                else if(view[deRotate(goNxt,1)].color != nxtCol3) ret = {cell:deRotate(goNxt,1),color:nxtCol3};
                else if(view[deRotate(goNxt,-1)].color != nxtCol3) ret = {cell:deRotate(goNxt,-1),color:nxtCol3};
                else ret = {cell:goNxt};
                ret = sanityCheck(ret);
                return ret;
            }
        }
        if(view[4].ant.type == 5 && isHighwayCenter()) {
            if(ret.cell >= 0) {
                ret = {cell:8-ret.cell};
                if(view[4].color == SPAWN && (view[4].ant.food > 90 || view[4].ant.food % 7 == 0) && getHighestWorker() == 0 && (view[4].ant.food < 140 || view[4].ant.food % 9 == 0) && view[0].color == 2 && view[4].ant.food > 50 && view[4].ant.food < 200) {
                    ret = {cell:deRotate(ret.cell,3),type:3};
                }
                if(view[ret.cell].ant != null && !view[ret.cell].ant.friend && view[ret.cell].ant.food == 0 && view[4].ant.food > 0) {
                    if(view[deRotate(ret.cell,1)].ant == null)
                        ret = {cell:deRotate(ret.cell,1),type:3};
                    if(view[deRotate(ret.cell,-1)].ant == null)
                        ret = {cell:deRotate(ret.cell,1),type:3};
                }
            }
            for(var i=0;i<9;i++) {
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                    ret = {cell:8-i};
                }
            }
        }
        if(ret.cell >= 0) {
            for(var i=0;i<9;i++) {
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                    var rr = basicHighwayMove();
                    if(rr.cell >= 0 && view[4].ant.type != 5)
                        ret = {cell:deRotate(rr.cell,-2)};
                }
            }
            if(view[ret.cell].ant != null) {
                var n = HIGHWAY_COLORS.indexOf(view[4].color) + 1;
                var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
                for(var i=0;i<9;i++) {
                    if(view[i].color == nextMove) {
                        if(view[i].ant == null) {
                            ret = {cell:i};
                            break;
                        }
                    }
                }
                if(view[4].ant.type == 5) ret = {cell:8-ret.cell};
            }
        }
        if(view[4].ant.type == 5) {
            var foodedEnemy = false;
            for(var i=0;i<9;i++) {
                if(getNumWorkers(3) >= 2) break;
                if(i != 4 && view[i].ant != null && view[i].ant.type == 5 && view[i].ant.food > 25) {
                    if(view[deRotate(i,1)].ant == null) {
                        ret = {cell:deRotate(i,1),type:3};
                    }
                    else if(view[deRotate(i,-1)].ant == null) {
                        ret = {cell:deRotate(i,-1),type:3};
                    }
                    else if(i%2 == 1 && view[deRotate(i,2)].ant == null) {
                        ret = {cell:deRotate(i,2),type:3};
                    }
                    else if(i%2 == 1 && view[deRotate(i,-2)].ant == null) {
                        ret = {cell:deRotate(i,-2),type:3};
                    }
                }
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 3 && view[8-i].ant == null) {
                    if(i == ret.cell) {
                        ret = {cell:deRotate(i,1)}
                    }
                    else {
                        return {cell:8-i};
                    }
                }
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.food == 0) {
                    foodedEnemy = true;
                }
            }
        }
        var numAnts = 0;
        for(var i=0;i<9;i++) {
            if(view[i].ant != null)
                numAnts++;
        }
        if(numAnts > 2 && sanityCheck(ret).cell == 4) {
            ret = {cell:findOpenSpace(0,1)};
        }
        if(view[4].ant.type == 3) {
            if(getNumWorkers(5) > 0) {
                for(var i=0;i<9;i++) {
                    if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                        ret = {cell:4};
                    }
                }
            }
        }
        if(view[4].ant.type == 4 && getNumWorkers(1) && isHighwayCenter()) {
            var workerPos = findWorker(1);
            for(var i=0;i<9;i++) {
                if(!areAdjacent(i,workerPos)) ret = {cell:i};
            }
        }
        if(ret.cell == -1) {
            if(isHighwayCenter()) {
                for(var i=0;i<9;i++) {
                    var p1 = deRotate(i,3);
                    var p2 = deRotate(i,-3);
                    if(view[i].color == view[p1].color && view[i].color == view[p2].color) {
                        ret = {cell:8-i};
                    }
                }
                if(view[4].ant.type == 1 || view[4].ant.type == 5) {
                    ret = {cell:8-ret.cell};
                }
            }
        }
        if(ret.cell >= 0)
            return sanityCheck(ret);
    }
}

switch(view[4].ant.type) {
    case 5:
        ret = doQueen();
        break;
    case 1:
    case 2:
        ret = doSweep();
        break;
    case 3:
    case 4:
        ret = doGuide();
        break;
    default:
        break;
}
//basic sanity check
ret = sanityCheck(ret);
return ret;

function sanityCheck(ret) {
    if(!ret || ret.cell < 0 || ret.cell > 8) {
        return {cell:4};
    }
    if(ret.color) {
        return ret;
    }
    if((ret.cell != 4 && view[ret.cell].ant != null) || (view[ret.cell].food > 0 && (view[4].ant.food > 0 && view[4].ant.type < 5))) {
        return {cell:4};
    }
    if(ret.type && (view[ret.cell].ant != null || view[ret.cell].food > 0 || view[4].ant.food == 0 || view[4].ant.type < 5)) {
        return {cell:4};
    }
    return ret;
}

function doQueen() {
    if((view[4].ant.food == SPAWN_MIN || (view[4].ant.food >= SPAWN_MIN && view[4].ant.food < FOOD_THRESHOLD && (view[4].ant.food % 3 == 1 || isOnHighway()))) && getHighestWorker() <= 1 ) {
        //prep for first ant
        var s0 = view[0].ant;
        var s1 = view[1].ant;
        var s2 = view[2].ant;
        var s3 = view[3].ant;
        var s5 = view[5].ant;
        var s6 = view[6].ant;
        var s7 = view[7].ant;
        var s8 = view[8].ant;
        var nullCount = 0 + (s0 == null?1:0) + (s1 == null?1:0) + (s2 == null?1:0) + (s3 == null?1:0) + (s5 == null?1:0) + (s6 == null?1:0) + (s7 == null?1:0) + (s8 == null?1:0);
        var nullCount2 = 0 + (s0 == null || s0.friend?1:0) + (s1 == null || s1.friend?1:0) + (s2 == null || s2.friend?1:0) + (s3 == null || s3.friend?1:0) + (s5 == null || s5.friend?1:0) + (s6 == null || s6.friend?1:0) + (s7 == null || s7.friend?1:0) + (s8 == null || s8.friend?1:0);
        if(nullCount >= 7 && nullCount2 >= 8 && view[1].food == 0 && view[3].food == 0 && view[5].food == 0 && view[7].food == 0) {
            var high = getHighestWorker();
            if (high <= 1 && view[4].color != SPAWN && !isOnHighway()) {
                // 50% chance of delaying the respawn by 1 additional move away from where we exploded
                // reduces the chance of a second, immediate explosion
                if(findFirstTrail() < 2 && view[4].ant.food > SPAWN_MIN+1) return foreverAlone();
                var pos1 = findWorker(1);
                if(pos1 >= 0) {
                    var space = deRotate(pos1,2);
                    if(view[space].ant != null) return {cell:findOpenSpace(0,1)};
                }
                return {cell:4,color:SPAWN};
            }
            //spawn first ant
            else if(view[4].color == SPAWN) {
                var pos1 = findWorker(1);
                if(pos1 < 0)  {
                    pos1 = findFirstTrail();
                    if(pos1 % 2 == 0) pos1 = deRotate(pos1,1);
                    else pos1 = deRotate(pos1,4);
                }
                var space = findOpenSpace(pos1,2);
                var high = getHighestWorker();
                if(space < 0) return {cell:4,color:TRAIL}
                if(high == 0) { //no workers
                    return {cell:space,type:1};
                }
                else if(high < 4) { //1 worker of type:high
                    return {cell:space,type:high+1};
                }
                else { //1 worker of type 4
                    //we have all workers, skip!
                }
            }
        }
        else {
            return foreverAlone();
        }
    }
    else if(view[4].ant.food == 1 && getHighestWorker() == 0 ) {
        var space = findOpenSpace(1,2);
        return {cell:space,type:1};
    }
    else if(view[4].ant.food >= 1 && getHighestWorker() < 4 && findWorker(1) >= 0) {
        //spawn remaining ants
        if(view[4].color == SPAWN && !isHighwayCenter()) {
            var pos1 = findWorker(getHighestWorker());
            var space = deRotate(pos1,2);
            var high = getHighestWorker();
            if(space < 0 || view[space].ant != null) return {cell:findOpenSpace(0,1)};
            if(high == 0) { //no workers
                return {cell:space,type:1};
            }
            else if(high < 4) { //1 worker of type:high
                return {cell:space,type:high+1};
            }
            else { //1 worker of type 4
                //we have all workers, skip!
            }
        }
    }
    if(view[4].color == SPAWN && getNumWorkers(3) == 1 && getNumWorkers(4) == 1) {
        var one = getNumWorkers(1);
        var two = getNumWorkers(2);
        if((one ^ two) == 1 && (findWorker(1) % 2 == 0 || findWorker(2) % 2 == 0))
            return {cell:4,color:1};
    }
    if(getNumWorkers(1) == 0 && getNumWorkers(2) == 0) {
        if(getNumWorkers(4) == 1 && getNumWorkers(3) == 0) {
            var pos4 = findWorker(4);
            if(view[deRotate(pos4,1)].ant == null && view[deRotate(pos4,2)].ant == null && findWorker(4) % 2 == 1) {
                //finish rotate with only one glider arm
                return {cell:4};
            }
        }
        return foreverAlone();
    }
    else if(getNumWorkers(1) >= 1 && getNumWorkers(2) >= 1 && getNumWorkers(3) >= 1 && getNumWorkers(4) >= 1) {
        if(view[4].color != 2 && findWorker(1)%2 == 1 && findWorker(2)%2 == 1) {
            return {cell:4,color:TRAIL};
        }
        //move diagonally
        var pos = findWorker(4);
        pos = deRotate(pos,1);
        var checkpos = view[deRotate(pos,4)];
        if(checkpos.ant != null && checkpos.ant.friend) {
            if(checkpos.ant.type == 2)
                return {cell:4};
            if(checkpos.ant.type == 1)
                return {cell:4};
        }
        return {cell:pos};
    }
    else {
        var pos = findWorker(4);
        if(pos < 0) {
            //if gliding along with only a buddy
            pos = findWorker(1);
            if(pos >= 0 && view[deRotate(pos,2)].food > 0 && view[deRotate(pos,1)].food == 0) {
                return {cell:4};
            }
        }
        if(pos < 0) {
            var s1 = view[1].ant;
            var s3 = view[3].ant;
            var s5 = view[5].ant;
            var s7 = view[7].ant;
            //return {cell:999}
            if(s1 == null) {
                if(s3 == null) {
                    return {cell:0};
                }
                if(s5 == null) {
                    return {cell:2};
                }
            }
            if(s7 == null) {
                if(s3 == null) {
                    return {cell:6};
                }
                if(s5 == null) {
                    return {cell:8};
                }
            }
            return {cell:4};
        }
        pos = deRotate(pos,1);
        var checkpos1 = view[pos];
        for(var i=0;i<9;i++) {
            if(i != 4 && view[i].ant != null && view[i].ant.type == 5 && view[i].ant.food > 2) {
                if(i%2==0) {
                    if(view[deRotate(i,1)].ant == null) return {cell:deRotate(i,1),type:3};
                    if(view[deRotate(i,-1)].ant == null) return {cell:deRotate(i,-1),type:3};
                }
                else {
                    if(view[deRotate(i,1)].ant == null) return {cell:deRotate(i,1),type:3};
                    if(view[deRotate(i,-1)].ant == null) return {cell:deRotate(i,-1),type:3};
                    if(view[deRotate(i,2)].ant == null) return {cell:deRotate(i,2),type:3};
                    if(view[deRotate(i,-2)].ant == null) return {cell:deRotate(i,-2),type:3};
                }
                return {cell:4};
            }
        }
        if(checkpos1.ant != null && view[deRotate(pos,1)].ant != null && !view[deRotate(pos,1)].ant.friend) {
            return foreverAlone();
        }

        var checkpos2 = view[deRotate(pos,4)];
        var checkpos3 = view[deRotate(checkpos,1)];
        if(checkpos1.ant != null && checkpos1.ant.friend && checkpos1.ant.type == 1 && checkpos2.ant != null && checkpos2.ant.friend && checkpos2.ant.type == 2 && checkpos3.ant != null && checkpos3.ant.friend && checkpos3.ant.type == 3) {
            //move out of spawn orientation
            return {cell:4};
        }
        if(view[pos].ant != null) {
            if(checkpos2.ant == null && checkpos1.ant == null) {
                return {cell:8-pos};
            }
            if(!view[pos].ant.friend) {
                return foreverAlone();
            }
            if(view[4].color == TRAIL) return foreverAlone();
            return {cell:4,color:TRAIL};
        }
        if(8 - findWorker(3) == findWorker(4)) {
            //finish rotate to the right
            return {cell:4};
        }
        if((view[deRotate(pos,1)].food > 0 || view[deRotate(pos,2)].food > 0) && view[deRotate(pos,1)].ant == null && view[4].color != TRAIL) {
            if(findWorker(1) < 0 || view[deRotate(findWorker(1),1)].food == 0) {
                return {cell:4};
            }
        }
        return {cell:pos};
    }
    return {cell:100+view[4].ant.type}; //oh god
}

//guides sit next to the queen
function doGuide() {
    var queenPos = findWorker(5);
    var ty = view[4].ant.type==3?2:1;
    var dir = view[4].ant.type==3?1:-1;
    if(queenPos >= 0 && queenPos%2 == 1 && view[queenPos].color == SPAWN) {
        if(view[deRotate(queenPos,dir*2)].ant == null) {
            return {cell:4};
        }
    }
    if(queenPos < 0 || findWorker(ty) < 0) {
        if(findWorker(ty) >= 0 && view[0].color != IDLE) return {cell:0,color:IDLE}
        return firebreak();
    }
    var checkpos = view[deRotate(queenPos,-2*dir)];
    if(view[4].ant.type==4 && checkpos.ant != null && checkpos.ant.friend && checkpos.ant.type == 1) {
        //attempt rotate
        return {cell:deRotate(queenPos,-dir)};
    }
    checkpos = view[deRotate(queenPos,4)];
    if(checkpos.ant != null && checkpos.ant.friend && checkpos.ant.type == ty) {
        //attempt rotate
        if(getNumWorkers(ty) == 1) {
            return {cell:4};
        }
    }
    var pos = deRotate(queenPos,dir);
    if(pos >= 0 && view[4].ant.type==3 && findWorker(4) < 0) {
        //wait for rotate
        if(view[4].color == TRAIL) {
            return {cell:4};
        }
    }
    if(pos >= 0 && findWorker(2) >= 0 && view[deRotate(findWorker(2),1)].ant != null) {
        //rotate
        return {cell:4,color:TRAIL};
    }
    if(pos < 0) pos = 4;
    else if(view[pos].ant != null) return {cell:deRotate(queenPos,4)};
    if(pos == 4 && view[queenPos].color == TRAIL) return {cell:queenPos,color:1};
    return {cell:pos};
}

//sweepers sit next to guides
function doSweep() {
    var queenPos = findWorker(5);
    var followType = view[4].ant.type==1?4:3;
    var pos = findWorker(followType);
    if(pos % 2 == 0 && getNumWorkers(followType) > 1) {
        //if there's more than one worker #4, we want to use the best one
        for(var i=pos+1;i<9;i++) {
            if(i != 4 && view[i].ant != null) {
                if(view[i].ant.friend && view[i].ant.type == followType) {
                    pos = i;
                    break;
                }
            }
        }
    }
    if(queenPos >= 0 && queenPos%2 == 1 && view[queenPos].color == SPAWN) {
        var p = findWorker(view[4].ant.type);
        if(p >= 0 && (deRotate(p,1) == queenPos || deRotate(p,-1) == queenPos)) {
            return {cell:8-queenPos};
        }
        return {cell:4};
    }
    if(queenPos >= 0 && pos < 0) {
        //if Worker #1 is the only ant besides the queen:
        //TODO
        if(view[queenPos].ant.food <= SPAWN_MIN || !(view[queenPos].ant.food < FOOD_THRESHOLD && view[queenPos].ant.food % 3 == 1)) {
            var go = deRotate(queenPos,-1);
            if((view[deRotate(queenPos,-2)].food > 0 || view[deRotate(queenPos,-3)].food > 0 || (queenPos %2 == 1 && view[deRotate(queenPos,-3)].food > 0)) && view[go].food == 0) {
                go = deRotate(queenPos,2);
                //return {cell:4};
            }
            return {cell:go};
        }
        else if(view[queenPos].ant.food < FOOD_THRESHOLD && view[queenPos].ant.food % 3 == 1) {
            return {cell:4};
        }
    }
    if(queenPos >= 0) {
        var dir = view[4].ant.type==1?1:-1;
        //var checkpos = view[deRotate(pos,-dir)];
        var moveTo = deRotate(pos,dir);
        if(moveTo >= 0 && view[moveTo].ant != null && view[moveTo].ant.friend && view[moveTo].ant.type == 5) {
            moveTo = deRotate(pos,-dir);
        }
        if(view[4].ant.type == 2 && findWorker(1) < 0 && view[queenPos].color != TRAIL) {
            moveTo = 4;
        }
        return {cell:moveTo};
    }
    else {
        if(pos < 0) return {cell:4}; //firebreak();
        var dir = view[4].ant.type==1?-1:1;
        var moveTo = deRotate(pos,dir);
        if(view[4].ant.food > 0 && view[moveTo].food > 0) {
            //have food, attempt to give to queen
            moveTo = deRotate(pos,-dir);
        }
        if(view[4].ant.type==1 && pos >= 0 && (view[deRotate(pos,dir*2)].food > 0 || view[deRotate(pos,dir*3)].food > 0)) {
            //attempt rotate
            moveTo = deRotate(pos,-dir);
        }
        if(view[4].ant.type==2 && pos >= 0 && (view[deRotate(pos,dir*2)].food > 0 || view[deRotate(pos,dir*3)].food > 0)) {
            //attempt rotate
            moveTo = deRotate(pos,-dir);
        }
        if(moveTo >= 0 && view[moveTo].ant != null && view[moveTo].ant.type == 5) {
            if(view[moveTo].ant.friend)
                moveTo = deRotate(moveTo,dir*2);
            else
                moveTo = deRotate(pos,-dir);
        }
        return {cell:moveTo};
    }
    return {cell:100+view[4].ant.type};//oh god
}

function foreverAlone() {
    var s0 = view[0].ant;
    var s1 = view[1].ant;
    var s2 = view[2].ant;
    var s3 = view[3].ant;
    var s5 = view[5].ant;
    var s6 = view[6].ant;
    var s7 = view[7].ant;
    var s8 = view[8].ant;
    if(!(s0 == null && s1 == null && s2 == null && s3 == null && s5 == null && s6 == null && s7 == null && s8 == null) && view[4].color == SPAWN) {
        if (view[0].color == TRAIL && !view[8].ant && view[8].color != TRAIL) return {cell: 8};
        else if (view[2].color == TRAIL && !view[6].ant && view[6].color != TRAIL) return {cell: 6};
        else if (view[6].color == TRAIL && !view[2].ant && view[2].color != TRAIL) return {cell: 2};
        else if (view[8].color == TRAIL && !view[0].ant && view[0].color != TRAIL) return {cell: 0};
        //Can't find color, or path is blocked? try diagonals regardless of color
        else if (!view[0].ant) return {cell: 0};
        else if (!view[2].ant) return {cell: 2};
        else if (!view[6].ant) return {cell: 6};
        else if (!view[8].ant) return {cell: 8};
        //Everything else failed? Stay put.
        else return {cell: 4};
    }
    if (view[4].color == TRAIL || view[4].color == SPAWN) { //If on colored square, try to move
        var totGreen = 0;
        for (var i = 0; i < 9; i++) { //Look for food
            if (view[i].food) {
                return {cell: i};
            }
            if(view[i].color == TRAIL) totGreen++;
        }
        var ret = getTrailMove();
        if(view[deRotate(ret.cell,1)].color == TRAIL && totGreen <= 4) ret.cell = deRotate(ret.cell,-1);
        else if(view[deRotate(ret.cell,-1)].color == TRAIL) ret.cell = deRotate(ret.cell,1);
        return ret;
    } else { //If not on colored square, look for food, or set current color to 2.
        for (var i = 0; i < 9; i++) { //Look for enemies
            if (i != 4 && view[i].ant != null && !view[i].ant.friend) {
                var r = findOpenSpace(8-i,1);
                if(view[r].color == TRAIL) r = deRotate(r,1);
                return {cell: r};
            }
        }
        return {cell: 4, color:TRAIL};
    }
}

function getTrailMove() {
    if (view[0].color == TRAIL && !view[8].ant && view[8].color != TRAIL) return {cell: 8};
    else if (view[2].color == TRAIL && !view[6].ant && view[6].color != TRAIL) return {cell: 6};
    else if (view[6].color == TRAIL && !view[2].ant && view[2].color != TRAIL) return {cell: 2};
    else if (view[8].color == TRAIL && !view[0].ant && view[0].color != TRAIL) return {cell: 0};
    //Can't find color, or path is blocked? try diagonals regardless of color
    else if (!view[0].ant) return {cell: 0};
    else if (!view[2].ant) return {cell: 2};
    else if (!view[6].ant) return {cell: 6};
    else if (!view[8].ant) return {cell: 8};
    //Everything else failed? Stay put.
    else return {cell: 4};
}

function firebreak() {
    var ret = -1;
    if(findWorker(5) >= 0) {
        return {cell:8-findWorker(5)};
    }
    if(view[4].color != 5) {
        var myView = [0,0,0,0,0,0,0,0,0]
        for(var i=0; i < 9; i++) {
            myView[i] = view[i].color
            if(view[4].ant.food > 0 && view[i].food > 0) {
                myView[i] = 8;
            }
            if(view[i].ant != null && !view[i].ant.friend) return {cell:findOpenSpace(deRotate(i,2),1)};
        }
        var ret = clearAhead(myView);
        if(ret == null)
            return {cell:4,color:5};
        else {
            if(!(view[ret.cell].ant != null && view[ret.cell].ant.friend == false) && (view[4].ant.food == 0 || view[ret.cell].food == 0))
                return ret;
            return {cell:4,color:5};
        }
    }
    if(view[1].color == 5 && view[3].color == 5 && view[5].color == 5 && view[7].color == 5) {
        if(view[0].color != 8) return {cell:0,color:8};
        if(view[1].color != 8) return {cell:1,color:8};
    }
    if(view[1].color == 5 && view[7].color != 5) ret = {cell:7};
    if(view[3].color == 5 && view[5].color != 5) ret = {cell:5};
    if(view[5].color == 5 && view[3].color != 5) ret = {cell:3};
    if(view[7].color == 5 && view[1].color != 5) ret = {cell:1};
    if(view[1].color != 5 && view[3].color != 5 && view[5].color != 5 && view[7].color != 5) ret = {cell:1};
    if((view[1].color == 5 && view[7].color == 5) || (view[3].color == 5 && view[5].color == 5)) ret = {cell:0};
    var loop = 0;
    while(ret.cell >= 0 && ((view[ret.cell].food > 0 && view[4].ant.food > 0) || view[ret.cell].ant != null) && loop < 9) {
        loop++;
        ret.cell = (ret.cell + 2) % 9;
    }
    if(loop < 9 && ret.cell >= 0) return ret;
    return {cell:4};
}

//7,6,4,2,3
//O7,D2

function highwayRobbery() {
    var move = basicHighwayMove();
    if(move.cell >= 0 && view[move.cell].ant != null) {
        var n = HIGHWAY_COLORS.indexOf(view[4].color) + (view[4].color%2==0?1:HIGHWAY_COLORS.length);
        var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
        for(var i=0;i<9;i++) {
            if(view[i].color == nextMove) {
                return {cell:i};
            }
        }
    }
    return move;
}

function basicHighwayMove() {
    var isQueen = view[4].ant.type == 5;
    if(isHighwayCenter()) {
        var n = HIGHWAY_COLORS.indexOf(view[4].color) + 1;
        var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
        for(var i=0;i<9;i++) {
            if(view[i].color == nextMove) {
                if(view[i].ant == null)
                    return {cell:i};
                else {
                    return {cell:deRotate(i,1)};
                }
            }
        }
    }
    else {
        if(view[4].color == 7) {
            //move diagonal to yellow (2)
            for(var i=0;i<9;i++) {
                if(i != 4 && i % 2 == 0 && view[i].color == 2) {
                    return {cell:i};
                }
            }
        }
        else {
            //move orthogonal to blue (7)
            for(var i=0;i<9;i++) {
                if(i % 2 == 1 && view[i].color == 7) {
                    //try ortho yellow first
                    for(var j=0;j<9;j++) {
                        if(j % 2 == 1 && view[j].color == 2 && areAdjacent(i,j))
                            return {cell:j};
                    }
                    return {cell:i};
                }
            }
            //if orthogonal blue doens't exist...
            //...try diagonal to magenta
            for(var i=0;i<9;i++) {
                if(i != 4 && i % 2 == 0 && view[i].color == 3) {
                    return {cell:i};
                }
            }
            if(view[4].color != 2) {
                //...try diagonal blue
                for(var i=0;i<9;i++) {
                    if(i % 2 == 0 && view[i].color == 7)
                        return {cell:i};
                }
            }
            //...and orthogonal yellow
            for(var i=0;i<9;i++) {
                if(i % 2 == 1 && view[i].color == 2)
                    return {cell:i};
            }
        }
        var n = HIGHWAY_COLORS.indexOf(view[4].color) + 1;
        var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
        for(var i=0;i<9;i++) {
            if(view[i].color == nextMove) {
                return {cell:i};
            }
        }
    }
    return {cell:-1};
}

function isOnHighway() {
    var match = 0;
    var nxt = HIGHWAY_COLORS[(HIGHWAY_COLORS.indexOf(view[4].color)+1) % HIGHWAY_COLORS.length];//4
    var prv = HIGHWAY_COLORS[(HIGHWAY_COLORS.indexOf(view[4].color)+HIGHWAY_COLORS.length-2) % HIGHWAY_COLORS.length];//6
    for(var i=0;i<9;i++) {
        if(HIGHWAY_COLORS.indexOf(view[i].color) >=0 && (i == 4 || view[i].color != view[4].color))
            match++;
    }
    if(match >= 5) {
        //7,6,4,2,3


        if((view[1].color == nxt && view[7].color == prv)||(view[1].color == prv && view[7].color == nxt) || 
            (view[3].color == nxt && view[5].color == prv)||(view[3].color == prv && view[5].color == nxt)) {
            return true;
        }
        if((view[1].color == view[8].color && (view[1].color == nxt || view[1].color == prv))||(view[1].color == view[6].color && (view[1].color == nxt || view[1].color == prv)) || 
            (view[3].color == view[2].color && (view[3].color == nxt || view[3].color == prv))||(view[3].color == view[8].color && (view[3].color == nxt || view[3].color == prv))) {
            return true;
        }
        if((view[0].color == view[7].color && (view[0].color == nxt || view[0].color == prv))||(view[2].color == view[7].color && (view[2].color == nxt || view[2].color == prv)) || 
            (view[0].color == view[5].color && (view[0].color == nxt || view[0].color == prv))||(view[6].color == view[5].color && (view[6].color == nxt || view[6].color == prv))) {
            return true;
        }
        if(isHighwayCenter()) {
            return true;
        }
    }
    return false;
}

function isHighwayCenter() {
    if(HIGHWAY_COLORS.indexOf(view[4].color) >=0 && (((view[0].color != view[8].color || view[2].color != view[6].color) && view[4].ant.type == 1) || (view[0].color != view[8].color && view[2].color != view[6].color))){
        var m1 = view[1].color == view[7].color;
        var m2 = view[2].color == view[8].color;
        var m3 = view[0].color == view[6].color;
        if((m1?1:0)+(m2?1:0)+(m3?1:0) >= 2) {
            if(view[3].color != view[5].color && ((view[2].color != view[5].color && view[8].color != view[5].color) || view[4].ant.type == 1) && ((view[3].color != view[0].color && view[3].color != view[6].color) || view[4].ant.type == 1)) {
                return true;
            }
        }
        m1 = view[3].color == view[5].color;
        m2 = view[0].color == view[2].color;
        m3 = view[6].color == view[8].color;
        if((m1?1:0)+(m2?1:0)+(m3?1:0) >= 2) {
            if(view[1].color != view[7].color && ((view[0].color != view[1].color && view[1].color != view[2].color) || view[4].ant.type == 1) && ((view[6].color != view[7].color && view[7].color != view[8].color) || view[4].ant.type == 1)) {
                return true;
            }
        }
    }
    return false;
}

function deRotateSide(m, amt) {
    return deRotate(m,amt*2);
}

/**Positive amount is clockwise**/
function deRotate(m, amt) {
    var rotationsCW = [1,2,5,8,7,6,3,0];
    var rotationsCCW = [3,6,7,8,5,2,1,0];
    if(m == 4 || m < 0 || m > 8 || amt == 0) return m;
    if(amt > 0)
        return rotationsCW[(rotationsCW.indexOf(m)+amt)%8];
    amt = -amt;
    return rotationsCCW[(rotationsCCW.indexOf(m)+amt)%8];
}

function areAdjacent(A, B) {
    if(A == 4 || B == 4 || A == B) return true;
    if(A % 2 == 0 && B % 2 == 0) return false;
    if(A % 2 == 1 && B % 2 == 0) return areAdjacent(B,A);
    if(A % 2 == 1 && B % 2 == 1) return !(8-A == B || 8-B == A);
    if(A == 0 && (B == 1 || B == 3)) return true;
    if(A == 2 && (B == 1 || B == 5)) return true;
    if(A == 6 && (B == 3 || B == 7)) return true;
    if(A == 8 && (B == 5 || B == 7)) return true;
    return false;
}

function findFirstTrail() {
    var pos = 0;
    var b = 0;
    while(view[pos].color != TRAIL && b < 8) {
        pos=deRotate(pos,1);
        b++;
    }
    return pos;
}

function clearAhead(sides) {
    var c=0;
    for(var i=0;i<9;i++) {
        if(view[i].color == 5) c++;
        if(view[i].color == 5 && i%2 == 0) c+=10;
    }
    if(c == 2) {
        if(view[0].color == 5 || view[2].color == 5 || view[6].color == 5 || view[8].color == 5) {
            return {cell:4,color:5};
        }
        if(view[0].ant == null)
            return {cell:0};
        if(view[2].ant == null)
            return {cell:2};
        if(view[6].ant == null)
            return {cell:6};
        if(view[8].ant == null)
            return {cell:8};
    }
    c = 0;
    sides[4] = 0;
    var toMatch =[{state:[1,1,1,
                          2,0,2,
                          0,1,0]},
                 {state:[0,2,1,
                         1,0,1,
                         0,2,1]},
                 {state:[0,1,0,
                         2,0,2,
                         1,1,1]},
                 {state:[1,2,0,
                         1,0,1,
                         1,2,0]}];
    for(var m=0;m<4;m++) {
        var score=0;
        for(var j=0;j<9;j++) {
            if(j!=4) {
                if(sides[j] == 5 && toMatch[m].state[j] == 1) {
                    score++;
                }
                if(sides[j] != 5 && (toMatch[m].state[j] == 0 || toMatch[m].state[j] == 2)) {
                    score++;
                }
                if(sides[j] == 5 && toMatch[m].state[j] == 2) {
                    score--;
                }
            }
        }
        if(score >= 6) {
            var clearOrder=[1,0,2];
            for(var r=0;r<clearOrder.length;r++) {
                var s = deRotateSide(clearOrder[r],m);
                if(view[s].color == 5) {
                    if(view[s].ant == null)
                        return {cell:s,color:8};
                    else
                        return {cell:4};
                }
            }
        }
    }
    return null;
}

function findOpenSpace(pos, dir) {
    if(pos > 8 || pos < 0) return pos;
    var b = 0;
    while(view[pos].ant != null && b < 8) {
        pos=deRotate(pos,dir);
        b++;
    }
    return pos;
}

function getHighestWorker() {
    var r=0;
    for(var i=0;i<9;i++) {
        if(i != 4 && view[i].ant != null) {
            if(view[i].ant.friend && view[i].ant.type > r) r = view[i].ant.type;
        }
    }
    return r;
}

function getNumWorkers(type) {
    var r=0;
    for(var i=0;i<9;i++) {
        if(i != 4 && view[i].ant != null) {
            if(view[i].ant.friend && view[i].ant.type == type) r++;
        }
    }
    return r;
}

function findWorker(type) {
    for(var i=0;i<9;i++) {
        if(i != 4 && view[i].ant != null) {
            if(view[i].ant.friend && view[i].ant.type == type) return i;
        }
    }
    return -1;
}
var TRAIL = 6;
var SPAWN = 3;
var IDLE = 4;
var FOOD_THRESHOLD = 150;
var SPAWN_MIN = 3;
var HIGHWAY_COLORS = [7,6,4,2,3];
var ret = {cell:4};
if(isOnHighway()) {
    var cont = true;
    //== Make best guess to if in a glider formation ==//
    if(view[4].ant.type == 5) {
        if((findWorker(1) >= 0 && findWorker(4) >= 0) || view[4].ant.food < 80) {
            cont = false;
        }
    }
    else if(view[4].ant.type == 4) {
        if(findWorker(1) >= 0 && findWorker(5) >= 0) {
            cont = false;
        }
    }
    else if(view[4].ant.type == 3) {
        if(findWorker(2) >= 0 && findWorker(5) >= 0) {
            cont = false;
        }
    }
    else if(view[4].ant.type == 2) {
        if(findWorker(5) < 0) {
            var pos3 = findWorker(3);
            if(pos3 >= 0 && view[pos3].ant.food == 0) {
                cont = false;
            }
        }
        else if(findWorker(3) >= 0 || (findWorker(1) >= 0 && view[findWorker(5)].color == SPAWN))
            cont = false;
    }
    else if(view[4].ant.type == 1) {
        if(findWorker(5) < 0) {
            var pos4 = findWorker(4);
            if(pos4 >= 0 && view[pos4].ant.food == 0) {
                cont = false;
            }
        }
        else if(!isHighwayCenter())
            cont = false;
    }
    if(findWorker(5) >= 0) {
        for(var i=0;i<9;i++) {
            if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                if(view[i].ant.food > 10 || view[i].ant.food == 0)
                    cont = true;
                else
                    cont = false;
            }
        }
    }
    //== End guesswork ==//
    if(cont) {
        ret = highwayRobbery();
        if(view[4].ant.type == 1) {
            //try to repair
            var curIndex = HIGHWAY_COLORS.indexOf(view[4].color);
            var prvCol = HIGHWAY_COLORS[(curIndex+1)%HIGHWAY_COLORS.length];
            var nxtCol1 = HIGHWAY_COLORS[(curIndex+HIGHWAY_COLORS.length-1)%HIGHWAY_COLORS.length];
            var nxtCol2 = HIGHWAY_COLORS[(curIndex+HIGHWAY_COLORS.length-2)%HIGHWAY_COLORS.length];
            var nxtCol3 = HIGHWAY_COLORS[(curIndex+HIGHWAY_COLORS.length-3)%HIGHWAY_COLORS.length];
            var prevAt = -1;
            for(var i=0;i<9;i++) {
                if(i%2 == 1 && view[i].color == prvCol && view[deRotate(i,1)].color == nxtCol1 && view[deRotate(i,-1)].color == nxtCol1) prevAt = i;
            }
            if(prevAt >= 0) {
                // yep, brute force it. Because I'm lazy.
                var goNxt = 8-prevAt;
                if(view[deRotate(goNxt,1)].color == nxtCol3 && view[deRotate(goNxt,-1)].color == prvCol) ret = {cell:goNxt};
                else if(view[deRotate(goNxt,1)].color == prvCol && view[deRotate(goNxt,-1)].color == nxtCol3) ret = {cell:goNxt};
                else if(view[goNxt].color != nxtCol1) ret = {cell:goNxt,color:nxtCol1};
                else if(view[deRotate(goNxt,2)].color != nxtCol2) ret = {cell:deRotate(goNxt,2),color:nxtCol2};
                else if(view[deRotate(goNxt,-2)].color != nxtCol2) ret = {cell:deRotate(goNxt,-2),color:nxtCol2};
                else if(view[deRotate(goNxt,1)].color != nxtCol3) ret = {cell:deRotate(goNxt,1),color:nxtCol3};
                else if(view[deRotate(goNxt,-1)].color != nxtCol3) ret = {cell:deRotate(goNxt,-1),color:nxtCol3};
                else ret = {cell:goNxt};
                ret = sanityCheck(ret);
                return ret;
            }
        }
        if(view[4].ant.type == 5 && isHighwayCenter()) {
            if(ret.cell >= 0) {
                ret = {cell:8-ret.cell};
                if(view[4].color == SPAWN && (view[4].ant.food > 90 || view[4].ant.food % 7 == 0) && getHighestWorker() == 0 && (view[4].ant.food < 140 || view[4].ant.food % 9 == 0) && view[0].color == 2 && view[4].ant.food > 50 && view[4].ant.food < 200) {
                    ret = {cell:deRotate(ret.cell,3),type:3};
                }
                if(view[ret.cell].ant != null && !view[ret.cell].ant.friend && view[ret.cell].ant.food == 0 && view[4].ant.food > 0) {
                    if(view[deRotate(ret.cell,1)].ant == null)
                        ret = {cell:deRotate(ret.cell,1),type:3};
                    if(view[deRotate(ret.cell,-1)].ant == null)
                        ret = {cell:deRotate(ret.cell,1),type:3};
                }
            }
            for(var i=0;i<9;i++) {
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                    ret = {cell:8-i};
                }
            }
        }
        if(ret.cell >= 0) {
            for(var i=0;i<9;i++) {
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                    var rr = basicHighwayMove();
                    if(rr.cell >= 0 && view[4].ant.type != 5)
                        ret = {cell:deRotate(rr.cell,-2)};
                }
            }
            if(view[ret.cell].ant != null) {
                var n = HIGHWAY_COLORS.indexOf(view[4].color) + 1;
                var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
                for(var i=0;i<9;i++) {
                    if(view[i].color == nextMove) {
                        if(view[i].ant == null) {
                            ret = {cell:i};
                            break;
                        }
                    }
                }
                if(view[4].ant.type == 5) ret = {cell:8-ret.cell};
            }
        }
        if(view[4].ant.type == 5) {
            var foodedEnemy = false;
            for(var i=0;i<9;i++) {
                if(getNumWorkers(3) >= 2) break;
                if(i != 4 && view[i].ant != null && view[i].ant.type == 5 && view[i].ant.food > 25) {
                    if(view[deRotate(i,1)].ant == null) {
                        ret = {cell:deRotate(i,1),type:3};
                    }
                    else if(view[deRotate(i,-1)].ant == null) {
                        ret = {cell:deRotate(i,-1),type:3};
                    }
                    else if(i%2 == 1 && view[deRotate(i,2)].ant == null) {
                        ret = {cell:deRotate(i,2),type:3};
                    }
                    else if(i%2 == 1 && view[deRotate(i,-2)].ant == null) {
                        ret = {cell:deRotate(i,-2),type:3};
                    }
                }
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 3 && view[8-i].ant == null) {
                    if(i == ret.cell) {
                        ret = {cell:deRotate(i,1)}
                    }
                    else {
                        return {cell:8-i};
                    }
                }
                if(view[i].ant != null && !view[i].ant.friend && view[i].ant.food == 0) {
                    foodedEnemy = true;
                }
            }
        }
        var numAnts = 0;
        for(var i=0;i<9;i++) {
            if(view[i].ant != null)
                numAnts++;
        }
        if(numAnts > 2 && sanityCheck(ret).cell == 4) {
            ret = {cell:findOpenSpace(0,1)};
        }
        if(view[4].ant.type == 3) {
            if(getNumWorkers(5) > 0) {
                for(var i=0;i<9;i++) {
                    if(view[i].ant != null && !view[i].ant.friend && view[i].ant.type == 5) {
                        ret = {cell:4};
                    }
                }
            }
        }
        if(view[4].ant.type == 4 && getNumWorkers(1) && isHighwayCenter()) {
            var workerPos = findWorker(1);
            for(var i=0;i<9;i++) {
                if(!areAdjacent(i,workerPos)) ret = {cell:i};
            }
        }
        if(ret.cell == -1) {
            if(isHighwayCenter()) {
                for(var i=0;i<9;i++) {
                    var p1 = deRotate(i,3);
                    var p2 = deRotate(i,-3);
                    if(view[i].color == view[p1].color && view[i].color == view[p2].color) {
                        ret = {cell:8-i};
                    }
                }
                if(view[4].ant.type == 1 || view[4].ant.type == 5) {
                    ret = {cell:8-ret.cell};
                }
            }
        }
        if(ret.cell >= 0)
            return sanityCheck(ret);
    }
}

switch(view[4].ant.type) {
    case 5:
        ret = doQueen();
        break;
    case 1:
    case 2:
        ret = doSweep();
        break;
    case 3:
    case 4:
        ret = doGuide();
        break;
    default:
        break;
}
//basic sanity check
ret = sanityCheck(ret);
return ret;

function sanityCheck(ret) {
    if(!ret || ret.cell < 0 || ret.cell > 8) {
        return {cell:4};
    }
    if(ret.color) {
        return ret;
    }
    if((ret.cell != 4 && view[ret.cell].ant != null) || (view[ret.cell].food > 0 && (view[4].ant.food > 0 && view[4].ant.type < 5))) {
        return {cell:4};
    }
    if(ret.type && (view[ret.cell].ant != null || view[ret.cell].food > 0 || view[4].ant.food == 0 || view[4].ant.type < 5)) {
        return {cell:4};
    }
    return ret;
}

function doQueen() {
    if((view[4].ant.food == SPAWN_MIN || (view[4].ant.food >= SPAWN_MIN && view[4].ant.food < FOOD_THRESHOLD && (view[4].ant.food % 3 == 1 || isOnHighway()))) && getHighestWorker() <= 1 ) {
        //prep for first ant
        var s0 = view[0].ant;
        var s1 = view[1].ant;
        var s2 = view[2].ant;
        var s3 = view[3].ant;
        var s5 = view[5].ant;
        var s6 = view[6].ant;
        var s7 = view[7].ant;
        var s8 = view[8].ant;
        var nullCount = 0 + (s0 == null?1:0) + (s1 == null?1:0) + (s2 == null?1:0) + (s3 == null?1:0) + (s5 == null?1:0) + (s6 == null?1:0) + (s7 == null?1:0) + (s8 == null?1:0);
        var nullCount2 = 0 + (s0 == null || s0.friend?1:0) + (s1 == null || s1.friend?1:0) + (s2 == null || s2.friend?1:0) + (s3 == null || s3.friend?1:0) + (s5 == null || s5.friend?1:0) + (s6 == null || s6.friend?1:0) + (s7 == null || s7.friend?1:0) + (s8 == null || s8.friend?1:0);
        if(nullCount >= 7 && nullCount2 >= 8 && view[1].food == 0 && view[3].food == 0 && view[5].food == 0 && view[7].food == 0) {
            var high = getHighestWorker();
            if (high <= 1 && view[4].color != SPAWN && !isOnHighway()) {
                // 50% chance of delaying the respawn by 1 additional move away from where we exploded
                // reduces the chance of a second, immediate explosion
                if(findFirstTrail() < 2 && view[4].ant.food > SPAWN_MIN+1) return foreverAlone();
                var pos1 = findWorker(1);
                if(pos1 >= 0) {
                    var space = deRotate(pos1,2);
                    if(view[space].ant != null) return {cell:findOpenSpace(0,1)};
                }
                return {cell:4,color:SPAWN};
            }
            //spawn first ant
            else if(view[4].color == SPAWN) {
                var pos1 = findWorker(1);
                if(pos1 < 0)  {
                    pos1 = findFirstTrail();
                    if(pos1 % 2 == 0) pos1 = deRotate(pos1,1);
                    else pos1 = deRotate(pos1,4);
                }
                var space = findOpenSpace(pos1,2);
                var high = getHighestWorker();
                if(space < 0) return {cell:4,color:TRAIL}
                if(high == 0) { //no workers
                    return {cell:space,type:1};
                }
                else if(high < 4) { //1 worker of type:high
                    return {cell:space,type:high+1};
                }
                else { //1 worker of type 4
                    //we have all workers, skip!
                }
            }
        }
        else {
            return foreverAlone();
        }
    }
    else if(view[4].ant.food == 1 && getHighestWorker() == 0 ) {
        var space = findOpenSpace(1,2);
        return {cell:space,type:1};
    }
    else if(view[4].ant.food >= 1 && getHighestWorker() < 4 && findWorker(1) >= 0) {
        //spawn remaining ants
        if(view[4].color == SPAWN && !isHighwayCenter()) {
            var pos1 = findWorker(getHighestWorker());
            var space = deRotate(pos1,2);
            var high = getHighestWorker();
            if(space < 0 || view[space].ant != null) return {cell:findOpenSpace(0,1)};
            if(high == 0) { //no workers
                return {cell:space,type:1};
            }
            else if(high < 4) { //1 worker of type:high
                return {cell:space,type:high+1};
            }
            else { //1 worker of type 4
                //we have all workers, skip!
            }
        }
    }
    if(view[4].color == SPAWN && getNumWorkers(3) == 1 && getNumWorkers(4) == 1) {
        var one = getNumWorkers(1);
        var two = getNumWorkers(2);
        if((one ^ two) == 1 && (findWorker(1) % 2 == 0 || findWorker(2) % 2 == 0))
            return {cell:4,color:1};
    }
    if(getNumWorkers(1) == 0 && getNumWorkers(2) == 0) {
        if(getNumWorkers(4) == 1 && getNumWorkers(3) == 0) {
            var pos4 = findWorker(4);
            if(view[deRotate(pos4,1)].ant == null && view[deRotate(pos4,2)].ant == null && findWorker(4) % 2 == 1) {
                //finish rotate with only one glider arm
                return {cell:4};
            }
        }
        return foreverAlone();
    }
    else if(getNumWorkers(1) >= 1 && getNumWorkers(2) >= 1 && getNumWorkers(3) >= 1 && getNumWorkers(4) >= 1) {
        if(view[4].color != 2 && findWorker(1)%2 == 1 && findWorker(2)%2 == 1) {
            return {cell:4,color:TRAIL};
        }
        //move diagonally
        var pos = findWorker(4);
        pos = deRotate(pos,1);
        var checkpos = view[deRotate(pos,4)];
        if(checkpos.ant != null && checkpos.ant.friend) {
            if(checkpos.ant.type == 2)
                return {cell:4};
            if(checkpos.ant.type == 1)
                return {cell:4};
        }
        return {cell:pos};
    }
    else {
        var pos = findWorker(4);
        if(pos < 0) {
            //if gliding along with only a buddy
            pos = findWorker(1);
            if(pos >= 0 && view[deRotate(pos,2)].food > 0 && view[deRotate(pos,1)].food == 0) {
                return {cell:4};
            }
        }
        if(pos < 0) {
            var s1 = view[1].ant;
            var s3 = view[3].ant;
            var s5 = view[5].ant;
            var s7 = view[7].ant;
            //return {cell:999}
            if(s1 == null) {
                if(s3 == null) {
                    return {cell:0};
                }
                if(s5 == null) {
                    return {cell:2};
                }
            }
            if(s7 == null) {
                if(s3 == null) {
                    return {cell:6};
                }
                if(s5 == null) {
                    return {cell:8};
                }
            }
            return {cell:4};
        }
        pos = deRotate(pos,1);
        var checkpos1 = view[pos];
        for(var i=0;i<9;i++) {
            if(i != 4 && view[i].ant != null && view[i].ant.type == 5 && view[i].ant.food > 2) {
                if(i%2==0) {
                    if(view[deRotate(i,1)].ant == null) return {cell:deRotate(i,1),type:3};
                    if(view[deRotate(i,-1)].ant == null) return {cell:deRotate(i,-1),type:3};
                }
                else {
                    if(view[deRotate(i,1)].ant == null) return {cell:deRotate(i,1),type:3};
                    if(view[deRotate(i,-1)].ant == null) return {cell:deRotate(i,-1),type:3};
                    if(view[deRotate(i,2)].ant == null) return {cell:deRotate(i,2),type:3};
                    if(view[deRotate(i,-2)].ant == null) return {cell:deRotate(i,-2),type:3};
                }
                return {cell:4};
            }
        }
        if(checkpos1.ant != null && view[deRotate(pos,1)].ant != null && !view[deRotate(pos,1)].ant.friend) {
            return foreverAlone();
        }

        var checkpos2 = view[deRotate(pos,4)];
        var checkpos3 = view[deRotate(checkpos,1)];
        if(checkpos1.ant != null && checkpos1.ant.friend && checkpos1.ant.type == 1 && checkpos2.ant != null && checkpos2.ant.friend && checkpos2.ant.type == 2 && checkpos3.ant != null && checkpos3.ant.friend && checkpos3.ant.type == 3) {
            //move out of spawn orientation
            return {cell:4};
        }
        if(view[pos].ant != null) {
            if(checkpos2.ant == null && checkpos1.ant == null) {
                return {cell:8-pos};
            }
            if(!view[pos].ant.friend) {
                return foreverAlone();
            }
            if(view[4].color == TRAIL) return foreverAlone();
            return {cell:4,color:TRAIL};
        }
        if(8 - findWorker(3) == findWorker(4)) {
            //finish rotate to the right
            return {cell:4};
        }
        if((view[deRotate(pos,1)].food > 0 || view[deRotate(pos,2)].food > 0) && view[deRotate(pos,1)].ant == null && view[4].color != TRAIL) {
            if(findWorker(1) < 0 || view[deRotate(findWorker(1),1)].food == 0) {
                return {cell:4};
            }
        }
        return {cell:pos};
    }
    return {cell:100+view[4].ant.type}; //oh god
}

//guides sit next to the queen
function doGuide() {
    var queenPos = findWorker(5);
    var ty = view[4].ant.type==3?2:1;
    var dir = view[4].ant.type==3?1:-1;
    if(queenPos >= 0 && queenPos%2 == 1 && view[queenPos].color == SPAWN) {
        if(view[deRotate(queenPos,dir*2)].ant == null) {
            return {cell:4};
        }
    }
    if(queenPos < 0 || findWorker(ty) < 0) {
        if(findWorker(ty) >= 0 && view[0].color != IDLE) return {cell:0,color:IDLE}
        return firebreak();
    }
    var checkpos = view[deRotate(queenPos,-2*dir)];
    if(view[4].ant.type==4 && checkpos.ant != null && checkpos.ant.friend && checkpos.ant.type == 1) {
        //attempt rotate
        return {cell:deRotate(queenPos,-dir)};
    }
    checkpos = view[deRotate(queenPos,4)];
    if(checkpos.ant != null && checkpos.ant.friend && checkpos.ant.type == ty) {
        //attempt rotate
        if(getNumWorkers(ty) == 1) {
            return {cell:4};
        }
    }
    var pos = deRotate(queenPos,dir);
    if(pos >= 0 && view[4].ant.type==3 && findWorker(4) < 0) {
        //wait for rotate
        if(view[4].color == TRAIL) {
            return {cell:4};
        }
    }
    if(pos >= 0 && findWorker(2) >= 0 && view[deRotate(findWorker(2),1)].ant != null) {
        //rotate
        return {cell:4,color:TRAIL};
    }
    if(pos < 0) pos = 4;
    else if(view[pos].ant != null) return {cell:deRotate(queenPos,4)};
    if(pos == 4 && view[queenPos].color == TRAIL) return {cell:queenPos,color:1};
    return {cell:pos};
}

//sweepers sit next to guides
function doSweep() {
    var queenPos = findWorker(5);
    var followType = view[4].ant.type==1?4:3;
    var pos = findWorker(followType);
    if(pos % 2 == 0 && getNumWorkers(followType) > 1) {
        //if there's more than one worker #4, we want to use the best one
        for(var i=pos+1;i<9;i++) {
            if(i != 4 && view[i].ant != null) {
                if(view[i].ant.friend && view[i].ant.type == followType) {
                    pos = i;
                    break;
                }
            }
        }
    }
    if(queenPos >= 0 && queenPos%2 == 1 && view[queenPos].color == SPAWN) {
        var p = findWorker(view[4].ant.type);
        if(p >= 0 && (deRotate(p,1) == queenPos || deRotate(p,-1) == queenPos)) {
            return {cell:8-queenPos};
        }
        return {cell:4};
    }
    if(queenPos >= 0 && pos < 0) {
        //if Worker #1 is the only ant besides the queen:
        //TODO
        if(view[queenPos].ant.food <= SPAWN_MIN || !(view[queenPos].ant.food < FOOD_THRESHOLD && view[queenPos].ant.food % 3 == 1)) {
            var go = deRotate(queenPos,-1);
            if((view[deRotate(queenPos,-2)].food > 0 || view[deRotate(queenPos,-3)].food > 0 || (queenPos %2 == 1 && view[deRotate(queenPos,-3)].food > 0)) && view[go].food == 0) {
                go = deRotate(queenPos,2);
                //return {cell:4};
            }
            return {cell:go};
        }
        else if(view[queenPos].ant.food < FOOD_THRESHOLD && view[queenPos].ant.food % 3 == 1) {
            return {cell:4};
        }
    }
    if(queenPos >= 0) {
        var dir = view[4].ant.type==1?1:-1;
        //var checkpos = view[deRotate(pos,-dir)];
        var moveTo = deRotate(pos,dir);
        if(moveTo >= 0 && view[moveTo].ant != null && view[moveTo].ant.friend && view[moveTo].ant.type == 5) {
            moveTo = deRotate(pos,-dir);
        }
        if(view[4].ant.type == 2 && findWorker(1) < 0 && view[queenPos].color != TRAIL) {
            moveTo = 4;
        }
        return {cell:moveTo};
    }
    else {
        if(pos < 0) return {cell:4}; //firebreak();
        var dir = view[4].ant.type==1?-1:1;
        var moveTo = deRotate(pos,dir);
        if(view[4].ant.food > 0 && view[moveTo].food > 0) {
            //have food, attempt to give to queen
            moveTo = deRotate(pos,-dir);
        }
        if(view[4].ant.type==1 && pos >= 0 && (view[deRotate(pos,dir*2)].food > 0 || view[deRotate(pos,dir*3)].food > 0)) {
            //attempt rotate
            moveTo = deRotate(pos,-dir);
        }
        if(view[4].ant.type==2 && pos >= 0 && (view[deRotate(pos,dir*2)].food > 0 || view[deRotate(pos,dir*3)].food > 0)) {
            //attempt rotate
            moveTo = deRotate(pos,-dir);
        }
        if(moveTo >= 0 && view[moveTo].ant != null && view[moveTo].ant.type == 5) {
            if(view[moveTo].ant.friend)
                moveTo = deRotate(moveTo,dir*2);
            else
                moveTo = deRotate(pos,-dir);
        }
        return {cell:moveTo};
    }
    return {cell:100+view[4].ant.type};//oh god
}

function foreverAlone() {
    var s0 = view[0].ant;
    var s1 = view[1].ant;
    var s2 = view[2].ant;
    var s3 = view[3].ant;
    var s5 = view[5].ant;
    var s6 = view[6].ant;
    var s7 = view[7].ant;
    var s8 = view[8].ant;
    if(!(s0 == null && s1 == null && s2 == null && s3 == null && s5 == null && s6 == null && s7 == null && s8 == null) && view[4].color == SPAWN) {
        if (view[0].color == TRAIL && !view[8].ant && view[8].color != TRAIL) return {cell: 8};
        else if (view[2].color == TRAIL && !view[6].ant && view[6].color != TRAIL) return {cell: 6};
        else if (view[6].color == TRAIL && !view[2].ant && view[2].color != TRAIL) return {cell: 2};
        else if (view[8].color == TRAIL && !view[0].ant && view[0].color != TRAIL) return {cell: 0};
        //Can't find color, or path is blocked? try diagonals regardless of color
        else if (!view[0].ant) return {cell: 0};
        else if (!view[2].ant) return {cell: 2};
        else if (!view[6].ant) return {cell: 6};
        else if (!view[8].ant) return {cell: 8};
        //Everything else failed? Stay put.
        else return {cell: 4};
    }
    if (view[4].color == TRAIL || view[4].color == SPAWN) { //If on colored square, try to move
        var totGreen = 0;
        for (var i = 0; i < 9; i++) { //Look for food
            if (view[i].food) {
                return {cell: i};
            }
            if(view[i].color == TRAIL) totGreen++;
        }
        var ret = getTrailMove();
        if(view[deRotate(ret.cell,1)].color == TRAIL && totGreen <= 4) ret.cell = deRotate(ret.cell,-1);
        else if(view[deRotate(ret.cell,-1)].color == TRAIL && totGreen <= 4) ret.cell = deRotate(ret.cell,1);
        return ret;
    } else { //If not on colored square, look for food, or set current color to 2.
        for (var i = 0; i < 9; i++) { //Look for enemies
            if (i != 4 && view[i].ant != null && !view[i].ant.friend) {
                var r = findOpenSpace(8-i,1);
                if(view[r].color == TRAIL) r = deRotate(r,1);
                return {cell: r};
            }
        }
        return {cell: 4, color:TRAIL};
    }
}

function getTrailMove() {
    if (view[0].color == TRAIL && !view[8].ant && view[8].color != TRAIL) return {cell: 8};
    else if (view[2].color == TRAIL && !view[6].ant && view[6].color != TRAIL) return {cell: 6};
    else if (view[6].color == TRAIL && !view[2].ant && view[2].color != TRAIL) return {cell: 2};
    else if (view[8].color == TRAIL && !view[0].ant && view[0].color != TRAIL) return {cell: 0};
    //Can't find color, or path is blocked? try diagonals regardless of color
    else if (!view[0].ant) return {cell: 0};
    else if (!view[2].ant) return {cell: 2};
    else if (!view[6].ant) return {cell: 6};
    else if (!view[8].ant) return {cell: 8};
    //Everything else failed? Stay put.
    else return {cell: 4};
}

function firebreak() {
    var ret = -1;
    if(findWorker(5) >= 0) {
        return {cell:8-findWorker(5)};
    }
    if(view[4].color != 5) {
        var myView = [0,0,0,0,0,0,0,0,0]
        for(var i=0; i < 9; i++) {
            myView[i] = view[i].color
            if(view[4].ant.food > 0 && view[i].food > 0) {
                myView[i] = 8;
            }
            if(view[i].ant != null && !view[i].ant.friend) return {cell:findOpenSpace(deRotate(i,2),1)};
        }
        var ret = clearAhead(myView);
        if(ret == null)
            return {cell:4,color:5};
        else {
            if(!(view[ret.cell].ant != null && view[ret.cell].ant.friend == false) && (view[4].ant.food == 0 || view[ret.cell].food == 0))
                return ret;
            return {cell:4,color:5};
        }
    }
    if(view[1].color == 5 && view[3].color == 5 && view[5].color == 5 && view[7].color == 5) {
        if(view[0].color != 8) return {cell:0,color:8};
        if(view[1].color != 8) return {cell:1,color:8};
    }
    if(view[1].color == 5 && view[7].color != 5) ret = {cell:7};
    if(view[3].color == 5 && view[5].color != 5) ret = {cell:5};
    if(view[5].color == 5 && view[3].color != 5) ret = {cell:3};
    if(view[7].color == 5 && view[1].color != 5) ret = {cell:1};
    if(view[1].color != 5 && view[3].color != 5 && view[5].color != 5 && view[7].color != 5) ret = {cell:1};
    if((view[1].color == 5 && view[7].color == 5) || (view[3].color == 5 && view[5].color == 5)) ret = {cell:0};
    var loop = 0;
    while(ret.cell >= 0 && ((view[ret.cell].food > 0 && view[4].ant.food > 0) || view[ret.cell].ant != null) && loop < 9) {
        loop++;
        ret.cell = (ret.cell + 2) % 9;
    }
    if(loop < 9 && ret.cell >= 0) return ret;
    return {cell:4};
}

//7,6,4,2,3
//O7,D2

function highwayRobbery() {
    var move = basicHighwayMove();
    if(move.cell >= 0 && view[move.cell].ant != null) {
        var n = HIGHWAY_COLORS.indexOf(view[4].color) + (view[4].color%2==0?1:HIGHWAY_COLORS.length);
        var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
        for(var i=0;i<9;i++) {
            if(view[i].color == nextMove) {
                return {cell:i};
            }
        }
    }
    return move;
}

function basicHighwayMove() {
    var isQueen = view[4].ant.type == 5;
    if(isHighwayCenter()) {
        var n = HIGHWAY_COLORS.indexOf(view[4].color) + 1;
        var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
        for(var i=0;i<9;i++) {
            if(view[i].color == nextMove) {
                if(view[i].ant == null)
                    return {cell:i};
                else {
                    return {cell:deRotate(i,1)};
                }
            }
        }
    }
    else {
        if(view[4].color == 7) {
            //move diagonal to yellow (2)
            for(var i=0;i<9;i++) {
                if(i != 4 && i % 2 == 0 && view[i].color == 2) {
                    return {cell:i};
                }
            }
        }
        else {
            //move orthogonal to blue (7)
            for(var i=0;i<9;i++) {
                if(i % 2 == 1 && view[i].color == 7) {
                    //try ortho yellow first
                    for(var j=0;j<9;j++) {
                        if(j % 2 == 1 && view[j].color == 2 && areAdjacent(i,j))
                            return {cell:j};
                    }
                    return {cell:i};
                }
            }
            //if orthogonal blue doens't exist...
            //...try diagonal to magenta
            for(var i=0;i<9;i++) {
                if(i != 4 && i % 2 == 0 && view[i].color == 3) {
                    return {cell:i};
                }
            }
            if(view[4].color != 2) {
                //...try diagonal blue
                for(var i=0;i<9;i++) {
                    if(i % 2 == 0 && view[i].color == 7)
                        return {cell:i};
                }
            }
            //...and orthogonal yellow
            for(var i=0;i<9;i++) {
                if(i % 2 == 1 && view[i].color == 2)
                    return {cell:i};
            }
        }
        var n = HIGHWAY_COLORS.indexOf(view[4].color) + 1;
        var nextMove = HIGHWAY_COLORS[n % HIGHWAY_COLORS.length];
        for(var i=0;i<9;i++) {
            if(view[i].color == nextMove) {
                return {cell:i};
            }
        }
    }
    return {cell:-1};
}

function isOnHighway() {
    var match = 0;
    var nxt = HIGHWAY_COLORS[(HIGHWAY_COLORS.indexOf(view[4].color)+1) % HIGHWAY_COLORS.length];//4
    var prv = HIGHWAY_COLORS[(HIGHWAY_COLORS.indexOf(view[4].color)+HIGHWAY_COLORS.length-2) % HIGHWAY_COLORS.length];//6
    for(var i=0;i<9;i++) {
        if(HIGHWAY_COLORS.indexOf(view[i].color) >=0 && (i == 4 || view[i].color != view[4].color))
            match++;
    }
    if(match >= 5) {
        //7,6,4,2,3


        if((view[1].color == nxt && view[7].color == prv)||(view[1].color == prv && view[7].color == nxt) || 
            (view[3].color == nxt && view[5].color == prv)||(view[3].color == prv && view[5].color == nxt)) {
            return true;
        }
        if((view[1].color == view[8].color && (view[1].color == nxt || view[1].color == prv))||(view[1].color == view[6].color && (view[1].color == nxt || view[1].color == prv)) || 
            (view[3].color == view[2].color && (view[3].color == nxt || view[3].color == prv))||(view[3].color == view[8].color && (view[3].color == nxt || view[3].color == prv))) {
            return true;
        }
        if((view[0].color == view[7].color && (view[0].color == nxt || view[0].color == prv))||(view[2].color == view[7].color && (view[2].color == nxt || view[2].color == prv)) || 
            (view[0].color == view[5].color && (view[0].color == nxt || view[0].color == prv))||(view[6].color == view[5].color && (view[6].color == nxt || view[6].color == prv))) {
            return true;
        }
        if(isHighwayCenter()) {
            return true;
        }
    }
    return false;
}

function isHighwayCenter() {
    if(HIGHWAY_COLORS.indexOf(view[4].color) >=0 && (((view[0].color != view[8].color || view[2].color != view[6].color) && view[4].ant.type == 1) || (view[0].color != view[8].color && view[2].color != view[6].color))){
        var m1 = view[1].color == view[7].color;
        var m2 = view[2].color == view[8].color;
        var m3 = view[0].color == view[6].color;
        if((m1?1:0)+(m2?1:0)+(m3?1:0) >= 2) {
            if(view[3].color != view[5].color && ((view[2].color != view[5].color && view[8].color != view[5].color) || view[4].ant.type == 1) && ((view[3].color != view[0].color && view[3].color != view[6].color) || view[4].ant.type == 1)) {
                return true;
            }
        }
        m1 = view[3].color == view[5].color;
        m2 = view[0].color == view[2].color;
        m3 = view[6].color == view[8].color;
        if((m1?1:0)+(m2?1:0)+(m3?1:0) >= 2) {
            if(view[1].color != view[7].color && ((view[0].color != view[1].color && view[1].color != view[2].color) || view[4].ant.type == 1) && ((view[6].color != view[7].color && view[7].color != view[8].color) || view[4].ant.type == 1)) {
                return true;
            }
        }
    }
    return false;
}

function deRotateSide(m, amt) {
    return deRotate(m,amt*2);
}

/**Positive amount is clockwise**/
function deRotate(m, amt) {
    var rotationsCW = [1,2,5,8,7,6,3,0];
    var rotationsCCW = [3,6,7,8,5,2,1,0];
    if(m == 4 || m < 0 || m > 8 || amt == 0) return m;
    if(amt > 0)
        return rotationsCW[(rotationsCW.indexOf(m)+amt)%8];
    amt = -amt;
    return rotationsCCW[(rotationsCCW.indexOf(m)+amt)%8];
}

function areAdjacent(A, B) {
    if(A == 4 || B == 4 || A == B) return true;
    if(A % 2 == 0 && B % 2 == 0) return false;
    if(A % 2 == 1 && B % 2 == 0) return areAdjacent(B,A);
    if(A % 2 == 1 && B % 2 == 1) return !(8-A == B || 8-B == A);
    if(A == 0 && (B == 1 || B == 3)) return true;
    if(A == 2 && (B == 1 || B == 5)) return true;
    if(A == 6 && (B == 3 || B == 7)) return true;
    if(A == 8 && (B == 5 || B == 7)) return true;
    return false;
}

function findFirstTrail() {
    var pos = 0;
    var b = 0;
    while(view[pos].color != TRAIL && b < 8) {
        pos=deRotate(pos,1);
        b++;
    }
    return pos;
}

function clearAhead(sides) {
    var c=0;
    for(var i=0;i<9;i++) {
        if(view[i].color == 5) c++;
        if(view[i].color == 5 && i%2 == 0) c+=10;
    }
    if(c == 2) {
        if(view[0].color == 5 || view[2].color == 5 || view[6].color == 5 || view[8].color == 5) {
            return {cell:4,color:5};
        }
        if(view[0].ant == null)
            return {cell:0};
        if(view[2].ant == null)
            return {cell:2};
        if(view[6].ant == null)
            return {cell:6};
        if(view[8].ant == null)
            return {cell:8};
    }
    c = 0;
    sides[4] = 0;
    var toMatch =[{state:[1,1,1,
                          2,0,2,
                          0,1,0]},
                 {state:[0,2,1,
                         1,0,1,
                         0,2,1]},
                 {state:[0,1,0,
                         2,0,2,
                         1,1,1]},
                 {state:[1,2,0,
                         1,0,1,
                         1,2,0]}];
    for(var m=0;m<4;m++) {
        var score=0;
        for(var j=0;j<9;j++) {
            if(j!=4) {
                if(sides[j] == 5 && toMatch[m].state[j] == 1) {
                    score++;
                }
                if(sides[j] != 5 && (toMatch[m].state[j] == 0 || toMatch[m].state[j] == 2)) {
                    score++;
                }
                if(sides[j] == 5 && toMatch[m].state[j] == 2) {
                    score--;
                }
            }
        }
        if(score >= 6) {
            var clearOrder=[1,0,2];
            for(var r=0;r<clearOrder.length;r++) {
                var s = deRotateSide(clearOrder[r],m);
                if(view[s].color == 5) {
                    if(view[s].ant == null)
                        return {cell:s,color:8};
                    else
                        return {cell:4};
                }
            }
        }
    }
    return null;
}

function findOpenSpace(pos, dir) {
    if(pos > 8 || pos < 0) return pos;
    var b = 0;
    while(view[pos].ant != null && b < 8) {
        pos=deRotate(pos,dir);
        b++;
    }
    return pos;
}

function getHighestWorker() {
    var r=0;
    for(var i=0;i<9;i++) {
        if(i != 4 && view[i].ant != null) {
            if(view[i].ant.friend && view[i].ant.type > r) r = view[i].ant.type;
        }
    }
    return r;
}

function getNumWorkers(type) {
    var r=0;
    for(var i=0;i<9;i++) {
        if(i != 4 && view[i].ant != null) {
            if(view[i].ant.friend && view[i].ant.type == type) r++;
        }
    }
    return r;
}

function findWorker(type) {
    for(var i=0;i<9;i++) {
        if(i != 4 && view[i].ant != null) {
            if(view[i].ant.friend && view[i].ant.type == type) return i;
        }
    }
    return -1;
}
36 added 2159 characters in body
source | link
35 Two minor bug fixes
source | link
34 HIGHWAY ROBBERY update
source | link
33 added 1163 characters in body
source | link
32 Fixed an initial spawning problem.
source | link
31 Missing newline
source | link
30 added 3799 characters in body
source | link
29 added 4497 characters in body
source | link
28 Tweak so it runs in Dave's controller.
source | link
27 new turning gif
source | link
26 Update 1/21
source | link
25 Fixed spawn orientation bug
source | link
24 added 5549 characters in body
source | link
23 added 866 characters in body
source | link
22 added 1064 characters in body
source | link
21 added 172 characters in body
source | link
20 Remove console.log
source | link
19 Turning animation
source | link
18 added 2706 characters in body
source | link
17 added 63 characters in body
source | link
16 added 11 characters in body
source | link
15 more robustness
source | link