Skip to content

Instantly share code, notes, and snippets.

@briandeheus
Created June 16, 2016 09:48
Show Gist options
  • Save briandeheus/475b7d820b35650c40693ae6d778d525 to your computer and use it in GitHub Desktop.
Save briandeheus/475b7d820b35650c40693ae6d778d525 to your computer and use it in GitHub Desktop.
Red Dress Matrix Helper
var matrix = Symbol('Matrix');
var length = Symbol('Length');
var xS = Symbol('x');
var yS = Symbol('y');
var parentS = Symbol('parent');
class BoundError extends Error {}
class RedDressWalker {
constructor (value, x, y, parent) {
this[xS] = x;
this[yS] = y;
this[parentS] = parent;
this.value = value;
}
move (x, y) {
let moveX = this[xS] + x;
let moveY = this[yS] + y;
this.value = this[parentS].find(moveX, moveY);
this[xS] = moveX;
this[yS] = moveY;
return this.value;
}
}
class RedDress {
/**
* Create a new RedDress matrix.
*
* @example
*
* let matrix = new RedDress(3, 3); // Creates an empty 3, 3 matrix.
*
* @param {int} rows - Rows constraint for the matrix
* @param {int} columns - Column constraints for the matrix.
*/
constructor (rows, columns) {
this.rows = rows;
this.columns = columns;
this[length] = rows * columns;
this[matrix] = new Array(this[length])
}
/**
* Check wether the specified coordinates are in the matrix.
* @param {int} x
* @param {int} y
* @private
*/
__check_bounds (x, y) {
if (x > this.rows - 1) {
throw new BoundError('Row is out of bounds');
}
if (y > this.columns - 1) {
throw new BoundError('Column is out of bounds');
}
}
/**
* Find a value in the matrix at X, Y
* @param {int} x
* @param {int} y
* @returns {*}
* @private
*/
__position_in_matrix (x, y) {
let realRow = x * this.columns;
return realRow + y;
}
bulkAdd (matrix) {
for (var i = 0, l = matrix.length; i < l; i += 1) {
var row = matrix[i];
for (var ii = 0, ll = row.length; ii < ll; ii += 1) {
this.add(row[ii], i, ii);
}
}
}
/**
* Add a new value to the matrix.
* @param {*} value - Value for the X, Y position
* @param {int} x - X coordinate in the matrix
* @param {int} y - Y coordinate in the matrix
* @param {boolean} withWalker - Returns a RedDressWalker if set to true
*/
add (value, x, y, withWalker=false) {
this.__check_bounds(x, y);
let position = this.__position_in_matrix(x, y);
this[matrix][position] = value;
if (withWalker === true) {
return new RedDressWalker(value, x, y, this);
}
}
/**
* Find a value at X, Y
* @param {int} x
* @param {int} y
* @param {boolean} withWalker
* @returns {*}
*/
find (x, y, withWalker=false) {
this.__check_bounds(x, y);
let position = this.__position_in_matrix(x, y);
let value = this[matrix][position];
if (withWalker === true) {
return new RedDressWalker(value, x, y, this);
} else {
return value;
}
}
getWalker (initialX, initialY) {
return new RedDressWalker(this.find(initialX, initialY), initialX, initialY, this);
}
}
let m = new RedDress(3, 3);
m.add('foo', 0, 0);
m.add('foo', 0, 1);
m.add('foo', 0, 2);
m.add('bar', 1, 0);
m.add('bar', 1, 1);
m.add('bar', 1, 2);
m.add('foo bar', 2, 0);
m.add('foo bar', 2, 1);
m.add('foo bar', 2, 2);
console.log('At 0,0:', m.find(0, 0));
console.log('At 1,0:', m.find(1, 0));
console.log('At 2,0:', m.find(2, 0));
let walker = m.getWalker(0, 0);
console.log('Walker:', walker.move(0, 1));
console.log('Walker:', walker.move(1, 0));
console.log('Walker:', walker.move(1, 0));
let m2 = new RedDress(3, 3);
m2.bulkAdd([
['0,0', '0,1', '0,2'],
['1,0', '1,1', '1,2'],
['2,0', '2,1', '2,2']
]);
let walker2 = m2.getWalker(0, 0);
console.log('Walker 2:', walker2.move(0, 0));
console.log('Walker 2:', walker2.move(1, 0));
console.log('Walker 2:', walker2.move(1, 0));
console.log(m2.find(1, 1));
console.log(m2.find(0, 0));
console.log(m2.find(2, 2));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment