forked from 0ad/0ad
Petra: reduce the CPU time for building placement
This was SVN commit r15244.
This commit is contained in:
parent
7105dabca7
commit
84d799ed9f
@ -55,7 +55,7 @@ m.Army.prototype.recalculatePosition = function(gameState, force)
|
|||||||
var pos = [0,0];
|
var pos = [0,0];
|
||||||
if (this.foeEntities.length !== 0)
|
if (this.foeEntities.length !== 0)
|
||||||
{
|
{
|
||||||
for each (var id in this.foeEntities)
|
for (var id of this.foeEntities)
|
||||||
{
|
{
|
||||||
var ent = gameState.getEntityById(id);
|
var ent = gameState.getEntityById(id);
|
||||||
var epos = ent.position();
|
var epos = ent.position();
|
||||||
@ -69,7 +69,7 @@ m.Army.prototype.recalculatePosition = function(gameState, force)
|
|||||||
|
|
||||||
this.ownPosition = [0,0];
|
this.ownPosition = [0,0];
|
||||||
var npos = 0; // same defenders may be sailing to defend us
|
var npos = 0; // same defenders may be sailing to defend us
|
||||||
for each (var id in this.ownEntities)
|
for (var id of this.ownEntities)
|
||||||
{
|
{
|
||||||
var ent = gameState.getEntityById(id);
|
var ent = gameState.getEntityById(id);
|
||||||
if (!ent.position())
|
if (!ent.position())
|
||||||
@ -96,9 +96,9 @@ m.Army.prototype.recalculateStrengths = function (gameState)
|
|||||||
|
|
||||||
// todo: deal with specifics.
|
// todo: deal with specifics.
|
||||||
|
|
||||||
for each (var id in this.foeEntities)
|
for (var id of this.foeEntities)
|
||||||
this.evaluateStrength(gameState.getEntityById(id));
|
this.evaluateStrength(gameState.getEntityById(id));
|
||||||
for each (var id in this.ownEntities)
|
for (var id of this.ownEntities)
|
||||||
this.evaluateStrength(gameState.getEntityById(id), true);
|
this.evaluateStrength(gameState.getEntityById(id), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,10 +293,10 @@ m.Army.prototype.merge = function (gameState, otherArmy)
|
|||||||
for (var i in otherArmy.assignedTo)
|
for (var i in otherArmy.assignedTo)
|
||||||
this.assignedTo[i] = otherArmy.assignedTo[i];
|
this.assignedTo[i] = otherArmy.assignedTo[i];
|
||||||
|
|
||||||
for each (var id in otherArmy.foeEntities)
|
for (var id of otherArmy.foeEntities)
|
||||||
this.addFoe(gameState, id);
|
this.addFoe(gameState, id);
|
||||||
// TODO: reassign those ?
|
// TODO: reassign those ?
|
||||||
for each (var id in otherArmy.ownEntities)
|
for (var id of otherArmy.ownEntities)
|
||||||
this.addOwn(gameState, id);
|
this.addOwn(gameState, id);
|
||||||
|
|
||||||
this.recalculatePosition(gameState, true);
|
this.recalculatePosition(gameState, true);
|
||||||
|
@ -267,28 +267,30 @@ m.BaseManager.prototype.removeDropsite = function (gameState, ent)
|
|||||||
m.BaseManager.prototype.findBestDropsiteLocation = function(gameState, resource)
|
m.BaseManager.prototype.findBestDropsiteLocation = function(gameState, resource)
|
||||||
{
|
{
|
||||||
|
|
||||||
var storeHousePlate = gameState.getTemplate(gameState.applyCiv("structures/{civ}_storehouse"));
|
var template = gameState.getTemplate(gameState.applyCiv("structures/{civ}_storehouse"));
|
||||||
|
|
||||||
// This builds a map. The procedure is fairly simple. It adds the resource maps
|
// This builds a map. The procedure is fairly simple. It adds the resource maps
|
||||||
// (which are dynamically updated and are made so that they will facilitate DP placement)
|
// (which are dynamically updated and are made so that they will facilitate DP placement)
|
||||||
// Then checks for a good spot in the territory. If none, and town/city phase, checks outside
|
// Then checks for a good spot in the territory. If none, and town/city phase, checks outside
|
||||||
// The AI will currently not build a CC if it wouldn't connect with an existing CC.
|
// The AI will currently not build a CC if it wouldn't connect with an existing CC.
|
||||||
|
|
||||||
var obstructions = m.createObstructionMap(gameState, this.accessIndex, storeHousePlate);
|
var obstructions = m.createObstructionMap(gameState, this.accessIndex, template);
|
||||||
obstructions.expandInfluences();
|
obstructions.expandInfluences();
|
||||||
|
|
||||||
var locateMap = new API3.Map(gameState.sharedScript);
|
|
||||||
|
|
||||||
var DPFoundations = gameState.getOwnFoundations().filter(API3.Filters.byType(gameState.applyCiv("foundation|structures/{civ}_storehouse")));
|
var DPFoundations = gameState.getOwnFoundations().filter(API3.Filters.byType(gameState.applyCiv("foundation|structures/{civ}_storehouse")));
|
||||||
|
|
||||||
var ccEnts = gameState.getOwnEntities().filter(API3.Filters.byClass("CivCentre")).toEntityArray();
|
var ccEnts = gameState.getOwnEntities().filter(API3.Filters.byClass("CivCentre")).toEntityArray();
|
||||||
|
|
||||||
// TODO: might be better to check dropsites someplace else.
|
var width = obstructions.width;
|
||||||
// loop over this in this.terrytoryindices. It's usually a little too much, but it's always enough.
|
var bestIdx = undefined;
|
||||||
var width = locateMap.width;
|
var bestVal = undefined;
|
||||||
|
var radius = Math.ceil(template.obstructionRadius() / gameState.cellSize);
|
||||||
|
|
||||||
for (var p = 0; p < this.territoryIndices.length; ++p)
|
for (var p = 0; p < this.territoryIndices.length; ++p)
|
||||||
{
|
{
|
||||||
var j = this.territoryIndices[p];
|
var j = this.territoryIndices[p];
|
||||||
|
if (obstructions.map[j] <= radius) // check room around
|
||||||
|
continue;
|
||||||
|
|
||||||
// we add 3 times the needed resource and once the other two (not food)
|
// we add 3 times the needed resource and once the other two (not food)
|
||||||
var total = 0;
|
var total = 0;
|
||||||
@ -355,22 +357,23 @@ m.BaseManager.prototype.findBestDropsiteLocation = function(gameState, resource)
|
|||||||
else if (dist < 6400)
|
else if (dist < 6400)
|
||||||
total /= 2;
|
total /= 2;
|
||||||
}
|
}
|
||||||
|
if (total == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
locateMap.map[j] = total;
|
if (bestVal !== undefined && total < bestVal)
|
||||||
|
continue;
|
||||||
|
bestVal = total;
|
||||||
|
bestIdx = j;
|
||||||
}
|
}
|
||||||
|
|
||||||
var best = locateMap.findBestTile(2, obstructions);
|
|
||||||
var bestIdx = best[0];
|
|
||||||
|
|
||||||
if (this.Config.debug == 2)
|
if (this.Config.debug == 2)
|
||||||
warn(" for dropsite best is " + best[1]);
|
warn(" for dropsite best is " + bestVal);
|
||||||
|
|
||||||
var quality = best[1];
|
if (bestVal <= 0)
|
||||||
if (quality <= 0)
|
return {"quality": bestVal, "pos": [0, 0]};
|
||||||
return {"quality": quality, "pos": [0, 0]};
|
|
||||||
var x = ((bestIdx % width) + 0.5) * gameState.cellSize;
|
var x = ((bestIdx % width) + 0.5) * gameState.cellSize;
|
||||||
var z = (Math.floor(bestIdx / width) + 0.5) * gameState.cellSize;
|
var z = (Math.floor(bestIdx / width) + 0.5) * gameState.cellSize;
|
||||||
return {"quality": quality, "pos": [x, z]};
|
return {"quality": bestVal, "pos": [x, z]};
|
||||||
};
|
};
|
||||||
|
|
||||||
m.BaseManager.prototype.getResourceLevel = function (gameState, type)
|
m.BaseManager.prototype.getResourceLevel = function (gameState, type)
|
||||||
|
@ -643,7 +643,7 @@ m.HQ.prototype.buildNewCC= function(gameState, queues)
|
|||||||
|
|
||||||
// Returns the best position to build a new Civil Centre
|
// Returns the best position to build a new Civil Centre
|
||||||
// Whose primary function would be to reach new resources of type "resource".
|
// Whose primary function would be to reach new resources of type "resource".
|
||||||
m.HQ.prototype.findEconomicCCLocation = function(gameState, resource, fromStrategic)
|
m.HQ.prototype.findEconomicCCLocation = function(gameState, template, resource, fromStrategic)
|
||||||
{
|
{
|
||||||
// This builds a map. The procedure is fairly simple. It adds the resource maps
|
// This builds a map. The procedure is fairly simple. It adds the resource maps
|
||||||
// (which are dynamically updated and are made so that they will facilitate DP placement)
|
// (which are dynamically updated and are made so that they will facilitate DP placement)
|
||||||
@ -652,45 +652,51 @@ m.HQ.prototype.findEconomicCCLocation = function(gameState, resource, fromStrate
|
|||||||
|
|
||||||
Engine.ProfileStart("findEconomicCCLocation");
|
Engine.ProfileStart("findEconomicCCLocation");
|
||||||
|
|
||||||
// create an empty map
|
|
||||||
var locateMap = new API3.Map(gameState.sharedScript);
|
|
||||||
locateMap.setMaxVal(255);
|
|
||||||
// obstruction map
|
// obstruction map
|
||||||
var obstructions = m.createObstructionMap(gameState, 0);
|
var obstructions = m.createObstructionMap(gameState, 0, template);
|
||||||
obstructions.expandInfluences();
|
obstructions.expandInfluences();
|
||||||
|
|
||||||
var ccEnts = gameState.getEntities().filter(API3.Filters.byClass("CivCentre")).toEntityArray();
|
var ccEnts = gameState.getEntities().filter(API3.Filters.byClass("CivCentre")).toEntityArray();
|
||||||
var dpEnts = gameState.getOwnDropsites().toEntityArray();
|
var dpEnts = gameState.getOwnDropsites().filter(API3.Filters.not(API3.Filters.byClassesOr(["CivCentre", "Elephant"]))).toEntityArray();
|
||||||
|
var ccList = [];
|
||||||
|
for (var cc of ccEnts)
|
||||||
|
ccList.push({"pos": cc.position(), "ally": gameState.isPlayerAlly(cc.owner())});
|
||||||
|
var dpList = [];
|
||||||
|
for (var dp of dpEnts)
|
||||||
|
dpList.push({"pos": dp.position()});
|
||||||
|
|
||||||
for (var j = 0; j < locateMap.length; ++j)
|
var width = this.territoryMap.width;
|
||||||
|
var radius = Math.ceil(template.obstructionRadius() / gameState.cellSize);
|
||||||
|
var bestIdx = undefined;
|
||||||
|
var bestVal = undefined;
|
||||||
|
|
||||||
|
for (var j = 0; j < this.territoryMap.length; ++j)
|
||||||
{
|
{
|
||||||
var norm = 0.5; // TODO adjust it, knowing that we will sum 5 maps
|
|
||||||
if (this.territoryMap.getOwnerIndex(j) !== 0 || this.borderMap.map[j] === 2)
|
if (this.territoryMap.getOwnerIndex(j) !== 0 || this.borderMap.map[j] === 2)
|
||||||
{
|
|
||||||
norm = 0;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
// We require that it is accessible from our starting position
|
// We require that it is accessible from our starting position
|
||||||
var index = gameState.ai.accessibility.landPassMap[j];
|
var index = gameState.ai.accessibility.landPassMap[j];
|
||||||
if (!this.allowedRegions[index])
|
if (!this.allowedRegions[index])
|
||||||
{
|
|
||||||
norm = 0;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
// and with enough room around to build the cc
|
||||||
|
if (obstructions.map[j] <= radius)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var norm = 0.5; // TODO adjust it, knowing that we will sum 5 maps
|
||||||
// checking distance to other cc
|
// checking distance to other cc
|
||||||
var pos = [j%locateMap.width+0.5, Math.floor(j/locateMap.width)+0.5];
|
var pos = [j%width+0.5, Math.floor(j/width)+0.5];
|
||||||
pos = [gameState.cellSize*pos[0], gameState.cellSize*pos[1]];
|
pos = [gameState.cellSize*pos[0], gameState.cellSize*pos[1]];
|
||||||
var minDist = Math.min();
|
var minDist = Math.min();
|
||||||
for (var cc of ccEnts)
|
|
||||||
|
for (var cc of ccList)
|
||||||
{
|
{
|
||||||
var dist = API3.SquareVectorDistance(cc.position(), pos);
|
var dist = API3.SquareVectorDistance(cc.pos, pos);
|
||||||
if (dist < 14000) // Reject if too near from any cc
|
if (dist < 14000) // Reject if too near from any cc
|
||||||
{
|
{
|
||||||
norm = 0
|
norm = 0
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!gameState.isPlayerAlly(cc.owner()))
|
if (!cc.ally)
|
||||||
continue;
|
continue;
|
||||||
if (dist < 20000) // Reject if too near from an allied cc
|
if (dist < 20000) // Reject if too near from an allied cc
|
||||||
{
|
{
|
||||||
@ -722,15 +728,13 @@ m.HQ.prototype.findEconomicCCLocation = function(gameState, resource, fromStrate
|
|||||||
norm *= 0.5;
|
norm *= 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var dp of dpEnts)
|
for (var dp of dpList)
|
||||||
{
|
{
|
||||||
if (dp.hasClass("Elephant") || dp.hasClass("CivCentre")) // CivCentre are already taken into account
|
var dist = API3.SquareVectorDistance(dp.pos, pos);
|
||||||
continue;
|
|
||||||
var dist = API3.SquareVectorDistance(dp.position(), pos);
|
|
||||||
if (dist < 3600)
|
if (dist < 3600)
|
||||||
{
|
{
|
||||||
norm = 0;
|
norm = 0;
|
||||||
continue;
|
break;
|
||||||
}
|
}
|
||||||
else if (dist < 6400)
|
else if (dist < 6400)
|
||||||
norm *= 0.5;
|
norm *= 0.5;
|
||||||
@ -746,16 +750,15 @@ m.HQ.prototype.findEconomicCCLocation = function(gameState, resource, fromStrate
|
|||||||
+ gameState.sharedScript.CCResourceMaps["stone"].map[j]
|
+ gameState.sharedScript.CCResourceMaps["stone"].map[j]
|
||||||
+ gameState.sharedScript.CCResourceMaps["metal"].map[j];
|
+ gameState.sharedScript.CCResourceMaps["metal"].map[j];
|
||||||
val *= norm;
|
val *= norm;
|
||||||
if (val > 255)
|
|
||||||
val = 255;
|
if (bestVal !== undefined && val < bestVal)
|
||||||
locateMap.map[j] = val;
|
continue;
|
||||||
|
bestVal = val;
|
||||||
|
bestIdx = j;
|
||||||
}
|
}
|
||||||
|
|
||||||
Engine.ProfileStop();
|
Engine.ProfileStop();
|
||||||
|
|
||||||
var best = locateMap.findBestTile(6, obstructions);
|
|
||||||
var bestIdx = best[0];
|
|
||||||
|
|
||||||
/* if (m.DebugEnabled())
|
/* if (m.DebugEnabled())
|
||||||
{
|
{
|
||||||
gameState.sharedScript.CCResourceMaps["wood"].dumpIm("woodMap.png", 300);
|
gameState.sharedScript.CCResourceMaps["wood"].dumpIm("woodMap.png", 300);
|
||||||
@ -769,14 +772,13 @@ m.HQ.prototype.findEconomicCCLocation = function(gameState, resource, fromStrate
|
|||||||
if (fromStrategic) // be less restrictive
|
if (fromStrategic) // be less restrictive
|
||||||
cut = 30;
|
cut = 30;
|
||||||
if (this.Config.debug)
|
if (this.Config.debug)
|
||||||
warn("on a trouve une base avec best (cut=" + cut + ") = " + best[1]);
|
warn("on a trouve une base avec best (cut=" + cut + ") = " + bestVal);
|
||||||
// not good enough.
|
// not good enough.
|
||||||
if (best[1] < cut)
|
if (bestVal < cut)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var bestIdx = best[0];
|
var x = (bestIdx%width + 0.5) * gameState.cellSize;
|
||||||
var x = ((bestIdx % locateMap.width) + 0.5) * gameState.cellSize;
|
var z = (Math.floor(bestIdx/width) + 0.5) * gameState.cellSize;
|
||||||
var z = (Math.floor(bestIdx / locateMap.width) + 0.5) * gameState.cellSize;
|
|
||||||
|
|
||||||
// Define a minimal number of wanted ships in the seas reaching this new base
|
// Define a minimal number of wanted ships in the seas reaching this new base
|
||||||
var index = gameState.ai.accessibility.landPassMap[bestIdx];
|
var index = gameState.ai.accessibility.landPassMap[bestIdx];
|
||||||
@ -795,30 +797,39 @@ m.HQ.prototype.findEconomicCCLocation = function(gameState, resource, fromStrate
|
|||||||
|
|
||||||
// Returns the best position to build a new Civil Centre
|
// Returns the best position to build a new Civil Centre
|
||||||
// Whose primary function would be to assure territorial continuity with our allies
|
// Whose primary function would be to assure territorial continuity with our allies
|
||||||
m.HQ.prototype.findStrategicCCLocation = function(gameState)
|
m.HQ.prototype.findStrategicCCLocation = function(gameState, template)
|
||||||
{
|
{
|
||||||
// This builds a map. The procedure is fairly simple.
|
// This builds a map. The procedure is fairly simple.
|
||||||
// We minimize the Sum((dist-300)**2) where the sum is on all allied CC
|
// We minimize the Sum((dist-300)**2) where the sum is on the three nearest allied CC
|
||||||
// with the constraints that all CC have dist > 200 and at least one have dist < 400
|
// with the constraints that all CC have dist > 200 and at least one have dist < 400
|
||||||
// This needs at least 2 CC. Otherwise, go back to economic CC.
|
// This needs at least 2 CC. Otherwise, go back to economic CC.
|
||||||
|
|
||||||
// TODO add CC foundations (needed for allied)
|
// TODO add CC foundations (needed for allied)
|
||||||
var ccEnts = gameState.getEntities().filter(API3.Filters.byClass("CivCentre")).toEntityArray();
|
var ccEnts = gameState.getEntities().filter(API3.Filters.byClass("CivCentre")).toEntityArray();
|
||||||
|
var ccList = [];
|
||||||
var numAllyCC = 0;
|
var numAllyCC = 0;
|
||||||
for (var cc of ccEnts)
|
for (var cc of ccEnts)
|
||||||
if (gameState.isPlayerAlly(cc.owner()))
|
{
|
||||||
numAllyCC += 1;
|
var ally = gameState.isPlayerAlly(cc.owner());
|
||||||
|
ccList.push({"pos": cc.position(), "ally": ally});
|
||||||
|
if (ally)
|
||||||
|
++numAllyCC;
|
||||||
|
}
|
||||||
if (numAllyCC < 2)
|
if (numAllyCC < 2)
|
||||||
return this.findEconomicCCLocation(gameState, "wood", true);
|
return this.findEconomicCCLocation(gameState, template, "wood", true);
|
||||||
|
|
||||||
Engine.ProfileStart("findStrategicCCLocation");
|
Engine.ProfileStart("findStrategicCCLocation");
|
||||||
|
|
||||||
// obstruction map
|
// obstruction map
|
||||||
var obstructions = m.createObstructionMap(gameState, 0);
|
var obstructions = m.createObstructionMap(gameState, 0, template);
|
||||||
obstructions.expandInfluences();
|
obstructions.expandInfluences();
|
||||||
|
|
||||||
var map = {};
|
|
||||||
var width = this.territoryMap.width;
|
var width = this.territoryMap.width;
|
||||||
|
var radius = Math.ceil(template.obstructionRadius() / gameState.cellSize);
|
||||||
|
var bestIdx = undefined;
|
||||||
|
var bestVal = undefined;
|
||||||
|
var currentVal, delta;
|
||||||
|
var distcc0, distcc1, distcc2;
|
||||||
|
|
||||||
for (var j = 0; j < this.territoryMap.length; ++j)
|
for (var j = 0; j < this.territoryMap.length; ++j)
|
||||||
{
|
{
|
||||||
@ -828,56 +839,68 @@ m.HQ.prototype.findStrategicCCLocation = function(gameState)
|
|||||||
var index = gameState.ai.accessibility.landPassMap[j];
|
var index = gameState.ai.accessibility.landPassMap[j];
|
||||||
if (!this.allowedRegions[index])
|
if (!this.allowedRegions[index])
|
||||||
continue;
|
continue;
|
||||||
|
// and with enough room around to build the cc
|
||||||
|
if (obstructions.map[j] <= radius)
|
||||||
|
continue;
|
||||||
|
|
||||||
// checking distances to other cc
|
// checking distances to other cc
|
||||||
var pos = [j%width+0.5, Math.floor(j/width)+0.5];
|
var pos = [j%width+0.5, Math.floor(j/width)+0.5];
|
||||||
pos = [gameState.cellSize*pos[0], gameState.cellSize*pos[1]];
|
pos = [gameState.cellSize*pos[0], gameState.cellSize*pos[1]];
|
||||||
var minDist = Math.min();
|
var minDist = Math.min();
|
||||||
var sumDelta = 0;
|
distcc0 = undefined;
|
||||||
for (var cc of ccEnts)
|
|
||||||
|
for (var cc of ccList)
|
||||||
{
|
{
|
||||||
var ccPos = cc.position();
|
var dist = API3.SquareVectorDistance(cc.pos, pos);
|
||||||
var dist = API3.SquareVectorDistance(ccPos, pos);
|
|
||||||
if (dist < 14000) // Reject if too near from any cc
|
if (dist < 14000) // Reject if too near from any cc
|
||||||
{
|
{
|
||||||
minDist = 0;
|
minDist = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!gameState.isPlayerAlly(cc.owner()))
|
if (!cc.ally)
|
||||||
continue;
|
continue;
|
||||||
if (dist < 40000) // Reject if quite near from ally cc
|
if (dist < 40000) // Reject if quite near from ally cc
|
||||||
{
|
{
|
||||||
minDist = 0;
|
minDist = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
var delta = Math.sqrt(dist) - 300;
|
|
||||||
if (cc.owner === PlayerID) // small preference territory continuity with our territory
|
|
||||||
delta = 1.05*delta; // rather than ally one
|
|
||||||
sumDelta += delta*delta;
|
|
||||||
if (dist < minDist)
|
if (dist < minDist)
|
||||||
minDist = dist;
|
minDist = dist;
|
||||||
|
|
||||||
|
if (!distcc0 || dist < distcc0)
|
||||||
|
{
|
||||||
|
distcc2 = distcc1;
|
||||||
|
distcc1 = distcc0;
|
||||||
|
distcc0 = dist;
|
||||||
|
}
|
||||||
|
else if (!distcc1 || dist < distcc1)
|
||||||
|
{
|
||||||
|
distcc2 = distcc1;
|
||||||
|
distcc1 = dist;
|
||||||
|
}
|
||||||
|
else if (!distcc2 || dist < distcc2)
|
||||||
|
distcc2 = dist;
|
||||||
}
|
}
|
||||||
if (minDist < 1 || (minDist > 170000 && !this.navalMap))
|
if (minDist < 1 || (minDist > 170000 && !this.navalMap))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
map[j] = 10 + sumDelta;
|
delta = Math.sqrt(distcc0) - 300; // favor a distance of 300
|
||||||
|
currentVal = delta*delta;
|
||||||
|
delta = Math.sqrt(distcc1) - 300;
|
||||||
|
currentVal += delta*delta;
|
||||||
|
if (distcc2)
|
||||||
|
{
|
||||||
|
delta = Math.sqrt(distcc2) - 300;
|
||||||
|
currentVal += delta*delta;
|
||||||
|
}
|
||||||
// disfavor border of the map
|
// disfavor border of the map
|
||||||
if (this.borderMap.map[j] === 1)
|
if (this.borderMap.map[j] === 1)
|
||||||
map[j] = map[j] + 10000;
|
currentVal += 10000;
|
||||||
}
|
|
||||||
|
|
||||||
var bestIdx = undefined;
|
if (bestVal !== undefined && currentVal > bestVal)
|
||||||
var bestVal = undefined;
|
|
||||||
var radius = 6;
|
|
||||||
for (var i in map)
|
|
||||||
{
|
|
||||||
if (obstructions.map[+i] <= radius)
|
|
||||||
continue;
|
continue;
|
||||||
var v = map[i];
|
bestVal = currentVal;
|
||||||
if (bestVal !== undefined && v > bestVal)
|
bestIdx = j;
|
||||||
continue;
|
|
||||||
bestVal = v;
|
|
||||||
bestIdx = i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.Config.debug > 0)
|
if (this.Config.debug > 0)
|
||||||
@ -923,8 +946,10 @@ m.HQ.prototype.findMarketLocation = function(gameState, template)
|
|||||||
var obstructions = m.createObstructionMap(gameState, 0);
|
var obstructions = m.createObstructionMap(gameState, 0);
|
||||||
obstructions.expandInfluences();
|
obstructions.expandInfluences();
|
||||||
|
|
||||||
var map = {};
|
|
||||||
var width = this.territoryMap.width;
|
var width = this.territoryMap.width;
|
||||||
|
var bestIdx = undefined;
|
||||||
|
var bestVal = undefined;
|
||||||
|
var radius = Math.ceil(template.obstructionRadius() / gameState.cellSize);
|
||||||
|
|
||||||
for (var j = 0; j < this.territoryMap.length; ++j)
|
for (var j = 0; j < this.territoryMap.length; ++j)
|
||||||
{
|
{
|
||||||
@ -933,13 +958,12 @@ m.HQ.prototype.findMarketLocation = function(gameState, template)
|
|||||||
continue;
|
continue;
|
||||||
if (this.basesMap.map[j] === 0) // inaccessible cell
|
if (this.basesMap.map[j] === 0) // inaccessible cell
|
||||||
continue;
|
continue;
|
||||||
|
if (obstructions.map[j] <= radius) // check room around
|
||||||
|
continue;
|
||||||
|
|
||||||
var ix = j%width;
|
var index = gameState.ai.accessibility.landPassMap[j];
|
||||||
var iy = Math.floor(j/width);
|
var pos = [j%width+0.5, Math.floor(j/width)+0.5];
|
||||||
var pos = [ix+0.5, iy+0.5];
|
|
||||||
pos = [gameState.cellSize*pos[0], gameState.cellSize*pos[1]];
|
pos = [gameState.cellSize*pos[0], gameState.cellSize*pos[1]];
|
||||||
|
|
||||||
var index = gameState.ai.accessibility.getAccessValue(pos);
|
|
||||||
// checking distances to other markets
|
// checking distances to other markets
|
||||||
var maxDist = 0;
|
var maxDist = 0;
|
||||||
for (var market of markets)
|
for (var market of markets)
|
||||||
@ -956,22 +980,10 @@ m.HQ.prototype.findMarketLocation = function(gameState, template)
|
|||||||
}
|
}
|
||||||
if (maxDist == 0)
|
if (maxDist == 0)
|
||||||
continue;
|
continue;
|
||||||
|
if (bestVal !== undefined && maxDist < bestVal)
|
||||||
map[j] = maxDist;
|
|
||||||
}
|
|
||||||
|
|
||||||
var bestIdx = undefined;
|
|
||||||
var bestVal = undefined;
|
|
||||||
var radius = Math.ceil(template.obstructionRadius() / gameState.cellSize);
|
|
||||||
for (var i in map)
|
|
||||||
{
|
|
||||||
if (obstructions.map[+i] <= radius)
|
|
||||||
continue;
|
continue;
|
||||||
var v = map[i];
|
bestVal = maxDist;
|
||||||
if (bestVal !== undefined && v < bestVal)
|
bestIdx = j;
|
||||||
continue;
|
|
||||||
bestVal = v;
|
|
||||||
bestIdx = i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.Config.debug > 0)
|
if (this.Config.debug > 0)
|
||||||
@ -997,11 +1009,17 @@ m.HQ.prototype.findDefensiveLocation = function(gameState, template)
|
|||||||
var enemyStructures = gameState.getEnemyStructures().filter(API3.Filters.byClassesOr(["CivCentre", "Fortress", "Tower"])).toEntityArray();
|
var enemyStructures = gameState.getEnemyStructures().filter(API3.Filters.byClassesOr(["CivCentre", "Fortress", "Tower"])).toEntityArray();
|
||||||
|
|
||||||
// obstruction map
|
// obstruction map
|
||||||
var obstructions = m.createObstructionMap(gameState, 0);
|
var obstructions = m.createObstructionMap(gameState, 0, template);
|
||||||
obstructions.expandInfluences();
|
obstructions.expandInfluences();
|
||||||
|
|
||||||
var map = {};
|
|
||||||
var width = this.territoryMap.width;
|
var width = this.territoryMap.width;
|
||||||
|
var bestIdx = undefined;
|
||||||
|
var bestVal = undefined;
|
||||||
|
if (template.hasClass("Fortress"))
|
||||||
|
var radius = Math.floor(template.obstructionRadius() / gameState.cellSize) + 2;
|
||||||
|
else
|
||||||
|
var radius = Math.ceil(template.obstructionRadius() / gameState.cellSize);
|
||||||
|
|
||||||
for (var j = 0; j < this.territoryMap.length; ++j)
|
for (var j = 0; j < this.territoryMap.length; ++j)
|
||||||
{
|
{
|
||||||
// do not try if well inside or outside territory
|
// do not try if well inside or outside territory
|
||||||
@ -1011,10 +1029,10 @@ m.HQ.prototype.findDefensiveLocation = function(gameState, template)
|
|||||||
continue;
|
continue;
|
||||||
if (this.basesMap.map[j] === 0) // inaccessible cell
|
if (this.basesMap.map[j] === 0) // inaccessible cell
|
||||||
continue;
|
continue;
|
||||||
|
if (obstructions.map[j] <= radius) // check room around
|
||||||
|
continue;
|
||||||
|
|
||||||
var ix = j%width;
|
var pos = [j%width+0.5, Math.floor(j/width)+0.5];
|
||||||
var iy = Math.floor(j/width);
|
|
||||||
var pos = [ix+0.5, iy+0.5];
|
|
||||||
pos = [gameState.cellSize*pos[0], gameState.cellSize*pos[1]];
|
pos = [gameState.cellSize*pos[0], gameState.cellSize*pos[1]];
|
||||||
// checking distances to other structures
|
// checking distances to other structures
|
||||||
var minDist = Math.min();
|
var minDist = Math.min();
|
||||||
@ -1055,25 +1073,9 @@ m.HQ.prototype.findDefensiveLocation = function(gameState, template)
|
|||||||
}
|
}
|
||||||
if (minDist < 0)
|
if (minDist < 0)
|
||||||
continue;
|
continue;
|
||||||
|
if (bestVal !== undefined && minDist > bestVal)
|
||||||
map[j] = minDist;
|
|
||||||
}
|
|
||||||
|
|
||||||
var bestIdx = undefined;
|
|
||||||
var bestVal = undefined;
|
|
||||||
if (template.hasClass("Fortress"))
|
|
||||||
var radius = Math.floor(template.obstructionRadius() / gameState.cellSize) + 2;
|
|
||||||
else
|
|
||||||
var radius = Math.ceil(template.obstructionRadius() / gameState.cellSize);
|
|
||||||
|
|
||||||
for (var j in map)
|
|
||||||
{
|
|
||||||
if (obstructions.map[+j] <= radius)
|
|
||||||
continue;
|
continue;
|
||||||
var v = map[j];
|
bestVal = minDist;
|
||||||
if (bestVal !== undefined && v > bestVal)
|
|
||||||
continue;
|
|
||||||
bestVal = v;
|
|
||||||
bestIdx = j;
|
bestIdx = j;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1538,7 +1540,7 @@ m.HQ.prototype.updateTerritories = function(gameState)
|
|||||||
else if (this.basesMap.map[j] === 0)
|
else if (this.basesMap.map[j] === 0)
|
||||||
{
|
{
|
||||||
var index = gameState.ai.accessibility.landPassMap[j];
|
var index = gameState.ai.accessibility.landPassMap[j];
|
||||||
if (!gameState.ai.HQ.allowedRegions[index])
|
if (!this.allowedRegions[index])
|
||||||
continue;
|
continue;
|
||||||
var distmin = Math.min();
|
var distmin = Math.min();
|
||||||
var baseID = undefined;
|
var baseID = undefined;
|
||||||
|
@ -94,9 +94,9 @@ m.ConstructionPlan.prototype.findGoodPosition = function(gameState)
|
|||||||
if (template.hasClass("CivCentre"))
|
if (template.hasClass("CivCentre"))
|
||||||
{
|
{
|
||||||
if (this.metadata.type)
|
if (this.metadata.type)
|
||||||
var pos = gameState.ai.HQ.findEconomicCCLocation(gameState, this.metadata.type);
|
var pos = gameState.ai.HQ.findEconomicCCLocation(gameState, template, this.metadata.type);
|
||||||
else
|
else
|
||||||
var pos = gameState.ai.HQ.findStrategicCCLocation(gameState);
|
var pos = gameState.ai.HQ.findStrategicCCLocation(gameState, template);
|
||||||
|
|
||||||
if (pos)
|
if (pos)
|
||||||
return { "x": pos[0], "z": pos[1], "angle": 3*Math.PI/4, "xx": pos[0], "zz": pos[1], "base": 0 };
|
return { "x": pos[0], "z": pos[1], "angle": 3*Math.PI/4, "xx": pos[0], "zz": pos[1], "base": 0 };
|
||||||
|
Loading…
Reference in New Issue
Block a user