AI improvements

- TKMayor
- CheckUnitCount - the adaptive recruitment of serf (it works better than fixed count of serfs per a city):
+ check to be sure that we have enough gold left for self-sufficient city (gold for a Metallurgist / Miner) because sometimes get AI stuck;
- Code:
Output := Max(0, gHands[fOwner].Stats.GetUnitQty(ut_Worker) - gHands[fOwner].Stats.GetUnitQty(ut_Serf)); for I := 0 to p.Units.Count - 1 do if not gHands[fOwner].Units[I].IsDeadOrDying AND (gHands[fOwner].Units[I] is TKMUnitSerf) AND (gHands[fOwner].Units[I].UnitTask = nil) then Exit; Output := Output + 1;
- GetMaxPlans - the adaptive addition of plan count (it really helps the AI to build the city faster):
- Code:
Output := 0; FreeWorkers := 0; for I := 0 to gHands[fOwner].Units.Count - 1 do if not gHands[fOwner].Units[I].IsDeadOrDying AND (gHands[fOwner].Units[I] is TKMUnitWorker) AND (gHands[fOwner].Units[I].UnitTask = nil) then Inc(FreeWorkers); if FreeWorkers <> 0 then Output := Max(1, FreeWorkers >> 3);
- CheckUnitCount - the adaptive recruitment of serf (it works better than fixed count of serfs per a city):
- TKMayorBalance
- AfterMissionInit - ware distribution: the AI is without gold powerless + everyone in MP does it
- Append - the array of priorities for a specific house (ht_School, ht_Metallurgists, etc.)
- UpdateBalanceCore - we don't need Inn at the start of the game when it slows down construction and takes resources
- UpdateBalanceMaterials - the adaptive variables StoneNeed and WoodNeed depending on the number of workers. For example:
- TKMCityPlanner
- Simple Snap function - a sort of "snap" provides already gAIFields.Influences.Ownership. However, there is not consideration of roads and other houses. The solution is really simple - just add the snap function to Bid criterium.
where fHousesSurroundings is an array of vectors which will move Loc of the specific building to 1 tile from the house plan.
- Code:
Price := 0; for I := Low(fHousesSurroundings[aHouse].FirstTile) to High(fHousesSurroundings[aHouse].FirstTile) do begin Y := aLoc.Y + fHousesSurroundings[aHouse].FirstTile[I].Y; X := aLoc.X + fHousesSurroundings[aHouse].FirstTile[I].X; // Snap to no-build areas if [tpBuild] * gTerrain.Land[Y,X].Passability = [] then Price := Price + NO_BUILD_PRICE; // Snap to roads if (([tpWalkRoad] * gTerrain.Land[Y,X].Passability <> []) OR (gTerrain.Land[Y, X].TileLock = tlRoadWork)) then Price := Price + ROAD_PRICE; end;
- BuildWineFields / BuildFarmFields (moved from Mayor) - don't build fields in the avoidBuilding area: gAIFields.Influences.AvoidBuilding[Y,X] = 0. For WineFields there can be used close surrounding tiles around house - it will not waste space.
- NextToTrees - I reworked it through findNearest method and implemented with MaxMin cluster merging algorithm which will find a center of cluster with specific maximal distance. Woodcutters can now share a forest. I also added the support of the CuttingPoint. Thanks ZblCoder! We love you (or those who will play future versions of KaM)!
- NextToOre ......
- Simple Snap function - a sort of "snap" provides already gAIFields.Influences.Ownership. However, there is not consideration of roads and other houses. The solution is really simple - just add the snap function to Bid criterium.
- TPathFindingRoad
- IsWalkableTile - you missed tlRoadWork ... when AI makes multiple plan close to each other in one tick it may cause doubled roads.
- Code:
Result := (([tpMakeRoads, tpWalkRoad] * gTerrain.Land[aY,aX].Passability <> []) or (gTerrain.Land[aY, aX].TileLock = tlRoadWork)) and (gHands[fOwner].BuildList.FieldworksList.HasField(KMPoint(aX, aY)) in [ft_None, ft_Road]) and not gHands[fOwner].BuildList.HousePlanList.HasPlan(KMPoint(aX, aY));
- MovementCost - the snap to no-build areas (1 tile from house)
- IsWalkableTile - you missed tlRoadWork ... when AI makes multiple plan close to each other in one tick it may cause doubled roads.
- TPathFindingRoadShortcuts - the snap to houses and no-build areas
I tested included features in your most favourite only-pro and the best map which was ever made

Rules: the same number of workers (20), I did not change weapons demands so the AI produces weapons in booth versions ONLY with 1 weapons workshop and 1 weapon smithy. So the difference between the production is given only by increased speed of building, faster supplying and sort of optimized production.
Old version

New version

Detail of Shared Forest in nobuild array (in the left part of image; in the right top part are chop-only woodcutters)

Another example of shared forest

In protected area:

Old version - soldiers after 60 min

New version - soldiers after 60 min

Criterium of recruited soldiers was counted via script
Old AI: (115+130+110+99+113)/5 = 113.4
New AI: (252+242+204+194+236)/5 = 225.6
The improvement is roughly 98%. There is probably still huge potential ... for example I miss something like Eye / Supervisor class instead of "Blind" searching space for a house plan.