Skip to content

Commit

Permalink
Implement new instructions.js grammar thingy
Browse files Browse the repository at this point in the history
Still need to clean up the code
  • Loading branch information
felixge committed Jun 13, 2011
1 parent 9d71760 commit 83b2357
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 49 deletions.
1 change: 1 addition & 0 deletions index.html
Expand Up @@ -9,6 +9,7 @@
<script type="text/javascript" src="js/dep/es5-shim.js"></script> <script type="text/javascript" src="js/dep/es5-shim.js"></script>
<script type="text/javascript" src="js/lib/grid.js"></script> <script type="text/javascript" src="js/lib/grid.js"></script>
<script type="text/javascript" src="js/lib/game.js"></script> <script type="text/javascript" src="js/lib/game.js"></script>
<script type="text/javascript" src="js/lib/instructions.js"></script>
<script type="text/javascript" src="js/lib/visualizer.js"></script> <script type="text/javascript" src="js/lib/visualizer.js"></script>
<script type="text/javascript" src="js/lib/program.js"></script> <script type="text/javascript" src="js/lib/program.js"></script>
<script type="text/javascript" src="js/lib/robot.js"></script> <script type="text/javascript" src="js/lib/robot.js"></script>
Expand Down
11 changes: 9 additions & 2 deletions js/lib/game.js
Expand Up @@ -52,12 +52,18 @@ Game.prototype._getRobot = function(a, b) {
return this._cells[a][b]; return this._cells[a][b];
}; };


Game.prototype._removeRobot = function(a, b) {
this._cells[a][b] = null;
};

Game.prototype._setRobot = function(a, b, robot) { Game.prototype._setRobot = function(a, b, robot) {
this._cells[a][b] = robot; this._cells[a][b] = robot;
robot.setCoordinates(a, b); robot.setCoordinates(a, b);
}; };


Game.prototype.kill = function(robot) { Game.prototype.kill = function(robot) {
var coordinates = robot.getCoordinates();
this._removeRobot(coordinates.a, coordinates.b);
var index = this._robots.indexOf(robot); var index = this._robots.indexOf(robot);
this._robots.splice(index, 1); this._robots.splice(index, 1);
this.emit('death', robot); this.emit('death', robot);
Expand All @@ -75,16 +81,17 @@ Game.prototype.isFirstStep = function() {
return this._step === 1; return this._step === 1;
}; };


Game.prototype.nextStep = function() { Game.prototype.nextTick = function() {
this._step++; this._step++;


if (this.isFirstStep()) { if (this.isFirstStep()) {
this._spawnInitialRobots(); this._spawnInitialRobots();
return; return;
} }


var self = this;
this.getRobots().forEach(function(robot) { this.getRobots().forEach(function(robot) {
robot.nextStep(); robot.nextTick();
}); });
}; };


Expand Down
52 changes: 47 additions & 5 deletions js/lib/instructions.js
@@ -1,20 +1,62 @@
module.exports = { var instructions = {
'init': {
costs: 0,
execute: function(game, robot, args) {}
},
'rotate': { 'rotate': {
costs: 1, costs: 1,
execute: function(game, robot, args) { execute: function(game, robot, args) {
robot.rotate(args[0]); robot.rotate(args[0]);
return args; }
},
'move': {
costs: 1,
execute: function(game, robot, args) {
robot.move();
}
},
'scan': {
costs: 1,
execute: function(game, robot, args) {
var coordinates = game._getCoordinatesInFrontOf(robot);
var otherRobot = game._getRobot(coordinates.a, coordinates.b);
if (!otherRobot) {
return ['empty'];
}

return (otherRobot.getPlayer() === robot.getPlayer())
? 'friend'
: 'enemy';
} }
}, },
'transfer': { 'transfer': {
costs: function(game, robot, args) { costs: function(game, robot, args) {
return 1;
}, },
execute: function() { execute: function(game, robot, args) {
var coordinates = game._getCoordinatesInFrontOf(robot);
var otherRobot = game._getRobot(coordinates.a, coordinates.b);
if (!otherRobot) {
return;
}

var sourceProgram = robot._code[args[0]];
otherRobot._code = $.extend(true, {}, otherRobot._code);

var destProgram = {};
otherRobot._code[otherRobot._currentProgram] = destProgram;
for (var key in sourceProgram) {
destProgram[key] = sourceProgram[key];
}

otherRobot._currentArgs = [];
otherRobot._currentInstruction = 'init';
otherRobot._remainingCycles = 0;
}, },
}, },
'build': { 'build': {
costs: function(game, robot, args) { costs: function(game, robot, args) {
return 10; return 2;
//if (args[0] === 'builder') { //if (args[0] === 'builder') {
//return 10; //return 10;
//} //}
Expand All @@ -26,7 +68,7 @@ module.exports = {
//return new Error('build: unknown type: ' + args[0]); //return new Error('build: unknown type: ' + args[0]);
}, },
execute: function(game, robot, args) { execute: function(game, robot, args) {
var coordinates = game.getCoordinatesInFrontOf(robot); game.buildRobot(robot);
}, },
} }
}; };
80 changes: 69 additions & 11 deletions js/lib/robot.js
Expand Up @@ -2,7 +2,11 @@ function Robot() {
this._a = null; this._a = null;
this._b = null; this._b = null;
this._rotation = null; this._rotation = null;
this._operation = null;
this._currentProgram = 'main';
this._currentArgs = [];
this._currentInstruction = 'init';
this._remainingCycles = 0;


this._code = null; this._code = null;
this._game = null; this._game = null;
Expand Down Expand Up @@ -62,6 +66,21 @@ Robot.prototype.rotate = function(direction) {
this._game.emit('rotate', this); this._game.emit('rotate', this);
}; };


Robot.prototype.move = function() {
var newCoordinates = this._game._getCoordinatesInFrontOf(this);
if (this._game._getRobot(newCoordinates.a, newCoordinates.b)) {
return;
}

var oldCoordinates = this.getCoordinates();
this.setCoordinates(newCoordinates.a, newCoordinates.b);

this._game._removeRobot(oldCoordinates.a, oldCoordinates.b);
this._game._setRobot(newCoordinates.a, newCoordinates.b, this);

this._game.emit('move', this, oldCoordinates);
};

Robot.prototype.build = function() { Robot.prototype.build = function() {
this._game.buildRobot(this); this._game.buildRobot(this);
}; };
Expand All @@ -72,24 +91,63 @@ Robot.prototype.scan = function() {
//if ( //if (
}; };


Robot.prototype.nextStep = function() { Robot._getCallbackName = function(instruction) {
var operation = this._operation || 'ready'; var firstLetter = instruction.substr(0, 1);
this._invoke(operation); var remainingLetters = instruction.substr(1);


return 'after' + firstLetter.toUpperCase() + remainingLetters;
}; };


Robot.prototype._invoke = function(operation) { Robot.prototype.nextTick = function() {
var name = operation.substr(0, 1).toUpperCase() + operation.substr(1); if (this._remainingCycles > 0) {
var r = this._code.main['after' + name].apply({}, this._args); this._remainingCycles--;
this._args = []; return;
}

var executeFn = instructions[this._currentInstruction].execute;
var resultArgs = executeFn.call({}, this._game, this, this._currentArgs);
if (resultArgs) {
resultArgs = [].concat(resultArgs);
}

var callbackName = Robot._getCallbackName(this._currentInstruction);
var callbackFn = this._code[this._currentProgram][callbackName];

if (!callbackFn) {
console.log('missing callback: ' + callbackName);
this._commitSuicide();
return;
}

var nextArgs = callbackFn.apply({}, resultArgs || []);
if (!nextArgs) {
console.log('emtpy method: ' + callbackName);
this._commitSuicide();
return;
}
var nextInstruction = nextArgs.shift();

if (!(nextInstruction in instructions)) {
console.log('unknown instruction: ' + nextInstruction);
this._commitSuicide();
return;
}

var costs = instructions[nextInstruction].costs;
if (typeof costs === 'function') {
costs = costs.call({}, this._game, this);
}


if (!r) { if (costs instanceof Error) {
console.log('costs error: ' + costs.message);
this._commitSuicide(); this._commitSuicide();
return; return;
} }


this._operation = r.shift(); this._remainingCycles = costs;
this[this._operation].apply(this, r); this._currentInstruction = nextInstruction;
this._currentArgs = nextArgs;
//console.log(this._currentInstruction, this._currentArgs);
}; };


Robot.prototype._commitSuicide = function() { Robot.prototype._commitSuicide = function() {
Expand Down
12 changes: 12 additions & 0 deletions js/lib/visualizer.js
Expand Up @@ -17,6 +17,7 @@ Visualizer.prototype.render = function(game) {
this._renderGrid(); this._renderGrid();


game.on('rotate', this._handleRotate.bind(this)); game.on('rotate', this._handleRotate.bind(this));
game.on('move', this._handleMove.bind(this));
game.on('spawn', this._handleSpawn.bind(this)); game.on('spawn', this._handleSpawn.bind(this));
game.on('death', this._handleDeath.bind(this)); game.on('death', this._handleDeath.bind(this));
}; };
Expand Down Expand Up @@ -69,6 +70,17 @@ Visualizer.prototype._handleRotate = function(robot) {
.addClass('rotate_' + rotation); .addClass('rotate_' + rotation);
}; };


Visualizer.prototype._handleMove = function(robot, oldCoordinates) {
var newCoordinates = robot.getCoordinates();

var $oldTd = this._getTd(oldCoordinates);
var $newTd = this._getTd(newCoordinates);

$newTd.append($oldTd.children().remove());
$newTd.attr('class', $oldTd.attr('class'));
$oldTd.attr('class', '');
};

Visualizer.prototype._handleSpawn = function(robot) { Visualizer.prototype._handleSpawn = function(robot) {
var coordinates = robot.getCoordinates(); var coordinates = robot.getCoordinates();
var $td = this._getTd(coordinates); var $td = this._getTd(coordinates);
Expand Down
43 changes: 20 additions & 23 deletions js/main.js
@@ -1,18 +1,33 @@
$(function() { $(function() {
var TIMEOUT = 0; var TIMEOUT = 0;


var programs = {};
Program.load('js/program/flooder.js', function(program) {
programs.red = program;
onProgramLoad();
});
Program.load('js/program/spinner.js', function(program) { Program.load('js/program/spinner.js', function(program) {
var game = Game.create(32); programs.blue = program;
game.add('red', program); onProgramLoad();
game.add('blue', program); });


function onProgramLoad() {
if (Object.keys(programs).length < 2) {
return;
}

var game = Game.create(20);
game.add('red', programs.red);
game.add('blue', programs.blue);


var visualizer = Visualizer.create($('.js_container')); var visualizer = Visualizer.create($('.js_container'));
visualizer.render(game); visualizer.render(game);


var interval; var interval;
function continueGame() { function continueGame() {
interval = setInterval(function() { interval = setInterval(function() {
game.nextStep(); game.nextTick();
}, TIMEOUT); }, TIMEOUT);
} }


Expand All @@ -32,23 +47,5 @@ $(function() {
}); });


continueGame(); continueGame();
}); };

//var grid = Grid.create(8);
//var visualizer = Visualizer.create();

//var SIZE = 8;
//var html = ['<table>'];

//for (var a = 0; a < SIZE; a++) {
//html.push('<tr>');
//for (var b = 0; b < SIZE; b++) {
//html.push('<td>' + a + ', ' + b + '</td>');
//}
//html.push('</tr>');
//}

//html.push('</table>');

//$('.js_grid_container').html(html.join('\n'));
}); });
23 changes: 18 additions & 5 deletions js/program/flooder.js
@@ -1,5 +1,5 @@
main: { main: {
afterReady: function() { afterInit: function() {
return ['scan']; return ['scan'];
}, },
afterScan: function(result) { afterScan: function(result) {
Expand All @@ -13,16 +13,29 @@ main: {


return ['rotate', 'right']; return ['rotate', 'right'];
}, },
afterBuild: function() {
return ['transfer', 'main'];
},
afterTransfer: function() { afterTransfer: function() {
return ['rotate', 'right']; return ['rotate', 'right'];
}, },
afterBuild: function() {
return ['rotate', 'right'];
},
afterRotate: function() { afterRotate: function() {
return ['scan']; return ['scan'];
} }
}, },
virus: { virus: {
afterReady: function() {} afterInit: function() {
return ['scan'];
},
afterScan: function(result) {
if (result === 'empty') {
return;
}

if (result === 'friend') {
return ['transfer', 'main'];
}

return;
},
} }
6 changes: 3 additions & 3 deletions js/program/spinner.js
@@ -1,11 +1,11 @@
main: { main: {
afterReady: function() { afterInit: function() {
return ['build']; return ['build'];
}, },
afterBuild: function() { afterBuild: function() {
return ['rotate', 'right']; return ['rotate', 'left'];
}, },
afterRotate: function() { afterRotate: function() {
return ['build']; return ['build'];
} },
} }

0 comments on commit 83b2357

Please sign in to comment.