Changeset 465 for branches/highdpi/AI/StdAI/ToolAI.pas
- Timestamp:
- Nov 30, 2023, 10:16:14 PM (12 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/highdpi/AI/StdAI/ToolAI.pas
r349 r465 11 11 type 12 12 TGroupTransportPlan = record 13 LoadLoc, uixTransport, nLoad, TurnsEmpty, TurnsLoaded: integer;14 uixLoad: array[0..15] of integer;13 LoadLoc, uixTransport, nLoad, TurnsEmpty, TurnsLoaded: Integer; 14 uixLoad: array[0..15] of Integer; 15 15 end; 16 16 … … 18 18 TToolAI = class(TCustomAI) 19 19 protected 20 {$IFDEF DEBUG}DebugMap: array[0..lxmax * lymax - 1] of integer;{$ENDIF}21 22 function CenterOfEmpire: integer;20 {$IFDEF DEBUG}DebugMap: array[0..lxmax * lymax - 1] of Integer;{$ENDIF} 21 22 function CenterOfEmpire: Integer; 23 23 // tile that is in the middle of all own cities 24 24 25 function CityTaxBalance(cix: integer; const CityReport: TCityReport): integer;25 function CityTaxBalance(cix: Integer; const CityReport: TCityReport): Integer; 26 26 // calculates exact difference of income and maintenance cost for a single city 27 27 // positive result = income higher than maintenance … … 29 29 // respects production and food converted to gold 30 30 // CityReport must have been prepared before 31 procedure SumCities(TaxRate: integer; var TaxSum, ScienceSum: integer);31 procedure SumCities(TaxRate: Integer; var TaxSum, ScienceSum: Integer); 32 32 // calculates exact total tax and science income 33 33 // tax is reduced by maintenance (so might be negative) … … 46 46 procedure JobAssignment_Initialize; 47 47 // initialization, must be called first of the JobAssignment functions 48 procedure JobAssignment_AddJob(Loc, Job, Score: integer);48 procedure JobAssignment_AddJob(Loc, Job, Score: Integer); 49 49 // add job for settlers with certain score 50 50 // jobs include founding cities! 51 procedure JobAssignment_AddUnit(uix: integer);51 procedure JobAssignment_AddUnit(uix: Integer); 52 52 // add a settler unit to do jobs 53 53 procedure JobAssignment_Go; … … 57 57 // starting a job one turn earlier counts the same as 4 points of score 58 58 // function does not cancel jobs that are already started 59 function JobAssignment_GotJob(uix: integer): boolean;59 function JobAssignment_GotJob(uix: Integer): Boolean; 60 60 // can be called after JobAssignment_Go to find out whether 61 61 // a certain settler has been assigned a job to … … 64 64 // calculates formations and districts 65 65 66 function CheckStep(MoveStyle, TimeBeforeStep, CrossCorner: integer;67 var TimeAfterStep, RecoverTurns: integer; FromTile, ToTile: integer;68 IsCapture: boolean): integer;66 function CheckStep(MoveStyle, TimeBeforeStep, CrossCorner: Integer; 67 var TimeAfterStep, RecoverTurns: Integer; FromTile, ToTile: Integer; 68 IsCapture: Boolean): Integer; 69 69 // forecast single unit move between adjacent tiles 70 70 // format of TimeBeforeStep and TimeAfterStep: $1000*number of turns + $800-MP left … … 74 74 // CrossCorner=1 for long moves that cross the tile corner, =0 for short ones that don't 75 75 76 function GetMyMoveStyle(mix, Health: integer): integer;77 78 function Unit_MoveEx(uix, ToLoc: integer; Options: integer = 0): integer;76 function GetMyMoveStyle(mix, Health: Integer): Integer; 77 78 function Unit_MoveEx(uix, ToLoc: Integer; Options: Integer = 0): Integer; 79 79 80 80 procedure SeaTransport_BeginInitialize; … … 90 90 // - all transports have same capacity 91 91 // - no transport is damaged 92 procedure SeaTransport_AddLoad(uix: integer);93 procedure SeaTransport_AddTransport(uix: integer);94 procedure SeaTransport_AddDestination(Loc: integer);95 function SeaTransport_MakeGroupPlan(var TransportPlan: TGroupTransportPlan): boolean;92 procedure SeaTransport_AddLoad(uix: Integer); 93 procedure SeaTransport_AddTransport(uix: Integer); 94 procedure SeaTransport_AddDestination(Loc: Integer); 95 function SeaTransport_MakeGroupPlan(var TransportPlan: TGroupTransportPlan): Boolean; 96 96 // make plan for group of units to transport from a single loading location by a single transport 97 97 // the plan optimizes: … … 103 103 // function returns false if no more transports are possible 104 104 105 function CurrentMStrength(Domain: integer): integer; 106 end; 107 105 function CurrentMStrength(Domain: Integer): Integer; 106 end; 108 107 109 108 const … … 132 131 mxAdjacent = $00000001; 133 132 134 135 var 136 nContinent, nOcean, nDistrict: integer; 137 Formation: array[0..lxmax * lymax - 1] of integer; 133 var 134 nContinent, nOcean, nDistrict: Integer; 135 Formation: array[0..lxmax * lymax - 1] of Integer; 138 136 // water: ocean index, land: continent index, sorted by size 139 137 // territory unpassable due to peace treaty divides a continent 140 District: array[0..lxmax * lymax - 1] of integer;138 District: array[0..lxmax * lymax - 1] of Integer; 141 139 // index of coherent own territory, sorted by size 142 CityResult: array[0..nCmax - 1] of integer;143 144 Advancedness: array[0..nAdv - 1] of integer;140 CityResult: array[0..nCmax - 1] of Integer; 141 142 Advancedness: array[0..nAdv - 1] of Integer; 145 143 // total number of prerequisites for each advance 146 147 144 148 145 implementation … … 152 149 153 150 type 154 pinteger = ^ integer;151 pinteger = ^Integer; 155 152 156 153 var 157 154 // for JobAssignment 158 MaxScore: integer;159 TileJob, TileJobScore: array[0..lxmax * lymax - 1] of byte;160 JobLocOfSettler: array[0..nUmax - 1] of integer; // ToAssign = find job155 MaxScore: Integer; 156 TileJob, TileJobScore: array[0..lxmax * lymax - 1] of Byte; 157 JobLocOfSettler: array[0..nUmax - 1] of Integer; // ToAssign = find job 161 158 162 159 // for Transport 163 TransportMoveStyle, TransportCapacity, nTransportLoad: integer; 164 InitComplete, HaveDestinations: boolean; 165 uixTransportLoad, TransportAvailable: array[0..nUmax - 1] of integer; 166 TurnsAfterLoad: array[0..lxmax * lymax - 1] of shortint; 167 168 169 procedure ReplaceD(Start, Stop: pinteger; Raider, Twix: integer); 160 TransportMoveStyle, TransportCapacity, nTransportLoad: Integer; 161 InitComplete, HaveDestinations: Boolean; 162 uixTransportLoad, TransportAvailable: array[0..nUmax - 1] of Integer; 163 TurnsAfterLoad: array[0..lxmax * lymax - 1] of ShortInt; 164 165 procedure ReplaceD(Start, Stop: pinteger; Raider, Twix: Integer); 170 166 begin 171 167 while Start <> Stop do … … 177 173 end; 178 174 179 function NextZero(Start, Stop: pinteger; Mask: cardinal): pinteger;175 function NextZero(Start, Stop: pinteger; Mask: Cardinal): pinteger; 180 176 begin 181 177 while (Start <> Stop) and (Start^ and Mask <> 0) do … … 184 180 end; 185 181 186 187 function TToolAI.CenterOfEmpire: integer; 188 var 189 cix, Loc, x, y, sy, n: integer; 190 a, su, sv: double; 191 begin 192 n := 0; 182 function TToolAI.CenterOfEmpire: Integer; 183 var 184 cix, Loc, X, Y, sy, N: Integer; 185 A, su, sv: Double; 186 begin 187 N := 0; 193 188 sy := 0; 194 189 su := 0; … … 199 194 if Loc >= 0 then 200 195 begin 201 y:= Loc div G.lx;202 x := Loc - y* G.lx;203 Inc(sy, y);204 a := 2 * pi * x/ G.lx;205 su := su + cos( a);206 sv := sv + sin( a);207 Inc( n);208 end; 209 end; 210 a:= arctan2(sv, su);211 x := round(G.lx * a/ (2 * pi));212 while x>= G.lx do213 Dec( x, G.lx);214 while x< 0 do215 Inc( x, G.lx);216 Result := ((2 * sy + n) div (2 * n)) * G.lx + x;217 end; 218 219 function TToolAI.CityTaxBalance(cix: integer; const CityReport: TCityReport): integer;220 var 221 i: integer;196 Y := Loc div G.lx; 197 X := Loc - Y * G.lx; 198 Inc(sy, Y); 199 A := 2 * pi * X / G.lx; 200 su := su + cos(A); 201 sv := sv + sin(A); 202 Inc(N); 203 end; 204 end; 205 A := arctan2(sv, su); 206 X := round(G.lx * A / (2 * pi)); 207 while X >= G.lx do 208 Dec(X, G.lx); 209 while X < 0 do 210 Inc(X, G.lx); 211 Result := ((2 * sy + N) div (2 * N)) * G.lx + X; 212 end; 213 214 function TToolAI.CityTaxBalance(cix: Integer; const CityReport: TCityReport): Integer; 215 var 216 I: Integer; 222 217 begin 223 218 Result := 0; … … 234 229 Inc(Result, CityReport.FoodRep - CityReport.Eaten); 235 230 end; 236 for i:= nWonder to nImp - 1 do237 if MyCity[cix].Built[ i] > 0 then238 Dec(Result, Imp[ i].Maint);239 end; 240 241 procedure TToolAI.SumCities(TaxRate: integer; var TaxSum, ScienceSum: integer);242 var 243 cix, p1: integer;231 for I := nWonder to nImp - 1 do 232 if MyCity[cix].Built[I] > 0 then 233 Dec(Result, Imp[I].Maint); 234 end; 235 236 procedure TToolAI.SumCities(TaxRate: Integer; var TaxSum, ScienceSum: Integer); 237 var 238 cix, p1: Integer; 244 239 CityReport: TCityReport; 245 240 begin … … 247 242 ScienceSum := 0; 248 243 if RO.Government = gAnarchy then 249 exit;244 Exit; 250 245 for p1 := 0 to nPl - 1 do 251 246 if RO.Tribute[p1] <= RO.TributePaid[p1] then … … 263 258 end; 264 259 265 266 260 //------------------------------------------------------------------------------ 267 261 // City Tiles Processing … … 274 268 procedure TToolAI.OptimizeCityTiles; 275 269 var 276 cix: integer;270 cix: Integer; 277 271 begin 278 272 for cix := 0 to RO.nCity - 1 do … … 284 278 procedure TToolAI.GetCityProdPotential; 285 279 var 286 cix: integer;280 cix: Integer; 287 281 Advice: TCityTileAdviceData; 288 282 begin … … 292 286 begin 293 287 Advice.ResourceWeights := rwMaxProd; 294 Server(sGetCityTileAdvice, me, cix, Advice);288 Server(sGetCityTileAdvice, Me, cix, Advice); 295 289 CityResult[cix] := Advice.CityReport.ProdRep; // considers factory, but shouldn't 296 290 end; … … 299 293 procedure TToolAI.GetCityTradePotential; 300 294 var 301 cix: integer;295 cix: Integer; 302 296 Advice: TCityTileAdviceData; 303 297 begin … … 307 301 begin 308 302 Advice.ResourceWeights := rwMaxScience; 309 Server(sGetCityTileAdvice, me, cix, Advice);303 Server(sGetCityTileAdvice, Me, cix, Advice); 310 304 CityResult[cix] := Advice.CityReport.Trade; 311 305 end; 312 306 end; 313 314 307 315 308 //------------------------------------------------------------------------------ … … 321 314 procedure TToolAI.JobAssignment_Initialize; 322 315 begin 323 fillchar(JobLocOfSettler, RO.nUn * sizeof(integer), $FF); // -1324 fillchar(TileJob, MapSize, jNone);325 fillchar(TileJobScore, MapSize, 0);316 FillChar(JobLocOfSettler, RO.nUn * SizeOf(Integer), $FF); // -1 317 FillChar(TileJob, MapSize, jNone); 318 FillChar(TileJobScore, MapSize, 0); 326 319 MaxScore := 0; 327 320 end; 328 321 329 procedure TToolAI.JobAssignment_AddJob(Loc, Job, Score: integer);322 procedure TToolAI.JobAssignment_AddJob(Loc, Job, Score: Integer); 330 323 begin 331 324 if Score > 255 then … … 340 333 end; 341 334 342 procedure TToolAI.JobAssignment_AddUnit(uix: integer);343 begin 344 assert(MyModel[MyUnit[uix].mix].Kind in [mkSettler, mkSlaves]);335 procedure TToolAI.JobAssignment_AddUnit(uix: Integer); 336 begin 337 Assert(MyModel[MyUnit[uix].mix].Kind in [mkSettler, mkSlaves]); 345 338 JobLocOfSettler[uix] := ToAssign; 346 339 end; 347 340 348 function TToolAI.JobAssignment_GotJob(uix: integer): boolean;341 function TToolAI.JobAssignment_GotJob(uix: Integer): Boolean; 349 342 begin 350 343 Result := JobLocOfSettler[uix] >= 0; … … 354 347 const 355 348 DistanceScore = 4; 356 StepSizeByTerrain: array[0..11] of integer =349 StepSizeByTerrain: array[0..11] of Integer = 357 350 (0, 0, 1, 2, 1, 1, 0, 1, 0, 1, 1, 2); 358 351 //Oc-Sh-Gr-De-Pr-Tu-Ar-Sw-XX-Fo-Hi-Mo 359 352 var 360 353 uix, BestScore, BestCount, BestLoc, BestJob, BestDistance, TestLoc, 361 NextLoc, TestDistance, V8, TestScore, StepSize, MoveResult: integer;362 UnitsToAssign: boolean;354 NextLoc, TestDistance, V8, TestScore, StepSize, MoveResult: Integer; 355 UnitsToAssign: Boolean; 363 356 Adjacent: TVicinity8Loc; 364 357 SettlerOfJobLoc, DistToLoc: array[0..lxmax * lymax - 1] of smallint; 365 358 // DistToLoc is only defined where SettlerOfJobLoc>=0 366 TileChecked: array[0..lxmax * lymax - 1] of boolean;367 begin 368 fillchar(SettlerOfJobLoc, MapSize * 2, $FF); // -1359 TileChecked: array[0..lxmax * lymax - 1] of Boolean; 360 begin 361 FillChar(SettlerOfJobLoc, MapSize * 2, $FF); // -1 369 362 370 363 // keep up jobs that are already started … … 387 380 BestJob := jNone; 388 381 BestScore := -999999; 389 FillChar(TileChecked, MapSize * sizeof(boolean), False);382 FillChar(TileChecked, MapSize * SizeOf(Boolean), False); 390 383 Pile.Create(MapSize); 391 384 Pile.Put(MyUnit[uix].Loc, 0); // start search for new job at current location … … 406 399 and (Map[NextLoc] and (fUnit or fOwned) <> fUnit) // no foreign unit 407 400 and ((RO.Territory[NextLoc] < 0) or 408 (RO.Territory[NextLoc] = me)) // no foreign territory401 (RO.Territory[NextLoc] = Me)) // no foreign territory 409 402 and (Map[TestLoc] and Map[NextLoc] and fInEnemyZoC = 0) then 410 403 // move not prevented by ZoC … … 421 414 ((SettlerOfJobLoc[TestLoc] < 0) or (DistToLoc[TestLoc] > TestDistance)) then 422 415 begin 423 TestScore := integer(TileJobScore[TestLoc]) - DistanceScore * TestDistance;416 TestScore := Integer(TileJobScore[TestLoc]) - DistanceScore * TestDistance; 424 417 if TestScore > BestScore then 425 418 BestCount := 0; … … 469 462 Unit_StartJob(uix, TileJob[JobLocOfSettler[uix]]); 470 463 end; 471 end; // JobAssignment_Go 472 464 end; 473 465 474 466 //------------------------------------------------------------------------------ … … 477 469 procedure TToolAI.AnalyzeMap; 478 470 var 479 i, j, Loc, Loc1, V8, Count, Kind, MostIndex: integer;471 I, J, Loc, Loc1, V8, Count, Kind, MostIndex: Integer; 480 472 Adjacent: TVicinity8Loc; 481 473 IndexOfID: array[0..lxmax * lymax - 1] of smallint; 482 474 IDOfIndex: array[0..lxmax * lymax div 2 - 1] of smallint; 483 475 begin 484 fillchar(District, MapSize * 4, $FF);476 FillChar(District, MapSize * 4, $FF); 485 477 for Loc := 0 to MapSize - 1 do 486 478 if Map[Loc] and fTerrain = fUNKNOWN then … … 508 500 Formation[Loc], Formation[Loc1]); 509 501 end; 510 if (RO.Territory[Loc] = me) and (Map[Loc] and fTerrain >= fGrass) then502 if (RO.Territory[Loc] = Me) and (Map[Loc] and fTerrain >= fGrass) then 511 503 begin 512 504 District[Loc] := Loc; … … 553 545 Inc(Count); 554 546 end; 555 for i:= 0 to Count - 2 do556 begin 557 MostIndex := i;558 for j := i+ 1 to Count - 1 do559 if IndexOfID[IDOfIndex[ j]] > IndexOfID[IDOfIndex[MostIndex]] then560 MostIndex := j;561 if MostIndex <> ithen562 begin 563 j := IDOfIndex[i];564 IDOfIndex[ i] := IDOfIndex[MostIndex];565 IDOfIndex[MostIndex] := j;566 end; 567 end; 568 for i:= 0 to Count - 1 do569 IndexOfID[IDOfIndex[ i]] := i;547 for I := 0 to Count - 2 do 548 begin 549 MostIndex := I; 550 for J := I + 1 to Count - 1 do 551 if IndexOfID[IDOfIndex[J]] > IndexOfID[IDOfIndex[MostIndex]] then 552 MostIndex := J; 553 if MostIndex <> I then 554 begin 555 J := IDOfIndex[I]; 556 IDOfIndex[I] := IDOfIndex[MostIndex]; 557 IDOfIndex[MostIndex] := J; 558 end; 559 end; 560 for I := 0 to Count - 1 do 561 IndexOfID[IDOfIndex[I]] := I; 570 562 571 563 case Kind of … … 594 586 end; 595 587 end; 596 597 588 598 589 //------------------------------------------------------------------------------ … … 614 605 // other: | Basic | 0| Speed | X X X | MaxTerrType | 615 606 616 function TToolAI.GetMyMoveStyle(mix, Health: integer): integer;607 function TToolAI.GetMyMoveStyle(mix, Health: Integer): Integer; 617 608 begin 618 609 with MyModel[mix] do … … 623 614 begin 624 615 Inc(Result, (50 + (Speed - 150) * 13 shr 7) shl 8); //HeavyCost 625 if RO.Wonder[woShinkansen].EffectiveOwner <> me then616 if RO.Wonder[woShinkansen].EffectiveOwner <> Me then 626 617 Inc(Result, Speed * (4 * 1311) shr 17); // RailCost 627 if (RO.Wonder[woGardens].EffectiveOwner <> me) or618 if (RO.Wonder[woGardens].EffectiveOwner <> Me) or 628 619 (Kind = mkSettler) and (Speed >= 200) then 629 620 Inc(Result, msHostile); … … 640 631 begin 641 632 Result := Speed; 642 if RO.Wonder[woMagellan].EffectiveOwner = me then633 if RO.Wonder[woMagellan].EffectiveOwner = Me then 643 634 Inc(Result, 200); 644 635 if Health < 100 then … … 655 646 end; 656 647 657 function TToolAI.CheckStep(MoveStyle, TimeBeforeStep, CrossCorner: integer;658 var TimeAfterStep, RecoverTurns: integer; FromTile, ToTile: integer;659 IsCapture: boolean): integer;660 var 661 MoveCost, RecoverCost: integer;648 function TToolAI.CheckStep(MoveStyle, TimeBeforeStep, CrossCorner: Integer; 649 var TimeAfterStep, RecoverTurns: Integer; FromTile, ToTile: Integer; 650 IsCapture: Boolean): Integer; 651 var 652 MoveCost, RecoverCost: Integer; 662 653 begin 663 654 //IsCapture:=true; 664 assert(((FromTile and fTerrain <= fMountains) or (FromTile and655 Assert(((FromTile and fTerrain <= fMountains) or (FromTile and 665 656 fTerrain = fUNKNOWN)) and ((ToTile and fTerrain <= fMountains) or 666 657 (ToTile and fTerrain = fUNKNOWN))); … … 710 701 if ToTile and fPeace <> 0 then 711 702 Result := csCheckTerritory; 712 exit;703 Exit; 713 704 end; 714 705 end; … … 829 820 begin 830 821 Result := csForbiddenTile; 831 exit;822 Exit; 832 823 end; 833 824 end … … 878 869 // must wait for next turn 879 870 Result := csOk; 880 exit;871 Exit; 881 872 end; 882 873 end; … … 898 889 Result := csForbiddenTile; 899 890 end; 900 end; // CheckStep891 end; 901 892 902 893 (* 903 894 -------- Pathfinding Reference Implementation -------- 904 895 var 905 MoveStyle,V8,Loc,Time,NextLoc,NextTime,RecoverTurns: integer;896 MoveStyle,V8,Loc,Time,NextLoc,NextTime,RecoverTurns: Integer; 906 897 Adjacent: TVicinity8Loc; 907 Reached: array[0..lxmax*lymax-1] of boolean;908 begin 909 fillchar(Reached, MapSize, false);898 Reached: array[0..lxmax*lymax-1] of Boolean; 899 begin 900 FillChar(Reached, MapSize, False); 910 901 MoveStyle:=GetMyMoveStyle(MyUnit[uix].mix, MyUnit[uix].Health); 911 902 Pile.Create(MapSize); … … 915 906 // todo: check exit condition, e.g. whether destination reached 916 907 917 Reached[Loc]:= true;908 Reached[Loc]:=True; 918 909 V8_to_Loc(Loc, Adjacent); 919 910 for V8:=0 to 7 do … … 925 916 Pile.Put(NextLoc, NextTime+RecoverTurns*$1000); 926 917 csForbiddenTile: 927 Reached[NextLoc]:= true; // don't check moving there again918 Reached[NextLoc]:=True; // don't check moving there again 928 919 csCheckTerritory: 929 920 if RO.Territory[NextLoc]=RO.Territory[Loc] then … … 936 927 *) 937 928 938 function TToolAI.Unit_MoveEx(uix, ToLoc: integer; Options: integer): integer;929 function TToolAI.Unit_MoveEx(uix, ToLoc: Integer; Options: Integer): Integer; 939 930 var 940 931 Loc, NextLoc, Temp, FromLoc, EndLoc, Time, V8, MoveResult, RecoverTurns, 941 NextTime, MoveStyle: integer;932 NextTime, MoveStyle: Integer; 942 933 Adjacent: TVicinity8Loc; 943 PreLoc: array[0..lxmax * lymax - 1] of integer;944 Reached: array[0..lxmax * lymax - 1] of boolean;934 PreLoc: array[0..lxmax * lymax - 1] of Integer; 935 Reached: array[0..lxmax * lymax - 1] of Boolean; 945 936 begin 946 937 Result := eOk; 947 938 FromLoc := MyUnit[uix].Loc; 948 939 if FromLoc = ToLoc then 949 exit;940 Exit; 950 941 951 942 FillChar(Reached, MapSize, False); … … 1012 1003 begin 1013 1004 Result := MoveResult; 1014 break;1005 Break; 1015 1006 end; 1016 1007 end; … … 1020 1011 end; 1021 1012 1022 1023 1013 //------------------------------------------------------------------------------ 1024 1014 // Oversea Transport … … 1026 1016 procedure TToolAI.SeaTransport_BeginInitialize; 1027 1017 begin 1028 fillchar(TransportAvailable, RO.nUn * sizeof(integer), $FF); // -11018 FillChar(TransportAvailable, RO.nUn * SizeOf(Integer), $FF); // -1 1029 1019 InitComplete := False; 1030 1020 HaveDestinations := False; … … 1035 1025 end; 1036 1026 1037 procedure TToolAI.SeaTransport_AddLoad(uix: integer);1038 var 1039 i: integer;1040 begin 1041 assert(not InitComplete); // call order violation!1027 procedure TToolAI.SeaTransport_AddLoad(uix: Integer); 1028 var 1029 I: Integer; 1030 begin 1031 Assert(not InitComplete); // call order violation! 1042 1032 if Map[MyUnit[uix].Loc] and fTerrain < fGrass then 1043 exit;1044 for i:= 0 to nTransportLoad - 1 do1045 if uix = uixTransportLoad[ i] then1046 exit;1033 Exit; 1034 for I := 0 to nTransportLoad - 1 do 1035 if uix = uixTransportLoad[I] then 1036 Exit; 1047 1037 uixTransportLoad[nTransportLoad] := uix; 1048 1038 Inc(nTransportLoad); 1049 1039 end; 1050 1040 1051 procedure TToolAI.SeaTransport_AddTransport(uix: integer);1052 var 1053 MoveStyle: integer;1054 begin 1055 assert(not InitComplete); // call order violation!1056 assert(MyModel[MyUnit[uix].mix].Cap[mcSeaTrans] > 0);1041 procedure TToolAI.SeaTransport_AddTransport(uix: Integer); 1042 var 1043 MoveStyle: Integer; 1044 begin 1045 Assert(not InitComplete); // call order violation! 1046 Assert(MyModel[MyUnit[uix].mix].Cap[mcSeaTrans] > 0); 1057 1047 TransportAvailable[uix] := 1; 1058 1048 with MyModel[MyUnit[uix].mix] do … … 1068 1058 end; 1069 1059 1070 procedure TToolAI.SeaTransport_AddDestination(Loc: integer);1071 begin 1072 assert(not InitComplete); // call order violation!1060 procedure TToolAI.SeaTransport_AddDestination(Loc: Integer); 1061 begin 1062 Assert(not InitComplete); // call order violation! 1073 1063 Pile.Put(Loc, $800); 1074 1064 HaveDestinations := True; … … 1077 1067 procedure TToolAI.SeaTransport_EndInitialize; 1078 1068 var 1079 Loc0, Time0, V8, Loc1, ArriveTime, RecoverTurns: integer;1069 Loc0, Time0, V8, Loc1, ArriveTime, RecoverTurns: Integer; 1080 1070 Adjacent: TVicinity8Loc; 1081 1071 begin 1082 assert(not InitComplete); // call order violation!1072 Assert(not InitComplete); // call order violation! 1083 1073 InitComplete := True; 1084 1074 if HaveDestinations then 1085 1075 begin // calculate TurnsAfterLoad from destination locs 1086 fillchar(TurnsAfterLoad, MapSize, $FF); // -11076 FillChar(TurnsAfterLoad, MapSize, $FF); // -1 1087 1077 while Pile.Get(Loc0, Time0) do 1088 1078 begin // search backward … … 1109 1099 end; 1110 1100 1111 1112 1101 function TToolAI.SeaTransport_MakeGroupPlan( 1113 var TransportPlan: TGroupTransportPlan): boolean;1114 var 1115 V8, i, j, iPicked, uix, Loc0, Time0, Loc1, RecoverTurns, MoveStyle,1102 var TransportPlan: TGroupTransportPlan): Boolean; 1103 var 1104 V8, I, J, iPicked, uix, Loc0, Time0, Loc1, RecoverTurns, MoveStyle, 1116 1105 TurnsLoaded, TurnCount, tuix, tuix1, ArriveTime, TotalDelay, 1117 1106 BestTotalDelay, GroupCount, BestGroupCount, BestLoadLoc, FullMovementLoc, 1118 nSelectedLoad, f, OriginContinent, a, b: integer;1119 CompleteFlag, NotReachedFlag, ContinueUnit: cardinal;1120 IsComplete, ok, IsFirstLoc: boolean;1107 nSelectedLoad, F, OriginContinent, A, B: Integer; 1108 CompleteFlag, NotReachedFlag, ContinueUnit: Cardinal; 1109 IsComplete, ok, IsFirstLoc: Boolean; 1121 1110 StartLocPtr, ArrivedEnd: pinteger; 1122 1111 Adjacent: TVicinity8Loc; 1123 uixSelectedLoad: array[0..15] of integer;1124 tuixSelectedLoad: array[0..15] of integer;1125 Arrived: array[0..lxmax * lymax] of cardinal;1112 uixSelectedLoad: array[0..15] of Integer; 1113 tuixSelectedLoad: array[0..15] of Integer; 1114 Arrived: array[0..lxmax * lymax] of Cardinal; 1126 1115 ResponsibleTransport: array[0..lxmax * lymax - 1] of smallint; 1127 TurnsBeforeLoad: array[0..lxmax * lymax - 1] of shortint;1128 GroupComplete: array[0..lxmax * lymax - 1] of boolean;1129 begin 1130 assert(InitComplete); // call order violation!1116 TurnsBeforeLoad: array[0..lxmax * lymax - 1] of ShortInt; 1117 GroupComplete: array[0..lxmax * lymax - 1] of Boolean; 1118 begin 1119 Assert(InitComplete); // call order violation! 1131 1120 1132 1121 if HaveDestinations and (nTransportLoad > 0) then … … 1139 1128 for tuix := 0 to nTransportLoad - 1 do 1140 1129 begin 1141 Loc_to_ab(MyUnit[uix].Loc, MyUnit[uixTransportLoad[tuix]].Loc, a, b);1142 if (abs( a) <= 1) and (abs(b) <= 1) then1130 Loc_to_ab(MyUnit[uix].Loc, MyUnit[uixTransportLoad[tuix]].Loc, A, B); 1131 if (abs(A) <= 1) and (abs(B) <= 1) then 1143 1132 begin 1144 assert((a <> 0) or (b<> 0));1133 Assert((A <> 0) or (B <> 0)); 1145 1134 Inc(GroupCount); 1146 1135 end; … … 1156 1145 for tuix := nTransportLoad - 1 downto 0 do 1157 1146 begin 1158 Loc_to_ab(TransportPlan.LoadLoc, MyUnit[uixTransportLoad[tuix]].Loc, a, b);1159 if (abs( a) <= 1) and (abs(b) <= 1) then1147 Loc_to_ab(TransportPlan.LoadLoc, MyUnit[uixTransportLoad[tuix]].Loc, A, B); 1148 if (abs(A) <= 1) and (abs(B) <= 1) then 1160 1149 begin 1161 1150 TransportPlan.uixLoad[TransportPlan.nLoad] := uixTransportLoad[tuix]; … … 1164 1153 Inc(TransportPlan.nLoad); 1165 1154 if TransportPlan.nLoad = TransportCapacity then 1166 break;1155 Break; 1167 1156 end; 1168 1157 end; 1169 1158 Result := True; 1170 exit;1159 Exit; 1171 1160 end; 1172 1161 end; … … 1176 1165 begin 1177 1166 // select units from same continent 1178 fillchar(Arrived, 4 * nContinent, 0); // misuse Arrived as counter1167 FillChar(Arrived, 4 * nContinent, 0); // misuse Arrived as counter 1179 1168 for tuix := 0 to nTransportLoad - 1 do 1180 1169 begin 1181 assert(Map[MyUnit[uixTransportLoad[tuix]].Loc] and fTerrain >= fGrass);1182 f:= Formation[MyUnit[uixTransportLoad[tuix]].Loc];1183 if f>= 0 then1184 Inc(Arrived[ f]);1170 Assert(Map[MyUnit[uixTransportLoad[tuix]].Loc] and fTerrain >= fGrass); 1171 F := Formation[MyUnit[uixTransportLoad[tuix]].Loc]; 1172 if F >= 0 then 1173 Inc(Arrived[F]); 1185 1174 end; 1186 1175 OriginContinent := 0; 1187 for f:= 1 to nContinent - 1 do1188 if Arrived[ f] > Arrived[OriginContinent] then1189 OriginContinent := f;1176 for F := 1 to nContinent - 1 do 1177 if Arrived[F] > Arrived[OriginContinent] then 1178 OriginContinent := F; 1190 1179 nSelectedLoad := 0; 1191 1180 for tuix := 0 to nTransportLoad - 1 do … … 1196 1185 Inc(nSelectedLoad); 1197 1186 if nSelectedLoad = 16 then 1198 break;1187 Break; 1199 1188 end; 1200 1189 1201 1190 Pile.Create(MapSize); 1202 fillchar(ResponsibleTransport, MapSize * 2, $FF); // -11203 fillchar(TurnsBeforeLoad, MapSize, $FF); // -11191 FillChar(ResponsibleTransport, MapSize * 2, $FF); // -1 1192 FillChar(TurnsBeforeLoad, MapSize, $FF); // -1 1204 1193 ok := False; 1205 1194 for uix := 0 to RO.nUn - 1 do … … 1214 1203 Result := False; 1215 1204 Pile.Free; 1216 exit;1205 Exit; 1217 1206 end; 1218 1207 while Pile.Get(Loc0, Time0) do … … 1235 1224 end; 1236 1225 1237 fillchar(Arrived, MapSize * 4, $55); // set NotReachedFlag for all tiles1238 fillchar(GroupComplete, MapSize, False);1226 FillChar(Arrived, MapSize * 4, $55); // set NotReachedFlag for all tiles 1227 FillChar(GroupComplete, MapSize, False); 1239 1228 BestLoadLoc := -1; 1240 1229 … … 1243 1232 begin 1244 1233 uix := uixSelectedLoad[tuix]; 1245 if MyUnit[uix].Movement = integer(MyModel[MyUnit[uix].mix].Speed) then1234 if MyUnit[uix].Movement = Integer(MyModel[MyUnit[uix].mix].Speed) then 1246 1235 begin 1247 1236 NotReachedFlag := 1 shl (2 * tuix); … … 1257 1246 if (TurnsBeforeLoad[Loc1] >= 0) and (TurnsAfterLoad[Loc1] >= 0) then 1258 1247 begin 1259 i:= 1;1248 I := 1; 1260 1249 GroupCount := 0; 1261 1250 for tuix1 := 0 to nSelectedLoad - 1 do 1262 1251 begin 1263 if Arrived[loc1] and i= 0 then1252 if Arrived[loc1] and I = 0 then 1264 1253 Inc(GroupCount); 1265 i := ishl 2;1254 I := I shl 2; 1266 1255 end; 1267 assert(GroupCount <= TransportCapacity);1256 Assert(GroupCount <= TransportCapacity); 1268 1257 if (GroupCount = TransportCapacity) or (GroupCount = nSelectedLoad) then 1269 1258 GroupComplete[loc1] := True; … … 1303 1292 begin 1304 1293 Pile.Put(MyUnit[uix].Loc, $1800 - MyUnit[uix].Movement); 1305 if MyUnit[uix].Movement = integer(MyModel[MyUnit[uix].mix].Speed) then1294 if MyUnit[uix].Movement = Integer(MyModel[MyUnit[uix].mix].Speed) then 1306 1295 FullMovementLoc := MyUnit[uix].Loc; 1307 1296 // surrounding tiles can be loaded immediately … … 1319 1308 if StartLocPtr <> ArrivedEnd then 1320 1309 begin 1321 Loc0 := ( integer(StartLocPtr) - integer(@Arrived)) shr 2;1310 Loc0 := (Integer(StartLocPtr) - Integer(@Arrived)) shr 2; 1322 1311 Inc(StartLocPtr); 1323 1312 Time0 := $800; … … 1327 1316 if IsFirstLoc then 1328 1317 ContinueUnit := ContinueUnit and not (1 shl tuix); 1329 break;1318 Break; 1330 1319 end; 1331 1320 IsFirstLoc := False; … … 1334 1323 if not GroupComplete[Loc0] and (Map[Loc0] and fTerrain <> fMountains) then 1335 1324 begin // check whether group complete -- no mountains because complete flag might be faked there 1336 i:= 1;1325 I := 1; 1337 1326 GroupCount := 0; 1338 1327 for tuix1 := 0 to nSelectedLoad - 1 do 1339 1328 begin 1340 if Arrived[Loc0] and i= 0 then1329 if Arrived[Loc0] and I = 0 then 1341 1330 Inc(GroupCount); 1342 i := ishl 2;1331 I := I shl 2; 1343 1332 end; 1344 assert(GroupCount <= TransportCapacity);1333 Assert(GroupCount <= TransportCapacity); 1345 1334 if (GroupCount = TransportCapacity) or (GroupCount = nSelectedLoad) then 1346 1335 GroupComplete[Loc0] := True; … … 1364 1353 if (TurnsBeforeLoad[Loc1] >= 0) and (TurnsAfterLoad[Loc1] >= 0) then 1365 1354 begin 1366 i:= 1;1355 I := 1; 1367 1356 GroupCount := 0; 1368 1357 for tuix1 := 0 to nSelectedLoad - 1 do 1369 1358 begin 1370 if Arrived[loc1] and i= 0 then1359 if Arrived[loc1] and I = 0 then 1371 1360 Inc(GroupCount); 1372 i := ishl 2;1361 I := I shl 2; 1373 1362 end; 1374 assert(GroupCount <= TransportCapacity);1363 Assert(GroupCount <= TransportCapacity); 1375 1364 if (GroupCount = TransportCapacity) or 1376 1365 (GroupCount = nSelectedLoad) then … … 1447 1436 if 1 shl (2 * tuix) and Arrived[BestLoadLoc] = 0 then 1448 1437 begin 1449 assert(uixTransportLoad[tuixSelectedLoad[tuix]] = uixSelectedLoad[tuix]);1438 Assert(uixTransportLoad[tuixSelectedLoad[tuix]] = uixSelectedLoad[tuix]); 1450 1439 TransportPlan.uixLoad[TransportPlan.nLoad] := uixSelectedLoad[tuix]; 1451 1440 uixTransportLoad[tuixSelectedLoad[tuix]] := … … 1455 1444 end; 1456 1445 Result := True; 1457 exit;1446 Exit; 1458 1447 end; 1459 1448 … … 1462 1451 for tuix := nSelectedLoad - 1 downto 0 do 1463 1452 begin 1464 assert(uixTransportLoad[tuixSelectedLoad[tuix]] = uixSelectedLoad[tuix]);1453 Assert(uixTransportLoad[tuixSelectedLoad[tuix]] = uixSelectedLoad[tuix]); 1465 1454 uixTransportLoad[tuixSelectedLoad[tuix]] := 1466 1455 uixTransportLoad[nTransportLoad - 1]; … … 1472 1461 end; 1473 1462 1474 1475 1463 //------------------------------------------------------------------------------ 1476 1464 // Misc 1477 1465 1478 function TToolAI.CurrentMStrength(Domain: integer): integer;1479 var 1480 i: integer;1466 function TToolAI.CurrentMStrength(Domain: Integer): Integer; 1467 var 1468 I: Integer; 1481 1469 begin 1482 1470 Result := 0; 1483 for i:= 0 to nUpgrade - 1 do1484 with upgrade[Domain, i] do1471 for I := 0 to nUpgrade - 1 do 1472 with upgrade[Domain, I] do 1485 1473 if (Preq = preNone) or (Preq >= 0) and 1486 1474 ((RO.Tech[Preq] >= tsApplicable) or (Preq in FutureTech) and … … 1494 1482 end; 1495 1483 1496 1497 1484 //------------------------------------------------------------------------------ 1498 1485 1499 1486 procedure SetAdvancedness; 1500 1487 var 1501 ad, j, Reduction, AgeThreshold: integer;1502 known: array[0..nAdv - 1] of integer;1503 1504 procedure MarkPreqs(ad: integer);1488 ad, J, Reduction, AgeThreshold: Integer; 1489 known: array[0..nAdv - 1] of Integer; 1490 1491 procedure MarkPreqs(ad: Integer); 1505 1492 var 1506 i: integer;1493 I: Integer; 1507 1494 begin 1508 1495 if known[ad] = 0 then 1509 1496 begin 1510 1497 known[ad] := 1; 1511 for i:= 0 to 2 do1512 if AdvPreq[ad, i] >= 0 then1513 MarkPreqs(AdvPreq[ad, i]);1498 for I := 0 to 2 do 1499 if AdvPreq[ad, I] >= 0 then 1500 MarkPreqs(AdvPreq[ad, I]); 1514 1501 end; 1515 1502 end; … … 1521 1508 FillChar(known, SizeOf(known), 0); 1522 1509 MarkPreqs(ad); 1523 for j:= 0 to nAdv - 1 do1524 if known[ j] > 0 then1510 for J := 0 to nAdv - 1 do 1511 if known[J] > 0 then 1525 1512 Inc(Advancedness[ad]); 1526 1513 end;
Note:
See TracChangeset
for help on using the changeset viewer.