advent13_cubicles.js
/**
     * @param {Point} point current position
     * @param {Point} previous array of positions we've already been to
     * @param {Point} numMoves how many moves it took to get here
     * @param {function} wallFilter predicate applied to points to filter out walls from possible next moves list  
     */
@param {Point} point current position
@param {Point} previous array of positions we've already been to
@param {Point} numMoves how many moves it took to get here
@param {function} wallFilter predicate applied to points to filter out walls from possible next moves list
@param { Point } point current position @param { Point } previous array of positions we ' ve already been to @param { Point } numMoves how many moves it took to get here @param { function } wallFilter predicate applied to points to filter out walls from possible next moves list
function Agent(point, previous, numMoves) {
        assert(typeof(point) === 'object', 'point must be Point: ' + point);
        assert(previous instanceof Array, 'previous must be Array: ' + previous);
        assert(typeof(numMoves) === 'number', 'numMoves must be number: ' + numMoves);
        var me = this;
        this.move = function(destination, maxMoves) {
            assert.equal(typeof(maxMoves), 'number', 'maxMoves must be a number');
            assert.ok(maxMoves >= 0, 'required: maxMoves >= 0; maxMoves = ' + maxMoves);
            if (point.equals(destination)) {
                return numMoves;
            }
            if (numMoves < maxMoves) {
                var neighbors = point.neighbors(wallFilter)
                        .filter(p => indexOfPoint(previous, p) === -1);
                neighbors.sort(destination.comparator);
                for (var i in neighbors) {
                    var nextAgent = new Agent(neighbors[i], previous.concat([point]), numMoves + 1);
                    var answer = nextAgent.move(destination, maxMoves);
                    if (answer >= 0) {
                        return answer;
                    }
                }
            }
            return -1; 
        };
    }
function Agent ( point , previous , numMoves ) { assert ( typeof ( point ) === 'object' , 'point must be Point: ' + point ) ; assert ( previous instanceof Array , 'previous must be Array: ' + previous ) ; assert ( typeof ( numMoves ) === 'number' , 'numMoves must be number: ' + numMoves ) ; var me = this ; this . move = function ( destination , maxMoves ) { assert . equal ( typeof ( maxMoves ) , 'number' , 'maxMoves must be a number' ) ; assert . ok ( maxMoves >= 0 , 'required: maxMoves >= 0; maxMoves = ' + maxMoves ) ; if ( point . equals ( destination ) ) { return numMoves ; } if ( numMoves < maxMoves ) { var neighbors = point . neighbors ( wallFilter ) . filter ( p => indexOfPoint ( previous , p ) === - 1 ) ; neighbors . sort ( destination . comparator ) ; for ( var i in neighbors ) { var nextAgent = new Agent ( neighbors [ i ] , previous . concat ( [ point ] ) , numMoves + 1 ) ; var answer = nextAgent . move ( destination , maxMoves ) ; if ( answer >= 0 ) { return answer ; } } } return - 1 ; } ; }
@param {Point} point current position
 @param {Point} previous array of positions we've already been to
 @param {Point} numMoves how many moves it took to get here
 @param {function} wallFilter predicate applied to points to filter out walls from possible next moves list
@param { Point } point current position @param { Point } previous array of positions we ' ve already been to @param { Point } numMoves how many moves it took to get here @param { function } wallFilter predicate applied to points to filter out walls from possible next moves list
// neighbors empty or no solution found