4
\$\begingroup\$

I'm writing a simple JavaScript game, which uses a 2-dimensional array as the main data structure. I wrote this function-class-thing that allows me to give any two integers, positive or negative. This class should "wrap" those integers back onto the game grid.

For example:

var g = new Grid(10, 10)
g.set(15, -2, "hello")
g.get(5, 8); //should be "hello"

Anyway, I'm striving to improve my JavaScript, so I'm wondering if there are any improvements (performance, "javascriptness", etc.) that I might be able to make.

var Grid = (function(w, h){
    this._width = w;
    this._height = h;
    this._grid = new Array((this._width * this._height) | 0);
    this.get = function(x, y){
            var coords = _normalize(x, y);
            return this._grid[(coords.y * coords.x) + coords.x];
    }
    this.set = function(x, y, item){
            var coords = _normalize(x, y);
            this._grid[(coords.y * coords.x) + coords.x] = item;
    }
    this._normalize = function(x, y){
            if(x < 0) x = (this._width + x) % this._width;
            else if(x >= this._width) x = x % this._width ;
            if(y < 0) y = (this._height + y) % this._height;
            else if(y >= this._height) y = y % this._height;
            return {'x': x, 'y': y};
    }
});
\$\endgroup\$
1
  • \$\begingroup\$ What should happen if x = -11 and width = 10? \$\endgroup\$
    – Just_Mad
    Commented Oct 10, 2013 at 8:29

1 Answer 1

3
\$\begingroup\$

I can't say, that my variant of normalize function is easier to understand, but at least it is linear and it works correct (as i think) with x, that is less than -width

this._normalize = function(x, y) {
    x = x % this._width;
    y = y % this._height;

    x = (this._width + x) % this._width;
    y = (this._height + y) % this._height;

    return {'x': x, 'y': y};
}

Also, you missed this statement in get and set functions (looks like a typo):

this.get = function(x, y){
    var coords = this._normalize(x, y);
    return this._grid[(coords.y * coords.x) + coords.x];
}
this.set = function(x, y, item){
    var coords = this._normalize(x, y);
    this._grid[(coords.y * coords.x) + coords.x] = item;
}

It is better to move get, set and normalize functions to Grid prototype. Putting these functions in prototype will increase execution speed and require less memory for creating an instance of Grid because these functions will not be created every time Grid instance is created. Like this:

var Grid = function(w, h){
    this._width = w;
    this._height = h;
    this._grid = new Array((this._width * this._height) | 0);
};
Grid.prototype.get = function(x, y) {
    // get code
};
Grid.prototype.set = function(x, y, item){
    // set code
};
Grid.prototype._normalize = function(x, y){
    // normalize code
};
\$\endgroup\$
3
  • \$\begingroup\$ Come to think of it, adding this._width to x right before taking the modulo with this._width doesn't actually do anything, right? So: x = (this._width) + x) % this._width is the same as x %= this._width. \$\endgroup\$ Commented Oct 10, 2013 at 8:42
  • \$\begingroup\$ It makes sense, when x < 0... But separating behavior for positive and negative values by if statements is also ok. \$\endgroup\$
    – Just_Mad
    Commented Oct 10, 2013 at 8:48
  • \$\begingroup\$ Ohh right, 'cause it's negative. Thank you :D \$\endgroup\$ Commented Oct 10, 2013 at 8:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.