Ticket #3586: headquarters-v3.patch

File headquarters-v3.patch, 10.4 KB (added by mimo, 8 years ago)
  • binaries/data/mods/public/simulation/ai/petra/config.js

     
    3030        "targetNumWorkers" : 40, // dummy, will be changed later
    3131        "targetNumTraders" : 5, // Target number of traders
    3232        "targetNumFishers" : 1, // Target number of fishers per sea
    33         "femaleRatio" : 0.5, // fraction of females among the workforce
     33        "supportRatio" : 0.5, // fraction of support workers among the workforce
    3434        "provisionFields" : 2
    3535    };
    3636
     
    125125    if (this.difficulty < 2)
    126126    {
    127127        this.Economy.cityPhase = 240000;
    128         this.Economy.femaleRatio = 0.7;
     128        this.Economy.supportRatio = 0.7;
    129129        this.Economy.provisionFields = 1;
    130130        this.Military.numWoodenTowers = (this.personality.defensive > 0.66) ? 1 : 0;
    131131    }
     
    132132    else if (this.difficulty < 3)
    133133    {
    134134        this.Economy.cityPhase = 1800;
    135         this.Economy.femaleRatio = 0.6;
     135        this.Economy.supportRatio = 0.6;
    136136        this.Economy.provisionFields = 1;
    137137        this.Military.numWoodenTowers = (this.personality.defensive > 0.66) ? 1 : 0;
    138138    }
     
    154154            this.Military.popForBarracks1 = 12;
    155155            this.Economy.popForTown = 55;
    156156            this.Economy.popForMarket = 60;
    157             this.Economy.femaleRatio = 0.3;
     157            this.Economy.supportRatio = 0.3;
    158158            this.priorities.defenseBuilding = 60;
    159159        }
    160160    }
  • binaries/data/mods/public/simulation/ai/petra/headquarters.js

     
    2929
    3030    // workers configuration
    3131    this.targetNumWorkers = this.Config.Economy.targetNumWorkers;
    32     this.femaleRatio = this.Config.Economy.femaleRatio;
     32    this.supportRatio = this.Config.Economy.supportRatio;
    3333
    3434    this.lastTerritoryUpdate = -1;
    3535    this.stopBuilding = new Map(); // list of buildings to stop (temporarily) production because no room
     
    211211            ent.setMetadata(PlayerID, "role", undefined);
    212212            ent.setMetadata(PlayerID, "subrole", undefined);
    213213            ent.setMetadata(PlayerID, "plan", undefined);
    214             ent.setMetadata(PlayerID, "PartOfArmy", undefined);     
     214            ent.setMetadata(PlayerID, "PartOfArmy", undefined);
    215215            if (ent.hasClass("Trader"))
    216216            {
    217217                ent.setMetadata(PlayerID, "role", "trader");
    218218                ent.setMetadata(PlayerID, "route", undefined);
    219219            }
    220             if (ent.hasClass("Female") || ent.hasClass("CitizenSoldier"))
     220            if (ent.hasClass("Worker"))
    221221            {
    222222                ent.setMetadata(PlayerID, "role", "worker");
    223223                ent.setMetadata(PlayerID, "subrole", "idle");
     
    379379// Called by the "town phase" research plan once it's started
    380380m.HQ.prototype.OnTownPhase = function(gameState)
    381381{
    382     if (this.Config.difficulty > 2 && this.femaleRatio > 0.4)
    383         this.femaleRatio = 0.4;
     382    if (this.Config.difficulty > 2 && this.supportRatio > 0.4)
     383        this.supportRatio = 0.4;
    384384
    385385    var phaseName = gameState.getTemplate(gameState.townPhase()).name();
    386386    m.chatNewPhase(gameState, phaseName, true);
     
    389389// Called by the "city phase" research plan once it's started
    390390m.HQ.prototype.OnCityPhase = function(gameState)
    391391{
    392     if (this.Config.difficulty > 2 && this.femaleRatio > 0.3)
    393         this.femaleRatio = 0.3;
     392    if (this.Config.difficulty > 2 && this.supportRatio > 0.3)
     393        this.supportRatio = 0.3;
    394394
    395395    // increase the priority of defense buildings to free this queue for our first fortress
    396396    gameState.ai.queueManager.changePriority("defenseBuilding", 2*this.Config.priorities.defenseBuilding);
     
    399399    m.chatNewPhase(gameState, phaseName, true);
    400400};
    401401
    402 // This code trains females and citizen workers, trying to keep close to a ratio of females/CS
    403 // TODO: this should choose a base depending on which base need workers
    404 // TODO: also there are several things that could be greatly improved here.
     402// This code trains citizen workers, trying to keep close to a ratio of worker/soldiers
    405403m.HQ.prototype.trainMoreWorkers = function(gameState, queues)
    406404{
    407     // Count the workers in the world and in progress
    408     var numFemales = gameState.countEntitiesAndQueuedByType(gameState.applyCiv("units/{civ}_support_female_citizen"), true);
     405    // default template
     406    var requirementsDef = [["cost", 1], ["costsResource", 1, "food"]];
     407    var classesDef = ["Support", "Worker"];
     408    var templateDef = this.findBestTrainableUnit(gameState, classesDef, requirementsDef);
    409409
    410410    // counting the workers that aren't part of a plan
    411     var numWorkers = 0;
     411    var numberOfWorkers = 0;   // all workers
     412    var numberOfSupports = 0;  // only support workers (i.e. non fighting)
    412413    gameState.getOwnUnits().forEach (function (ent) {
    413414        if (ent.getMetadata(PlayerID, "role") == "worker" && ent.getMetadata(PlayerID, "plan") == undefined)
    414             ++numWorkers;
     415        {
     416            ++numberOfWorkers;
     417            if (ent.hasClass("Support"))
     418                ++numberOfSupports;
     419        }
    415420    });
    416     var numInTraining = 0;
     421    var numberInTraining = 0;
    417422    gameState.getOwnTrainingFacilities().forEach(function(ent) {
    418423        ent.trainingQueue().forEach(function(item) {
     424            numberInTraining += item.count;
    419425            if (item.metadata && item.metadata.role && item.metadata.role == "worker" && item.metadata.plan == undefined)
    420                 numWorkers += item.count;
    421             numInTraining += item.count;
     426            {
     427                numberOfWorkers += item.count;
     428                if (ent.hasClass("Support"))
     429                    numberOfSupports += item.count;
     430            }
    422431        });
    423432    });
    424433
    425434    // Anticipate the optimal batch size when this queue will start
    426     // and adapt the batch size of the first and second queued workers and females to the present population
     435    // and adapt the batch size of the first and second queued workers to the present population
    427436    // to ease a possible recovery if our population was drastically reduced by an attack
    428437    // (need to go up to second queued as it is accounted in queueManager)
    429     var size = numWorkers < 12 ? 1 : Math.min(5, Math.ceil(numWorkers / 10));
     438    var size = numberOfWorkers < 12 ? 1 : Math.min(5, Math.ceil(numberOfWorkers / 10));
    430439    if (queues.villager.plans[0])
    431440    {
    432441        queues.villager.plans[0].number = Math.min(queues.villager.plans[0].number, size);
     
    440449            queues.citizenSoldier.plans[1].number = Math.min(queues.citizenSoldier.plans[1].number, size);
    441450    }
    442451
    443     var numQueuedF = queues.villager.countQueuedUnits();
    444     var numQueuedS = queues.citizenSoldier.countQueuedUnits();
    445     var numQueued = numQueuedS + numQueuedF;
    446     var numTotal = numWorkers + numQueued;
     452    var numberOfQueuedSupports = queues.villager.countQueuedUnits();
     453    var numberOfQueuedSoldiers = queues.citizenSoldier.countQueuedUnits();
     454    var numberQueued = numberOfQueuedSupports + numberOfQueuedSoldiers;
     455    var numberTotal = numberOfWorkers + numberQueued;
    447456
    448     if (this.saveResources && numTotal > this.Config.Economy.popForTown + 10)
     457    if (this.saveResources && numberTotal > this.Config.Economy.popForTown + 10)
    449458        return;
    450     if (numTotal > this.targetNumWorkers || (numTotal >= this.Config.Economy.popForTown &&
     459    if (numberTotal > this.targetNumWorkers || (numberTotal >= this.Config.Economy.popForTown &&
    451460        gameState.currentPhase() == 1 && !gameState.isResearching(gameState.townPhase())))
    452461        return;
    453     if (numQueued > 50 || (numQueuedF > 20 && numQueuedS > 20) || numInTraining > 15)
     462    if (numberQueued > 50 || (numberOfQueuedSupports > 20 && numberOfQueuedSoldiers > 20) || numberInTraining > 15)
    454463        return;
    455464
    456     // default template
    457     var templateDef = gameState.applyCiv("units/{civ}_support_female_citizen");
    458465    // Choose whether we want soldiers instead.
    459     let femaleRatio = (gameState.isDisabledTemplates(gameState.applyCiv("structures/{civ}_field")) ? Math.min(this.femaleRatio, 0.2) : this.femaleRatio);
     466    let supportRatio = (gameState.isDisabledTemplates(gameState.applyCiv("structures/{civ}_field")) ? Math.min(this.supportRatio, 0.2) : this.supportRatio);
    460467    let template;
    461     if (!gameState.templates[templateDef] || ((numFemales+numQueuedF) > 8 && (numFemales+numQueuedF)/numTotal > femaleRatio))
     468    if ((numberOfSupports + numberOfQueuedSupports) > 8 && (numberOfSupports + numberOfQueuedSupports)/numberTotal > supportRatio)
    462469    {
    463470        let requirements;
    464         if (numTotal < 45)
     471        if (numberTotal < 45)
    465472            requirements = [ ["cost", 1], ["speed", 0.5], ["costsResource", 0.5, "stone"], ["costsResource", 0.5, "metal"]];
    466473        else
    467474            requirements = [ ["strength", 1] ];
    468475
     476        let classes = ["CitizenSoldier", "Infantry"];
    469477        let proba = Math.random();
    470         if (proba < 0.6)
    471         {   // we require at least 30% ranged and 30% melee
    472             let classes = proba < 0.3 ? ["CitizenSoldier", "Infantry", "Ranged"] : ["CitizenSoldier", "Infantry", "Melee"];
    473             template = this.findBestTrainableUnit(gameState, classes, requirements);
    474         }
    475         if (!template)
    476             template = this.findBestTrainableUnit(gameState, ["CitizenSoldier", "Infantry"], requirements);
     478        //  we require at least 30% ranged and 30% melee
     479        if ( proba < 0.3 )
     480            classes.push("Ranged")
     481        else if ( proba < 0.6 )
     482            classes.push("Melee");
     483
     484        template = this.findBestTrainableUnit(gameState, classes, requirements);
    477485    }
    478     if (!template && gameState.templates[templateDef])
    479         template = templateDef;
    480486
     487    // If the template variable is empty, the default unit (Support unit)
     488    // would be used in the next turn
     489    //
    481490    // base "0" means "auto"
    482     if (template === gameState.applyCiv("units/{civ}_support_female_citizen"))
    483         queues.villager.addPlan(new m.TrainingPlan(gameState, template, { "role": "worker", "base": 0 }, size, size));
     491    if (!template && templateDef)
     492        queues.villager.addPlan(new m.TrainingPlan(gameState, templateDef, { "role": "worker", "base": 0 }, size, size));
    484493    else if (template)
    485494        queues.citizenSoldier.addPlan(new m.TrainingPlan(gameState, template, { "role": "worker", "base": 0 }, size, size));
    486495};
     
    504513    var availableResources = gameState.ai.queueManager.getAvailableResources(gameState); // available (gathered) resources
    505514    for (let type in remainingResources)
    506515    {
    507         if (type === "food")
    508             continue;
    509516        if (availableResources[type] > 800)
    510517            continue;
    511518        if (remainingResources[type] > 800)
     
    638645        }
    639646        this.turnCache.gatherRates = true;
    640647    }
    641    
     648
    642649    return this.currentRates;
    643650};
    644651
     
    20652072        "wantedRates": this.wantedRates,
    20662073        "currentRates": this.currentRates,
    20672074        "lastFailedGather": this.lastFailedGather,
    2068         "femaleRatio": this.femaleRatio,
     2075        "supportRatio": this.supportRatio,
    20692076        "targetNumWorkers": this.targetNumWorkers,
    20702077        "lastTerritoryUpdate": this.lastTerritoryUpdate,
    20712078        "stopBuilding": this.stopBuilding,