var staircase2walls = function(valueFunctions, origin, corners, requiredLandplotValue) { var numOfAgents = valueFunctions.length; var numOfCorners = corners.length; TRACE(numOfAgents,numOfAgents+" agents("+_.pluck(valueFunctions,"color")+"), trying to give each a value of "+requiredLandplotValue+" using a 2-walls staircase algorithm with "+numOfCorners+" corners: "+JSON.stringify(corners)); // for each agent, calculate the acceptable corner square with the smallest taxicab distance from the origin: valueFunctions.forEach(function(valueFunction) { valueFunction.square = jsts.algorithm.cornerSquareWithMinTaxicabDistance(valueFunction, corners, requiredLandplotValue, "NE", origin) }); // get the agent with the square with the smallest taxicab distance overall: var iWinningAgent = _.argmin(valueFunctions, function(valueFunction) { return valueFunction.square.t; }); var winningAgent = valueFunctions[iWinningAgent]; if (winningAgent===Infinity) winningAgent = {square:{t:Infinity}}; // bug in _.min if (!isFinite(winningAgent.square.t)) { TRACE(numOfAgents, "-- no square with the required value "+requiredLandplotValue); if (requiredLandplotValue<=1) console.dir(valueFunctions); return []; } var landplot = { minx: winningAgent.square.x, miny: winningAgent.square.y, maxx: winningAgent.square.x+winningAgent.square.s, maxy: winningAgent.square.y+winningAgent.square.s, }; if (winningAgent.color) landplot.color = winningAgent.color; TRACE(numOfAgents, "++ agent "+iWinningAgent+" gets from the square "+JSON.stringify(winningAgent.square)+" the landplot "+JSON.stringify(landplot)); if (valueFunctions.length==1) return [landplot]; var remainingValueFunctions = valueFunctions.slice(0,iWinningAgent).concat(valueFunctions.slice(iWinningAgent+1,valueFunctions.length)); var remainingCorners = jsts.algorithm.updatedCornersNorthEast(corners, landplot); var remainingLandplots = staircase2walls(remainingValueFunctions, origin, remainingCorners, requiredLandplotValue); remainingLandplots.push(landplot); return remainingLandplots; }
var staircase4walls = function(valueFunctions, border, requiredLandplotValue) { var numOfAgents = valueFunctions.length; TRACE(numOfAgents,numOfAgents+" agents("+_.pluck(valueFunctions,"color")+"), trying to give each a value of "+requiredLandplotValue+" using a 4-walls staircase algorithm with border: "+JSON.stringify(border)); var rectangles = jsts.algorithm.rectanglesCoveringSouthernLevels(levels); var squaresFound = false; // for each agent, calculate all level squares with value 1: valueFunctions.forEach(function(valueFunction) { var levelSquares = []; for (var i=0; i<rectangles.length; ++i) { var rectangle = rectangles[i]; var minx=rectangle.minx, maxx=rectangle.maxx, miny=rectangle.miny; var squareSizeEast = valueFunction.sizeOfSquareWithValue({x:minx,y:miny}, requiredLandplotValue, "NE"); var squareSizeWest = valueFunction.sizeOfSquareWithValue({x:maxx,y:miny}, requiredLandplotValue, "NW"); if (minx+squareSizeEast <= maxx && miny+squareSizeEast<=yLength/2) levelSquares.push({minx:minx, miny:miny, maxx:minx+squareSizeEast, maxy:miny+squareSizeEast}); if (maxx-squareSizeWest >= minx && miny+squareSizeWest<=yLength/2) levelSquares.push({maxx:maxx, miny:miny, minx:maxx-squareSizeWest, maxy:miny+squareSizeWest}); } if (levelSquares.length>0) { squaresFound = true; valueFunction.square = _.min(levelSquares, function(square){return square.maxy}); } else { valueFunction.square = {maxy:Infinity}; } }); if (squaresFound) { // get the agent with the square with the smallest height overall: var iWinningAgent = _.argmin(valueFunctions, function(valueFunction) { return valueFunction.square.maxy; }); var winningAgent = valueFunctions[iWinningAgent]; if (!winningAgent.square || !isFinite(winningAgent.square.maxy)) { TRACE(numOfAgents, "-- no southern square with the required value "+requiredLandplotValue); if (requiredLandplotValue<=1) console.log(util.inspect(valueFunctions,{depth:3})); return []; } var landplot = winningAgent.square; if (winningAgent.color) landplot.color = winningAgent.color; TRACE(numOfAgents, "++ agent "+iWinningAgent+" gets the southern landplot "+JSON.stringify(landplot)); if (valueFunctions.length==1) return [landplot]; var remainingValueFunctions = valueFunctions.slice(0,iWinningAgent).concat(valueFunctions.slice(iWinningAgent+1,valueFunctions.length)); var remainingLevels = jsts.algorithm.updatedLevels(levels, landplot,"S"); var remainingLandplots = staircase4walls(yLength, remainingValueFunctions, remainingLevels, requiredLandplotValue); remainingLandplots.push(landplot); return remainingLandplots; } else { var newLevels = [{y:yLength,minx:0,maxx:1}] return staircase4wallsNorth(yLength, valueFunctions, newLevels, requiredLandplotValue); } }