anchor.diff:  
   
   {
  +var
  +  GA_BUILDER_WORKER_COEF : Single = 8.516485214;
  +  GA_BUILDER_EXHAUSTION_ARR: array[WARE_MIN..WARE_MAX] of Single = (
  +    1.597312808, 2.605776548, 6.652187347, 4.734027863, 4.655752659, 2.305694342, 3.052431107, 2.866589546, 0.3297367692, 4.905310631, 4.637497902, 1.792099953, 1.758574486, 8.000164986, 4.496774197, 9.744778633, 8.297982216, 7.661552429, 1.597817659, 4.179779053, 1.837774515, 9.829838753, 5.807341576, 1.473491907, 5.093095303, 0.7045341134, 2.986746073, 1.279728413
  +  );
  +  GA_BUILDER_FRACTION_ARR: array[WARE_MIN..WARE_MAX] of Single = (
  +    52.44208145, 97.94073486, 81.27591705, 14.42814064, 39.30894089, 23.50471687, 3.592087984, 90.95751953, 5.030199528, 14.30461979, 15.02885342, 23.04277039, 38.70484161, 34.08721161, 46.43330002, 36.89776611, 36.55716705, 61.80127335, 52.2832222, 64.24739075, 1.925330043, 89.33174133, 29.77691841, 100, 38.04268646, 88.26511383, 46.45424652, 85.67434692
  +  );
  +  // Length 30
  +  //GA_BUILDER_HOUSE_ARR: array[HOUSE_MIN..HOUSE_MAX] of Single = (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29);
  +
  +  //function ChooseHousesToBuildGA(aWorkerCnt: Integer): Boolean;
  +
  +
  +function TKMCityBuilder.ChooseHousesToBuildGA(aWorkerCnt: Integer): Boolean;
  +const
  +  BASIC_HOUSES: set of THouseType = [ht_School, ht_Barracks, ht_Inn, ht_MarketPlace, ht_Store];
  +var
  +  MaxPlans: Integer;
  +  RequiredHouses: TRequiredHousesArray;
  +  WareBalance: TWareBalanceArray;
  +
  +
  +  function GetHouseToUnlock(var aUnlockProcedure: Boolean; var aHT, aFollowingHouse: THouseType): Boolean;
  +  var
  +    Output: Boolean;
  +    initHT: THouseType;
  +  begin
  +    Output := True;
  +    // Repeat until is avaiable house finded (to unlock target house)
  +    initHT := aHT;
  +    aFollowingHouse := ht_None;
  +    while Output AND not gHands[fOwner].Locks.HouseCanBuild(aHT) do
  +    begin
  +      aUnlockProcedure := True;
  +      if gHands[fOwner].Locks.HouseBlocked[aHT] then // House is blocked -> unlock impossible
  +        Output := False
  +      else
  +      begin
  +        aFollowingHouse := aHT;
  +        aHT := gRes.Houses[aHT].ReleasedBy; // House have to be unlocked by this house
  +      end;
  +    end;
  +    // Output = false only in case that house is already under construction OR is blocked by script / settings from the map editor
  +    Result := Output AND ( (initHT = aHT) OR (gHands[fOwner].Stats.GetHouseTotal(aHT) = 0) );
  +  end;
  +
  +
  +  function AddToConstruction(aHT: THouseType; aUnlockProcedureRequired: Boolean = False): TConstructionState;
  +  var
  +    UnlockProcedure: Boolean;
  +    FollowingHouse: THouseType;
  +    Output: TConstructionState;
  +  begin
  +    Output := cs_CannotPlaceHouse;
  +    UnlockProcedure := aUnlockProcedureRequired; // Unlock procedure = build house as soon as possible -> avoid to build house plan inside of tree (remove tree will take time)
  +    // Check if AI can build house (if is house blocked [by script] ignore it)
  +    if GetHouseToUnlock(UnlockProcedure, aHT, FollowingHouse) then
  +    begin
  +      if GA_PLANNER then
  +        Output := BuildHouse_GA_MODE(aHT)
  +      else
  +        Output := BuildHouse(UnlockProcedure OR (aHT = ht_Farm), False, False, aHT); // Farms should be build as soon as possible
  +    end
  +    else if (FollowingHouse <> ht_none) AND (gHands[fOwner].Stats.GetHouseQty(ht_School) > 0) then // Activate house reservation (only when is first school completed)
  +    begin
  +      Output := BuildHouse(True, True, False, FollowingHouse);
  +    end;
  +    Result := Output;
  +  end;
  +
  +  procedure SelectBestHouses();
  +  var
  +    I: Integer;
  +    WT, HighWT: TWareType;
  +    HighPriority: Single;
  +    WarePriorityArr: array[WARE_MIN..WARE_MAX] of Single;
  +  begin
  +    for WT := Low(WarePriorityArr) to High(WarePriorityArr) do
  +      WarePriorityArr[WT] := ( + WareBalance[WT].Fraction * GA_BUILDER_FRACTION_ARR[WT] *1000
  +                               - WareBalance[WT].Exhaustion * GA_BUILDER_EXHAUSTION_ARR[WT]
  +                             ) * RequiredHouses[ PRODUCTION[WT] ];
  +
  +    for I := 0 to 4 do
  +    begin
  +      if (MaxPlans <= 0) then
  +        Exit;
  +      HighPriority := 0;
  +      for WT := Low(WarePriorityArr) to High(WarePriorityArr) do
  +        if (HighPriority < WarePriorityArr[WT]) then
  +        begin
  +          HighPriority := WarePriorityArr[WT];
  +          HighWT := WT;
  +        end;
  +      if (HighPriority = 0) then
  +        Exit;
  +      WarePriorityArr[HighWT] := 0;
  +      // Try build required houses
  +      case AddToConstruction( PRODUCTION[HighWT] ) of
  +        cs_NoNodeAvailable: Exit;
  +        cs_HouseReservation, cs_RemoveTreeProcedure: begin end;
  +        cs_HousePlaced:
  +        begin
  +          MaxPlans := MaxPlans - 1;
  +          RequiredHouses[  PRODUCTION[HighWT]  ] := 0; // Make sure that next node will not scan this house in this tick
  +        end;
  +        cs_CannotPlaceHouse:
  +        begin
  +          RequiredHouses[  PRODUCTION[HighWT]  ] := 0; // Make sure that next node will not scan this house in this tick
  +        end;
  +      end;
  +
  +    end;
  +  end;
  +
  +  procedure CheckHouseReservation();
  +  var
  +    I: Integer;
  +    HT: THouseType;
  +  begin
  +    for HT := Low(fPlanner.PlannedHouses) to High(fPlanner.PlannedHouses) do
  +      for I := 0 to fPlanner.PlannedHouses[HT].Count - 1 do
  +        with fPlanner.PlannedHouses[HT].Plans[I] do
  +          if not Placed AND (HouseReservation OR RemoveTreeInPlanProcedure)
  +             AND (cs_HousePlaced = AddToConstruction(HT)) then
  +          begin
  +            MaxPlans := MaxPlans - 1;
  +            RequiredHouses[HT] := 0;
  +          end;
  +  end;
  +var
  +  HT: THouseType;
  +begin
  +  RequiredHouses := fPredictor.RequiredHouses;
  +  WareBalance := fPredictor.WareBalance;
  +
  +  CheckHouseReservation();
  +  MaxPlans := Ceil(aWorkerCnt / GA_BUILDER_WORKER_COEF);
  +  if (MaxPlans <= 0) then
  +    Exit;
  +
  +  // Basic houses (for city management)
  +  for HT in BASIC_HOUSES do
  +    if (RequiredHouses[HT] > 0) AND (AddToConstruction(HT, True) = cs_HousePlaced) then
  +      if (MaxPlans <= 0) then
  +        break;
  +
  +  SelectBestHouses();
  +
  +end;
  +
  +
  +function TKMCityBuilder.ChooseHousesToBuild(aMaxCnt: Integer): Boolean;
  +type
  +  TSetOfWare = set of TWareType;
  +const
  +  BASIC_HOUSES: set of THouseType = [ht_School, ht_Barracks, ht_Inn, ht_MarketPlace, ht_Store];
  +  BUILD_WARE: TSetOfWare = [wt_GoldOre, wt_Coal, wt_Gold, wt_Stone, wt_Trunk, wt_Wood];
  +  FOOD_WARE: TSetOfWare = [wt_Corn, wt_Flour, wt_Bread, wt_Pig, wt_Sausages, wt_Wine, wt_Fish];
  +  WEAPON_WARE: TSetOfWare = [wt_Skin, wt_Leather, wt_Horse, wt_IronOre, wt_Coal, wt_Steel, wt_Axe, wt_Bow, wt_Pike, wt_Armor, wt_Shield, wt_Sword, wt_Arbalet, wt_Hallebard, wt_MetalShield, wt_MetalArmor];
  +var
  +  RequiredHouses: TRequiredHousesArray;
  +  WareBalance: TWareBalanceArray;
  +
  +
  +  function GetHouseToUnlock(var aUnlockProcedure: Boolean; var aHT, aFollowingHouse: THouseType): Boolean;
  +  var
  +    Output: Boolean;
  +    initHT: THouseType;
  +  begin
  +    Output := True;
  +    // Repeat until is avaiable house finded (to unlock target house)
  +    initHT := aHT;
  +    aFollowingHouse := ht_None;
  +    while Output AND not gHands[fOwner].Locks.HouseCanBuild(aHT) do
  +    begin
  +      aUnlockProcedure := True;
  +      if gHands[fOwner].Locks.HouseBlocked[aHT] then // House is blocked -> unlock impossible
  +        Output := False
  +      else
  +      begin
  +        aFollowingHouse := aHT;
  +        aHT := gRes.Houses[aHT].ReleasedBy; // House have to be unlocked by this house
  +      end;
  +    end;
  +    // Output = false only in case that house is already under construction OR is blocked by script / settings from the map editor
  +    Result := Output AND ( (initHT = aHT) OR (gHands[fOwner].Stats.GetHouseTotal(aHT) = 0) );
  +  end;
  +
  +
  +  function AddToConstruction(aHT: THouseType; aUnlockProcedureRequired: Boolean = False): TConstructionState;
  +  var
  +    UnlockProcedure: Boolean;
  +    FollowingHouse: THouseType;
  +    Output: TConstructionState;
  +  begin
  +    Output := cs_CannotPlaceHouse;
  +    UnlockProcedure := aUnlockProcedureRequired; // Unlock procedure = build house as soon as possible -> avoid to build house plan inside of tree (remove tree will take time)
  +    // Check if AI can build house (if is house blocked [by script] ignore it)
  +    if GetHouseToUnlock(UnlockProcedure, aHT, FollowingHouse) then
  +    begin
  +      aMaxCnt := aMaxCnt - 1;
  +      if GA_PLANNER then
  +        Output := BuildHouse_GA_MODE(aHT)
  +      else
  +        Output := BuildHouse(UnlockProcedure, False, aHT);
  +    end
  +    else if (FollowingHouse <> ht_none) AND (gHands[fOwner].Stats.GetHouseQty(ht_School) > 0) then // Activate house reservation
  +    begin
  +      Output := BuildHouse(True, True, FollowingHouse);
  +    end;
  +    Result := Output;
  +  end;
  +
  +  function SelectHouse(const aSetOfWare: TSetOfWare): Boolean;
  +  const
  +    FRACTION_COEF = 3.0;
  +  var
  +    Output: Boolean;
  +    I: Integer;
  +    Priority, POM_Priority: Single;
  +    Ware, WT, POM_WT: TWareType;
  +    WareOrder: array[0..5] of TWareType;
  +    WarePriority: array[0..5] of Single;
  +  begin
  +    Output := False;
  +    // Basic producing houses (secure resources for building)
  +    for I := Low(WareOrder) to High(WareOrder) do
  +    begin
  +      WareOrder[I] := wt_None;
  +      WarePriority[I] := 0; // Doesn't have to be initialized but in this case compilation throws warning
  +    end;
  +    // Find the most required house to be build
  +    for Ware in aSetOfWare do
  +    begin
  +      WT := Ware;
  +      if (RequiredHouses[ PRODUCTION[WT] ] > 0) then
  +      begin
  +        Priority := WareBalance[WT].Exhaustion - WareBalance[WT].Fraction * FRACTION_COEF;
  +        for I := Low(WareOrder) to High(WareOrder) do
  +          if (WT = wt_None) then
  +            break
  +          else if (WareOrder[I] = wt_None) OR (Priority < WarePriority[I]) then // Buble sort is best for few elements
  +          begin
  +            POM_WT := WT;
  +            WT := WareOrder[I];
  +            WareOrder[I] := POM_WT;
  +            POM_Priority := Priority;
  +            Priority := WarePriority[I];
  +            WarePriority[I] := POM_Priority;
  +          end;
  +      end;
  +    end;
  +    // Try build required houses
  +    for I := Low(WareOrder) to High(WareOrder) do
  +    begin
  +      if (WareOrder[I] = wt_None) then
  +        break;
  +      case AddToConstruction(PRODUCTION[ WareOrder[I] ]) of
  +        cs_NoNodeAvailable: break;
  +        cs_HouseReservation, cs_RemoveTreeProcedure: Output := True;
  +        cs_HousePlaced:
  +        begin
  +          Output := True;
  +          aMaxCnt := aMaxCnt - 1;
  +          if (aMaxCnt <= 0) then
  +            break;
  +          RequiredHouses[  PRODUCTION[ WareOrder[I] ]  ] := 0; // Make sure that next node will not scan this house in this tick
  +        end;
  +        cs_CannotPlaceHouse:
  +        begin
  +          RequiredHouses[  PRODUCTION[ WareOrder[I] ]  ] := 0; // Make sure that next node will not scan this house in this tick
  +          //Dec(aRequiredHouses[  PRODUCTION[ WareOrder[I] ]  ]);
  +        end;
  +      end;
  +    end;
  +    Result := Output;
  +  end;
  +
  +  procedure CheckHouseReservation();
  +  var
  +    I: Integer;
  +    HT: THouseType;
  +  begin
  +    for HT := Low(fPlanner.PlannedHouses) to High(fPlanner.PlannedHouses) do
  +      for I := 0 to fPlanner.PlannedHouses[HT].Count - 1 do
  +        with fPlanner.PlannedHouses[HT].Plans[I] do
  +          if not Placed AND (HouseReservation OR RemoveTreeInPlanProcedure)
  +             AND (cs_HousePlaced = AddToConstruction(HT)) then
  +          begin
  +            aMaxCnt := aMaxCnt - 1;
  +            RequiredHouses[HT] := 0;
  +          end;
  +  end;
  +var
  +  Output: Boolean;
  +  POMCoal: Integer;
  +  HT: THouseType;
  +begin
  +  Output := False;
  +  RequiredHouses := fPredictor.RequiredHouses;
  +  WareBalance := fPredictor.WareBalance;
  +
  +  CheckHouseReservation();
  +  if (aMaxCnt <= 0) then
  +    Exit;
  +
  +  // Basic houses (for city management)
  +  for HT in BASIC_HOUSES do
  +    if (RequiredHouses[HT] > 0) AND (AddToConstruction(HT, True) = cs_HousePlaced) then
  +    begin
  +      Output := True;
  +      if (aMaxCnt <= 0) then
  +        break;
  +    end;
  +
  +  WareBalance[wt_Trunk].Fraction := Max(0, RequiredHouses[ht_Woodcutters] - gHands[fOwner].Stats.GetHouseQty(ht_Woodcutters) - 4);
  +  POMCoal := RequiredHouses[ht_CoalMine]; // Coal is used by resource (Gold) and by weapon division -> extract just Gold requirements
  +  RequiredHouses[ht_CoalMine] := Max(0,gHands[fOwner].Stats.GetHouseTotal(ht_GoldMine)-gHands[fOwner].Stats.GetHouseTotal(ht_CoalMine));
  +  RequiredHouses[ht_Woodcutters] := Max(0,RequiredHouses[ht_Woodcutters] - Round(Byte(WareBalance[wt_Gold].Exhaustion < 20) * RequiredHouses[ht_Woodcutters] * 0.5));
  +  if (aMaxCnt > 0) AND SelectHouse(BUILD_WARE) then
  +    Output := True;
  +
  +  // Make sure that gold will be produced (stones and wood are fines because of initial influence and order of construction)
  +  //if (gHands[fOwner].Stats.GetWareBalance(wt_Wood) < 10) AND (WareBalance[wt_Gold].Exhaustion < 20) then
  +  if (gHands[fOwner].Stats.GetWareBalance(wt_Wood) < 10) then
  +    Exit;
  +
  +  // Now return coal count back to original values
  +  WareBalance[wt_Coal].Fraction := (gHands[fOwner].Stats.GetHouseTotal(ht_CoalMine) - RequiredHouses[ht_CoalMine]) / POMCoal;
  +  RequiredHouses[ht_CoalMine] := POMCoal;
  +  if (aMaxCnt > 0) then
  +  begin
  +    Output := SelectHouse(FOOD_WARE);
  +    SelectHouse(WEAPON_WARE);
  +    SelectHouse(FOOD_WARE);
  +  end;
  +
  +  Result := Output;
  +end;
  +
   procedure TKMCityBuilder.UpdateBuildNode(var aNode: TBuildNode);
     function IsPlan(aPoint: TKMPoint; aLock: TTileLock; aField: TFieldType): Boolean;
     begin
  
positive.code:   end
    else
    begin
      // new house cannot be added
    end;
    Result := Output
  end;
  
  
  function TKMCityBuilder.ChooseHousesToBuild(aMaxCnt: Integer): Boolean;
  type
    TSetOfWare = set of TWareType;
  const
    BASIC_HOUSES: set of THouseType = [ht_School, ht_Barracks, ht_Inn, ht_MarketPlace, ht_Store];
    BUILD_WARE: TSetOfWare = [wt_GoldOre, wt_Coal, wt_Gold, wt_Stone, wt_Trunk, wt_Wood];
    FOOD_WARE: TSetOfWare = [wt_Corn, wt_Flour, wt_Bread, wt_Pig, wt_Sausages, wt_Wine, wt_Fish];
    WEAPON_WARE: TSetOfWare = [wt_Skin, wt_Leather, wt_Horse, wt_IronOre, wt_Coal, wt_Steel, wt_Axe, wt_Bow, wt_Pike, wt_Armor, wt_Shield, wt_Sword, wt_Arbalet, wt_Hallebard, wt_MetalShield, wt_MetalArmor];
  var
    RequiredHouses: TRequiredHousesArray;
    WareBalance: TWareBalanceArray;
  
  
negative.code:   // Build roads
    procedure BuildRoad();
    var
      I, ActiveWorkers: Integer;
    begin
      ActiveWorkers := 0;
      with aNode do
      begin
        // Remove elements of exist road from list
        for I := FieldList.Count - 1 downto 0 do
          if IsCompletedRoad(FieldList.Items[I]) then
          begin
            UnlockPointOfNode(FieldList.Items[I], True);
            FieldList.Delete(I);
          end
          else if not ShortcutMode then
  