blob: 7a9766370b99fc1b2236a9afe7f4c955f2f9eb58 [file] [log] [blame]
'use strict';
var util = require('./util');
var C = require('./constants');
/**
* Helper class to store node information, apply and revert changes easily.
*
* @param {Board} jboard Board object to make changes on.
* @param {Node} parent Parent node or null if no parent.
* @param {Object} info Node information - ko coordinate, comment, etc.
* @constructor
*/
var Node = function(jboard, parent, info) {
this.jboard = jboard;
this.parent = parent;
this.info = info ? util.extend({}, info) : {};
this.children = [];
this.changes = [];
if(parent) {
parent.children.push(this); // register child
this.info.captures = util.extend({}, parent.info.captures);
} else {
this.info.captures = {1: 0, 2: 0}; // C.BLACK, C.WHITE
}
};
/**
* Helper method to clear parent node's markers. Created to achieve SGF like
* stateless marker behavaior.
*/
Node.prototype.clearParentMarks = function() {
if(!this.parent)
return;
for(var i=this.parent.changes.length-1; i>=0; i--) {
var item = this.parent.changes[i];
if('mark' in item)
this.setMark(item.c, C.MARK.NONE);
}
};
/**
* Helper method to make changes to a board while saving them in the node.
*
* @param {Object} c Coordinate or array of them.
* @param {int} val Type.
*/
Node.prototype.setType = function(c, val) {
if(c instanceof Array) {
for(var i=0, len=c.length; i<len; ++i)
this.setType(c[i], val); // avoid repeating ourselves
return;
}
// Store both change and previous value to enable reversion
this.changes.push({c: c.copy(), type: val, old: this.jboard.getType(c)});
this.jboard.setType(c, val);
};
/**
* Helper method to make changes to a board while saving them in the node.
*
* @param {Object} c Coordinate or array of them.
* @param {int} val Mark.
*/
Node.prototype.setMark = function(c, val) {
if(c instanceof Array) {
for(var i=0, len=c.length; i<len; ++i)
this.setMark(c[i], val); // avoid repeating ourselves
return;
}
// Store both change and previous value to enable reversion
this.changes.push({c: c.copy(), mark: val, old: this.jboard.getMark(c)});
this.jboard.setMark(c, val);
};
/**
* Apply changes of this node to board.
*/
Node.prototype.apply = function() {
for(var i=0; i<this.changes.length; i++) {
var item = this.changes[i];
if('type' in item)
this.jboard.setType(item.c, item.type);
else
this.jboard.setMark(item.c, item.mark);
}
};
/**
* Revert changes of this node to board.
*/
Node.prototype.revert = function() {
for(var i=this.changes.length-1; i>=0; i--) {
var item = this.changes[i];
if('type' in item)
this.jboard.setType(item.c, item.old);
else
this.jboard.setMark(item.c, item.old);
}
};
module.exports = Node;