Skip to content
Browse files

Implement new instructions.js grammar thingy

Still need to clean up the code
  • Loading branch information...
1 parent 9d71760 commit 83b23577c384c83f9fe3b576f176c144a2f560f5 @felixge committed Jun 13, 2011
Showing with 179 additions and 49 deletions.
  1. +1 −0 index.html
  2. +9 −2 js/lib/game.js
  3. +47 −5 js/lib/instructions.js
  4. +69 −11 js/lib/robot.js
  5. +12 −0 js/lib/visualizer.js
  6. +20 −23 js/main.js
  7. +18 −5 js/program/flooder.js
  8. +3 −3 js/program/spinner.js
View
1 index.html
@@ -9,6 +9,7 @@
<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/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/program.js"></script>
<script type="text/javascript" src="js/lib/robot.js"></script>
View
11 js/lib/game.js
@@ -52,12 +52,18 @@ Game.prototype._getRobot = function(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) {
this._cells[a][b] = robot;
robot.setCoordinates(a, b);
};
Game.prototype.kill = function(robot) {
+ var coordinates = robot.getCoordinates();
+ this._removeRobot(coordinates.a, coordinates.b);
var index = this._robots.indexOf(robot);
this._robots.splice(index, 1);
this.emit('death', robot);
@@ -75,16 +81,17 @@ Game.prototype.isFirstStep = function() {
return this._step === 1;
};
-Game.prototype.nextStep = function() {
+Game.prototype.nextTick = function() {
this._step++;
if (this.isFirstStep()) {
this._spawnInitialRobots();
return;
}
+ var self = this;
this.getRobots().forEach(function(robot) {
- robot.nextStep();
+ robot.nextTick();
});
};
View
52 js/lib/instructions.js
@@ -1,20 +1,62 @@
-module.exports = {
+var instructions = {
+ 'init': {
+ costs: 0,
+ execute: function(game, robot, args) {}
+ },
'rotate': {
costs: 1,
execute: function(game, robot, args) {
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': {
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': {
costs: function(game, robot, args) {
- return 10;
+ return 2;
//if (args[0] === 'builder') {
//return 10;
//}
@@ -26,7 +68,7 @@ module.exports = {
//return new Error('build: unknown type: ' + args[0]);
},
execute: function(game, robot, args) {
- var coordinates = game.getCoordinatesInFrontOf(robot);
+ game.buildRobot(robot);
},
}
};
View
80 js/lib/robot.js
@@ -2,7 +2,11 @@ function Robot() {
this._a = null;
this._b = null;
this._rotation = null;
- this._operation = null;
+
+ this._currentProgram = 'main';
+ this._currentArgs = [];
+ this._currentInstruction = 'init';
+ this._remainingCycles = 0;
this._code = null;
this._game = null;
@@ -62,6 +66,21 @@ Robot.prototype.rotate = function(direction) {
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() {
this._game.buildRobot(this);
};
@@ -72,24 +91,63 @@ Robot.prototype.scan = function() {
//if (
};
-Robot.prototype.nextStep = function() {
- var operation = this._operation || 'ready';
- this._invoke(operation);
+Robot._getCallbackName = function(instruction) {
+ var firstLetter = instruction.substr(0, 1);
+ var remainingLetters = instruction.substr(1);
+ return 'after' + firstLetter.toUpperCase() + remainingLetters;
};
-Robot.prototype._invoke = function(operation) {
- var name = operation.substr(0, 1).toUpperCase() + operation.substr(1);
- var r = this._code.main['after' + name].apply({}, this._args);
- this._args = [];
+Robot.prototype.nextTick = function() {
+ if (this._remainingCycles > 0) {
+ this._remainingCycles--;
+ 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();
return;
}
- this._operation = r.shift();
- this[this._operation].apply(this, r);
+ this._remainingCycles = costs;
+ this._currentInstruction = nextInstruction;
+ this._currentArgs = nextArgs;
+ //console.log(this._currentInstruction, this._currentArgs);
};
Robot.prototype._commitSuicide = function() {
View
12 js/lib/visualizer.js
@@ -17,6 +17,7 @@ Visualizer.prototype.render = function(game) {
this._renderGrid();
game.on('rotate', this._handleRotate.bind(this));
+ game.on('move', this._handleMove.bind(this));
game.on('spawn', this._handleSpawn.bind(this));
game.on('death', this._handleDeath.bind(this));
};
@@ -69,6 +70,17 @@ Visualizer.prototype._handleRotate = function(robot) {
.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) {
var coordinates = robot.getCoordinates();
var $td = this._getTd(coordinates);
View
43 js/main.js
@@ -1,18 +1,33 @@
$(function() {
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) {
- var game = Game.create(32);
- game.add('red', program);
- game.add('blue', program);
+ programs.blue = program;
+ onProgramLoad();
+ });
+
+
+ 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'));
visualizer.render(game);
var interval;
function continueGame() {
interval = setInterval(function() {
- game.nextStep();
+ game.nextTick();
}, TIMEOUT);
}
@@ -32,23 +47,5 @@ $(function() {
});
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'));
+ };
});
View
23 js/program/flooder.js
@@ -1,5 +1,5 @@
main: {
- afterReady: function() {
+ afterInit: function() {
return ['scan'];
},
afterScan: function(result) {
@@ -13,16 +13,29 @@ main: {
return ['rotate', 'right'];
},
- afterBuild: function() {
- return ['transfer', 'main'];
- },
afterTransfer: function() {
return ['rotate', 'right'];
},
+ afterBuild: function() {
+ return ['rotate', 'right'];
+ },
afterRotate: function() {
return ['scan'];
}
},
virus: {
- afterReady: function() {}
+ afterInit: function() {
+ return ['scan'];
+ },
+ afterScan: function(result) {
+ if (result === 'empty') {
+ return;
+ }
+
+ if (result === 'friend') {
+ return ['transfer', 'main'];
+ }
+
+ return;
+ },
}
View
6 js/program/spinner.js
@@ -1,11 +1,11 @@
main: {
- afterReady: function() {
+ afterInit: function() {
return ['build'];
},
afterBuild: function() {
- return ['rotate', 'right'];
+ return ['rotate', 'left'];
},
afterRotate: function() {
return ['build'];
- }
+ },
}

0 comments on commit 83b2357

Please sign in to comment.
Something went wrong with that request. Please try again.