Note that there are some explanatory texts on larger screens.

plurals
  1. POTerrarium code in Eloquent Javascript not working
    text
    copied!<p>This is a code from the book Eloquent Javascript. It creates a 2D object called Terrarium where in insects can move. Insects are moved using the function:terrarium.step . But when I run it says 'center is undefined'. center is the argument of a function:Terrarium.prototype.listSurroundings. This function calls another function which uses a method of center as an argument. What could be wrong? I am attaching the whole code here including initialisation of terrarium etc. </p> <pre><code>function forEach(array,action) { for(var i=0;i&lt;array.length;i++) {action(array[i]);} } function forEachIn(object, action) { for (var property in object) { if (Object.prototype.hasOwnProperty.call(object, property)) action(property, object[property]); } } function Dictionary(startValues) { this.values = startValues || {}; } Dictionary.prototype.store = function(name, value) { this.values[name] = value; }; Dictionary.prototype.lookup = function(name) { return this.values[name]; }; Dictionary.prototype.contains = function(name) { return Object.prototype.propertyIsEnumerable.call(this.values, name); }; Dictionary.prototype.each = function(action) { forEachIn(this.values, action); }; function Point(x, y) { this.x = x; this.y = y; } Point.prototype.add = function(other) { return new Point(this.x + other.x, this.y + other.y); }; function Grid(width, height) { this.width = width; this.height = height; this.cells = new Array(width * height); } Grid.prototype.valueAt = function(point) { return this.cells[point.y * this.width + point.x]; }; Grid.prototype.setValueAt = function(point, value) { this.cells[point.y * this.width + point.x] = value; }; Grid.prototype.isInside = function(point) { return point.x &gt;= 0 &amp;&amp; point.y &gt;= 0 &amp;&amp; point.x &lt; this.width &amp;&amp; point.y &lt; this.height; }; Grid.prototype.moveValue = function(from, to) { this.setValueAt(to, this.valueAt(from)); this.setValueAt(from, undefined); }; Grid.prototype.each = function(action) { for (var y = 0; y &lt; this.height; y++) { for (var x = 0; x &lt; this.width; x++) { var point = new Point(x, y); action(point, this.valueAt(point)); } } }; var directions = new Dictionary( {"n": new Point( 0, -1), "ne": new Point( 1, -1), "e": new Point( 1, 0), "se": new Point( 1, 1), "s": new Point( 0, 1), "sw": new Point(-1, 1), "w": new Point(-1, 0), "nw": new Point(-1, -1)}); function StupidBug() {}; StupidBug.prototype.act = function(surroundings) { return {type: "move", direction: "s"}; }; var wall = {}; function elementFromCharacter(character) { if (character == " ") return undefined; else if (character == "#") return wall; else if (character == "o") return new StupidBug(); } function Terrarium(plan) { var grid = new Grid(plan[0].length, plan.length); for (var y = 0; y &lt; plan.length; y++) { var line = plan[y]; for (var x = 0; x &lt; line.length; x++) { grid.setValueAt(new Point(x, y), elementFromCharacter(line.charAt(x))); } } this.grid = grid; } wall.character = "#"; StupidBug.prototype.character = "o"; function characterFromElement(element) { if (element == undefined) return " "; else return element.character; } Terrarium.prototype.toString = function() { var characters = []; var endOfLine = this.grid.width - 1; this.grid.each(function(point, value) { characters.push(characterFromElement(value)); if (point.x == endOfLine) characters.push("\n"); }); return characters.join(""); }; function bind(func, object) { return function(){ return func.apply(object, arguments); }; } function method(object, name) { return function() { object[name].apply(object, arguments); }; } Terrarium.prototype.listActingCreatures = function() { var found = []; this.grid.each(function(point, value) { if (value != undefined &amp;&amp; value.act) found.push({object: value, point: point}); }); return found; }; Terrarium.prototype.listSurroundings = function(center) { var result = {}; var grid = this.grid; directions.each(function(name, direction) { var place = center.add(direction); if (grid.isInside(place)) result[name] = characterFromElement(grid.valueAt(place)); else result[name] = "#"; }); return result; }; Terrarium.prototype.processCreature = function(creature, point) { var action = creature.act(this.listSurroundings(point)); if (action.type == "move" &amp;&amp; directions.contains(action.direction)) { var to = point.add(directions.lookup(action.direction)); if (this.grid.isInside(to) &amp;&amp; this.grid.valueAt(to) == undefined) this.grid.moveValue(point, to); } else { throw new Error("Unsupported action: " + action.type); } }; Terrarium.prototype.step = function() { forEach(this.listActingCreatures(), bind(this.processCreature, this)); }; var thePlan = ["############################", "# # # o ##", "# #", "# ##### #", "## # # ## #", "### ## # #", "# ### # #", "# #### #", "# ## o #", "# o # o ### #", "# # #", "############################"] var terrarium = new Terrarium(thePlan); terrarium.step(); alert(terrarium); </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload