| '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; |