Changeset 465 for branches/highdpi/AI/StdAI
- Timestamp:
- Nov 30, 2023, 10:16:14 PM (2 years ago)
- Location:
- branches/highdpi/AI/StdAI
- Files:
-
- 9 edited
-
AI.pas (modified) (133 diffs)
-
Barbarina.pas (modified) (75 diffs)
-
CustomAI.pas (modified) (47 diffs)
-
CustomAI_Reload.pas (modified) (34 diffs)
-
Pile.pas (modified) (6 diffs)
-
Protocol.pas (modified) (10 diffs)
-
StdAI.ai.txt (modified) (1 diff)
-
StdAI.lpr (modified) (2 diffs)
-
ToolAI.pas (modified) (71 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/highdpi/AI/StdAI/AI.pas
r349 r465 23 23 24 24 nResearchOrder = 46; 25 ResearchOrder: array[0..1, 0..nResearchOrder - 1] of integer =25 ResearchOrder: array[0..1, 0..nResearchOrder - 1] of Integer = 26 26 ((adWheel, adWarriorCode, adHorsebackRiding, adCeremonialBurial, adPolytheism, 27 27 adMonarchy, adMysticism, adPoetry, adAstronomy, adMonotheism, … … 76 76 77 77 // mil research 78 BetterQuality: array[0..nModelCat - 1] of integer = (50, 50, 80, 80);78 BetterQuality: array[0..nModelCat - 1] of Integer = (50, 50, 80, 80); 79 79 MaxBuildWorseThanBestModel = 20; 80 80 MaxExistWorseThanBestModel = 50; … … 85 85 nRequestedTechs = 48; 86 86 87 PlayerHash: array[0..nPl - 1] of integer =87 PlayerHash: array[0..nPl - 1] of Integer = 88 88 (7, 6, 0, 2, 10, 8, 12, 14, 4, 1, 3, 5, 9, 11, 13); 89 89 … … 92 92 93 93 TPersistentData = record 94 LastResearchTech, BehaviorFlags, TheologyPartner: integer;94 LastResearchTech, BehaviorFlags, TheologyPartner: Integer; 95 95 RejectTurn: array[Suggestion, 0..15] of smallint; 96 RequestedTechs: array[0..nRequestedTechs - 1] of integer;96 RequestedTechs: array[0..nRequestedTechs - 1] of Integer; 97 97 // ad + p shl 8 + Turn shl 16 98 98 end; 99 99 100 100 TAI = class(TBarbarina) 101 constructor Create(Nation: integer); override;101 constructor Create(Nation: Integer); override; 102 102 103 103 procedure SetDataDefaults; override; … … 106 106 Data: ^TPersistentData; 107 107 WarNations, BombardingNations, mixSettlers, mixCaravan, mixTownGuard, 108 mixSlaves, mixMilitia, mixCruiser, OceanWithShip: integer;108 mixSlaves, mixMilitia, mixCruiser, OceanWithShip: Integer; 109 109 NegoCause: (Routine, CheckBarbarina); 110 SettlerSurplus: array[0..maxCOD - 1] of integer;111 uixPatrol: array[0..maxCOD - 1] of integer;112 113 ContinentPresence: array[0..maxCOD - 1] of integer;114 OceanPresence: array[0..maxCOD - 1] of integer;115 UnitLack: array[0..maxCOD - 1, mctGroundDefender..mctGroundAttacker] of integer;116 117 TotalPopulation: array[0..nPl - 1] of integer;118 ContinentPopulation: array[0..nPl - 1, 0..maxCOD - 1] of integer;110 SettlerSurplus: array[0..maxCOD - 1] of Integer; 111 uixPatrol: array[0..maxCOD - 1] of Integer; 112 113 ContinentPresence: array[0..maxCOD - 1] of Integer; 114 OceanPresence: array[0..maxCOD - 1] of Integer; 115 UnitLack: array[0..maxCOD - 1, mctGroundDefender..mctGroundAttacker] of Integer; 116 117 TotalPopulation: array[0..nPl - 1] of Integer; 118 ContinentPopulation: array[0..nPl - 1, 0..maxCOD - 1] of Integer; 119 119 // 1 means enemy territory spotted but no city 120 DistrictPopulation: array[0..maxCOD - 1] of integer;121 122 ModelCat: array[0..nMmax - 1] of integer;123 ModelQuality: array[0..nMmax - 1] of integer;124 ModelBestQuality: array[0..nModelCat - 1] of integer;125 126 AdvanceValue: array[0..nAdv - 1] of integer;127 AdvanceValuesSet: boolean;120 DistrictPopulation: array[0..maxCOD - 1] of Integer; 121 122 ModelCat: array[0..nMmax - 1] of Integer; 123 ModelQuality: array[0..nMmax - 1] of Integer; 124 ModelBestQuality: array[0..nModelCat - 1] of Integer; 125 126 AdvanceValue: array[0..nAdv - 1] of Integer; 127 AdvanceValuesSet: Boolean; 128 128 129 129 procedure DoTurn; override; 130 130 procedure DoNegotiation; override; 131 function ChooseResearchAdvance: integer; override;132 function ChooseStealAdvance: integer; override;133 function ChooseGovernment: integer; override;134 function WantNegotiation(Nation: integer; NegoTime: TNegoTime): boolean; override;135 function OnNegoRejected_CancelTreaty: boolean; override;136 137 procedure FindBestTrade(Nation: integer; var adWanted, adGiveAway: integer);131 function ChooseResearchAdvance: Integer; override; 132 function ChooseStealAdvance: Integer; override; 133 function ChooseGovernment: Integer; override; 134 function WantNegotiation(Nation: Integer; NegoTime: TNegoTime): Boolean; override; 135 function OnNegoRejected_CancelTreaty: Boolean; override; 136 137 procedure FindBestTrade(Nation: Integer; var adWanted, adGiveAway: Integer); 138 138 procedure CheckGender; 139 139 procedure AnalyzeMap; … … 141 141 procedure AttackAndPatrol; 142 142 procedure MoveUnitsHome; 143 procedure CheckAttack(uix: integer);144 procedure Patrol(uix: integer);143 procedure CheckAttack(uix: Integer); 144 procedure Patrol(uix: Integer); 145 145 procedure SetCityProduction; 146 146 procedure SetAdvanceValues; 147 function HavePort: boolean;148 {$IFDEF DEBUG}procedure TraceAdvanceValues(Nation: integer);{$ENDIF}147 function HavePort: Boolean; 148 {$IFDEF DEBUG}procedure TraceAdvanceValues(Nation: Integer);{$ENDIF} 149 149 150 150 // research 151 procedure RateModel(const mi: TModelInfo; var Category, Quality: integer);152 procedure RateMyModel(mix: integer; var Category, Quality: integer);153 function IsBetterModel(const mi: TModelInfo): boolean;151 procedure RateModel(const mi: TModelInfo; var Category, Quality: Integer); 152 procedure RateMyModel(mix: Integer; var Category, Quality: Integer); 153 function IsBetterModel(const mi: TModelInfo): Boolean; 154 154 155 155 //terraforming 156 procedure TileWorkPlan(Loc, cix: integer; var Value, NextJob, TotalWork: integer);156 procedure TileWorkPlan(Loc, cix: Integer; var Value, NextJob, TotalWork: Integer); 157 157 procedure ProcessSettlers; 158 158 159 159 // diplomacy 160 function MostWanted(Nation, adGiveAway: integer): integer;160 function MostWanted(Nation, adGiveAway: Integer): Integer; 161 161 162 162 end; … … 174 174 175 175 var 176 LeaveOutValue: array[0..nAdv - 1] of integer; 177 178 179 constructor TAI.Create(Nation: integer); 176 LeaveOutValue: array[0..nAdv - 1] of Integer; 177 178 constructor TAI.Create(Nation: Integer); 180 179 begin 181 180 inherited; 182 Data := pointer(RO.Data);181 Data := Pointer(RO.Data); 183 182 {$IFDEF DEBUG} 184 183 if Nation = 1 then … … 193 192 begin 194 193 LastResearchTech := -1; 195 if PlayerHash[ me] > 7 then194 if PlayerHash[Me] > 7 then 196 195 BehaviorFlags := bFemale 197 196 else … … 199 198 DebugMessage(1, 'Gender:=' + char(48 + BehaviorFlags and bGender)); 200 199 TheologyPartner := -1; 201 fillchar(RejectTurn, sizeof(RejectTurn), $FF);202 Fillchar(RequestedTechs, sizeof(RequestedTechs), $FF);200 FillChar(RejectTurn, SizeOf(RejectTurn), $FF); 201 Fillchar(RequestedTechs, SizeOf(RequestedTechs), $FF); 203 202 end; 204 203 end; 205 204 206 function TAI.OnNegoRejected_CancelTreaty: boolean;205 function TAI.OnNegoRejected_CancelTreaty: Boolean; 207 206 begin 208 207 Data.RejectTurn[suContact, Opponent] := RO.Turn; … … 210 209 end; 211 210 212 213 211 //------------------------------- 214 212 // RESEARCH 215 213 //------------------------------- 216 214 217 procedure TAI.RateModel(const mi: TModelInfo; var Category, Quality: integer);215 procedure TAI.RateModel(const mi: TModelInfo; var Category, Quality: Integer); 218 216 var 219 EffectiveTransport: integer;217 EffectiveTransport: Integer; 220 218 begin 221 219 if mi.Kind >= mkScout then 222 220 begin 223 221 Category := mctNone; 224 exit;222 Exit; 225 223 end; 226 224 case mi.Domain of … … 294 292 end; 295 293 296 procedure TAI.RateMyModel(mix: integer; var Category, Quality: integer);294 procedure TAI.RateMyModel(mix: Integer; var Category, Quality: Integer); 297 295 var 298 296 mi: TModelInfo; 299 297 begin 300 MakeModelInfo( me, mix, MyModel[mix], mi);298 MakeModelInfo(Me, mix, MyModel[mix], mi); 301 299 RateModel(mi, Category, Quality); 302 300 end; 303 301 304 function TAI.IsBetterModel(const mi: TModelInfo): boolean;302 function TAI.IsBetterModel(const mi: TModelInfo): Boolean; 305 303 var 306 mix, Cat, Quality, Cat1, Quality1: integer;304 mix, Cat, Quality, Cat1, Quality1: Integer; 307 305 begin 308 306 RateModel(mi, Cat, Quality); … … 314 312 begin 315 313 Result := False; 316 exit;314 Exit; 317 315 end; 318 316 end; … … 320 318 end; 321 319 322 function TAI.ChooseResearchAdvance: integer;320 function TAI.ChooseResearchAdvance: Integer; 323 321 var 324 adNext, iad, i, ad, Count, EarliestNeeded, EarliestNeeded_NoLeaveOut,325 NewResearch, StateOfArt, mix: integer;322 adNext, iad, I, ad, Count, EarliestNeeded, EarliestNeeded_NoLeaveOut, 323 NewResearch, StateOfArt, mix: Integer; 326 324 mi: TModelInfo; 327 Entry: array[0..nAdv - 1] of boolean;328 ok: boolean;329 330 function MarkEntry(ad: integer): boolean;325 Entry: array[0..nAdv - 1] of Boolean; 326 ok: Boolean; 327 328 function MarkEntry(ad: Integer): Boolean; 331 329 begin 332 330 if RO.Tech[ad] >= tsApplicable then … … 375 373 end; 376 374 377 procedure OptimizeDevModel(OptimizeCaps: integer);375 procedure OptimizeDevModel(OptimizeCaps: Integer); 378 376 var 379 f, Cat, OriginalCat, Quality, BestQuality, Best: integer;377 F, Cat, OriginalCat, Quality, BestQuality, Best: Integer; 380 378 mi: TModelInfo; 381 379 begin 382 MakeModelInfo( me, 0, RO.DevModel, mi);380 MakeModelInfo(Me, 0, RO.DevModel, mi); 383 381 RateModel(mi, OriginalCat, BestQuality); 384 382 repeat 385 383 Best := -1; 386 for f:= 0 to nFeature - 1 do387 if (1 shl fand OptimizeCaps <> 0) and388 ((Feature[ f].Preq < 0) or IsResearched(Feature[f].Preq)) // check prerequisite389 and (RO.DevModel.Weight + Feature[ f].Weight <= RO.DevModel.MaxWeight) and390 not (( f >= mcFirstNonCap) and (RO.DevModel.Cap[f] > 0)) then391 begin 392 if SetNewModelFeature( f, RO.DevModel.Cap[f] + 1) >= rExecuted then384 for F := 0 to nFeature - 1 do 385 if (1 shl F and OptimizeCaps <> 0) and 386 ((Feature[F].Preq < 0) or IsResearched(Feature[F].Preq)) // check prerequisite 387 and (RO.DevModel.Weight + Feature[F].Weight <= RO.DevModel.MaxWeight) and 388 not ((F >= mcFirstNonCap) and (RO.DevModel.Cap[F] > 0)) then 389 begin 390 if SetNewModelFeature(F, RO.DevModel.Cap[F] + 1) >= rExecuted then 393 391 begin 394 MakeModelInfo( me, 0, RO.DevModel, mi);392 MakeModelInfo(Me, 0, RO.DevModel, mi); 395 393 RateModel(mi, Cat, Quality); 396 assert(Cat = OriginalCat);394 Assert(Cat = OriginalCat); 397 395 if Quality > BestQuality then 398 396 begin 399 Best := f;397 Best := F; 400 398 BestQuality := Quality; 401 399 end; 402 SetNewModelFeature( f, RO.DevModel.Cap[f] - 1);400 SetNewModelFeature(F, RO.DevModel.Cap[F] - 1); 403 401 end; 404 402 end; … … 408 406 end; 409 407 410 function LeaveOutsMissing(ad: integer): boolean;408 function LeaveOutsMissing(ad: Integer): Boolean; 411 409 var 412 i: integer;410 I: Integer; 413 411 begin 414 412 Result := False; … … 424 422 Result := True 425 423 else 426 for i:= 0 to 1 do427 if AdvPreq[ad, i] >= 0 then428 Result := Result or LeaveOutsMissing(AdvPreq[ad, i]);424 for I := 0 to 1 do 425 if AdvPreq[ad, I] >= 0 then 426 Result := Result or LeaveOutsMissing(AdvPreq[ad, I]); 429 427 end; 430 428 … … 434 432 Result := Barbarina_ChooseResearchAdvance; 435 433 if Result >= 0 then 436 exit;434 Exit; 437 435 end; 438 436 … … 446 444 Result := ad; 447 445 if Result >= 0 then 448 exit;446 Exit; 449 447 450 448 if Data.BehaviorFlags and bBarbarina = 0 then … … 462 460 OptimizeDevModel(1 shl mcOffense + 1 shl mcDefense + 1 shl 463 461 mcMob + 1 shl mcLongRange + 1 shl mcFanatic); 464 MakeModelInfo( me, 0, RO.DevModel, mi);462 MakeModelInfo(Me, 0, RO.DevModel, mi); 465 463 if IsBetterModel(mi) then 466 464 begin 467 465 Result := adMilitary; 468 exit;466 Exit; 469 467 end; 470 468 … … 473 471 SetNewModelFeature(mcOffense, 1); 474 472 OptimizeDevModel(1 shl mcOffense + 1 shl mcDefense + 1 shl mcFanatic); 475 MakeModelInfo( me, 0, RO.DevModel, mi);473 MakeModelInfo(Me, 0, RO.DevModel, mi); 476 474 if IsBetterModel(mi) then 477 475 begin 478 476 Result := adMilitary; 479 exit;477 Exit; 480 478 end; 481 479 end; … … 493 491 SetNewModelFeature(mcWeapons, 0); 494 492 SetNewModelFeature(mcDefense, 3); 495 exit;493 Exit; 496 494 end; 497 495 end; … … 508 506 OptimizeDevModel(1 shl mcDefense+1 shl mcSeaTrans+1 shl mcTurbines 509 507 +1 shl mcAirDef); 510 MakeModelInfo( me,0,RO.DevModel,mi);508 MakeModelInfo(Me,0,RO.DevModel,mi); 511 509 if IsBetterModel(mi) then 512 begin result:=adMilitary; exit end;510 begin Result:=adMilitary; Exit end; 513 511 end; 514 512 … … 521 519 OptimizeDevModel(1 shl mcOffense+1 shl mcDefense 522 520 +1 shl mcLongRange+1 shl mcAirDef+1 shl mcRadar); 523 MakeModelInfo( me,0,RO.DevModel,mi);521 MakeModelInfo(Me,0,RO.DevModel,mi); 524 522 if IsBetterModel(mi) then 525 begin result:=adMilitary; exit end;523 begin Result:=adMilitary; Exit end; 526 524 end 527 525 end; … … 547 545 begin 548 546 ok := True; 549 break;547 Break; 550 548 end; 551 549 if not ok then … … 590 588 begin // 2 of 3 required 591 589 Count := 0; 592 for i:= 0 to 2 do593 if RO.Tech[AdvPreq[ad, i]] >= tsApplicable then590 for I := 0 to 2 do 591 if RO.Tech[AdvPreq[ad, I]] >= tsApplicable then 594 592 Inc(Count); 595 593 if Count >= 2 then 596 594 begin 597 595 Result := ad; 598 exit;596 Exit; 599 597 end; 600 598 end … … 604 602 begin 605 603 Result := ad; 606 exit;604 Exit; 607 605 end; 608 606 end; … … 620 618 begin // go for future techs 621 619 Result := -1; 622 i:= 0;620 I := 0; 623 621 for ad := nAdv - 4 to nAdv - 1 do 624 622 if (RO.Tech[ad] < MaxFutureTech) and (RO.Tech[AdvPreq[ad, 0]] >= 625 623 tsApplicable) then 626 624 begin 627 Inc( i);628 if random( i) = 0 then625 Inc(I); 626 if random(I) = 0 then 629 627 Result := ad; 630 628 end; 631 assert((Result < 0) or AdvanceResearchable(Result));632 exit;633 end; 634 635 assert(NewResearch >= 0);636 fillchar(Entry, sizeof(Entry), False);629 Assert((Result < 0) or AdvanceResearchable(Result)); 630 Exit; 631 end; 632 633 Assert(NewResearch >= 0); 634 FillChar(Entry, SizeOf(Entry), False); 637 635 MarkEntry(NewResearch); 638 636 Result := -1; … … 640 638 if Entry[ad] and ((Result < 0) or (Advancedness[ad] > Advancedness[Result])) then 641 639 Result := ad; 642 assert(Result >= 0);640 Assert(Result >= 0); 643 641 end; 644 642 645 function TAI.ChooseStealAdvance: integer;643 function TAI.ChooseStealAdvance: Integer; 646 644 var 647 ad: integer;645 ad: Integer; 648 646 begin 649 647 Result := -1; … … 654 652 end; 655 653 656 657 654 //------------------------------- 658 655 // TERRAFORMING … … 662 659 twpAllowFarmland = $0001; 663 660 664 procedure TAI.TileWorkPlan(Loc, cix: integer; var Value, NextJob, TotalWork: integer);661 procedure TAI.TileWorkPlan(Loc, cix: Integer; var Value, NextJob, TotalWork: Integer); 665 662 var 666 OldTile, TerrType: cardinal;663 OldTile, TerrType: Cardinal; 667 664 TileInfo: TTileInfo; 668 665 begin … … 672 669 begin 673 670 Value := 3 * 8 - 1; 674 exit;671 Exit; 675 672 end; // better than any tile with 2 food 676 673 … … 693 690 Map[Loc] := Map[Loc] and not fTerrain or fGrass; 694 691 TerrType := fGrass; 695 Map[Loc] := Map[Loc] or cardinal(SpecialTile(Loc, TerrType, G.lx) shl 5);692 Map[Loc] := Map[Loc] or Cardinal(SpecialTile(Loc, TerrType, G.lx) shl 5); 696 693 end 697 694 else if IsResearched(adExplosives) and … … 704 701 Map[Loc] := Map[Loc] and not fTerrain or fGrass; 705 702 TerrType := fGrass; 706 Map[Loc] := Map[Loc] or cardinal(SpecialTile(Loc, TerrType, G.lx) shl 5);703 Map[Loc] := Map[Loc] or Cardinal(SpecialTile(Loc, TerrType, G.lx) shl 5); 707 704 end; 708 705 if (Terrain[TerrType].MineEff > 0) and (RO.Government <> gDespotism) then … … 767 764 end; 768 765 end; 769 Server(sGetTileInfo, me, Loc, TileInfo);766 Server(sGetTileInfo, Me, Loc, TileInfo); 770 767 Value := TileInfo.Food * 8 + TileInfo.Prod * 2 + TileInfo.Trade; 771 768 Map[Loc] := OldTile; … … 775 772 procedure TAI.ProcessSettlers; 776 773 var 777 i, uix, cix, ecix, dtr, Loc, RadiusLoc, Special, Food, Prod, Trade,774 I, uix, cix, ecix, dtr, Loc, RadiusLoc, Special, Food, Prod, Trade, 778 775 CityFood, Happy, TestScore, BestNearCityScore, BestUnusedValue, 779 BestUnusedLoc, Value, NextJob, TotalWork, V21, part, Loc1: integer;780 Tile: cardinal;781 FoodOk, Started: boolean;776 BestUnusedLoc, Value, NextJob, TotalWork, V21, part, Loc1: Integer; 777 Tile: Cardinal; 778 FoodOk, Started: Boolean; 782 779 Radius: TVicinity21Loc; 783 780 CityAreaInfo: TCityAreaInfo; 784 TileFood, ResourceScore, CityScore: array[0..lxmax * lymax - 1] of integer;785 786 procedure AddJob(Loc, Job, Score: integer);781 TileFood, ResourceScore, CityScore: array[0..lxmax * lymax - 1] of Integer; 782 783 procedure AddJob(Loc, Job, Score: Integer); 787 784 // set Score=1 for low-priority jobs 788 785 begin … … 792 789 end; 793 790 794 procedure ReserveCityRadius(Loc: integer);791 procedure ReserveCityRadius(Loc: Integer); 795 792 var 796 V21, RadiusLoc: integer;793 V21, RadiusLoc: Integer; 797 794 Radius: TVicinity21Loc; 798 795 begin … … 811 808 procedure ScoreRoadConnections; 812 809 var 813 V8, nFragments, Loc, Loc1, History, RoadScore, a, b, FullyDeveloped,814 ConnectMask: integer;815 BridgeOk: boolean;810 V8, nFragments, Loc, Loc1, History, RoadScore, A, B, FullyDeveloped, 811 ConnectMask: Integer; 812 BridgeOk: Boolean; 816 813 Adjacent: TVicinity8Loc; 817 814 begin … … 824 821 if ((1 shl (Map[Loc] and fTerrain)) and (1 shl fOcean or 1 shl 825 822 fShore or 1 shl fDesert or 1 shl fArctic or 1 shl fUNKNOWN) = 0) and 826 (RO.Territory[Loc] = me) and (Map[Loc] and FullyDeveloped = 0) and823 (RO.Territory[Loc] = Me) and (Map[Loc] and FullyDeveloped = 0) and 827 824 (BridgeOk or (Map[Loc] and fRiver = 0)) then 828 825 begin … … 838 835 Loc1 := Adjacent[V8 and 7]; 839 836 History := History shl 1; 840 if (Loc1 >= 0) and (RO.Territory[Loc1] = me) and837 if (Loc1 >= 0) and (RO.Territory[Loc1] = Me) and 841 838 (Map[Loc1] and ConnectMask <> 0) then 842 839 begin … … 854 851 else if History and 4 <> 0 then 855 852 begin 856 V8_to_ab((V8 - 1) and 7, a, b);857 ab_to_Loc(Loc, a shl 1, bshl 1, Loc1);853 V8_to_ab((V8 - 1) and 7, A, B); 854 ab_to_Loc(Loc, A shl 1, B shl 1, Loc1); 858 855 if (Loc1 >= 0) and (Map[Loc1] and ConnectMask <> 0) then 859 856 Dec(nFragments); … … 879 876 880 877 begin 881 fillchar(SettlerSurplus, sizeof(SettlerSurplus), 0);878 FillChar(SettlerSurplus, SizeOf(SettlerSurplus), 0); 882 879 JobAssignment_Initialize; 883 880 884 881 if (Data.BehaviorFlags and bBarbarina = 0) or (RO.nCity < 3) then 885 882 begin 886 fillchar(TileFood, sizeof(TileFood), 0);887 fillchar(ResourceScore, sizeof(ResourceScore), 0);883 FillChar(TileFood, SizeOf(TileFood), 0); 884 FillChar(ResourceScore, SizeOf(ResourceScore), 0); 888 885 for Loc := 0 to MapSize - 1 do 889 886 if Map[Loc] and fTerrain <> fUNKNOWN then … … 926 923 927 924 // rate possible new cities 928 fillchar(CityScore, MapSize * sizeof(integer), 0);925 FillChar(CityScore, MapSize * SizeOf(Integer), 0); 929 926 for Loc := 0 to MapSize - 1 do 930 927 begin … … 933 930 ((RO.Government <> gDespotism) or (Map[Loc] and fSpecial = fSpecial1)) or 934 931 (Map[Loc] and (fTerrain or fSpecial) = fPrairie or fSpecial1)); 935 if FoodOk and ((RO.Territory[Loc] < 0) or (RO.Territory[Loc] = me)) then932 if FoodOk and ((RO.Territory[Loc] < 0) or (RO.Territory[Loc] = Me)) then 936 933 begin 937 934 TestScore := 0; … … 953 950 if CityFood >= MinCityFood then // city is worth founding 954 951 begin 955 TestScore := (72 + 2 * TestScore) shl 8 + ((loc xor me) * 4567) mod 251;952 TestScore := (72 + 2 * TestScore) shl 8 + ((loc xor Me) * 4567) mod 251; 956 953 // some unexactness, random but always the same for this tile 957 954 if TestScore > BestNearCityScore then … … 991 988 if not (Map[RadiusLoc] and fTerrain in [fDesert, fArctic]) then 992 989 begin 993 assert(RadiusLoc >= 0);990 Assert(RadiusLoc >= 0); 994 991 TileWorkPlan(RadiusLoc, cix, Value, NextJob, TotalWork); 995 992 if (NextJob = jRoad) and (Built[imPalace] + … … 1003 1000 begin // tile could be exploited 1004 1001 RadiusLoc := Radius[V21]; 1005 assert(RadiusLoc >= 0);1002 Assert(RadiusLoc >= 0); 1006 1003 if not (Map[RadiusLoc] and fTerrain in [fDesert, fArctic]) then 1007 1004 begin … … 1027 1024 if Data.BehaviorFlags and bBarbarina = 0 then // low priority jobs 1028 1025 for Loc := 0 to MapSize - 1 do 1029 if RO.Territory[Loc] = me then1026 if RO.Territory[Loc] = Me then 1030 1027 begin 1031 1028 Tile := Map[Loc]; … … 1051 1048 begin 1052 1049 for part := 0 to nShipPart - 1 do 1053 for i:= 0 to ColonyShipPlan[part].nLocFoundCity - 1 do1054 begin 1055 Loc := ColonyShipPlan[part].LocFoundCity[ i];1050 for I := 0 to ColonyShipPlan[part].nLocFoundCity - 1 do 1051 begin 1052 Loc := ColonyShipPlan[part].LocFoundCity[I]; 1056 1053 Started := False; 1057 1054 for uix := 0 to RO.nUn - 1 do … … 1059 1056 begin 1060 1057 Started := True; 1061 break;1058 Break; 1062 1059 end; 1063 1060 if not Started then … … 1122 1119 begin // settlers could be added to this city 1123 1120 Happy := BasicHappy; 1124 for i:= 0 to nWonder - 1 do1125 if Built[ i] > 0 then1121 for I := 0 to nWonder - 1 do 1122 if Built[I] > 0 then 1126 1123 Inc(Happy); 1127 1124 if Built[imTemple] > 0 then … … 1130 1127 begin 1131 1128 Inc(Happy, 2); 1132 if RO.Wonder[woBach].EffectiveOwner = me then1129 if RO.Wonder[woBach].EffectiveOwner = Me then 1133 1130 Inc(Happy, 1); 1134 1131 end; … … 1145 1142 end; 1146 1143 end; 1147 end; // ProcessSettlers 1148 1144 end; 1149 1145 1150 1146 //------------------------------- … … 1154 1150 procedure TAI.DoTurn; 1155 1151 var 1156 emix, i, p1, TaxSum, ScienceSum, NewTaxRate: integer;1157 AllHateMe: boolean;1152 emix, I, p1, TaxSum, ScienceSum, NewTaxRate: Integer; 1153 AllHateMe: Boolean; 1158 1154 {$IFDEF PERF} 1159 1155 PF, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9: int64; … … 1161 1157 begin 1162 1158 {$IFDEF DEBUG} 1163 fillchar(DebugMap, sizeof(DebugMap), 0);1159 FillChar(DebugMap, SizeOf(DebugMap), 0); 1164 1160 {$ENDIF} 1165 1161 … … 1173 1169 WarNations := PresenceUnknown; 1174 1170 for p1 := 0 to nPl - 1 do 1175 if (p1 <> me) and (1 shl p1 and RO.Alive <> 0) and (RO.Treaty[p1] < trPeace) then1171 if (p1 <> Me) and (1 shl p1 and RO.Alive <> 0) and (RO.Treaty[p1] < trPeace) then 1176 1172 Inc(WarNations, 1 shl p1); 1177 1173 BombardingNations := 0; … … 1189 1185 CheckGender; 1190 1186 1191 if G.Difficulty[ me] < MaxDiff then // not on beginner level1187 if G.Difficulty[Me] < MaxDiff then // not on beginner level 1192 1188 begin 1193 1189 if (Data.LastResearchTech = adHorsebackRiding) and (RO.ResearchTech < 0) and 1194 1190 (random(6) = 0) and (HavePort or (ContinentPresence[0] and not 1195 (1 shl me or PresenceUnknown) <> 0)) then1191 (1 shl Me or PresenceUnknown) <> 0)) then 1196 1192 begin 1197 1193 Data.BehaviorFlags := Data.BehaviorFlags or bBarbarina_Hide; … … 1210 1206 begin 1211 1207 AllHateMe := False; 1212 break;1208 Break; 1213 1209 end; 1214 1210 if AllHateMe then … … 1306 1302 else 1307 1303 begin 1308 if (RO.TaxRate = 0) or (RO.Money < (TotalPopulation[ me] - 4) * 2) then1304 if (RO.TaxRate = 0) or (RO.Money < (TotalPopulation[Me] - 4) * 2) then 1309 1305 NewTaxRate := RO.TaxRate // don't check decreasing tax 1310 1306 else … … 1313 1309 begin 1314 1310 SumCities(NewTaxRate, TaxSum, ScienceSum); 1315 if RO.Money + TaxSum >= (TotalPopulation[ me] - 4) then1316 break; // enough1311 if RO.Money + TaxSum >= (TotalPopulation[Me] - 4) then 1312 Break; // enough 1317 1313 Inc(NewTaxRate, 10); 1318 1314 end; … … 1328 1324 // research completed 1329 1325 for p1 := 0 to nPl - 1 do 1330 if (p1 <> me) and (1 shl p1 and RO.Alive <> 0) and1326 if (p1 <> Me) and (1 shl p1 and RO.Alive <> 0) and 1331 1327 (RO.EnemyReport[p1].TurnOfCivilReport + TechReportOutdated > RO.Turn) and 1332 1328 (RO.EnemyReport[p1].Tech[Data.LastResearchTech] < tsSeen) then 1333 1329 begin // latest researched advance might be of interest to this nation 1334 for i:= 0 to nRequestedTechs - 1 do1335 if (Data.RequestedTechs[ i] >= 0) and1336 (Data.RequestedTechs[ i] shr 8 and $F = p1) then1337 Data.RequestedTechs[ i] := -1;1330 for I := 0 to nRequestedTechs - 1 do 1331 if (Data.RequestedTechs[I] >= 0) and 1332 (Data.RequestedTechs[I] shr 8 and $F = p1) then 1333 Data.RequestedTechs[I] := -1; 1338 1334 end; 1339 1335 if RO.ResearchTech = adMilitary then … … 1341 1337 else 1342 1338 Data.LastResearchTech := RO.ResearchTech; 1343 for i:= 0 to nRequestedTechs - 1 do1344 if (Data.RequestedTechs[ i] >= 0) and1345 (RO.Tech[Data.RequestedTechs[ i] and $FF] >= tsSeen) then1346 Data.RequestedTechs[ i] := -1;1339 for I := 0 to nRequestedTechs - 1 do 1340 if (Data.RequestedTechs[I] >= 0) and 1341 (RO.Tech[Data.RequestedTechs[I] and $FF] >= tsSeen) then 1342 Data.RequestedTechs[I] := -1; 1347 1343 1348 1344 // prepare negotiation … … 1350 1346 SetAdvanceValues; 1351 1347 1352 1353 1348 {$IFDEF DEBUG} 1354 1349 (*for p1:=0 to nPl-1 do 1355 if (p1<> me) and (1 shl p1 and RO.Alive<>0) and (RO.Treaty[p1]>=trPeace)1350 if (p1<>Me) and (1 shl p1 and RO.Alive<>0) and (RO.Treaty[p1]>=trPeace) 1356 1351 and (RO.EnemyReport[p1].TurnOfCivilReport>=0) then 1357 1352 TraceAdvanceValues(p1);*) … … 1368 1363 1369 1364 {$IFDEF DEBUG} 1370 procedure TAI.TraceAdvanceValues(Nation: integer);1365 procedure TAI.TraceAdvanceValues(Nation: Integer); 1371 1366 var 1372 ad: integer;1367 ad: Integer; 1373 1368 begin 1374 1369 for ad := 0 to nAdv - 1 do … … 1380 1375 end; 1381 1376 end; 1382 1383 1377 {$ENDIF} 1384 1385 1378 1386 1379 procedure TAI.CheckGender; 1387 1380 var 1388 p1, NewGender: integer;1381 p1, NewGender: Integer; 1389 1382 begin 1390 1383 NewGender := -1; 1391 1384 for p1 := 0 to nPl - 1 do 1392 if (p1 <> me) and (1 shl p1 and RO.Alive <> 0) and1385 if (p1 <> Me) and (1 shl p1 and RO.Alive <> 0) and 1393 1386 (RO.Treaty[p1] >= trFriendlyContact) then 1394 if PlayerHash[ me] > PlayerHash[p1] then1387 if PlayerHash[Me] > PlayerHash[p1] then 1395 1388 begin 1396 1389 if NewGender = bMale then 1397 1390 begin 1398 1391 NewGender := -2; 1399 break;1392 Break; 1400 1393 end; // ambiguous, don't change gender 1401 1394 NewGender := bFemale; … … 1406 1399 begin 1407 1400 NewGender := -2; 1408 break;1401 Break; 1409 1402 end; // ambiguous, don't change gender 1410 1403 NewGender := bMale; … … 1417 1410 end; 1418 1411 1419 1420 1412 procedure TAI.SetAdvanceValues; 1421 1413 1422 procedure RateResearchAdv(ad, Time: integer);1414 procedure RateResearchAdv(ad, Time: Integer); 1423 1415 var 1424 Value: integer;1416 Value: Integer; 1425 1417 begin 1426 1418 if Time = 0 then … … 1432 1424 end; 1433 1425 1434 procedure SetPreqValues(ad, Value: integer);1426 procedure SetPreqValues(ad, Value: Integer); 1435 1427 begin 1436 1428 if (RO.Tech[ad] < tsSeen) and (ad <> RO.ResearchTech) then … … 1455 1447 end; 1456 1448 1457 procedure RateImpPreq(iix, Value: integer);1449 procedure RateImpPreq(iix, Value: Integer); 1458 1450 begin 1459 1451 if (Value > 0) and (Imp[iix].Preq >= 0) then … … 1462 1454 1463 1455 var 1464 emix, cix, adMissing, iad, ad, Count, i, Time, d, CurrentCost,1465 CurrentStrength, MaxSize, MaxTrade: integer;1466 PreView, Emergency, Bombarded: boolean;1456 emix, cix, adMissing, iad, ad, Count, I, Time, D, CurrentCost, 1457 CurrentStrength, MaxSize, MaxTrade: Integer; 1458 PreView, Emergency, Bombarded: Boolean; 1467 1459 begin 1468 1460 if AdvanceValuesSet then 1469 exit;1461 Exit; 1470 1462 AdvanceValuesSet := True; 1471 1463 1472 fillchar(AdvanceValue, sizeof(AdvanceValue), 0);1464 FillChar(AdvanceValue, SizeOf(AdvanceValue), 0); 1473 1465 1474 1466 // rate techs to ensure research progress … … 1490 1482 begin // 2 of 3 required 1491 1483 Count := 0; 1492 for i:= 0 to 2 do1493 if (AdvPreq[ad, i] = RO.ResearchTech) or1494 (RO.Tech[AdvPreq[ad, i]] >= tsSeen) then1484 for I := 0 to 2 do 1485 if (AdvPreq[ad, I] = RO.ResearchTech) or 1486 (RO.Tech[AdvPreq[ad, I]] >= tsSeen) then 1495 1487 Inc(Count); 1496 1488 if Count >= 2 then … … 1500 1492 if ad <> adMassProduction then // don't score third preq for MP 1501 1493 begin 1502 for i:= 0 to 2 do1503 if (AdvPreq[ad, i] <> RO.ResearchTech) and1504 (RO.Tech[AdvPreq[ad, i]] < tsSeen) then1505 RateResearchAdv(AdvPreq[ad, i], Time);1494 for I := 0 to 2 do 1495 if (AdvPreq[ad, I] <> RO.ResearchTech) and 1496 (RO.Tech[AdvPreq[ad, I]] < tsSeen) then 1497 RateResearchAdv(AdvPreq[ad, I], Time); 1506 1498 end; 1507 1499 Inc(Time, 2 - Count); … … 1511 1503 begin 1512 1504 Count := 0; 1513 for i:= 0 to 1 do1514 if (AdvPreq[ad, i] <> preNone) and (AdvPreq[ad, i] <> RO.ResearchTech) and1515 (RO.Tech[AdvPreq[ad, i]] < tsSeen) then1505 for I := 0 to 1 do 1506 if (AdvPreq[ad, I] <> preNone) and (AdvPreq[ad, I] <> RO.ResearchTech) and 1507 (RO.Tech[AdvPreq[ad, I]] < tsSeen) then 1516 1508 begin 1517 RateResearchAdv(AdvPreq[ad, i], Time);1509 RateResearchAdv(AdvPreq[ad, I], Time); 1518 1510 Inc(Count); 1519 1511 end; … … 1544 1536 1545 1537 // rate military techs 1546 for d:= 0 to nDomains - 1 do1538 for D := 0 to nDomains - 1 do 1547 1539 begin 1548 1540 CurrentCost := 0; 1549 1541 CurrentStrength := 0; 1550 1542 for PreView := True downto False do 1551 for i:= 0 to nUpgrade - 1 do1552 with Upgrade[ d, i] do1543 for I := 0 to nUpgrade - 1 do 1544 with Upgrade[D, I] do 1553 1545 if (Preq >= 0) and not (Preq in FutureTech) then 1554 1546 if ((Ro.ResearchTech = Preq) or (RO.Tech[Preq] >= tsSeen)) = PreView then … … 1561 1553 else 1562 1554 begin // rate 1563 if ( i> 0) and (Trans > 0) then1555 if (I > 0) and (Trans > 0) then 1564 1556 Inc(AdvanceValue[Preq], $400); 1565 1557 if Cost <= CurrentCost then 1566 Inc(AdvanceValue[Preq], (4 - d) * Strength * $400 div1567 (CurrentStrength + Upgrade[ d, 0].Strength))1558 Inc(AdvanceValue[Preq], (4 - D) * Strength * $400 div 1559 (CurrentStrength + Upgrade[D, 0].Strength)) 1568 1560 else 1569 Inc(AdvanceValue[Preq], (4 - d) * Strength * $200 div1570 (CurrentStrength + Upgrade[ d, 0].Strength));1561 Inc(AdvanceValue[Preq], (4 - D) * Strength * $200 div 1562 (CurrentStrength + Upgrade[D, 0].Strength)); 1571 1563 end; 1572 1564 end; … … 1648 1640 procedure TAI.AnalyzeMap; 1649 1641 var 1650 cix, Loc, Loc1, V8, f1, p1: integer;1642 cix, Loc, Loc1, V8, f1, p1: Integer; 1651 1643 Adjacent: TVicinity8Loc; 1652 1644 begin … … 1654 1646 1655 1647 // collect nation presence information for continents and oceans 1656 fillchar(ContinentPresence, sizeof(ContinentPresence), 0);1657 fillchar(OceanPresence, sizeof(OceanPresence), 0);1648 FillChar(ContinentPresence, SizeOf(ContinentPresence), 0); 1649 FillChar(OceanPresence, SizeOf(OceanPresence), 0); 1658 1650 for Loc := 0 to MapSize - 1 do 1659 1651 begin … … 1707 1699 end; 1708 1700 1709 fillchar(TotalPopulation, sizeof(TotalPopulation), 0);1710 fillchar(ContinentPopulation, sizeof(ContinentPopulation), 0);1711 fillchar(DistrictPopulation, 4 * nDistrict, 0);1701 FillChar(TotalPopulation, SizeOf(TotalPopulation), 0); 1702 FillChar(ContinentPopulation, SizeOf(ContinentPopulation), 0); 1703 FillChar(DistrictPopulation, 4 * nDistrict, 0); 1712 1704 1713 1705 // count population … … 1724 1716 if Loc >= 0 then 1725 1717 begin 1726 Inc(TotalPopulation[ me], Size);1727 assert(District[Loc] >= 0);1718 Inc(TotalPopulation[Me], Size); 1719 Assert(District[Loc] >= 0); 1728 1720 if District[Loc] < maxCOD then 1729 1721 Inc(DistrictPopulation[District[Loc]], Size); … … 1733 1725 procedure TAI.CollectModelCatStat; 1734 1726 var 1735 i, uix, Cat, mix, Quality: integer;1727 I, uix, Cat, mix, Quality: Integer; 1736 1728 begin 1737 1729 // categorize models … … 1779 1771 if (Loc >= 0) and (mix = mixCruiser) and (Map[Loc] and fTerrain < fGrass) then 1780 1772 begin 1781 i:= Formation[Loc];1782 if ( i >= 0) and (i< maxCOD) then1783 OceanWithShip := OceanWithShip or (1 shl i);1773 I := Formation[Loc]; 1774 if (I >= 0) and (I < maxCOD) then 1775 OceanWithShip := OceanWithShip or (1 shl I); 1784 1776 end; 1785 1777 end; 1786 1787 1778 1788 1779 procedure TAI.MoveUnitsHome; 1789 1780 const 1790 1781 PatrolDestination = lxmax * lymax; 1791 FirstSurplusLoop: array[mctGroundDefender..mctGroundAttacker] of integer = (2, 1);1782 FirstSurplusLoop: array[mctGroundDefender..mctGroundAttacker] of Integer = (2, 1); 1792 1783 var 1793 Cat, i, mix, cix, uix, Loop, nModelOrder: integer;1784 Cat, I, mix, cix, uix, Loop, nModelOrder: Integer; 1794 1785 Adjacent: TVicinity8Loc; 1795 LocNeed: array[0..lxmax * lymax - 1] of shortint;1796 Destination: array[0..nUmax - 1] of integer;1797 DistrictNeed, DistrictNeed0: array[0..maxCOD - 1] of integer;1798 ModelOrder: array[0..nMmax - 1] of integer;1799 complete, Fortified: boolean;1800 1801 function IsBombarded(cix: integer): boolean;1786 LocNeed: array[0..lxmax * lymax - 1] of ShortInt; 1787 Destination: array[0..nUmax - 1] of Integer; 1788 DistrictNeed, DistrictNeed0: array[0..maxCOD - 1] of Integer; 1789 ModelOrder: array[0..nMmax - 1] of Integer; 1790 complete, Fortified: Boolean; 1791 1792 function IsBombarded(cix: Integer): Boolean; 1802 1793 var 1803 Loc1, V8: integer;1794 Loc1, V8: Integer; 1804 1795 Adjacent: TVicinity8Loc; 1805 1796 begin … … 1818 1809 begin 1819 1810 Result := True; 1820 exit;1811 Exit; 1821 1812 end; 1822 1813 end; … … 1824 1815 end; 1825 1816 1826 procedure TryUtilize(uix: integer);1817 procedure TryUtilize(uix: Integer); 1827 1818 var 1828 cix, ProdCost, UtilizeCost: integer;1819 cix, ProdCost, UtilizeCost: Integer; 1829 1820 begin 1830 1821 if (MyUnit[uix].Health = 100) and (Map[MyUnit[uix].Loc] and … … 1838 1829 UtilizeCost := MyModel[MyUnit[uix].mix].Cost; 1839 1830 if Prod < (ProdCost - UtilizeCost * 2 div 3) * 1840 BuildCostMod[G.Difficulty[ me]] div 12 then1831 BuildCostMod[G.Difficulty[Me]] div 12 then 1841 1832 Unit_Disband(uix); 1842 1833 end; … … 1844 1835 end; 1845 1836 1846 procedure FindDestination(uix: integer);1837 procedure FindDestination(uix: Integer); 1847 1838 var 1848 MoveStyle, V8, Loc1, Time, NextLoc, NextTime, RecoverTurns: integer;1849 Reached: array[0..lxmax * lymax - 1] of boolean;1850 begin 1851 fillchar(Reached, MapSize, False);1839 MoveStyle, V8, Loc1, Time, NextLoc, NextTime, RecoverTurns: Integer; 1840 Reached: array[0..lxmax * lymax - 1] of Boolean; 1841 begin 1842 FillChar(Reached, MapSize, False); 1852 1843 Pile.Create(MapSize); 1853 1844 with MyUnit[uix] do … … 1863 1854 if (District[Loc1] >= 0) and (District[Loc1] < maxCOD) then 1864 1855 begin 1865 assert(DistrictNeed[District[Loc1]] > 0);1856 Assert(DistrictNeed[District[Loc1]] > 0); 1866 1857 Dec(DistrictNeed[District[Loc1]]); 1867 1858 end; 1868 1859 Destination[uix] := Loc1; 1869 break;1860 Break; 1870 1861 end; 1871 1862 Reached[Loc1] := True; … … 1874 1865 begin 1875 1866 NextLoc := Adjacent[V8]; 1876 if (NextLoc >= 0) and not Reached[NextLoc] and (RO.Territory[NextLoc] = me) then1867 if (NextLoc >= 0) and not Reached[NextLoc] and (RO.Territory[NextLoc] = Me) then 1877 1868 case CheckStep(MoveStyle, Time, V8 and 1, NextTime, RecoverTurns, 1878 1869 Map[Loc1], Map[NextLoc], False) of … … 1882 1873 Reached[NextLoc] := True; // don't check moving there again 1883 1874 csCheckTerritory: 1884 assert(False);1875 Assert(False); 1885 1876 end; 1886 1877 end; … … 1896 1887 Unit_Disband(uix); 1897 1888 1898 fillchar(UnitLack, sizeof(UnitLack), 0);1899 fillchar(Destination, 4 * RO.nUn, $FF);1900 for i:= 0 to maxCOD - 1 do1901 if uixPatrol[ i] >= 0 then1902 Destination[uixPatrol[ i]] := PatrolDestination;1889 FillChar(UnitLack, SizeOf(UnitLack), 0); 1890 FillChar(Destination, 4 * RO.nUn, $FF); 1891 for I := 0 to maxCOD - 1 do 1892 if uixPatrol[I] >= 0 then 1893 Destination[uixPatrol[I]] := PatrolDestination; 1903 1894 for uix := 0 to RO.nUn - 1 do 1904 1895 if (MyUnit[uix].mix = mixMilitia) or (MyUnit[uix].mix = mixCruiser) then … … 1912 1903 if ModelCat[mix] = Cat then 1913 1904 begin 1914 i:= nModelOrder;1915 while ( i > 0) and (ModelQuality[mix] < ModelQuality[ModelOrder[i- 1]]) do1916 begin 1917 ModelOrder[ i] := ModelOrder[i- 1];1918 Dec( i);1919 end; 1920 ModelOrder[ i] := mix;1905 I := nModelOrder; 1906 while (I > 0) and (ModelQuality[mix] < ModelQuality[ModelOrder[I - 1]]) do 1907 begin 1908 ModelOrder[I] := ModelOrder[I - 1]; 1909 Dec(I); 1910 end; 1911 ModelOrder[I] := mix; 1921 1912 Inc(nModelOrder); 1922 1913 end; … … 1931 1922 TryUtilize(uix); 1932 1923 1933 fillchar(LocNeed, MapSize, 0);1934 fillchar(DistrictNeed, sizeof(DistrictNeed), 0);1924 FillChar(LocNeed, MapSize, 0); 1925 FillChar(DistrictNeed, SizeOf(DistrictNeed), 0); 1935 1926 1936 1927 for cix := 0 to RO.nCity - 1 do … … 1955 1946 for uix := 0 to RO.nUn - 1 do 1956 1947 with MyUnit[uix] do 1957 if (Loc >= 0) and (Job = jCity) and (RO.Territory[Loc] = me) then1948 if (Loc >= 0) and (Job = jCity) and (RO.Territory[Loc] = Me) then 1958 1949 begin 1959 1950 LocNeed[Loc] := 1; … … 1963 1954 1964 1955 complete := Loop >= FirstSurplusLoop[Cat]; 1965 for i:= nModelOrder - 1 downto 0 do1956 for I := nModelOrder - 1 downto 0 do 1966 1957 begin 1967 1958 for Fortified := True downto False do 1968 1959 for uix := 0 to RO.nUn - 1 do 1969 1960 with MyUnit[uix] do 1970 if (mix = ModelOrder[ i]) and (Loc >= 0) and1961 if (mix = ModelOrder[I]) and (Loc >= 0) and 1971 1962 (Destination[uix] < 0) and (Master < 0) and 1972 1963 ((Flags and unFortified <> 0) = Fortified) and (LocNeed[Loc] > 0) then … … 1981 1972 for uix := 0 to RO.nUn - 1 do 1982 1973 with MyUnit[uix] do 1983 if (mix = ModelOrder[ i]) and (Loc >= 0) and (Destination[uix] < 0) and1974 if (mix = ModelOrder[I]) and (Loc >= 0) and (Destination[uix] < 0) and 1984 1975 (Master < 0) then 1985 1976 if (District[Loc] >= 0) and (District[Loc] < maxCOD) and … … 1998 1989 // distribute obsolete settlers 1999 1990 repeat 2000 fillchar(LocNeed, MapSize, 0);2001 fillchar(DistrictNeed, sizeof(DistrictNeed), 0);1991 FillChar(LocNeed, MapSize, 0); 1992 FillChar(DistrictNeed, SizeOf(DistrictNeed), 0); 2002 1993 2003 1994 for cix := 0 to RO.nCity - 1 do … … 2049 2040 for uix := 0 to RO.nUn - 1 do 2050 2041 with MyUnit[uix] do 2051 if (Loc >= 0) and (RO.Territory[Loc] = me) and (District[Loc] >= 0) and2042 if (Loc >= 0) and (RO.Territory[Loc] = Me) and (District[Loc] >= 0) and 2052 2043 (District[Loc] < maxCOD) and (ModelQuality[mix] > 0) then 2053 2044 case ModelCat[mix] of … … 2055 2046 Dec(UnitLack[District[Loc], ModelCat[mix]]) 2056 2047 end; 2057 end; // MoveUnitsHome 2058 2059 2060 procedure TAI.CheckAttack(uix: integer); 2048 end; 2049 2050 procedure TAI.CheckAttack(uix: Integer); 2061 2051 var 2062 2052 AttackScore, BestCount, AttackLoc, TestLoc, NextLoc, TestTime, V8, 2063 2053 TestScore, euix, MyDamage, EnemyDamage, OldLoc, AttackForecast, 2064 MoveResult, AttackResult, MoveStyle, NextTime, RecoverTurns: integer;2065 Tile: cardinal;2066 Exhausted: boolean;2054 MoveResult, AttackResult, MoveStyle, NextTime, RecoverTurns: Integer; 2055 Tile: Cardinal; 2056 Exhausted: Boolean; 2067 2057 Adjacent: TVicinity8Loc; 2068 Reached: array[0..lxmax * lymax - 1] of boolean;2058 Reached: array[0..lxmax * lymax - 1] of Boolean; 2069 2059 2070 2060 begin … … 2075 2065 AttackScore := -999999; 2076 2066 AttackLoc := -1; 2077 fillchar(Reached, MapSize, False);2067 FillChar(Reached, MapSize, False); 2078 2068 Pile.Create(MapSize); 2079 2069 Pile.Put(Loc, $800 - Movement); … … 2087 2077 if ((Tile and fUnit) <> 0) and ((Tile and fOwned) = 0) then 2088 2078 begin // enemy unit 2089 assert(TestTime < $1000);2079 Assert(TestTime < $1000); 2090 2080 Unit_FindEnemyDefender(TestLoc, euix); 2091 2081 if RO.Treaty[RO.EnemyUn[euix].Owner] < trPeace then … … 2176 2166 until Exhausted; 2177 2167 end; 2178 end; // CheckAttack 2179 2180 2181 procedure TAI.Patrol(uix: integer); 2168 end; 2169 2170 procedure TAI.Patrol(uix: Integer); 2182 2171 const 2183 2172 DistanceScore = 4; 2184 2173 var 2185 2174 PatrolScore, BestCount, PatrolLoc, TestLoc, NextLoc, TestTime, V8, 2186 TestScore, OldLoc, MoveResult, MoveStyle, NextTime, RecoverTurns: integer;2187 Tile: cardinal;2188 Exhausted, CaptureOnly: boolean;2175 TestScore, OldLoc, MoveResult, MoveStyle, NextTime, RecoverTurns: Integer; 2176 Tile: Cardinal; 2177 Exhausted, CaptureOnly: Boolean; 2189 2178 Adjacent: TVicinity8Loc; 2190 AdjacentUnknown: array[0..lxmax * lymax - 1] of shortint;2179 AdjacentUnknown: array[0..lxmax * lymax - 1] of ShortInt; 2191 2180 2192 2181 begin … … 2207 2196 // assume a score of 50 is the best achievable 2208 2197 or CaptureOnly and (TestTime >= $1000) then 2209 break;2198 Break; 2210 2199 2211 2200 TestScore := 0; … … 2282 2271 until Exhausted; 2283 2272 end; 2284 end; // Patrol2273 end; 2285 2274 2286 2275 procedure TAI.AttackAndPatrol; 2287 2276 const 2288 2277 nAttackCatOrder = 3; 2289 AttackCatOrder: array[0..nAttackCatOrder - 1] of integer =2278 AttackCatOrder: array[0..nAttackCatOrder - 1] of Integer = 2290 2279 (mctGroundAttacker, mctCruiser, mctGroundDefender); 2291 2280 var 2292 iCat, uix, uix1: integer;2293 IsPatrolUnit, Fortified: boolean;2281 iCat, uix, uix1: Integer; 2282 IsPatrolUnit, Fortified: Boolean; 2294 2283 begin 2295 2284 for uix := 0 to RO.nUn - 1 do … … 2310 2299 CheckAttack(uix); 2311 2300 2312 fillchar(uixPatrol, sizeof(uixPatrol), $FF);2301 FillChar(uixPatrol, SizeOf(uixPatrol), $FF); 2313 2302 for uix := 0 to RO.nUn - 1 do 2314 2303 with MyUnit[uix], MyModel[mix] do … … 2342 2331 Patrol(uix); 2343 2332 end; 2344 end; // AttackAndPatrol 2345 2346 2347 function TAI.HavePort: boolean; 2333 end; 2334 2335 function TAI.HavePort: Boolean; 2348 2336 var 2349 V8, cix, AdjacentLoc, f: integer;2337 V8, cix, AdjacentLoc, F: Integer; 2350 2338 Adjacent: TVicinity8Loc; 2351 2339 begin … … 2361 2349 if (AdjacentLoc >= 0) and ((Map[AdjacentLoc] and fTerrain) < fGrass) then 2362 2350 begin 2363 f:= Formation[AdjacentLoc];2364 if ( f >= 0) and (f < maxCOD) and (OceanPresence[f] and2365 not (1 shl me) <> 0) then2351 F := Formation[AdjacentLoc]; 2352 if (F >= 0) and (F < maxCOD) and (OceanPresence[F] and 2353 not (1 shl Me) <> 0) then 2366 2354 Result := True; 2367 2355 end; … … 2369 2357 end; 2370 2358 end; 2371 2372 2359 2373 2360 procedure TAI.SetCityProduction; 2374 2361 var 2375 2362 uix, cix, iix, dtr, V8, V21, NewImprovement, AdjacentLoc, MaxSettlers, 2376 maxcount, cixMilAcademy: integer;2377 TerrType: cardinal;2363 maxcount, cixMilAcademy: Integer; 2364 TerrType: Cardinal; 2378 2365 IsPort, IsNavalBase, NeedCruiser, CheckProd, Destructed, ProduceSettlers, 2379 ProduceMil: boolean;2366 ProduceMil: Boolean; 2380 2367 Adjacent: TVicinity8Loc; 2381 2368 Radius: TVicinity21Loc; 2382 2369 Report: TCityReport; 2383 HomeCount, CityProdRep: array[0..nCmax - 1] of integer;2384 MilProdCity: array[0..nCmax - 1] of boolean;2385 2386 procedure TryBuild(Improvement: integer);2370 HomeCount, CityProdRep: array[0..nCmax - 1] of Integer; 2371 MilProdCity: array[0..nCmax - 1] of Boolean; 2372 2373 procedure TryBuild(Improvement: Integer); 2387 2374 begin 2388 2375 if (NewImprovement = imTrGoods) // not already improvement of higher priority found … … 2394 2381 end; 2395 2382 2396 procedure TryDestruct(Improvement: integer);2383 procedure TryDestruct(Improvement: Integer); 2397 2384 begin 2398 2385 if Destructed or (MyCity[cix].Built[Improvement] = 0) then 2399 exit;2386 Exit; 2400 2387 if City_CurrentImprovementProject(cix) >= 0 then 2401 2388 City_RebuildImprovement(cix, Improvement) … … 2405 2392 and (Imp[CurrentImprovementProject].Kind in [ikCommon,ikNatGlobal,ikNatLocal]) 2406 2393 and ((Imp[CurrentImprovementProject].Cost*3-Imp[Improvement].Cost*2) 2407 *BuildCostMod[G.Difficulty[ me]]>MyCity[cix].Prod*(12*3)) then}2394 *BuildCostMod[G.Difficulty[Me]]>MyCity[cix].Prod*(12*3)) then} 2408 2395 Destructed := True; 2409 2396 end; 2410 2397 2411 function ChooseBuildModel(Cat: integer): integer;2398 function ChooseBuildModel(Cat: Integer): Integer; 2412 2399 var 2413 Count, mix: integer;2400 Count, mix: Integer; 2414 2401 begin 2415 2402 Count := 0; … … 2422 2409 Result := mix; 2423 2410 end; 2424 assert(Count > 0);2411 Assert(Count > 0); 2425 2412 end; 2426 2413 … … 2428 2415 // find military production cities 2429 2416 var 2430 cix, Total, d, Threshold, NewThreshold, Share, SharePlus, cixWorst: integer;2431 begin 2432 fillchar(MilProdCity, RO.nCity, 0);2417 cix, Total, D, Threshold, NewThreshold, Share, SharePlus, cixWorst: Integer; 2418 begin 2419 FillChar(MilProdCity, RO.nCity, 0); 2433 2420 GetCityProdPotential; 2434 for d:= 0 to maxCOD - 1 do2421 for D := 0 to maxCOD - 1 do 2435 2422 begin 2436 2423 Total := 0; 2437 2424 for cix := 0 to RO.nCity - 1 do 2438 2425 with MyCity[cix] do 2439 if (Loc >= 0) and (District[Loc] = d) then2426 if (Loc >= 0) and (District[Loc] = D) then 2440 2427 Total := Total + CityResult[cix]; 2441 2428 if Total = 0 then … … 2446 2433 for cix := 0 to RO.nCity - 1 do 2447 2434 with MyCity[cix] do 2448 if (Loc >= 0) and (District[Loc] = d) and2435 if (Loc >= 0) and (District[Loc] = D) and 2449 2436 (Built[imBarracks] + Built[imMilAcademy] > 0) then 2450 2437 begin … … 2461 2448 for cix := 0 to RO.nCity - 1 do 2462 2449 with MyCity[cix] do 2463 if (Loc >= 0) and (District[Loc] = d) and2450 if (Loc >= 0) and (District[Loc] = D) and 2464 2451 (Built[imBarracks] + Built[imMilAcademy] = 0) and 2465 2452 (Built[imObservatory] = 0) and (CityResult[cix] < Threshold) and … … 2478 2465 for cix := 0 to RO.nCity - 1 do 2479 2466 with MyCity[cix] do 2480 if (Loc >= 0) and (District[Loc] = d) and2467 if (Loc >= 0) and (District[Loc] = D) and 2481 2468 (Built[imBarracks] + Built[imMilAcademy] = 0) and 2482 2469 (CityResult[cix] >= Threshold) then … … 2484 2471 { if (cixWorst>=0) 2485 2472 and (Share-CityResult[cixWorst]*2>=Total*MilProdShare div 100) then 2486 MilProdCity[cixWorst]:= false;}2473 MilProdCity[cixWorst]:=False;} 2487 2474 end; 2488 2475 … … 2491 2478 if cixStateImp[imPalace] >= 0 then 2492 2479 begin 2493 d:= District[MyCity[cixStateImp[imPalace]].Loc];2494 if ( d >= 0) and (d< maxCOD) then2480 D := District[MyCity[cixStateImp[imPalace]].Loc]; 2481 if (D >= 0) and (D < maxCOD) then 2495 2482 begin 2496 2483 cixMilAcademy := -1; 2497 2484 for cix := 0 to RO.nCity - 1 do 2498 2485 with MyCity[cix] do 2499 if (Loc >= 0) and (District[Loc] = d) and2486 if (Loc >= 0) and (District[Loc] = D) and 2500 2487 (Built[imObservatory] + Built[imPalace] = 0) and 2501 2488 ((cixMilAcademy < 0) or (CityResult[cix] > CityResult[cixMilAcademy])) then … … 2513 2500 procedure ChangeHomeCities; 2514 2501 var 2515 uix, NewHome, HomeSupport, NewHomeSupport, SingleSupport: integer;2502 uix, NewHome, HomeSupport, NewHomeSupport, SingleSupport: Integer; 2516 2503 begin 2517 2504 if RO.Government in [gAnarchy, gFundamentalism] then 2518 exit;2505 Exit; 2519 2506 for uix := 0 to RO.nUn - 1 do 2520 2507 with MyUnit[uix] do … … 2564 2551 2565 2552 begin 2566 fillchar(HomeCount, 4 * RO.nCity, 0);2553 FillChar(HomeCount, 4 * RO.nCity, 0); 2567 2554 for uix := 0 to RO.nUn - 1 do 2568 2555 with MyUnit[uix] do … … 2757 2744 begin 2758 2745 TryBuild(imHarbor); 2759 break;2746 Break; 2760 2747 end; 2761 2748 end; … … 2775 2762 TryBuild(imRecycling); 2776 2763 if (Report.Trade - Report.Corruption >= 11) and 2777 (RO.Money < TotalPopulation[ me] * 2) then2764 (RO.Money < TotalPopulation[Me] * 2) then 2778 2765 TryBuild(imBank); 2779 2766 if (RO.NatBuilt[imStockEx] = 0) and … … 2812 2799 2813 2800 // rebuild imps no longer needed 2814 if (RO.TaxRate = 0) and (RO.Money >= TotalPopulation[ me] * 4) then2801 if (RO.TaxRate = 0) and (RO.Money >= TotalPopulation[Me] * 4) then 2815 2802 TryDestruct(imBank) 2816 2803 else if Report.Happy * 2 >= Size + 6 then … … 2836 2823 2837 2824 ChangeHomeCities; 2838 end; // SetCityProduction 2839 2840 2841 function TAI.ChooseGovernment: integer; 2825 end; 2826 2827 function TAI.ChooseGovernment: Integer; 2842 2828 begin 2843 2829 if Data.BehaviorFlags and bBarbarina <> 0 then … … 2856 2842 end; 2857 2843 2858 2859 2844 //------------------------------- 2860 2845 // DIPLOMACY 2861 2846 //------------------------------- 2862 2847 2863 function TAI.MostWanted(Nation, adGiveAway: integer): integer;2848 function TAI.MostWanted(Nation, adGiveAway: Integer): Integer; 2864 2849 var 2865 ad: integer;2850 ad: Integer; 2866 2851 begin 2867 2852 Result := -1; … … 2891 2876 end; 2892 2877 2893 procedure TAI.FindBestTrade(Nation: integer; var adWanted, adGiveAway: integer);2878 procedure TAI.FindBestTrade(Nation: Integer; var adWanted, adGiveAway: Integer); 2894 2879 var 2895 i, ad, ead, adTestGiveAway: integer;2880 I, ad, ead, adTestGiveAway: Integer; 2896 2881 begin 2897 2882 adWanted := -1; … … 2903 2888 begin 2904 2889 adTestGiveAway := -1; 2905 for i:= 0 to nRequestedTechs - 1 do2906 if (Data.RequestedTechs[ i] >= 0) and2907 (Data.RequestedTechs[ i] and $FFFF = Nation shl 8 + ead) then2890 for I := 0 to nRequestedTechs - 1 do 2891 if (Data.RequestedTechs[I] >= 0) and 2892 (Data.RequestedTechs[I] and $FFFF = Nation shl 8 + ead) then 2908 2893 adTestGiveAway := -2; // already requested before 2909 2894 if adTestGiveAway = -1 then … … 2928 2913 end; 2929 2914 2930 2931 function TAI.WantNegotiation(Nation: integer; NegoTime: TNegoTime): boolean; 2915 function TAI.WantNegotiation(Nation: Integer; NegoTime: TNegoTime): Boolean; 2932 2916 var 2933 p1, Count, adWanted, adGiveAway: integer;2917 p1, Count, adWanted, adGiveAway: Integer; 2934 2918 begin 2935 2919 if Data.BehaviorFlags and bBarbarina = bBarbarina then 2936 2920 begin 2937 2921 Result := Barbarina_WantNegotiation(Nation, NegoTime); 2938 exit;2922 Exit; 2939 2923 end; 2940 2924 … … 2944 2928 begin 2945 2929 Result := False; 2946 exit;2930 Exit; 2947 2931 end; 2948 2932 Count := 0; 2949 2933 for p1 := 0 to nPl - 1 do 2950 if (p1 <> me) and (1 shl p1 and RO.Alive <> 0) and (RO.Treaty[p1] >= trPeace) then2934 if (p1 <> Me) and (1 shl p1 and RO.Alive <> 0) and (RO.Treaty[p1] >= trPeace) then 2951 2935 Inc(Count); 2952 2936 if Count >= 3 then // enough peace made 2953 2937 begin 2954 2938 Result := False; 2955 exit;2939 Exit; 2956 2940 end; 2957 2941 end; … … 2994 2978 procedure TAI.DoNegotiation; 2995 2979 var 2996 i, adWanted, adGiveAway, adToGet, Slot: integer;2997 BuildFreeOffer: boolean;2980 I, adWanted, adGiveAway, adToGet, Slot: Integer; 2981 BuildFreeOffer: Boolean; 2998 2982 begin 2999 2983 if MyLastAction = scDipOffer then … … 3026 3010 begin 3027 3011 Barbarina_DoNegotiation; 3028 exit;3012 Exit; 3029 3013 end; 3030 3014 … … 3032 3016 begin 3033 3017 Barbarina_DoCheckNegotiation; 3034 exit;3018 Exit; 3035 3019 end; 3036 3020 … … 3047 3031 (OppoOffer.nDeliver + OppoOffer.nCost = 1) and 3048 3032 (OppoOffer.Price[0] and opMask = opTreaty) and 3049 ( integer(OppoOffer.Price[0] - opTreaty) > RO.Treaty[Opponent]) and3033 (Integer(OppoOffer.Price[0] - opTreaty) > RO.Treaty[Opponent]) and 3050 3034 ((OppoOffer.Price[0] - opTreaty < trAlliance) or 3051 3035 (RO.Tech[adScience] >= tsSeen)) then 3052 3036 MyAction := scDipAccept // accept all treaties 3053 3037 else if (RO.Treaty[Opponent] >= trPeace) and (OppoOffer.nDeliver = 1) and 3054 (OppoOffer.Price[0] and $FFFF0000 = opCivilReport + cardinal(Opponent) shl 16) and3038 (OppoOffer.Price[0] and $FFFF0000 = opCivilReport + Cardinal(Opponent) shl 16) and 3055 3039 (OppoOffer.nCost = 1) and (OppoOffer.Price[1] and $FFFF0000 = 3056 opCivilReport + cardinal(me) shl 16) then3040 opCivilReport + Cardinal(Me) shl 16) then 3057 3041 MyAction := scDipAccept // accept exchange of civil reports 3058 3042 else if (OppoOffer.nDeliver = 1) and (OppoOffer.nCost = 1) and … … 3084 3068 adWanted := MostWanted(Opponent, OppoOffer.Price[1] - opTech); 3085 3069 if (OppoOffer.Price[0] and opMask = opTech) and 3086 ( cardinal(adWanted) = OppoOffer.Price[0] - opTech) then3070 (Cardinal(adWanted) = OppoOffer.Price[0] - opTech) then 3087 3071 MyAction := scDipAccept // opponent's offer is already perfect 3088 3072 else if adWanted >= 0 then … … 3140 3124 MyOffer.Price[1] := opTech + adWanted; 3141 3125 MyAction := scDipOffer; 3142 for i:= 0 to nRequestedTechs - 1 do3143 if Data.RequestedTechs[ i] < 0 then3126 for I := 0 to nRequestedTechs - 1 do 3127 if Data.RequestedTechs[I] < 0 then 3144 3128 begin 3145 Slot := i;3146 break;3129 Slot := I; 3130 Break; 3147 3131 end 3148 else if ( i = 0) or (Data.RequestedTechs[i] shr 16 <3132 else if (I = 0) or (Data.RequestedTechs[I] shr 16 < 3149 3133 Data.RequestedTechs[Slot] shr 16) then // find most outdated entry 3150 Slot := i;3134 Slot := I; 3151 3135 Data.RequestedTechs[Slot] := RO.Turn shl 16 + Opponent shl 8 + adWanted; 3152 3136 end; 3153 3137 end; 3154 3138 end; 3155 end; // Negotiation 3156 3139 end; 3157 3140 3158 3141 procedure SetLeaveOutValue; 3159 3142 3160 procedure Process(ad: integer);3143 procedure Process(ad: Integer); 3161 3144 var 3162 i: integer;3145 I: Integer; 3163 3146 begin 3164 3147 if LeaveOutValue[ad] < 0 then 3165 3148 begin 3166 3149 LeaveOutValue[ad] := 0; 3167 for i:= 0 to 1 do3168 if AdvPreq[ad, i] >= 0 then3169 begin 3170 Process(AdvPreq[ad, i]);3171 if AdvPreq[ad, i] in LeaveOutTechs then3172 Inc(LeaveOutValue[ad], LeaveOutValue[AdvPreq[ad, i]] + 1);3150 for I := 0 to 1 do 3151 if AdvPreq[ad, I] >= 0 then 3152 begin 3153 Process(AdvPreq[ad, I]); 3154 if AdvPreq[ad, I] in LeaveOutTechs then 3155 Inc(LeaveOutValue[ad], LeaveOutValue[AdvPreq[ad, I]] + 1); 3173 3156 end; 3174 3157 end; … … 3176 3159 3177 3160 var 3178 ad: integer;3161 ad: Integer; 3179 3162 begin 3180 3163 FillChar(LeaveOutValue, SizeOf(LeaveOutValue), $FF); … … 3185 3168 3186 3169 initialization 3187 RWDataSize := sizeof(TPersistentData);3170 RWDataSize := SizeOf(TPersistentData); 3188 3171 SetLeaveOutValue; 3189 3172 -
branches/highdpi/AI/StdAI/Barbarina.pas
r349 r465 25 25 type 26 26 TColonyShipPlan = array[0..nShipPart - 1] of record 27 cixProducing: integer;28 LocResource: array[0..maxModern - 1] of integer;29 nLocResource: integer;30 LocFoundCity: array[0..maxModern - 1] of integer;31 nLocFoundCity: integer;27 cixProducing: Integer; 28 LocResource: array[0..maxModern - 1] of Integer; 29 nLocResource: Integer; 30 LocFoundCity: array[0..maxModern - 1] of Integer; 31 nLocFoundCity: Integer; 32 32 end; 33 33 34 34 TBarbarina = class(TToolAI) 35 constructor Create(Nation: integer); override;35 constructor Create(Nation: Integer); override; 36 36 37 37 protected 38 38 ColonyShipPlan: TColonyShipPlan; 39 function Barbarina_GoHidden: boolean; // whether we should prepare for barbarina mode40 function Barbarina_Go: boolean; // whether we should switch to barbarina mode now39 function Barbarina_GoHidden: Boolean; // whether we should prepare for barbarina mode 40 function Barbarina_Go: Boolean; // whether we should switch to barbarina mode now 41 41 procedure Barbarina_DoTurn; 42 42 procedure Barbarina_SetCityProduction; 43 function Barbarina_ChooseResearchAdvance: integer;44 function Barbarina_WantCheckNegotiation(Nation: integer): boolean;43 function Barbarina_ChooseResearchAdvance: Integer; 44 function Barbarina_WantCheckNegotiation(Nation: Integer): Boolean; 45 45 procedure Barbarina_DoCheckNegotiation; 46 function Barbarina_WantNegotiation(Nation: integer; NegoTime: TNegoTime): boolean;46 function Barbarina_WantNegotiation(Nation: Integer; NegoTime: TNegoTime): Boolean; 47 47 procedure Barbarina_DoNegotiation; 48 48 procedure MakeColonyShipPlan; 49 49 50 50 private 51 TurnOfMapAnalysis, Neighbours: integer;52 ContinentPresence: array[0..maxCOD - 1] of integer;53 OceanPresence: array[0..maxCOD - 1] of integer;54 ContinentSize: array[0..maxCOD - 1] of integer;55 OceanSize: array[0..maxCOD - 1] of integer;56 mixBest: array[0..nModelCategory - 1] of integer;51 TurnOfMapAnalysis, Neighbours: Integer; 52 ContinentPresence: array[0..maxCOD - 1] of Integer; 53 OceanPresence: array[0..maxCOD - 1] of Integer; 54 ContinentSize: array[0..maxCOD - 1] of Integer; 55 OceanSize: array[0..maxCOD - 1] of Integer; 56 mixBest: array[0..nModelCategory - 1] of Integer; 57 57 NegoCause: (CancelTreaty); 58 function IsModelAvailable(rmix: integer): boolean;58 function IsModelAvailable(rmix: Integer): Boolean; 59 59 procedure FindBestModels; 60 60 procedure AnalyzeMap; 61 procedure RateAttack(uix: integer);62 function DoAttack(uix, AttackLoc: integer): boolean;63 function ProcessMove(uix: integer): boolean;61 procedure RateAttack(uix: Integer); 62 function DoAttack(uix, AttackLoc: Integer): Boolean; 63 function ProcessMove(uix: Integer): Boolean; 64 64 procedure AttackAndPatrol; 65 65 end; … … 73 73 type 74 74 TResearchModel = record 75 Category, Domain, Weight, adStop, FutMStrength: integer;76 Upgrades: cardinal;77 Cap: array [0..nFeature - 1] of integer;75 Category, Domain, Weight, adStop, FutMStrength: Integer; 76 Upgrades: Cardinal; 77 Cap: array [0..nFeature - 1] of Integer; 78 78 end; 79 79 … … 93 93 94 94 nResearchOrder = 40; 95 ResearchOrder: array[0..nResearchOrder - 1] of integer =95 ResearchOrder: array[0..nResearchOrder - 1] of Integer = 96 96 (adBronzeWorking, -adMapMaking, adChivalry, adMonotheism, adIronWorking, 97 97 adGunPowder, adTheology, adConstruction, adCodeOfLaws, -adEngineering, … … 171 171 172 172 var 173 Moved: array[0..numax - 1] of boolean;174 UnitPresence: array[0..lxmax * lymax - 1] of byte;173 Moved: array[0..numax - 1] of Boolean; 174 UnitPresence: array[0..lxmax * lymax - 1] of Byte; 175 175 euixMap: array[0..lxmax * lymax - 1] of smallint; 176 176 uixAttack: array[0..neumax - 1] of smallint; 177 AttackScore: array[0..neumax - 1] of integer;178 179 constructor TBarbarina.Create(Nation: integer);177 AttackScore: array[0..neumax - 1] of Integer; 178 179 constructor TBarbarina.Create(Nation: Integer); 180 180 begin 181 181 inherited; … … 184 184 185 185 // whether one of the existing models matches a specific research model 186 function TBarbarina.IsModelAvailable(rmix: integer): boolean;186 function TBarbarina.IsModelAvailable(rmix: Integer): Boolean; 187 187 var 188 i, mix, MStrength: integer;188 I, mix, MStrength: Integer; 189 189 begin 190 190 Result := False; … … 199 199 Result := MStrength < (MyModel[mix].MStrength * 3) div 2; 200 200 // for future techs: don't count model available if 50% stronger possible 201 for i:= 0 to nFeature - 1 do202 if MyModel[mix].Cap[ i] < Cap[i] then201 for I := 0 to nFeature - 1 do 202 if MyModel[mix].Cap[I] < Cap[I] then 203 203 begin 204 204 Result := False; 205 break;205 Break; 206 206 end; 207 207 if Result then 208 break;208 Break; 209 209 end; 210 210 end; 211 211 end; 212 212 213 function TBarbarina.Barbarina_GoHidden: boolean;213 function TBarbarina.Barbarina_GoHidden: Boolean; 214 214 var 215 V21, Loc1, cix: integer;215 V21, Loc1, cix: Integer; 216 216 Radius: TVicinity21Loc; 217 217 begin … … 238 238 end; 239 239 240 function TBarbarina.Barbarina_Go: boolean;240 function TBarbarina.Barbarina_Go: Boolean; 241 241 begin 242 242 if IsResearched(adMassProduction) then … … 249 249 Result := (RO.nCity >= 3) and IsResearched(adMapMaking) and 250 250 IsModelAvailable(EntryModel_Base); 251 exit;251 Exit; 252 252 end; 253 253 Result := Result and ((RO.nUn >= RO.nCity * 3) or 254 (RO.Wonder[woZeus].EffectiveOwner = me));254 (RO.Wonder[woZeus].EffectiveOwner = Me)); 255 255 end; 256 256 257 257 procedure TBarbarina.AnalyzeMap; 258 258 var 259 Loc, Loc1, V8, f1, p1, cix: integer;259 Loc, Loc1, V8, f1, p1, cix: Integer; 260 260 Adjacent: TVicinity8Loc; 261 261 begin 262 262 if TurnOfMapAnalysis = RO.Turn then 263 exit;263 Exit; 264 264 265 265 // inherited; 266 266 267 267 // collect nation presence information for continents and oceans 268 fillchar(ContinentPresence, sizeof(ContinentPresence), 0);269 fillchar(OceanPresence, sizeof(OceanPresence), 0);270 fillchar(ContinentSize, sizeof(ContinentSize), 0);271 fillchar(OceanSize, sizeof(OceanSize), 0);268 FillChar(ContinentPresence, SizeOf(ContinentPresence), 0); 269 FillChar(OceanPresence, SizeOf(OceanPresence), 0); 270 FillChar(ContinentSize, SizeOf(ContinentSize), 0); 271 FillChar(OceanSize, SizeOf(OceanSize), 0); 272 272 for Loc := 0 to MapSize - 1 do 273 273 begin … … 339 339 procedure TBarbarina.FindBestModels; 340 340 var 341 i, mix, rmix, cat: integer;341 I, mix, rmix, cat: Integer; 342 342 begin 343 for i:= 0 to nModelCategory - 1 do344 mixBest[ i] := -1;343 for I := 0 to nModelCategory - 1 do 344 mixBest[I] := -1; 345 345 for rmix := nResearchModel - 1 downto 0 do 346 346 with ResearchModel[rmix] do … … 351 351 begin 352 352 mixBest[Category] := mix; 353 for i:= 0 to nFeature - 1 do354 if MyModel[mix].Cap[ i] < Cap[i] then353 for I := 0 to nFeature - 1 do 354 if MyModel[mix].Cap[I] < Cap[I] then 355 355 begin 356 356 mixBest[Category] := -1; 357 break;357 Break; 358 358 end; 359 359 if mixBest[Category] >= 0 then 360 break;360 Break; 361 361 end; 362 362 for mix := 3 to RO.nModel - 1 do … … 387 387 begin 388 388 mixBest[ctSeaTrans] := mix; 389 break;389 Break; 390 390 end; 391 391 end; … … 406 406 407 407 // find one unit to destroy each known enemy unit, result in uixAttack 408 procedure TBarbarina.RateAttack(uix: integer);408 procedure TBarbarina.RateAttack(uix: Integer); 409 409 var 410 410 MoveStyle, TestLoc, TestTime, NextLoc, NextTime, V8, RemHealth, 411 RecoverTurns, Score, BestScore, euixBest, uixOld: integer;412 NextTile: cardinal;411 RecoverTurns, Score, BestScore, euixBest, uixOld: Integer; 412 NextTile: Cardinal; 413 413 Adjacent: TVicinity8Loc; 414 414 Defense: ^TUnitInfo; 415 Reached: array[0..lxmax * lymax - 1] of boolean;415 Reached: array[0..lxmax * lymax - 1] of Boolean; 416 416 begin 417 417 with MyUnit[uix] do … … 419 419 begin 420 420 BestScore := 0; 421 fillchar(Reached, MapSize, False);421 FillChar(Reached, MapSize, False); 422 422 MoveStyle := GetMyMoveStyle(mix, Health); 423 423 Pile.Create(MapSize); … … 494 494 end; 495 495 496 function TBarbarina.DoAttack(uix, AttackLoc: integer): boolean;496 function TBarbarina.DoAttack(uix, AttackLoc: Integer): Boolean; 497 497 // AttackLoc=maNextCity means bombard only 498 498 var 499 499 MoveResult, Kind, Temp, MoveStyle, TestLoc, TestTime, NextLoc, 500 NextTime, V8, RecoverTurns, ecix: integer;501 NextTile: cardinal;502 AttackPositionReached, IsBombardment: boolean;500 NextTime, V8, RecoverTurns, ecix: Integer; 501 NextTile: Cardinal; 502 AttackPositionReached, IsBombardment: Boolean; 503 503 Adjacent: TVicinity8Loc; 504 PreLoc: array[0..lxmax * lymax - 1] of word;505 Reached: array[0..lxmax * lymax - 1] of boolean;504 PreLoc: array[0..lxmax * lymax - 1] of Word; 505 Reached: array[0..lxmax * lymax - 1] of Boolean; 506 506 begin 507 507 Result := False; … … 516 516 else 517 517 Kind := 0; 518 fillchar(Reached, MapSize, False);518 FillChar(Reached, MapSize, False); 519 519 AttackPositionReached := False; 520 520 MoveStyle := GetMyMoveStyle(mix, Health); … … 524 524 begin 525 525 if (TestTime >= $800) or (AttackLoc = maNextCity) and (TestTime > $800 - 100) then 526 break;526 Break; 527 527 Reached[TestLoc] := True; 528 528 V8_to_Loc(TestLoc, Adjacent); … … 537 537 begin 538 538 City_FindEnemyCity(NextLoc, ecix); 539 assert(ecix >= 0);539 Assert(ecix >= 0); 540 540 with RO.EnemyCity[ecix] do 541 541 if (Size > 2) and (Flags and ciCoastalFort = 0) then … … 547 547 begin 548 548 AttackPositionReached := True; 549 break;549 Break; 550 550 end 551 551 else if not Reached[NextLoc] then … … 572 572 begin 573 573 PreLoc[NextLoc] := TestLoc; 574 break;574 Break; 575 575 end; 576 576 end; 577 577 Pile.Free; 578 578 if not AttackPositionReached then 579 exit;579 Exit; 580 580 581 581 TestLoc := AttackLoc; … … 601 601 begin 602 602 City_FindEnemyCity(AttackLoc, ecix); 603 assert(ecix >= 0);603 Assert(ecix >= 0); 604 604 while (Movement >= 100) and (RO.EnemyCity[ecix].Size > 2) do 605 605 Unit_Step(uix, AttackLoc); … … 611 611 end; 612 612 613 function TBarbarina.ProcessMove(uix: integer): boolean;613 function TBarbarina.ProcessMove(uix: Integer): Boolean; 614 614 // return true if no new enemy spotted 615 615 const … … 618 618 PatrolScore, BestCount, PatrolLoc, TestLoc, NextLoc, TestTime, V8, 619 619 TestScore, MoveResult, MoveStyle, NextTime, TerrOwner, Kind, Temp, 620 RecoverTurns, MaxScore: integer;621 Tile, NextTile: cardinal;622 CaptureOnly, PeaceBorder, done, NextToEnemyCity: boolean;620 RecoverTurns, MaxScore: Integer; 621 Tile, NextTile: Cardinal; 622 CaptureOnly, PeaceBorder, done, NextToEnemyCity: Boolean; 623 623 Adjacent: TVicinity8Loc; 624 AdjacentUnknown: array[0..lxmax * lymax - 1] of shortint;625 PreLoc: array[0..lxmax * lymax - 1] of word;626 MoreTurn: array[0..lxmax * lymax - 1] of byte;624 AdjacentUnknown: array[0..lxmax * lymax - 1] of ShortInt; 625 PreLoc: array[0..lxmax * lymax - 1] of Word; 626 MoreTurn: array[0..lxmax * lymax - 1] of Byte; 627 627 628 628 begin … … 637 637 if Map[Loc] and fCity = 0 then 638 638 Unit_MoveEx(uix, maNextCity); 639 exit;639 Exit; 640 640 end; 641 641 … … 666 666 // assume a score of $400 is the best achievable 667 667 or CaptureOnly and (TestTime >= $1000) then 668 break;668 Break; 669 669 670 670 TestScore := 0; 671 671 Tile := Map[TestLoc]; 672 assert(Tile and (fUnit or fOwned) <> fUnit);672 Assert(Tile and (fUnit or fOwned) <> fUnit); 673 673 TerrOwner := RO.Territory[TestLoc]; 674 674 AdjacentUnknown[TestLoc] := 0; … … 743 743 TestScore := $400 - 14 744 744 else if AdjacentUnknown[TestLoc] > 0 then 745 if PeaceBorder or (TerrOwner >= 0) and (TerrOwner <> me) and745 if PeaceBorder or (TerrOwner >= 0) and (TerrOwner <> Me) and 746 746 (RO.Treaty[TerrOwner] < trPeace) then 747 747 TestScore := $400 - 32 + AdjacentUnknown[TestLoc] … … 790 790 end; 791 791 if PatrolLoc = Loc then 792 exit;792 Exit; 793 793 TestLoc := PatrolLoc; 794 794 NextLoc := PreLoc[TestLoc]; … … 814 814 Result := MoveResult and rEnemySpotted = 0; 815 815 done := True; 816 break;817 end; 818 assert(Loc = NextLoc);816 Break; 817 end; 818 Assert(Loc = NextLoc); 819 819 end; 820 820 if Loc >= 0 then … … 833 833 if Result then 834 834 Moved[uix] := True; 835 end; // ProcessMove835 end; 836 836 837 837 procedure TBarbarina.AttackAndPatrol; … … 839 839 procedure SetCityDefenders; 840 840 var 841 uix, cix, V8, Loc1, Best, uixBest, det: integer;841 uix, cix, V8, Loc1, Best, uixBest, det: Integer; 842 842 Adjacent: TVicinity8Loc; 843 IsPort: boolean;843 IsPort: Boolean; 844 844 begin 845 845 for cix := 0 to RO.nCity - 1 do … … 887 887 procedure ProcessSeaTransport; 888 888 var 889 i, f, uix, Loc1, a, b: integer;890 ready, go: boolean;889 I, F, uix, Loc1, A, B: Integer; 890 ready, go: Boolean; 891 891 TransportPlan: TGroupTransportPlan; 892 892 begin 893 893 go := False; 894 for f:= 0 to maxCOD - 1 do895 if ( f < nContinent) and (ContinentPresence[f] and not896 (1 shl me or PresenceUnknown) <> 0) then894 for F := 0 to maxCOD - 1 do 895 if (F < nContinent) and (ContinentPresence[F] and not 896 (1 shl Me or PresenceUnknown) <> 0) then 897 897 go := True; // any enemy island known? 898 898 if not go then 899 exit;899 Exit; 900 900 901 901 SeaTransport_BeginInitialize; … … 907 907 (MyModel[mix].Attack > 0) and (Map[Loc] and fTerrain >= fGrass) then 908 908 begin 909 f:= Formation[Loc];910 if ( f >= 0) and (f < maxCOD) and (ContinentPresence[f] and911 not (1 shl me) = 0) then909 F := Formation[Loc]; 910 if (F >= 0) and (F < maxCOD) and (ContinentPresence[F] and 911 not (1 shl Me) = 0) then 912 912 begin 913 913 go := True; … … 932 932 if Map[Loc1] and fTerrain >= fGrass then 933 933 begin 934 f:= Formation[Loc1];935 if ( f >= 0) and (f < maxCOD) and (ContinentPresence[f] and936 not (1 shl me or PresenceUnknown) <> 0) then934 F := Formation[Loc1]; 935 if (F >= 0) and (F < maxCOD) and (ContinentPresence[F] and 936 not (1 shl Me or PresenceUnknown) <> 0) then 937 937 SeaTransport_AddDestination(Loc1); 938 938 end; … … 948 948 end; 949 949 if ready then 950 for i:= 0 to TransportPlan.nLoad - 1 do950 for I := 0 to TransportPlan.nLoad - 1 do 951 951 begin 952 952 Loc_to_ab(TransportPlan.LoadLoc, 953 MyUnit[TransportPlan.uixLoad[ i]].Loc, a, b);954 ready := ready and (abs( a) <= 1) and (abs(b) <= 1);953 MyUnit[TransportPlan.uixLoad[I]].Loc, A, B); 954 ready := ready and (abs(A) <= 1) and (abs(B) <= 1); 955 955 end; 956 956 if ready then 957 957 begin 958 for i:= 0 to TransportPlan.nLoad - 1 do959 begin 960 Unit_Step(TransportPlan.uixLoad[ i], TransportPlan.LoadLoc);961 Moved[TransportPlan.uixLoad[ i]] := True;958 for I := 0 to TransportPlan.nLoad - 1 do 959 begin 960 Unit_Step(TransportPlan.uixLoad[I], TransportPlan.LoadLoc); 961 Moved[TransportPlan.uixLoad[I]] := True; 962 962 end; 963 963 end 964 964 else 965 965 begin 966 for i:= 0 to TransportPlan.nLoad - 1 do967 begin 968 Unit_MoveEx(TransportPlan.uixLoad[ i], TransportPlan.LoadLoc, mxAdjacent);969 Moved[TransportPlan.uixLoad[ i]] := True;966 for I := 0 to TransportPlan.nLoad - 1 do 967 begin 968 Unit_MoveEx(TransportPlan.uixLoad[I], TransportPlan.LoadLoc, mxAdjacent); 969 Moved[TransportPlan.uixLoad[I]] := True; 970 970 end; 971 971 end; … … 973 973 end; 974 974 975 procedure ProcessUnload(uix: integer);976 977 procedure Unload(Kind, ToLoc: integer);975 procedure ProcessUnload(uix: Integer); 976 977 procedure Unload(Kind, ToLoc: Integer); 978 978 var 979 uix1: integer;979 uix1: Integer; 980 980 begin 981 981 for uix1 := 0 to RO.nUn - 1 do … … 987 987 Unit_Step(uix1, ToLoc); 988 988 UnitPresence[ToLoc] := UnitPresence[ToLoc] or Kind; 989 break;989 Break; 990 990 end; 991 991 end; … … 993 993 var 994 994 uix1, MoveStyle, TestLoc, TestTime, NextLoc, NextTime, V8, 995 RecoverTurns, nSlow, nFast, SlowUnloadLoc, FastUnloadLoc, EndLoc, f: integer;996 NextTile: cardinal;995 RecoverTurns, nSlow, nFast, SlowUnloadLoc, FastUnloadLoc, EndLoc, F: Integer; 996 NextTile: Cardinal; 997 997 Adjacent: TVicinity8Loc; 998 Reached: array[0..lxmax * lymax - 1] of boolean;998 Reached: array[0..lxmax * lymax - 1] of Boolean; 999 999 begin 1000 1000 // inventory … … 1017 1017 FastUnloadLoc := -1; 1018 1018 EndLoc := -1; 1019 fillchar(Reached, MapSize, False);1019 FillChar(Reached, MapSize, False); 1020 1020 Pile.Create(MapSize); 1021 1021 Pile.Put(Loc, $800 - Movement); … … 1034 1034 else if NextTile and fTerrain >= fGrass then 1035 1035 begin 1036 f:= Formation[NextLoc];1037 if ( f >= 0) and (f< maxCOD) and1038 (ContinentPresence[ f] and not (1 shl me or PresenceUnknown) <> 0) and1036 F := Formation[NextLoc]; 1037 if (F >= 0) and (F < maxCOD) and 1038 (ContinentPresence[F] and not (1 shl Me or PresenceUnknown) <> 0) and 1039 1039 (NextTile and (fUnit or fOwned) <> fUnit) then 1040 1040 begin … … 1074 1074 1075 1075 if EndLoc < 0 then 1076 exit;1076 Exit; 1077 1077 if Loc <> EndLoc then 1078 1078 Unit_MoveEx(uix, EndLoc); 1079 1079 if Loc <> EndLoc then 1080 exit;1080 Exit; 1081 1081 if SlowUnloadLoc >= 0 then 1082 1082 begin … … 1092 1092 begin 1093 1093 Moved[uix] := False; 1094 exit;1094 Exit; 1095 1095 end 1096 1096 until False; … … 1099 1099 1100 1100 var 1101 uix, euix, Kind, euixBest, AttackLoc: integer;1102 OldTile: cardinal;1103 BackToStart, FirstLoop: boolean;1101 uix, euix, Kind, euixBest, AttackLoc: Integer; 1102 OldTile: Cardinal; 1103 BackToStart, FirstLoop: Boolean; 1104 1104 begin 1105 fillchar(UnitPresence, MapSize, 0);1105 FillChar(UnitPresence, MapSize, 0); 1106 1106 for uix := 0 to RO.nUn - 1 do 1107 1107 with MyUnit[uix] do … … 1116 1116 end; 1117 1117 1118 fillchar(Moved, RO.nUn, False);1118 FillChar(Moved, RO.nUn, False); 1119 1119 for uix := 0 to RO.nUn - 1 do 1120 1120 if (MyUnit[uix].Master >= 0) or (MyUnit[uix].TroopLoad > 0) then … … 1128 1128 if RO.nEnemyUn > 0 then 1129 1129 begin 1130 fillchar(euixMap, MapSize * 2, $FF);1131 fillchar(AttackScore, RO.nEnemyUn * 4, 0);1130 FillChar(euixMap, MapSize * 2, $FF); 1131 FillChar(AttackScore, RO.nEnemyUn * 4, 0); 1132 1132 for euix := 0 to RO.nEnemyUn - 1 do 1133 1133 with RO.EnemyUn[euix] do … … 1140 1140 end; 1141 1141 if not BackToStart then 1142 break;1142 Break; 1143 1143 1144 1144 for uix := 0 to RO.nUn - 1 do … … 1155 1155 euixBest := euix; 1156 1156 if euixBest < 0 then 1157 break;1157 Break; 1158 1158 uix := uixAttack[euixBest]; 1159 1159 AttackLoc := RO.EnemyUn[euixBest].Loc; … … 1202 1202 begin 1203 1203 BackToStart := True; 1204 break;1204 Break; 1205 1205 end 1206 1206 until not BackToStart; 1207 end; // AttackAndPatrol1207 end; 1208 1208 1209 1209 procedure TBarbarina.Barbarina_SetCityProduction; … … 1214 1214 1 shl woMagellan + 1 shl woEiffel + 1 shl woLiberty + 1 shl woShinkansen; 1215 1215 1216 function LowPriority(cix: integer): boolean;1216 function LowPriority(cix: Integer): Boolean; 1217 1217 var 1218 part, cixHighPriority, TestDistance: integer;1218 part, cixHighPriority, TestDistance: Integer; 1219 1219 begin 1220 1220 Result := False; … … 1228 1228 begin 1229 1229 Result := True; 1230 exit;1230 Exit; 1231 1231 end; 1232 1232 end; … … 1234 1234 end; 1235 1235 1236 function ChooseWonderToBuild(WonderAvailable: integer; AllowCoastal: boolean): integer;1236 function ChooseWonderToBuild(WonderAvailable: Integer; AllowCoastal: Boolean): Integer; 1237 1237 var 1238 Count, iix: integer;1238 Count, iix: Integer; 1239 1239 begin 1240 1240 if (WonderAvailable and PrimeWonder > 0) and (AllowCoastal or … … 1267 1267 begin 1268 1268 Result := iix; 1269 exit;1269 Exit; 1270 1270 end; 1271 1271 end; … … 1273 1273 1274 1274 var 1275 i, iix, cix, mix, uix, mixProduce, mixShip, V8, V21, Loc1, TotalPop,1276 AlonePop, f, f1, nTownGuard, ShipPart, ProduceShipPart, TestDistance,1277 part, WonderAvailable, WonderInWork, cixNewCapital, Center, Score, BestScore: integer;1278 mixCount: array[0..nmmax - 1] of integer;1275 I, iix, cix, mix, uix, mixProduce, mixShip, V8, V21, Loc1, TotalPop, 1276 AlonePop, F, f1, nTownGuard, ShipPart, ProduceShipPart, TestDistance, 1277 part, WonderAvailable, WonderInWork, cixNewCapital, Center, Score, BestScore: Integer; 1278 mixCount: array[0..nmmax - 1] of Integer; 1279 1279 //RareLoc: array[0..5] of integer; 1280 1280 Adjacent: TVicinity8Loc; 1281 1281 IsCoastal, IsPort, IsUnitProjectObsolete, HasSettler, SpezializeShipProduction, 1282 1282 AlgaeAvailable, ProjectComplete, DoLowPriority, WillProduceColonyShip, 1283 ImportantCity: boolean;1283 ImportantCity: Boolean; 1284 1284 Radius: TVicinity21Loc; 1285 1285 Report: TCityReportNew; … … 1289 1289 FindBestModels; 1290 1290 1291 fillchar(mixCount, RO.nModel * 4, 0);1291 FillChar(mixCount, RO.nModel * 4, 0); 1292 1292 for uix := 0 to RO.nUn - 1 do 1293 1293 with MyUnit[uix] do … … 1317 1317 begin 1318 1318 Inc(TotalPop, Size); 1319 f:= Formation[Loc];1320 if ( f < 0) or (f >= maxCOD) or (ContinentPresence[f] = 1 shl me) then1319 F := Formation[Loc]; 1320 if (F < 0) or (F >= maxCOD) or (ContinentPresence[F] = 1 shl Me) then 1321 1321 Inc(AlonePop, Size); 1322 1322 end; … … 1358 1358 if (f1 >= 0) and (f1 < maxCOD) and 1359 1359 ((OceanSize[f1] >= 8) or (OceanPresence[f1] and not 1360 (1 shl me) <> 0)) then1360 (1 shl Me) <> 0)) then 1361 1361 begin // prefer non-coastal cities 1362 1362 Dec(Score, 18); 1363 break;1363 Break; 1364 1364 end; 1365 1365 end; … … 1390 1390 (LowPriority(cix) = DoLowPriority) then 1391 1391 begin 1392 f:= Formation[Loc];1392 F := Formation[Loc]; 1393 1393 IsCoastal := False; 1394 1394 IsPort := False; … … 1402 1402 f1 := Formation[Loc1]; 1403 1403 if (f1 >= 0) and (f1 < maxCOD) and (OceanSize[f1] >= 8) and 1404 (OceanPresence[f1] and not (1 shl me) <> 0) then1404 (OceanPresence[f1] and not (1 shl Me) <> 0) then 1405 1405 begin 1406 1406 IsPort := True; 1407 break;1407 Break; 1408 1408 end; 1409 1409 end; … … 1412 1412 (RO.Model[City_CurrentUnitProject(cix)].Kind <> mkSettler) then 1413 1413 begin 1414 i:= nModelCategory - 1;1415 while ( i >= 0) and (City_CurrentUnitProject(cix) <> mixBest[i]) do1416 Dec( i);1417 IsUnitProjectObsolete := i< 0;1414 I := nModelCategory - 1; 1415 while (I >= 0) and (City_CurrentUnitProject(cix) <> mixBest[I]) do 1416 Dec(I); 1417 IsUnitProjectObsolete := I < 0; 1418 1418 end 1419 1419 else … … 1581 1581 City_StartImprovement(cix,imMissileBat)} 1582 1582 else if IsPort and (not SpezializeShipProduction or 1583 ( f < 0) or (f >= maxCOD) or (ContinentPresence[f] = 1 shl me)) and1583 (F < 0) or (F >= maxCOD) or (ContinentPresence[F] = 1 shl Me)) and 1584 1584 (Built[imDockyard] = 0) and City_Improvable(cix, imDockyard) then 1585 1585 City_StartImprovement(cix, imDockyard) 1586 1586 else if IsPort and (mixShip >= 0) and 1587 (not SpezializeShipProduction or ( f< 0) or1588 ( f >= maxCOD) or (ContinentPresence[f] = 1 shl me)) then1587 (not SpezializeShipProduction or (F < 0) or 1588 (F >= maxCOD) or (ContinentPresence[F] = 1 shl Me)) then 1589 1589 City_StartUnitProduction(cix, mixShip) 1590 1590 else if (Built[imBarracks] + Built[imMilAcademy] = 0) and … … 1600 1600 if (City_CurrentImprovementProject(cix) = imCourt) and 1601 1601 (Built[imTownHall] > 0) and (prod >= imp[imCourt].cost * 1602 BuildCostMod[G.Difficulty[ me]] div 12 -1603 (imp[imTownHall].cost * BuildCostMod[G.Difficulty[ me]] div 12) *1602 BuildCostMod[G.Difficulty[Me]] div 12 - 1603 (imp[imTownHall].cost * BuildCostMod[G.Difficulty[Me]] div 12) * 1604 1604 2 div 3) then 1605 1605 City_RebuildImprovement(cix, imTownHall) … … 1614 1614 if City_RebuildImprovement(cix, iix) < rExecuted then 1615 1615 City_SellImprovement(cix, iix); 1616 break;1616 Break; 1617 1617 end; 1618 1618 end; 1619 1619 end; 1620 1620 1621 function TBarbarina.Barbarina_ChooseResearchAdvance: integer;1621 function TBarbarina.Barbarina_ChooseResearchAdvance: Integer; 1622 1622 var 1623 nPreq, rmix, rmixChosen, i, MaxWeight, MaxDefense, ChosenPreq: integer;1624 NeedSeaUnits, ready: boolean;1623 nPreq, rmix, rmixChosen, I, MaxWeight, MaxDefense, ChosenPreq: Integer; 1624 NeedSeaUnits, ready: Boolean; 1625 1625 ModelExists: set of 0..nModelCategory - 1; 1626 known: array[0..nAdv - 1] of integer;1627 1628 procedure ChoosePreq(ad: integer);1626 known: array[0..nAdv - 1] of Integer; 1627 1628 procedure ChoosePreq(ad: Integer); 1629 1629 var 1630 i: integer;1631 PreqOk: boolean;1630 I: Integer; 1631 PreqOk: Boolean; 1632 1632 begin 1633 assert(RO.Tech[ad] < tsApplicable);1633 Assert(RO.Tech[ad] < tsApplicable); 1634 1634 if known[ad] = 0 then 1635 1635 begin … … 1637 1637 PreqOk := True; 1638 1638 if not (ad in [adScience, adMassProduction]) and (RO.Tech[ad] < tsSeen) then 1639 for i:= 0 to 1 do1640 if (AdvPreq[ad, i] >= 0) and (RO.Tech[AdvPreq[ad, i]] < tsApplicable) then1639 for I := 0 to 1 do 1640 if (AdvPreq[ad, I] >= 0) and (RO.Tech[AdvPreq[ad, I]] < tsApplicable) then 1641 1641 begin 1642 1642 PreqOk := False; 1643 ChoosePreq(AdvPreq[ad, i]);1643 ChoosePreq(AdvPreq[ad, I]); 1644 1644 end; 1645 1645 if PreqOk then … … 1697 1697 ready := (MaxWeight >= Weight) and (MaxDefense >= Cap[mcDefense]); 1698 1698 if ready then 1699 for i:= 0 to nFeature - 1 do1700 if (Cap[ i] > 0) and (Feature[i].Preq <> preNone) and1701 ((Feature[ i].Preq < 0) or not IsResearched(Feature[i].Preq)) then1699 for I := 0 to nFeature - 1 do 1700 if (Cap[I] > 0) and (Feature[I].Preq <> preNone) and 1701 ((Feature[I].Preq < 0) or not IsResearched(Feature[I].Preq)) then 1702 1702 ready := False; 1703 1703 if ready then 1704 1704 begin 1705 for i:= 0 to nUpgrade - 1 do1706 if (Upgrades and (1 shl i) <> 0) and not1707 IsResearched(Upgrade[Domain, i].Preq) then1705 for I := 0 to nUpgrade - 1 do 1706 if (Upgrades and (1 shl I) <> 0) and not 1707 IsResearched(Upgrade[Domain, I].Preq) then 1708 1708 ready := False; 1709 1709 end; 1710 1710 if ready then 1711 1711 begin 1712 include(ModelExists, Category);1712 Include(ModelExists, Category); 1713 1713 if not IsModelAvailable(rmix) then 1714 1714 rmixChosen := rmix; … … 1719 1719 begin 1720 1720 PrepareNewModel(Domain); 1721 for i:= 0 to nFeature - 1 do1722 if ( i < 2) or (Cap[i] > 0) then1723 SetNewModelFeature( i, Cap[i]);1724 if RO.Wonder[woSun].EffectiveOwner = me then1721 for I := 0 to nFeature - 1 do 1722 if (I < 2) or (Cap[I] > 0) then 1723 SetNewModelFeature(I, Cap[I]); 1724 if RO.Wonder[woSun].EffectiveOwner = Me then 1725 1725 begin 1726 1726 //if Cap[mcWeapons]>=2*Cap[mcArmor] then … … 1730 1730 end; 1731 1731 Result := adMilitary; 1732 exit;1732 Exit; 1733 1733 end; 1734 1734 1735 1735 NeedSeaUnits := True; 1736 i:= 0;1737 while ( i < nResearchOrder) and (not NeedSeaUnits and (ResearchOrder[i] < 0) or1738 IsResearched(abs(ResearchOrder[ i]))) do1739 Inc( i);1740 if i>= nResearchOrder then // list done, continue with future tech1736 I := 0; 1737 while (I < nResearchOrder) and (not NeedSeaUnits and (ResearchOrder[I] < 0) or 1738 IsResearched(abs(ResearchOrder[I]))) do 1739 Inc(I); 1740 if I >= nResearchOrder then // list done, continue with future tech 1741 1741 begin 1742 1742 if random(2) = 1 then … … 1750 1750 nPreq := 0; 1751 1751 ChosenPreq := -1; 1752 ChoosePreq(abs(ResearchOrder[ i]));1753 assert(nPreq > 0);1752 ChoosePreq(abs(ResearchOrder[I])); 1753 Assert(nPreq > 0); 1754 1754 Result := ChosenPreq; 1755 1755 end; 1756 1756 end; 1757 1757 1758 function TBarbarina.Barbarina_WantCheckNegotiation(Nation: integer): boolean;1758 function TBarbarina.Barbarina_WantCheckNegotiation(Nation: Integer): Boolean; 1759 1759 begin 1760 1760 if (RO.Tech[adTheRepublic] < tsSeen) and (RO.Tech[adTheology] >= tsApplicable) and … … 1769 1769 begin 1770 1770 if RO.Tech[adTheRepublic] >= tsSeen then 1771 exit; // default reaction1771 Exit; // default reaction 1772 1772 if MyLastAction = scContact then 1773 1773 begin … … 1797 1797 end; 1798 1798 1799 function TBarbarina.Barbarina_WantNegotiation(Nation: integer;1800 NegoTime: TNegoTime): boolean;1799 function TBarbarina.Barbarina_WantNegotiation(Nation: Integer; 1800 NegoTime: TNegoTime): Boolean; 1801 1801 var 1802 uix, TestLoc, V8: integer;1802 uix, TestLoc, V8: Integer; 1803 1803 Adjacent: TVicinity8Loc; 1804 1804 begin … … 1812 1812 if RO.Turn >= RO.LastCancelTreaty[Nation] + CancelTreatyTurns then 1813 1813 begin 1814 if (RO.Turn and 3 = (Nation + $F - me) and 3) and1814 if (RO.Turn and 3 = (Nation + $F - Me) and 3) and 1815 1815 (RO.Treaty[Nation] > trPeace) then 1816 1816 begin … … 1838 1838 NegoCause := CancelTreaty; 1839 1839 Result := True; 1840 exit;1840 Exit; 1841 1841 end; 1842 1842 end; … … 1858 1858 procedure TBarbarina.MakeColonyShipPlan; 1859 1859 var 1860 i, V21, V21C, CityLoc, Loc1, part, cix, BestValue, TestValue, FoodCount,1861 ProdCount, ProdExtra, Score, BestScore: integer;1862 Tile: cardinal;1863 ok, check: boolean;1860 I, V21, V21C, CityLoc, Loc1, part, cix, BestValue, TestValue, FoodCount, 1861 ProdCount, ProdExtra, Score, BestScore: Integer; 1862 Tile: Cardinal; 1863 ok, check: Boolean; 1864 1864 Radius, RadiusC: TVicinity21Loc; 1865 1865 begin … … 1887 1887 begin 1888 1888 part := (Tile and fModern) shr 25 - 1; 1889 if RO.Ship[ me].Parts[part] < ShipNeed[part] then1889 if RO.Ship[Me].Parts[part] < ShipNeed[part] then 1890 1890 // not enough of this kind already 1891 1891 begin … … 1893 1893 if ColonyShipPlan[part].cixProducing >= 0 then 1894 1894 begin // another city is already assigned to this ship part, choose one of the two 1895 TestValue := (ID and $FFF) shl 4 + ((ID shr 12) + 15 - me) and $F;1895 TestValue := (ID and $FFF) shl 4 + ((ID shr 12) + 15 - Me) and $F; 1896 1896 BestValue := 1897 1897 (MyCity[ColonyShipPlan[part].cixProducing].ID and $FFF) shl 1898 1898 4 + ((MyCity[ColonyShipPlan[part].cixProducing].ID shr 12) + 1899 15 - me) and $F;1899 15 - Me) and $F; 1900 1900 if TestValue <= BestValue then 1901 1901 ok := False; … … 1912 1912 check := False; 1913 1913 for part := 0 to nShipPart - 1 do 1914 if (RO.Ship[ me].Parts[part] < ShipNeed[part]) // not enough of this kind already1914 if (RO.Ship[Me].Parts[part] < ShipNeed[part]) // not enough of this kind already 1915 1915 and (ColonyShipPlan[part].cixProducing < 0) then // no city to produce 1916 1916 check := True; … … 1931 1931 end; 1932 1932 for part := 0 to nShipPart - 1 do 1933 if (RO.Ship[ me].Parts[part] < ShipNeed[part]) // not enough of this kind already1933 if (RO.Ship[Me].Parts[part] < ShipNeed[part]) // not enough of this kind already 1934 1934 and (ColonyShipPlan[part].cixProducing < 0) // no city to produce 1935 1935 and (ColonyShipPlan[part].nLocResource > 0) then // resource is known 1936 1936 begin 1937 for i:= 0 to ColonyShipPlan[part].nLocResource - 1 do1937 for I := 0 to ColonyShipPlan[part].nLocResource - 1 do 1938 1938 begin 1939 1939 BestScore := 0; 1940 V21_to_Loc(ColonyShipPlan[part].LocResource[ i], Radius);1940 V21_to_Loc(ColonyShipPlan[part].LocResource[I], Radius); 1941 1941 for V21 := 1 to 26 do 1942 1942 begin // check all potential cities in range … … 1984 1984 Dec(ProdCount, 5 - FoodCount); 1985 1985 Score := ProdCount * 4 + ProdExtra * 8 + FoodCount; 1986 Score := Score shl 8 + ((CityLoc xor me) * 4567) mod 251;1986 Score := Score shl 8 + ((CityLoc xor Me) * 4567) mod 251; 1987 1987 // some unexactness, random but always the same for this tile 1988 1988 end; -
branches/highdpi/AI/StdAI/CustomAI.pas
r303 r465 13 13 TCustomAI = class 14 14 public 15 procedure Process(Command: integer; var Data);15 procedure Process(Command: Integer; var Data); 16 16 17 17 // overridables 18 constructor Create(Nation: integer); virtual;18 constructor Create(Nation: Integer); virtual; 19 19 destructor Destroy; override; 20 20 procedure SetDataDefaults; virtual; 21 21 procedure SetDataRandom; virtual; 22 22 procedure OnBeforeEnemyAttack(UnitInfo: TUnitInfo; 23 ToLoc, EndHealth, EndHealthDef: integer); virtual;24 procedure OnBeforeEnemyCapture(UnitInfo: TUnitInfo; ToLoc: integer); virtual;23 ToLoc, EndHealth, EndHealthDef: Integer); virtual; 24 procedure OnBeforeEnemyCapture(UnitInfo: TUnitInfo; ToLoc: Integer); virtual; 25 25 procedure OnAfterEnemyAttack; virtual; 26 26 procedure OnAfterEnemyCapture; virtual; 27 27 28 28 protected 29 me: integer; // index of the controlled nation29 Me: Integer; // index of the controlled nation 30 30 RO: ^TPlayerContext; 31 31 Map: ^TTileList; … … 34 34 MyModel: ^TModelList; 35 35 36 cixStateImp: array[imPalace..imSpacePort] of integer;36 cixStateImp: array[imPalace..imSpacePort] of Integer; 37 37 38 38 // negotiation 39 Opponent: integer; // nation i'm in negotiation with, -1 indicates no-negotiation mode40 MyAction, MyLastAction, OppoAction: integer;39 Opponent: Integer; // nation i'm in negotiation with, -1 indicates no-negotiation mode 40 MyAction, MyLastAction, OppoAction: Integer; 41 41 MyOffer, MyLastOffer, OppoOffer: TOffer; 42 42 … … 44 44 procedure DoTurn; virtual; 45 45 procedure DoNegotiation; virtual; 46 function ChooseResearchAdvance: integer; virtual;47 function ChooseStealAdvance: integer; virtual;48 function ChooseGovernment: integer; virtual;49 function WantNegotiation(Nation: integer; NegoTime: TNegoTime): boolean; virtual;50 function OnNegoRejected_CancelTreaty: boolean; virtual;46 function ChooseResearchAdvance: Integer; virtual; 47 function ChooseStealAdvance: Integer; virtual; 48 function ChooseGovernment: Integer; virtual; 49 function WantNegotiation(Nation: Integer; NegoTime: TNegoTime): Boolean; virtual; 50 function OnNegoRejected_CancelTreaty: Boolean; virtual; 51 51 52 52 // general functions 53 function IsResearched(Advance: integer): boolean;54 function ResearchCost: integer;55 function ChangeAttitude(Nation, Attitude: integer): integer;56 function Revolution: integer;57 function ChangeRates(Tax, Lux: integer): integer;58 function PrepareNewModel(Domain: integer): integer;59 function SetNewModelFeature(F, Count: integer): integer;60 function AdvanceResearchable(Advance: integer): boolean;61 function AdvanceStealable(Advance: integer): boolean;62 function GetJobProgress(Loc: integer; var JobProgress: TJobProgressData): boolean;63 function DebugMessage(Level: integer; Text: string): boolean;64 function SetDebugMap(var DebugMap): boolean;53 function IsResearched(Advance: Integer): Boolean; 54 function ResearchCost: Integer; 55 function ChangeAttitude(Nation, Attitude: Integer): Integer; 56 function Revolution: Integer; 57 function ChangeRates(Tax, Lux: Integer): Integer; 58 function PrepareNewModel(Domain: Integer): Integer; 59 function SetNewModelFeature(F, Count: Integer): Integer; 60 function AdvanceResearchable(Advance: Integer): Boolean; 61 function AdvanceStealable(Advance: Integer): Boolean; 62 function GetJobProgress(Loc: Integer; var JobProgress: TJobProgressData): Boolean; 63 function DebugMessage(Level: Integer; Text: string): Boolean; 64 function SetDebugMap(var DebugMap): Boolean; 65 65 66 66 // unit functions 67 procedure Unit_FindMyDefender(Loc: integer; var uix: integer);68 procedure Unit_FindEnemyDefender(Loc: integer; var euix: integer);69 function Unit_Move(uix, ToLoc: integer): integer;70 function Unit_Step(uix, ToLoc: integer): integer;71 function Unit_Attack(uix, ToLoc: integer): integer;72 function Unit_DoMission(uix, MissionType, ToLoc: integer): integer;73 function Unit_MoveForecast(uix, ToLoc: integer;74 var RemainingMovement: integer): boolean;75 function Unit_AttackForecast(uix, ToLoc, AttackMovement: integer;76 var RemainingHealth: integer): boolean;77 function Unit_DefenseForecast(euix, ToLoc: integer;78 var RemainingHealth: integer): boolean;79 function Unit_Disband(uix: integer): integer;80 function Unit_StartJob(uix, NewJob: integer): integer;81 function Unit_SetHomeHere(uix: integer): integer;82 function Unit_Load(uix: integer): integer;83 function Unit_Unload(uix: integer): integer;84 function Unit_SelectTransport(uix: integer): integer;85 function Unit_AddToCity(uix: integer): integer;67 procedure Unit_FindMyDefender(Loc: Integer; var uix: Integer); 68 procedure Unit_FindEnemyDefender(Loc: Integer; var euix: Integer); 69 function Unit_Move(uix, ToLoc: Integer): Integer; 70 function Unit_Step(uix, ToLoc: Integer): Integer; 71 function Unit_Attack(uix, ToLoc: Integer): Integer; 72 function Unit_DoMission(uix, MissionType, ToLoc: Integer): Integer; 73 function Unit_MoveForecast(uix, ToLoc: Integer; 74 var RemainingMovement: Integer): Boolean; 75 function Unit_AttackForecast(uix, ToLoc, AttackMovement: Integer; 76 var RemainingHealth: Integer): Boolean; 77 function Unit_DefenseForecast(euix, ToLoc: Integer; 78 var RemainingHealth: Integer): Boolean; 79 function Unit_Disband(uix: Integer): Integer; 80 function Unit_StartJob(uix, NewJob: Integer): Integer; 81 function Unit_SetHomeHere(uix: Integer): Integer; 82 function Unit_Load(uix: Integer): Integer; 83 function Unit_Unload(uix: Integer): Integer; 84 function Unit_SelectTransport(uix: Integer): Integer; 85 function Unit_AddToCity(uix: Integer): Integer; 86 86 87 87 // city functions 88 procedure City_FindMyCity(Loc: integer; var cix: integer);89 procedure City_FindEnemyCity(Loc: integer; var ecix: integer);90 function City_HasProject(cix: integer): boolean;91 function City_CurrentImprovementProject(cix: integer): integer;92 function City_CurrentUnitProject(cix: integer): integer;93 function City_GetTileInfo(cix, TileLoc: integer; var TileInfo: TTileInfo): integer;94 function City_GetReport(cix: integer; var Report: TCityReport): integer;95 function City_GetHypoReport(cix, HypoTiles, HypoTax, HypoLux: integer;96 var Report: TCityReport): integer;97 function City_GetReportNew(cix: integer; var Report: TCityReportNew): integer;98 function City_GetHypoReportNew(cix, HypoTiles, HypoTaxRate, HypoLuxuryRate: integer;99 var Report: TCityReportNew): integer;100 function City_GetAreaInfo(cix: integer; var AreaInfo: TCityAreaInfo): integer;101 function City_StartUnitProduction(cix, mix: integer): integer;102 function City_StartEmigration(cix, mix: integer;103 AllowDisbandCity, AsConscripts: boolean): integer;104 function City_StartImprovement(cix, iix: integer): integer;105 function City_Improvable(cix, iix: integer): boolean;106 function City_StopProduction(cix: integer): integer;107 function City_BuyProject(cix: integer): integer;108 function City_SellImprovement(cix, iix: integer): integer;109 function City_RebuildImprovement(cix, iix: integer): integer;110 function City_SetTiles(cix, NewTiles: integer): integer;111 procedure City_OptimizeTiles(cix: integer; ResourceWeights: cardinal = rwMaxGrowth);88 procedure City_FindMyCity(Loc: Integer; var cix: Integer); 89 procedure City_FindEnemyCity(Loc: Integer; var ecix: Integer); 90 function City_HasProject(cix: Integer): Boolean; 91 function City_CurrentImprovementProject(cix: Integer): Integer; 92 function City_CurrentUnitProject(cix: Integer): Integer; 93 function City_GetTileInfo(cix, TileLoc: Integer; var TileInfo: TTileInfo): Integer; 94 function City_GetReport(cix: Integer; var Report: TCityReport): Integer; 95 function City_GetHypoReport(cix, HypoTiles, HypoTax, HypoLux: Integer; 96 var Report: TCityReport): Integer; 97 function City_GetReportNew(cix: Integer; var Report: TCityReportNew): Integer; 98 function City_GetHypoReportNew(cix, HypoTiles, HypoTaxRate, HypoLuxuryRate: Integer; 99 var Report: TCityReportNew): Integer; 100 function City_GetAreaInfo(cix: Integer; var AreaInfo: TCityAreaInfo): Integer; 101 function City_StartUnitProduction(cix, mix: Integer): Integer; 102 function City_StartEmigration(cix, mix: Integer; 103 AllowDisbandCity, AsConscripts: Boolean): Integer; 104 function City_StartImprovement(cix, iix: Integer): Integer; 105 function City_Improvable(cix, iix: Integer): Boolean; 106 function City_StopProduction(cix: Integer): Integer; 107 function City_BuyProject(cix: Integer): Integer; 108 function City_SellImprovement(cix, iix: Integer): Integer; 109 function City_RebuildImprovement(cix, iix: Integer): Integer; 110 function City_SetTiles(cix, NewTiles: Integer): Integer; 111 procedure City_OptimizeTiles(cix: Integer; ResourceWeights: Cardinal = rwMaxGrowth); 112 112 113 113 // negotiation 114 function Nego_CheckMyAction: integer;114 function Nego_CheckMyAction: Integer; 115 115 116 116 private 117 HaveTurned: boolean;117 HaveTurned: Boolean; 118 118 UnwantedNego: set of 0..nPl - 1; 119 119 Contacted: set of 0..nPl - 1; … … 125 125 Server: TServerCall; 126 126 G: TNewGameData; 127 RWDataSize, MapSize: integer;128 decompose24: cardinal;129 nodata: pointer;127 RWDataSize, MapSize: Integer; 128 decompose24: Cardinal; 129 nodata: Pointer; 130 130 131 131 const … … 139 139 140 140 type 141 TVicinity8Loc = array[0..7] of integer;142 TVicinity21Loc = array[0..27] of integer;141 TVicinity8Loc = array[0..7] of Integer; 142 TVicinity21Loc = array[0..27] of Integer; 143 143 144 144 145 145 procedure Init(NewGameData: TNewGameData); 146 146 147 procedure ab_to_Loc(Loc0, a, b: integer; var Loc: integer);148 procedure Loc_to_ab(Loc0, Loc: integer; var a, b: integer);149 procedure ab_to_V8( a, b: integer; var V8: integer);150 procedure V8_to_ab(V8: integer; var a, b: integer);151 procedure ab_to_V21( a, b: integer; var V21: integer);152 procedure V21_to_ab(V21: integer; var a, b: integer);153 procedure V8_to_Loc(Loc0: integer; var VicinityLoc: TVicinity8Loc);154 procedure V21_to_Loc(Loc0: integer; var VicinityLoc: TVicinity21Loc);155 function Distance(Loc0, Loc1: integer): integer;147 procedure ab_to_Loc(Loc0, A, B: Integer; var Loc: Integer); 148 procedure Loc_to_ab(Loc0, Loc: Integer; var A, B: Integer); 149 procedure ab_to_V8(A, B: Integer; var V8: Integer); 150 procedure V8_to_ab(V8: Integer; var A, B: Integer); 151 procedure ab_to_V21(A, B: Integer; var V21: Integer); 152 procedure V21_to_ab(V21: Integer; var A, B: Integer); 153 procedure V8_to_Loc(Loc0: Integer; var VicinityLoc: TVicinity8Loc); 154 procedure V21_to_Loc(Loc0: Integer; var VicinityLoc: TVicinity21Loc); 155 function Distance(Loc0, Loc1: Integer): Integer; 156 156 157 157 … … 159 159 160 160 const 161 ab_v8: array[-4..4] of integer = (5, 6, 7, 4, -1, 0, 3, 2, 1);162 v8_a: array[0..7] of integer = (1, 1, 0, -1, -1, -1, 0, 1);163 v8_b: array[0..7] of integer = (0, 1, 1, 1, 0, -1, -1, -1);164 165 166 procedure ab_to_Loc(Loc0, a, b: integer; var Loc: integer);161 ab_v8: array[-4..4] of Integer = (5, 6, 7, 4, -1, 0, 3, 2, 1); 162 v8_a: array[0..7] of Integer = (1, 1, 0, -1, -1, -1, 0, 1); 163 v8_b: array[0..7] of Integer = (0, 1, 1, 1, 0, -1, -1, -1); 164 165 166 procedure ab_to_Loc(Loc0, A, B: Integer; var Loc: Integer); 167 167 {relative location from Loc0} 168 168 var 169 y0: integer;170 begin 171 assert((Loc0 >= 0) and (Loc0 < MapSize) and (a - b+ G.lx >= 0));172 y0 := cardinal(Loc0) * decompose24 shr 24;173 Loc := (Loc0 + ( a - b + y0 and 1 + G.lx + G.lx) shr 1) mod G.lx + G.lx * (y0 + a + b);169 y0: Integer; 170 begin 171 Assert((Loc0 >= 0) and (Loc0 < MapSize) and (A - B + G.lx >= 0)); 172 y0 := Cardinal(Loc0) * decompose24 shr 24; 173 Loc := (Loc0 + (A - B + y0 and 1 + G.lx + G.lx) shr 1) mod G.lx + G.lx * (y0 + A + B); 174 174 if Loc >= MapSize then 175 175 Loc := -$1000; 176 176 end; 177 177 178 procedure Loc_to_ab(Loc0, Loc: integer; var a, b: integer);178 procedure Loc_to_ab(Loc0, Loc: Integer; var A, B: Integer); 179 179 {$IFDEF FPC}// freepascal 180 180 var 181 dx, dy: integer;181 dx, dy: Integer; 182 182 begin 183 183 dx := ((Loc mod G.lx * 2 + Loc div G.lx and 1) - (Loc0 mod G.lx * 2 + Loc0 div 184 184 G.lx and 1) + 3 * G.lx) mod (2 * G.lx) - G.lx; 185 185 dy := Loc div G.lx - Loc0 div G.lx; 186 a:= (dx + dy) div 2;187 b:= (dy - dx) div 2;186 A := (dx + dy) div 2; 187 B := (dy - dx) div 2; 188 188 end; 189 189 … … 195 195 // calculate 196 196 push ecx 197 div byte ptr [G]197 div Byte ptr [G] 198 198 xor ebx,ebx 199 199 mov bl,ah // ebx:=Loc0 mod G.lx … … 201 201 and ecx,$000000FF // ecx:=Loc0 div G.lx 202 202 mov eax,edx 203 div byte ptr [G]203 div Byte ptr [G] 204 204 xor edx,edx 205 205 mov dl,ah // edx:=Loc mod G.lx … … 218 218 mov edx,dword ptr [G] 219 219 cmp eax,edx 220 jl @ a220 jl @A 221 221 sub eax,edx 222 222 sub eax,edx 223 223 jmp @ok 224 @ a:224 @A: 225 225 neg edx 226 226 cmp eax,edx … … 235 235 add eax,ebx 236 236 sar edx,1 // edx:=b 237 mov ebx,[ b]237 mov ebx,[B] 238 238 mov [ebx],edx 239 239 sar eax,1 // eax:=a 240 mov [ a],eax240 mov [A],eax 241 241 242 242 pop ebx … … 244 244 {$ENDIF} 245 245 246 procedure ab_to_V8( a, b: integer; var V8: integer);247 begin 248 assert((abs(a) <= 1) and (abs(b) <= 1) and ((a <> 0) or (b<> 0)));249 V8 := ab_v8[2 * b + b + a];250 end; 251 252 procedure V8_to_ab(V8: integer; var a, b: integer);253 begin 254 a:= v8_a[V8];255 b:= V8_b[V8];256 end; 257 258 procedure ab_to_V21( a, b: integer; var V21: integer);259 begin 260 V21 := ( a + b + 3) shl 2 + (a - b+ 3) shr 1;261 end; 262 263 procedure V21_to_ab(V21: integer; var a, b: integer);264 var 265 dx, dy: integer;246 procedure ab_to_V8(A, B: Integer; var V8: Integer); 247 begin 248 Assert((abs(A) <= 1) and (abs(B) <= 1) and ((A <> 0) or (B <> 0))); 249 V8 := ab_v8[2 * B + B + A]; 250 end; 251 252 procedure V8_to_ab(V8: Integer; var A, B: Integer); 253 begin 254 A := v8_a[V8]; 255 B := V8_b[V8]; 256 end; 257 258 procedure ab_to_V21(A, B: Integer; var V21: Integer); 259 begin 260 V21 := (A + B + 3) shl 2 + (A - B + 3) shr 1; 261 end; 262 263 procedure V21_to_ab(V21: Integer; var A, B: Integer); 264 var 265 dx, dy: Integer; 266 266 begin 267 267 dy := V21 shr 2 - 3; 268 268 dx := V21 and 3 shl 1 - 3 + (dy + 3) and 1; 269 a:= (dx + dy) div 2;270 b:= (dy - dx) div 2;271 end; 272 273 procedure V8_to_Loc(Loc0: integer; var VicinityLoc: TVicinity8Loc);274 var 275 x0, y0, lx: integer;269 A := (dx + dy) div 2; 270 B := (dy - dx) div 2; 271 end; 272 273 procedure V8_to_Loc(Loc0: Integer; var VicinityLoc: TVicinity8Loc); 274 var 275 x0, y0, lx: Integer; 276 276 begin 277 277 lx := G.lx; 278 y0 := cardinal(Loc0) * decompose24 shr 24;278 y0 := Cardinal(Loc0) * decompose24 shr 24; 279 279 x0 := Loc0 - y0 * lx; // Loc0 mod lx; 280 280 VicinityLoc[1] := Loc0 + lx * 2; … … 323 323 end; 324 324 325 procedure V21_to_Loc(Loc0: integer; var VicinityLoc: TVicinity21Loc);326 var 327 dx, dy, bit, y0, xComp, yComp, xComp0, xCompSwitch: integer;328 dst: ^ integer;329 begin 330 y0 := cardinal(Loc0) * decompose24 shr 24;325 procedure V21_to_Loc(Loc0: Integer; var VicinityLoc: TVicinity21Loc); 326 var 327 dx, dy, bit, y0, xComp, yComp, xComp0, xCompSwitch: Integer; 328 dst: ^Integer; 329 begin 330 y0 := Cardinal(Loc0) * decompose24 shr 24; 331 331 xComp0 := Loc0 - y0 * G.lx - 1; // Loc0 mod G.lx -1 332 332 xCompSwitch := xComp0 - 1 + y0 and 1; … … 368 368 end; 369 369 370 function Distance(Loc0, Loc1: integer): integer;371 var 372 a, b, dx, dy: integer;373 begin 374 Loc_to_ab(Loc0, Loc1, a, b);375 dx := abs( a - b);376 dy := abs( a + b);370 function Distance(Loc0, Loc1: Integer): Integer; 371 var 372 A, B, dx, dy: Integer; 373 begin 374 Loc_to_ab(Loc0, Loc1, A, B); 375 dx := abs(A - B); 376 dy := abs(A + B); 377 377 Result := dx + dy + abs(dx - dy) shr 1; 378 378 end; … … 381 381 procedure Init(NewGameData: TNewGameData); 382 382 {$IFDEF DEBUG}var 383 Loc: integer;383 Loc: Integer; 384 384 {$ENDIF} 385 385 begin … … 389 389 {$IFDEF DEBUG} 390 390 for Loc := 0 to MapSize - 1 do 391 assert(cardinal(Loc) * decompose24 shr 24 = cardinal(Loc div G.lx));391 Assert(Cardinal(Loc) * decompose24 shr 24 = Cardinal(Loc div G.lx)); 392 392 {$ENDIF} 393 393 end; 394 394 395 395 396 constructor TCustomAI.Create(Nation: integer);396 constructor TCustomAI.Create(Nation: Integer); 397 397 begin 398 398 inherited Create; 399 me := Nation;400 RO := pointer(G.RO[Nation]);401 Map := pointer(RO.Map);402 MyUnit := pointer(RO.Un);403 MyCity := pointer(RO.City);404 MyModel := pointer(RO.Model);399 Me := Nation; 400 RO := Pointer(G.RO[Nation]); 401 Map := Pointer(RO.Map); 402 MyUnit := Pointer(RO.Un); 403 MyCity := Pointer(RO.City); 404 MyModel := Pointer(RO.Model); 405 405 Opponent := -1; 406 406 end; … … 408 408 destructor TCustomAI.Destroy; 409 409 begin 410 Server(sSetDebugMap, me, 0, nodata^);411 end; 412 413 414 procedure TCustomAI.Process(Command: integer; var Data);415 var 416 Nation, NewResearch, NewGov, Count, ad, cix, iix: integer;410 Server(sSetDebugMap, Me, 0, nodata^); 411 end; 412 413 414 procedure TCustomAI.Process(Command: Integer; var Data); 415 var 416 Nation, NewResearch, NewGov, Count, ad, cix, iix: Integer; 417 417 NegoTime: TNegoTime; 418 418 begin … … 420 420 cTurn, cContinue: 421 421 begin 422 if RO.Alive and (1 shl me) = 0 then422 if RO.Alive and (1 shl Me) = 0 then 423 423 begin // I'm dead, huhu 424 Server(sTurn, me, 0, nodata^);425 exit;424 Server(sTurn, Me, 0, nodata^); 425 Exit; 426 426 end; 427 427 if Command = cTurn then 428 428 begin 429 fillchar(cixStateImp, sizeof(cixStateImp), $FF);429 FillChar(cixStateImp, SizeOf(cixStateImp), $FF); 430 430 for cix := 0 to RO.nCity - 1 do 431 431 if MyCity[cix].Loc >= 0 then … … 437 437 NewGov := ChooseGovernment; 438 438 if NewGov > gAnarchy then 439 Server(sSetGovernment, me, NewGov, nodata^);439 Server(sSetGovernment, Me, NewGov, nodata^); 440 440 end; 441 441 HaveTurned := False; … … 446 446 if OnNegoRejected_CancelTreaty then 447 447 if RO.Treaty[Opponent] >= trPeace then 448 if Server(sCancelTreaty, me, 0, nodata^) < rExecuted then449 assert(False);448 if Server(sCancelTreaty, Me, 0, nodata^) < rExecuted then 449 Assert(False); 450 450 end 451 451 else … … 459 459 if RO.Government <> gAnarchy then 460 460 for Nation := 0 to nPl - 1 do 461 if (Nation <> me) and (1 shl Nation and RO.Alive <> 0) and461 if (Nation <> Me) and (1 shl Nation and RO.Alive <> 0) and 462 462 (RO.Treaty[Nation] >= trNone) and not (Nation in Contacted) and not 463 463 (Nation in UnwantedNego) and 464 (Server(scContact - sExecute + Nation shl 4, me, 0, nodata^) >= rExecuted) then464 (Server(scContact - sExecute + Nation shl 4, Me, 0, nodata^) >= rExecuted) then 465 465 if WantNegotiation(Nation, NegoTime) then 466 466 begin 467 if Server(scContact + Nation shl 4, me, 0, nodata^) >= rExecuted then467 if Server(scContact + Nation shl 4, Me, 0, nodata^) >= rExecuted then 468 468 begin 469 include(Contacted, Nation);469 Include(Contacted, Nation); 470 470 Opponent := Nation; 471 471 MyAction := scContact; 472 exit;472 Exit; 473 473 end; 474 474 end 475 475 else 476 include(UnwantedNego, Nation);476 Include(UnwantedNego, Nation); 477 477 if NegoTime = BeginOfTurn then 478 478 begin … … 483 483 end 484 484 else 485 break;485 Break; 486 486 until False; 487 487 if RO.Happened and phTech <> 0 then … … 499 499 end; 500 500 end; 501 Server(sSetResearch, me, NewResearch, nodata^);501 Server(sSetResearch, Me, NewResearch, nodata^); 502 502 end; 503 if Server(sTurn, me, 0, nodata^) < rExecuted then504 assert(False);503 if Server(sTurn, Me, 0, nodata^) < rExecuted then 504 Assert(False); 505 505 end; 506 506 scContact: 507 if WantNegotiation( integer(Data), EnemyCalled) then507 if WantNegotiation(Integer(Data), EnemyCalled) then 508 508 begin 509 if Server(scDipStart, me, 0, nodata^) < rExecuted then510 assert(False);511 Opponent := integer(Data);509 if Server(scDipStart, Me, 0, nodata^) < rExecuted then 510 Assert(False); 511 Opponent := Integer(Data); 512 512 MyAction := scDipStart; 513 513 end 514 514 else 515 515 begin 516 if Server(scReject, me, 0, nodata^) < rExecuted then517 assert(False);516 if Server(scReject, Me, 0, nodata^) < rExecuted then 517 Assert(False); 518 518 end; 519 519 scDipStart, scDipNotice, scDipAccept, scDipCancelTreaty, scDipOffer, scDipBreak: … … 538 538 end; 539 539 DoNegotiation; 540 assert((MyAction = scDipNotice) or (MyAction = scDipAccept) or540 Assert((MyAction = scDipNotice) or (MyAction = scDipAccept) or 541 541 (MyAction = scDipCancelTreaty) or (MyAction = scDipOffer) or (MyAction = scDipBreak)); 542 542 if MyAction = scDipOffer then 543 Server(MyAction, me, 0, MyOffer)543 Server(MyAction, Me, 0, MyOffer) 544 544 else 545 Server(MyAction, me, 0, nodata^);545 Server(MyAction, Me, 0, nodata^); 546 546 end; 547 547 cShowEndContact: … … 568 568 569 569 procedure TCustomAI.OnBeforeEnemyAttack(UnitInfo: TUnitInfo; 570 ToLoc, EndHealth, EndHealthDef: integer);571 begin 572 end; 573 574 procedure TCustomAI.OnBeforeEnemyCapture(UnitInfo: TUnitInfo; ToLoc: integer);570 ToLoc, EndHealth, EndHealthDef: Integer); 571 begin 572 end; 573 574 procedure TCustomAI.OnBeforeEnemyCapture(UnitInfo: TUnitInfo; ToLoc: Integer); 575 575 begin 576 576 end; … … 584 584 end; 585 585 586 function TCustomAI.ChooseResearchAdvance: integer;586 function TCustomAI.ChooseResearchAdvance: Integer; 587 587 begin 588 588 Result := -1; 589 589 end; 590 590 591 function TCustomAI.ChooseStealAdvance: integer;591 function TCustomAI.ChooseStealAdvance: Integer; 592 592 begin 593 593 Result := -1; 594 594 end; 595 595 596 function TCustomAI.ChooseGovernment: integer;596 function TCustomAI.ChooseGovernment: Integer; 597 597 begin 598 598 Result := gDespotism; 599 599 end; 600 600 601 function TCustomAI.WantNegotiation(Nation: integer; NegoTime: TNegoTime): boolean;601 function TCustomAI.WantNegotiation(Nation: Integer; NegoTime: TNegoTime): Boolean; 602 602 begin 603 603 Result := False; 604 604 end; 605 605 606 function TCustomAI.OnNegoRejected_CancelTreaty: boolean;606 function TCustomAI.OnNegoRejected_CancelTreaty: Boolean; 607 607 begin 608 608 Result := False; … … 613 613 procedure TCustomAI.StealAdvance; 614 614 var 615 Steal, ad, Count: integer;615 Steal, ad, Count: Integer; 616 616 begin 617 617 Steal := ChooseStealAdvance; … … 628 628 end; 629 629 if Steal >= 0 then 630 Server(sStealTech, me, Steal, nodata^);630 Server(sStealTech, Me, Steal, nodata^); 631 631 RO.Happened := RO.Happened and not phStealTech; 632 632 end; 633 633 634 function TCustomAI.IsResearched(Advance: integer): boolean;634 function TCustomAI.IsResearched(Advance: Integer): Boolean; 635 635 begin 636 636 Result := (Advance = preNone) or (Advance <> preNA) and (RO.Tech[Advance] >= tsApplicable); 637 637 end; 638 638 639 function TCustomAI.ResearchCost: integer;640 begin 641 Server(sGetTechCost, me, 0, Result);642 end; 643 644 function TCustomAI.ChangeAttitude(Nation, Attitude: integer): integer;645 begin 646 Result := Server(sSetAttitude + Nation shl 4, me, Attitude, nodata^);647 end; 648 649 function TCustomAI.Revolution: integer;650 begin 651 Result := Server(sRevolution, me, 0, nodata^);652 end; 653 654 function TCustomAI.ChangeRates(Tax, Lux: integer): integer;655 begin 656 Result := Server(sSetRates, me, Tax div 10 and $f + Lux div 10 and $fshl 4, nodata^);657 end; 658 659 function TCustomAI.PrepareNewModel(Domain: integer): integer;660 begin 661 Result := Server(sCreateDevModel, me, Domain, nodata^);662 end; 663 664 function TCustomAI.SetNewModelFeature(F, Count: integer): integer;665 begin 666 Result := Server(sSetDevModelCap + Count shl 4, me, F, nodata^);667 end; 668 669 function TCustomAI.AdvanceResearchable(Advance: integer): boolean;670 begin 671 Result := Server(sSetResearch - sExecute, me, Advance, nodata^) >= rExecuted;672 end; 673 674 function TCustomAI.AdvanceStealable(Advance: integer): boolean;675 begin 676 Result := Server(sStealTech - sExecute, me, Advance, nodata^) >= rExecuted;677 end; 678 679 function TCustomAI.GetJobProgress(Loc: integer;680 var JobProgress: TJobProgressData): boolean;681 begin 682 Result := Server(sGetJobProgress, me, Loc, JobProgress) >= rExecuted;683 end; 684 685 function TCustomAI.DebugMessage(Level: integer; Text: string): boolean;686 begin 687 Text := copy('P' + char(48 + me) + ' ' + Text, 1, 254);688 Server(sMessage, me, Level, PChar(Text)^);639 function TCustomAI.ResearchCost: Integer; 640 begin 641 Server(sGetTechCost, Me, 0, Result); 642 end; 643 644 function TCustomAI.ChangeAttitude(Nation, Attitude: Integer): Integer; 645 begin 646 Result := Server(sSetAttitude + Nation shl 4, Me, Attitude, nodata^); 647 end; 648 649 function TCustomAI.Revolution: Integer; 650 begin 651 Result := Server(sRevolution, Me, 0, nodata^); 652 end; 653 654 function TCustomAI.ChangeRates(Tax, Lux: Integer): Integer; 655 begin 656 Result := Server(sSetRates, Me, Tax div 10 and $F + Lux div 10 and $F shl 4, nodata^); 657 end; 658 659 function TCustomAI.PrepareNewModel(Domain: Integer): Integer; 660 begin 661 Result := Server(sCreateDevModel, Me, Domain, nodata^); 662 end; 663 664 function TCustomAI.SetNewModelFeature(F, Count: Integer): Integer; 665 begin 666 Result := Server(sSetDevModelCap + Count shl 4, Me, F, nodata^); 667 end; 668 669 function TCustomAI.AdvanceResearchable(Advance: Integer): Boolean; 670 begin 671 Result := Server(sSetResearch - sExecute, Me, Advance, nodata^) >= rExecuted; 672 end; 673 674 function TCustomAI.AdvanceStealable(Advance: Integer): Boolean; 675 begin 676 Result := Server(sStealTech - sExecute, Me, Advance, nodata^) >= rExecuted; 677 end; 678 679 function TCustomAI.GetJobProgress(Loc: Integer; 680 var JobProgress: TJobProgressData): Boolean; 681 begin 682 Result := Server(sGetJobProgress, Me, Loc, JobProgress) >= rExecuted; 683 end; 684 685 function TCustomAI.DebugMessage(Level: Integer; Text: string): Boolean; 686 begin 687 Text := Copy('P' + char(48 + Me) + ' ' + Text, 1, 254); 688 Server(sMessage, Me, Level, PChar(Text)^); 689 689 690 690 Result := True; … … 693 693 end; 694 694 695 function TCustomAI.SetDebugMap(var DebugMap): boolean;696 begin 697 Server(sSetDebugMap, me, 0, DebugMap);695 function TCustomAI.SetDebugMap(var DebugMap): Boolean; 696 begin 697 Server(sSetDebugMap, Me, 0, DebugMap); 698 698 699 699 Result := True; … … 702 702 end; 703 703 704 procedure TCustomAI.Unit_FindMyDefender(Loc: integer; var uix: integer);705 begin 706 if Server(sGetDefender, me, Loc, uix) < rExecuted then704 procedure TCustomAI.Unit_FindMyDefender(Loc: Integer; var uix: Integer); 705 begin 706 if Server(sGetDefender, Me, Loc, uix) < rExecuted then 707 707 uix := -1; 708 708 end; 709 709 710 procedure TCustomAI.Unit_FindEnemyDefender(Loc: integer; var euix: integer);710 procedure TCustomAI.Unit_FindEnemyDefender(Loc: Integer; var euix: Integer); 711 711 begin 712 712 euix := RO.nEnemyUn - 1; … … 715 715 end; 716 716 717 function TCustomAI.Unit_Move(uix, ToLoc: integer): integer;718 var 719 Step: integer;720 DestinationReached: boolean;717 function TCustomAI.Unit_Move(uix, ToLoc: Integer): Integer; 718 var 719 Step: Integer; 720 DestinationReached: Boolean; 721 721 Advice: TMoveAdviceData; 722 722 begin 723 assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0)); // is a unit723 Assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0)); // is a unit 724 724 {Loc_to_ab(MyUnit[uix].Loc,ToLoc,a,b); 725 assert((a<>0) or (b<>0));726 if ( a>=-1) and (a<=1) and (b>=-1) and (b<=1) then725 Assert((A<>0) or (B<>0)); 726 if (A>=-1) and (A<=1) and (B>=-1) and (B<=1) then 727 727 begin // move to adjacent tile 728 !!!problem: if move is invalid, return codes are not consistent with other branch (eNoWay)728 !!!problem: if Move is invalid, return codes are not consistent with other branch (eNoWay) 729 729 Advice.nStep:=1; 730 Advice.dx[0]:= a-b;731 Advice.dy[0]:= a+b;730 Advice.dx[0]:=A-B; 731 Advice.dy[0]:=A+B; 732 732 Advice.MoreTurns:=0; 733 733 Advice.MaxHostile_MovementLeft:=MyUnit[uix].Movement; 734 result:=eOK;734 Result:=eOK; 735 735 end 736 736 else} … … 739 739 Advice.MoreTurns := 9999; 740 740 Advice.MaxHostile_MovementLeft := 100; 741 Result := Server(sGetMoveAdvice, me, uix, Advice);741 Result := Server(sGetMoveAdvice, Me, uix, Advice); 742 742 end; 743 743 if Result = eOk then … … 755 755 begin 756 756 DestinationReached := True; 757 break;757 Break; 758 758 end // stop next to destination 759 759 else if Step = Advice.nStep then … … 761 761 762 762 if (Step = Advice.nStep) or (Result <> eOK) and (Result <> eLoaded) then 763 break;763 Break; 764 764 765 765 Result := Server(sMoveUnit + (Advice.dx[Step] and 7) shl 4 + 766 (Advice.dy[Step] and 7) shl 7, me, uix, nodata^);766 (Advice.dy[Step] and 7) shl 7, Me, uix, nodata^); 767 767 Inc(Step); 768 768 if RO.Happened and phStealTech <> 0 then … … 779 779 end; 780 780 781 function TCustomAI.Unit_Step(uix, ToLoc: integer): integer;782 var 783 a, b: integer;784 begin 785 Loc_to_ab(MyUnit[uix].Loc, ToLoc, a, b);786 assert(((a <> 0) or (b <> 0)) and (a >= -1) and (a <= 1) and (b >= -1) and (b<= 1));787 Result := Server(sMoveUnit + (( a - b) and 7) shl 4 + ((a + b) and 7) shl 7, me, uix, nodata^);781 function TCustomAI.Unit_Step(uix, ToLoc: Integer): Integer; 782 var 783 A, B: Integer; 784 begin 785 Loc_to_ab(MyUnit[uix].Loc, ToLoc, A, B); 786 Assert(((A <> 0) or (B <> 0)) and (A >= -1) and (A <= 1) and (B >= -1) and (B <= 1)); 787 Result := Server(sMoveUnit + ((A - B) and 7) shl 4 + ((A + B) and 7) shl 7, Me, uix, nodata^); 788 788 if RO.Happened and phStealTech <> 0 then 789 789 StealAdvance; 790 790 end; 791 791 792 function TCustomAI.Unit_Attack(uix, ToLoc: integer): integer;793 var 794 a, b: integer;795 begin 796 assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0) // is a unit792 function TCustomAI.Unit_Attack(uix, ToLoc: Integer): Integer; 793 var 794 A, B: Integer; 795 begin 796 Assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0) // is a unit 797 797 and ((Map[ToLoc] and (fUnit or fOwned) = fUnit) // is an attack 798 798 or (Map[ToLoc] and (fCity or fOwned) = fCity) and 799 799 (MyModel[MyUnit[uix].mix].Domain <> dGround))); // is a bombardment 800 Loc_to_ab(MyUnit[uix].Loc, ToLoc, a, b);801 assert(((a <> 0) or (b <> 0)) and (a >= -1) and (a <= 1) and (b >= -1) and (b<= 1));800 Loc_to_ab(MyUnit[uix].Loc, ToLoc, A, B); 801 Assert(((A <> 0) or (B <> 0)) and (A >= -1) and (A <= 1) and (B >= -1) and (B <= 1)); 802 802 // attack to adjacent tile 803 Result := Server(sMoveUnit + ( a - b) and 7 shl 4 + (a + b) and 7 shl 7, me, uix, nodata^);804 end; 805 806 function TCustomAI.Unit_DoMission(uix, MissionType, ToLoc: integer): integer;807 var 808 a, b: integer;809 begin 810 Result := Server(sSetSpyMission + MissionType shl 4, me, 0, nodata^);803 Result := Server(sMoveUnit + (A - B) and 7 shl 4 + (A + B) and 7 shl 7, Me, uix, nodata^); 804 end; 805 806 function TCustomAI.Unit_DoMission(uix, MissionType, ToLoc: Integer): Integer; 807 var 808 A, B: Integer; 809 begin 810 Result := Server(sSetSpyMission + MissionType shl 4, Me, 0, nodata^); 811 811 if Result >= rExecuted then 812 812 begin 813 assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0) // is a unit813 Assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0) // is a unit 814 814 and (MyModel[MyUnit[uix].mix].Kind = mkDiplomat)); // is a commando 815 Loc_to_ab(MyUnit[uix].Loc, ToLoc, a, b);816 assert(((a <> 0) or (b <> 0)) and (a >= -1) and (a <= 1) and (b >= -1) and (b<= 1));815 Loc_to_ab(MyUnit[uix].Loc, ToLoc, A, B); 816 Assert(((A <> 0) or (B <> 0)) and (A >= -1) and (A <= 1) and (B >= -1) and (B <= 1)); 817 817 // city must be adjacent 818 Result := Server(sMoveUnit - sExecute + ( a - b) and 7 shl 4 + (a + b) and 7 shl 7, me, uix, nodata^);818 Result := Server(sMoveUnit - sExecute + (A - B) and 7 shl 4 + (A + B) and 7 shl 7, Me, uix, nodata^); 819 819 if Result = eMissionDone then 820 Result := Server(sMoveUnit + ( a - b) and 7 shl 4 + (a + b) and 7 shl 7, me, uix, nodata^)820 Result := Server(sMoveUnit + (A - B) and 7 shl 4 + (A + B) and 7 shl 7, Me, uix, nodata^) 821 821 else if (Result <> eNoTime_Move) and (Result <> eTreaty) and (Result <> eNoTurn) then 822 822 Result := eInvalid; // not a special commando mission! … … 824 824 end; 825 825 826 function TCustomAI.Unit_MoveForecast(uix, ToLoc: integer;827 var RemainingMovement: integer): boolean;826 function TCustomAI.Unit_MoveForecast(uix, ToLoc: Integer; 827 var RemainingMovement: Integer): Boolean; 828 828 var 829 829 Advice: TMoveAdviceData; 830 830 begin 831 assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0)); // is a unit831 Assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0)); // is a unit 832 832 Advice.ToLoc := ToLoc; 833 833 Advice.MoreTurns := 0; 834 834 Advice.MaxHostile_MovementLeft := 100; 835 if Server(sGetMoveAdvice, me, uix, Advice) = eOk then835 if Server(sGetMoveAdvice, Me, uix, Advice) = eOk then 836 836 begin 837 837 RemainingMovement := Advice.MaxHostile_MovementLeft; … … 846 846 847 847 // negative RemainingHealth is remaining helth of defender if lost 848 function TCustomAI.Unit_AttackForecast(uix, ToLoc, AttackMovement: integer;849 var RemainingHealth: integer): boolean;848 function TCustomAI.Unit_AttackForecast(uix, ToLoc, AttackMovement: Integer; 849 var RemainingHealth: Integer): Boolean; 850 850 var 851 851 BattleForecast: TBattleForecast; 852 852 begin 853 assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0) // is a unit853 Assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0) // is a unit 854 854 and (Map[ToLoc] and (fUnit or fOwned) = fUnit)); // is an attack 855 855 RemainingHealth := -$100; … … 858 858 with MyUnit[uix] do 859 859 begin 860 BattleForecast.pAtt := me;860 BattleForecast.pAtt := Me; 861 861 BattleForecast.mixAtt := mix; 862 862 BattleForecast.HealthAtt := Health; … … 864 864 BattleForecast.FlagsAtt := Flags; 865 865 BattleForecast.Movement := AttackMovement; 866 if Server(sGetBattleForecast, me, ToLoc, BattleForecast) >= rExecuted then866 if Server(sGetBattleForecast, Me, ToLoc, BattleForecast) >= rExecuted then 867 867 begin 868 868 if BattleForecast.EndHealthAtt > 0 then … … 875 875 end; 876 876 877 function TCustomAI.Unit_DefenseForecast(euix, ToLoc: integer;878 var RemainingHealth: integer): boolean;877 function TCustomAI.Unit_DefenseForecast(euix, ToLoc: Integer; 878 var RemainingHealth: Integer): Boolean; 879 879 var 880 880 BattleForecast: TBattleForecast; 881 881 begin 882 assert((euix >= 0) and (euix < RO.nEnemyUn) and (RO.EnemyUn[euix].Loc >= 0) // is an enemy unit882 Assert((euix >= 0) and (euix < RO.nEnemyUn) and (RO.EnemyUn[euix].Loc >= 0) // is an enemy unit 883 883 and (Map[ToLoc] and (fUnit or fOwned) = (fUnit or fOwned))); // is an attack 884 884 RemainingHealth := $100; … … 892 892 BattleForecast.FlagsAtt := Flags; 893 893 BattleForecast.Movement := 100; 894 if Server(sGetBattleForecast, me, ToLoc, BattleForecast) >= rExecuted then894 if Server(sGetBattleForecast, Me, ToLoc, BattleForecast) >= rExecuted then 895 895 begin 896 896 if BattleForecast.EndHealthDef > 0 then … … 903 903 end; 904 904 905 function TCustomAI.Unit_Disband(uix: integer): integer;906 begin 907 Result := Server(sRemoveUnit, me, uix, nodata^);908 end; 909 910 function TCustomAI.Unit_StartJob(uix, NewJob: integer): integer;911 begin 912 Result := Server(sStartJob + NewJob shl 4, me, uix, nodata^);913 end; 914 915 function TCustomAI.Unit_SetHomeHere(uix: integer): integer;916 begin 917 Result := Server(sSetUnitHome, me, uix, nodata^);918 end; 919 920 function TCustomAI.Unit_Load(uix: integer): integer;921 begin 922 Result := Server(sLoadUnit, me, uix, nodata^);923 end; 924 925 function TCustomAI.Unit_Unload(uix: integer): integer;926 begin 927 Result := Server(sUnloadUnit, me, uix, nodata^);928 end; 929 930 function TCustomAI.Unit_AddToCity(uix: integer): integer;931 begin 932 Result := Server(sAddToCity, me, uix, nodata^);933 end; 934 935 function TCustomAI.Unit_SelectTransport(uix: integer): integer;936 begin 937 Result := Server(sSelectTransport, me, uix, nodata^);938 end; 939 940 941 procedure TCustomAI.City_FindMyCity(Loc: integer; var cix: integer);905 function TCustomAI.Unit_Disband(uix: Integer): Integer; 906 begin 907 Result := Server(sRemoveUnit, Me, uix, nodata^); 908 end; 909 910 function TCustomAI.Unit_StartJob(uix, NewJob: Integer): Integer; 911 begin 912 Result := Server(sStartJob + NewJob shl 4, Me, uix, nodata^); 913 end; 914 915 function TCustomAI.Unit_SetHomeHere(uix: Integer): Integer; 916 begin 917 Result := Server(sSetUnitHome, Me, uix, nodata^); 918 end; 919 920 function TCustomAI.Unit_Load(uix: Integer): Integer; 921 begin 922 Result := Server(sLoadUnit, Me, uix, nodata^); 923 end; 924 925 function TCustomAI.Unit_Unload(uix: Integer): Integer; 926 begin 927 Result := Server(sUnloadUnit, Me, uix, nodata^); 928 end; 929 930 function TCustomAI.Unit_AddToCity(uix: Integer): Integer; 931 begin 932 Result := Server(sAddToCity, Me, uix, nodata^); 933 end; 934 935 function TCustomAI.Unit_SelectTransport(uix: Integer): Integer; 936 begin 937 Result := Server(sSelectTransport, Me, uix, nodata^); 938 end; 939 940 941 procedure TCustomAI.City_FindMyCity(Loc: Integer; var cix: Integer); 942 942 begin 943 943 if Map[Loc] and (fCity or fOwned) <> fCity or fOwned then … … 951 951 end; 952 952 953 procedure TCustomAI.City_FindEnemyCity(Loc: integer; var ecix: integer);953 procedure TCustomAI.City_FindEnemyCity(Loc: Integer; var ecix: Integer); 954 954 begin 955 955 if Map[Loc] and (fCity or fOwned) <> fCity then … … 963 963 end; 964 964 965 function TCustomAI.City_HasProject(cix: integer): boolean;965 function TCustomAI.City_HasProject(cix: Integer): Boolean; 966 966 begin 967 967 Result := MyCity[cix].Project and (cpImp + cpIndex) <> cpImp + imTrGoods; 968 968 end; 969 969 970 function TCustomAI.City_CurrentImprovementProject(cix: integer): integer;970 function TCustomAI.City_CurrentImprovementProject(cix: Integer): Integer; 971 971 begin 972 972 if MyCity[cix].Project and cpImp = 0 then … … 980 980 end; 981 981 982 function TCustomAI.City_CurrentUnitProject(cix: integer): integer;982 function TCustomAI.City_CurrentUnitProject(cix: Integer): Integer; 983 983 begin 984 984 if MyCity[cix].Project and cpImp <> 0 then … … 988 988 end; 989 989 990 function TCustomAI.City_GetTileInfo(cix, TileLoc: integer;991 var TileInfo: TTileInfo): integer;990 function TCustomAI.City_GetTileInfo(cix, TileLoc: Integer; 991 var TileInfo: TTileInfo): Integer; 992 992 begin 993 993 TileInfo.ExplCity := cix; 994 Result := Server(sGetHypoCityTileInfo, me, TileLoc, TileInfo);995 end; 996 997 function TCustomAI.City_GetReport(cix: integer; var Report: TCityReport): integer;994 Result := Server(sGetHypoCityTileInfo, Me, TileLoc, TileInfo); 995 end; 996 997 function TCustomAI.City_GetReport(cix: Integer; var Report: TCityReport): Integer; 998 998 begin 999 999 Report.HypoTiles := -1; 1000 1000 Report.HypoTax := -1; 1001 1001 Report.HypoLux := -1; 1002 Result := Server(sGetCityReport, me, cix, Report);1003 end; 1004 1005 function TCustomAI.City_GetHypoReport(cix, HypoTiles, HypoTax, HypoLux: integer;1006 var Report: TCityReport): integer;1002 Result := Server(sGetCityReport, Me, cix, Report); 1003 end; 1004 1005 function TCustomAI.City_GetHypoReport(cix, HypoTiles, HypoTax, HypoLux: Integer; 1006 var Report: TCityReport): Integer; 1007 1007 begin 1008 1008 Report.HypoTiles := HypoTiles; 1009 1009 Report.HypoTax := HypoTax; 1010 1010 Report.HypoLux := HypoLux; 1011 Result := Server(sGetCityReport, me, cix, Report);1012 end; 1013 1014 function TCustomAI.City_GetReportNew(cix: integer; var Report: TCityReportNew): integer;1011 Result := Server(sGetCityReport, Me, cix, Report); 1012 end; 1013 1014 function TCustomAI.City_GetReportNew(cix: Integer; var Report: TCityReportNew): Integer; 1015 1015 begin 1016 1016 Report.HypoTiles := -1; 1017 1017 Report.HypoTaxRate := -1; 1018 1018 Report.HypoLuxuryRate := -1; 1019 Result := Server(sGetCityReportNew, me, cix, Report);1019 Result := Server(sGetCityReportNew, Me, cix, Report); 1020 1020 end; 1021 1021 1022 1022 function TCustomAI.City_GetHypoReportNew(cix, HypoTiles, HypoTaxRate, 1023 HypoLuxuryRate: integer; var Report: TCityReportNew): integer;1023 HypoLuxuryRate: Integer; var Report: TCityReportNew): Integer; 1024 1024 begin 1025 1025 Report.HypoTiles := HypoTiles; 1026 1026 Report.HypoTaxRate := HypoTaxRate; 1027 1027 Report.HypoLuxuryRate := HypoLuxuryRate; 1028 Result := Server(sGetCityReportNew, me, cix, Report);1029 end; 1030 1031 function TCustomAI.City_GetAreaInfo(cix: integer; var AreaInfo: TCityAreaInfo): integer;1032 begin 1033 Result := Server(sGetCityAreaInfo, me, cix, AreaInfo);1034 end; 1035 1036 function TCustomAI.City_StartUnitProduction(cix, mix: integer): integer;1028 Result := Server(sGetCityReportNew, Me, cix, Report); 1029 end; 1030 1031 function TCustomAI.City_GetAreaInfo(cix: Integer; var AreaInfo: TCityAreaInfo): Integer; 1032 begin 1033 Result := Server(sGetCityAreaInfo, Me, cix, AreaInfo); 1034 end; 1035 1036 function TCustomAI.City_StartUnitProduction(cix, mix: Integer): Integer; 1037 1037 begin 1038 1038 if (MyCity[cix].Project and (cpImp + cpIndex) <> mix) then 1039 1039 // not already producing that 1040 Result := Server(sSetCityProject, me, cix, mix);1041 end; 1042 1043 function TCustomAI.City_StartEmigration(cix, mix: integer;1044 AllowDisbandCity, AsConscripts: boolean): integer;1045 var 1046 NewProject: integer;1040 Result := Server(sSetCityProject, Me, cix, mix); 1041 end; 1042 1043 function TCustomAI.City_StartEmigration(cix, mix: Integer; 1044 AllowDisbandCity, AsConscripts: Boolean): Integer; 1045 var 1046 NewProject: Integer; 1047 1047 begin 1048 1048 NewProject := mix; … … 1051 1051 if AsConscripts then 1052 1052 NewProject := NewProject or cpConscripts; 1053 Result := Server(sSetCityProject, me, cix, NewProject);1054 end; 1055 1056 function TCustomAI.City_StartImprovement(cix, iix: integer): integer;1057 var 1058 NewProject: integer;1053 Result := Server(sSetCityProject, Me, cix, NewProject); 1054 end; 1055 1056 function TCustomAI.City_StartImprovement(cix, iix: Integer): Integer; 1057 var 1058 NewProject: Integer; 1059 1059 begin 1060 1060 NewProject := iix + cpImp; 1061 1061 if (MyCity[cix].Project and (cpImp + cpIndex) <> NewProject) then 1062 1062 // not already producing that 1063 Result := Server(sSetCityProject, me, cix, NewProject);1064 end; 1065 1066 function TCustomAI.City_Improvable(cix, iix: integer): boolean;1067 var 1068 NewProject: integer;1063 Result := Server(sSetCityProject, Me, cix, NewProject); 1064 end; 1065 1066 function TCustomAI.City_Improvable(cix, iix: Integer): Boolean; 1067 var 1068 NewProject: Integer; 1069 1069 begin 1070 1070 NewProject := iix + cpImp; 1071 Result := Server(sSetCityProject - sExecute, me, cix, NewProject) >= rExecuted;1072 end; 1073 1074 function TCustomAI.City_StopProduction(cix: integer): integer;1075 var 1076 NewProject: integer;1071 Result := Server(sSetCityProject - sExecute, Me, cix, NewProject) >= rExecuted; 1072 end; 1073 1074 function TCustomAI.City_StopProduction(cix: Integer): Integer; 1075 var 1076 NewProject: Integer; 1077 1077 begin 1078 1078 NewProject := imTrGoods + cpImp; 1079 Result := Server(sSetCityProject, me, cix, NewProject);1080 end; 1081 1082 function TCustomAI.City_BuyProject(cix: integer): integer;1083 begin 1084 Result := Server(sBuyCityProject, me, cix, nodata^);1085 end; 1086 1087 function TCustomAI.City_SellImprovement(cix, iix: integer): integer;1088 begin 1089 Result := Server(sSellCityImprovement, me, cix, iix);1090 end; 1091 1092 function TCustomAI.City_RebuildImprovement(cix, iix: integer): integer;1093 begin 1094 Result := Server(sRebuildCityImprovement, me, cix, iix);1095 end; 1096 1097 function TCustomAI.City_SetTiles(cix, NewTiles: integer): integer;1098 begin 1099 Result := Server(sSetCityTiles, me, cix, NewTiles);1100 end; 1101 1102 procedure TCustomAI.City_OptimizeTiles(cix: integer; ResourceWeights: cardinal);1079 Result := Server(sSetCityProject, Me, cix, NewProject); 1080 end; 1081 1082 function TCustomAI.City_BuyProject(cix: Integer): Integer; 1083 begin 1084 Result := Server(sBuyCityProject, Me, cix, nodata^); 1085 end; 1086 1087 function TCustomAI.City_SellImprovement(cix, iix: Integer): Integer; 1088 begin 1089 Result := Server(sSellCityImprovement, Me, cix, iix); 1090 end; 1091 1092 function TCustomAI.City_RebuildImprovement(cix, iix: Integer): Integer; 1093 begin 1094 Result := Server(sRebuildCityImprovement, Me, cix, iix); 1095 end; 1096 1097 function TCustomAI.City_SetTiles(cix, NewTiles: Integer): Integer; 1098 begin 1099 Result := Server(sSetCityTiles, Me, cix, NewTiles); 1100 end; 1101 1102 procedure TCustomAI.City_OptimizeTiles(cix: Integer; ResourceWeights: Cardinal); 1103 1103 var 1104 1104 Advice: TCityTileAdviceData; 1105 1105 begin 1106 1106 Advice.ResourceWeights := ResourceWeights; 1107 Server(sGetCityTileAdvice, me, cix, Advice);1107 Server(sGetCityTileAdvice, Me, cix, Advice); 1108 1108 City_SetTiles(cix, Advice.Tiles); 1109 1109 end; … … 1111 1111 1112 1112 // negotiation 1113 function TCustomAI.Nego_CheckMyAction: integer;1114 begin 1115 assert(Opponent >= 0); // only allowed in negotiation mode1116 assert((MyAction = scDipNotice) or (MyAction = scDipAccept) or1113 function TCustomAI.Nego_CheckMyAction: Integer; 1114 begin 1115 Assert(Opponent >= 0); // only allowed in negotiation mode 1116 Assert((MyAction = scDipNotice) or (MyAction = scDipAccept) or 1117 1117 (MyAction = scDipCancelTreaty) or (MyAction = scDipOffer) or (MyAction = scDipBreak)); 1118 1118 if MyAction = scDipOffer then 1119 Result := Server(MyAction - sExecute, me, 0, MyOffer)1119 Result := Server(MyAction - sExecute, Me, 0, MyOffer) 1120 1120 else 1121 Result := Server(MyAction - sExecute, me, 0, nodata^);1121 Result := Server(MyAction - sExecute, Me, 0, nodata^); 1122 1122 end; 1123 1123 1124 1124 1125 1125 initialization 1126 nodata := pointer(0);1126 nodata := Pointer(0); 1127 1127 RWDataSize := 0; 1128 1128 -
branches/highdpi/AI/StdAI/CustomAI_Reload.pas
r210 r465 13 13 TCustomAI=class 14 14 public 15 procedure Process(Command: integer; var Data);15 procedure Process(Command: Integer; var Data); 16 16 17 17 // overridables 18 constructor Create(Nation: integer); virtual;18 constructor Create(Nation: Integer); virtual; 19 19 destructor Destroy; override; 20 20 procedure SetDataDefaults; virtual; 21 21 procedure SetDataRandom; virtual; 22 22 procedure OnBeforeEnemyAttack(UnitInfo: TUnitInfo; 23 ToLoc, EndHealth, EndHealthDef: integer); virtual;24 procedure OnBeforeEnemyCapture(UnitInfo: TUnitInfo; ToLoc: integer); virtual;23 ToLoc, EndHealth, EndHealthDef: Integer); virtual; 24 procedure OnBeforeEnemyCapture(UnitInfo: TUnitInfo; ToLoc: Integer); virtual; 25 25 procedure OnAfterEnemyAttack; virtual; 26 26 procedure OnAfterEnemyCapture; virtual; 27 27 28 28 protected 29 me: integer; // index of the controlled nation29 Me: Integer; // index of the controlled nation 30 30 RO: ^TPlayerContext; 31 31 Map: ^TTileList; … … 34 34 MyModel: ^TModelList; 35 35 36 cixStateImp: array[imPalace..imSpacePort] of integer;36 cixStateImp: array[imPalace..imSpacePort] of Integer; 37 37 38 38 // negotiation 39 Opponent: integer; // nation i'm in negotiation with, -1 indicates no-negotiation mode40 MyAction, MyLastAction, OppoAction: integer;39 Opponent: Integer; // nation i'm in negotiation with, -1 indicates no-negotiation mode 40 MyAction, MyLastAction, OppoAction: Integer; 41 41 MyOffer, MyLastOffer, OppoOffer: TOffer; 42 42 … … 44 44 procedure DoTurn; virtual; 45 45 procedure DoNegotiation; virtual; 46 function ChooseResearchAdvance: integer; virtual;47 function ChooseStealAdvance: integer; virtual;48 function ChooseGovernment: integer; virtual;49 function WantNegotiation(Nation: integer; NegoTime: TNegoTime): boolean; virtual;50 function OnNegoRejected_CancelTreaty: boolean; virtual;46 function ChooseResearchAdvance: Integer; virtual; 47 function ChooseStealAdvance: Integer; virtual; 48 function ChooseGovernment: Integer; virtual; 49 function WantNegotiation(Nation: Integer; NegoTime: TNegoTime): Boolean; virtual; 50 function OnNegoRejected_CancelTreaty: Boolean; virtual; 51 51 52 52 // general functions 53 function IsResearched(Advance: integer): boolean;54 function ResearchCost: integer;55 function ChangeAttitude(Nation, Attitude: integer): integer;56 function Revolution: integer;57 function ChangeRates(Tax,Lux: integer): integer;58 function PrepareNewModel(Domain: integer): integer;59 function SetNewModelFeature(F, Count: integer): integer;60 function AdvanceResearchable(Advance: integer): boolean;61 function AdvanceStealable(Advance: integer): boolean;62 function DebugMessage(Level: integer; Text: string): boolean;63 function SetDebugMap(var DebugMap): boolean;53 function IsResearched(Advance: Integer): Boolean; 54 function ResearchCost: Integer; 55 function ChangeAttitude(Nation, Attitude: Integer): Integer; 56 function Revolution: Integer; 57 function ChangeRates(Tax,Lux: Integer): Integer; 58 function PrepareNewModel(Domain: Integer): Integer; 59 function SetNewModelFeature(F, Count: Integer): Integer; 60 function AdvanceResearchable(Advance: Integer): Boolean; 61 function AdvanceStealable(Advance: Integer): Boolean; 62 function DebugMessage(Level: Integer; Text: string): Boolean; 63 function SetDebugMap(var DebugMap): Boolean; 64 64 65 65 // unit functions 66 procedure Unit_FindMyDefender(Loc: integer; var uix: integer);67 procedure Unit_FindEnemyDefender(Loc: integer; var euix: integer);68 function Unit_Move(uix,ToLoc: integer): integer;69 function Unit_Step(uix,ToLoc: integer): integer;70 function Unit_Attack(uix,ToLoc: integer): integer;71 function Unit_DoMission(uix,MissionType,ToLoc: integer): integer;72 function Unit_MoveForecast(uix,ToLoc: integer; var RemainingMovement: integer): boolean;73 function Unit_AttackForecast(uix,ToLoc,AttackMovement: integer; var RemainingHealth: integer): boolean;74 function Unit_DefenseForecast(euix,ToLoc: integer; var RemainingHealth: integer): boolean;75 function Unit_Disband(uix: integer): integer;76 function Unit_StartJob(uix,NewJob: integer): integer;77 function Unit_SetHomeHere(uix: integer): integer;78 function Unit_Load(uix: integer): integer;79 function Unit_Unload(uix: integer): integer;80 function Unit_AddToCity(uix: integer): integer;66 procedure Unit_FindMyDefender(Loc: Integer; var uix: Integer); 67 procedure Unit_FindEnemyDefender(Loc: Integer; var euix: Integer); 68 function Unit_Move(uix,ToLoc: Integer): Integer; 69 function Unit_Step(uix,ToLoc: Integer): Integer; 70 function Unit_Attack(uix,ToLoc: Integer): Integer; 71 function Unit_DoMission(uix,MissionType,ToLoc: Integer): Integer; 72 function Unit_MoveForecast(uix,ToLoc: Integer; var RemainingMovement: Integer): Boolean; 73 function Unit_AttackForecast(uix,ToLoc,AttackMovement: Integer; var RemainingHealth: Integer): Boolean; 74 function Unit_DefenseForecast(euix,ToLoc: Integer; var RemainingHealth: Integer): Boolean; 75 function Unit_Disband(uix: Integer): Integer; 76 function Unit_StartJob(uix,NewJob: Integer): Integer; 77 function Unit_SetHomeHere(uix: Integer): Integer; 78 function Unit_Load(uix: Integer): Integer; 79 function Unit_Unload(uix: Integer): Integer; 80 function Unit_AddToCity(uix: Integer): Integer; 81 81 82 82 // city functions 83 procedure City_FindMyCity(Loc: integer; var cix: integer);84 procedure City_FindEnemyCity(Loc: integer; var ecix: integer);85 function City_HasProject(cix: integer): boolean;86 function City_CurrentImprovementProject(cix: integer): integer;87 function City_CurrentUnitProject(cix: integer): integer;88 function City_GetTileInfo(cix,TileLoc: integer; var TileInfo: TTileInfo): integer;89 function City_GetReport(cix: integer; var Report: TCityReport): integer;90 function City_GetHypoReport(cix, HypoTiles, HypoTax, HypoLux: integer; var Report: TCityReport): integer;91 function City_GetAreaInfo(cix: integer; var AreaInfo: TCityAreaInfo): integer;92 function City_StartUnitProduction(cix,mix: integer): integer;93 function City_StartEmigration(cix,mix: integer; AllowDisbandCity, AsConscripts: boolean): integer;94 function City_StartImprovement(cix,iix: integer): integer;95 function City_Improvable(cix,iix: integer): boolean;96 function City_StopProduction(cix: integer): integer;97 function City_BuyProject(cix: integer): integer;98 function City_SellImprovement(cix,iix: integer): integer;99 function City_RebuildImprovement(cix,iix: integer): integer;100 function City_SetTiles(cix,NewTiles: integer): integer;83 procedure City_FindMyCity(Loc: Integer; var cix: Integer); 84 procedure City_FindEnemyCity(Loc: Integer; var ecix: Integer); 85 function City_HasProject(cix: Integer): Boolean; 86 function City_CurrentImprovementProject(cix: Integer): Integer; 87 function City_CurrentUnitProject(cix: Integer): Integer; 88 function City_GetTileInfo(cix,TileLoc: Integer; var TileInfo: TTileInfo): Integer; 89 function City_GetReport(cix: Integer; var Report: TCityReport): Integer; 90 function City_GetHypoReport(cix, HypoTiles, HypoTax, HypoLux: Integer; var Report: TCityReport): Integer; 91 function City_GetAreaInfo(cix: Integer; var AreaInfo: TCityAreaInfo): Integer; 92 function City_StartUnitProduction(cix,mix: Integer): Integer; 93 function City_StartEmigration(cix,mix: Integer; AllowDisbandCity, AsConscripts: Boolean): Integer; 94 function City_StartImprovement(cix,iix: Integer): Integer; 95 function City_Improvable(cix,iix: Integer): Boolean; 96 function City_StopProduction(cix: Integer): Integer; 97 function City_BuyProject(cix: Integer): Integer; 98 function City_SellImprovement(cix,iix: Integer): Integer; 99 function City_RebuildImprovement(cix,iix: Integer): Integer; 100 function City_SetTiles(cix,NewTiles: Integer): Integer; 101 101 102 102 // negotiation 103 function Nego_CheckMyAction: integer;103 function Nego_CheckMyAction: Integer; 104 104 105 105 private 106 HaveTurned: boolean;106 HaveTurned: Boolean; 107 107 UnwantedNego: set of 0..nPl-1; 108 108 Contacted: set of 0..nPl-1; … … 114 114 Server: TServerCall; 115 115 G: TNewGameData; 116 RWDataSize, MapSize: integer;117 decompose24: cardinal;118 nodata: pointer;116 RWDataSize, MapSize: Integer; 117 decompose24: Cardinal; 118 nodata: Pointer; 119 119 120 120 const … … 126 126 127 127 type 128 TVicinity8Loc=array[0..7] of integer;129 TVicinity21Loc=array[0..27] of integer;128 TVicinity8Loc=array[0..7] of Integer; 129 TVicinity21Loc=array[0..27] of Integer; 130 130 131 131 132 132 procedure Init(NewGameData: TNewGameData); 133 133 134 procedure ab_to_Loc(Loc0, a,b: integer; var Loc: integer);135 procedure Loc_to_ab(Loc0,Loc: integer; var a,b: integer);136 procedure ab_to_V8( a,b: integer; var V8: integer);137 procedure V8_to_ab(V8: integer; var a,b: integer);138 procedure ab_to_V21( a,b: integer; var V21: integer);139 procedure V21_to_ab(V21: integer; var a,b: integer);140 procedure V8_to_Loc(Loc0: integer; var VicinityLoc: TVicinity8Loc);141 procedure V21_to_Loc(Loc0: integer; var VicinityLoc: TVicinity21Loc);134 procedure ab_to_Loc(Loc0,A,B: Integer; var Loc: Integer); 135 procedure Loc_to_ab(Loc0,Loc: Integer; var A,B: Integer); 136 procedure ab_to_V8(A,B: Integer; var V8: Integer); 137 procedure V8_to_ab(V8: Integer; var A,B: Integer); 138 procedure ab_to_V21(A,B: Integer; var V21: Integer); 139 procedure V21_to_ab(V21: Integer; var A,B: Integer); 140 procedure V8_to_Loc(Loc0: Integer; var VicinityLoc: TVicinity8Loc); 141 procedure V21_to_Loc(Loc0: Integer; var VicinityLoc: TVicinity21Loc); 142 142 143 143 … … 145 145 146 146 const 147 ab_v8: array[-4..4] of integer = (5,6,7,4,-1,0,3,2,1);148 v8_a: array[0..7] of integer = (1,1,0,-1,-1,-1,0,1);149 v8_b: array[0..7] of integer = (0,1,1,1,0,-1,-1,-1);150 151 152 procedure ab_to_Loc(Loc0, a,b: integer; var Loc: integer);147 ab_v8: array[-4..4] of Integer = (5,6,7,4,-1,0,3,2,1); 148 v8_a: array[0..7] of Integer = (1,1,0,-1,-1,-1,0,1); 149 v8_b: array[0..7] of Integer = (0,1,1,1,0,-1,-1,-1); 150 151 152 procedure ab_to_Loc(Loc0,A,B: Integer; var Loc: Integer); 153 153 {relative location from Loc0} 154 154 var 155 y0: integer;156 begin 157 assert((Loc0>=0) and (Loc0<MapSize) and (a-b+G.lx>=0));158 y0:= cardinal(Loc0)*decompose24 shr 24;159 Loc:=(Loc0+( a-b+y0 and 1+G.lx+G.lx) shr 1) mod G.lx +G.lx*(y0+a+b);155 y0: Integer; 156 begin 157 Assert((Loc0>=0) and (Loc0<MapSize) and (A-B+G.lx>=0)); 158 y0:=Cardinal(Loc0)*decompose24 shr 24; 159 Loc:=(Loc0+(A-B+y0 and 1+G.lx+G.lx) shr 1) mod G.lx +G.lx*(y0+A+B); 160 160 if Loc>=MapSize then Loc:=-$1000 161 161 end; 162 162 163 procedure Loc_to_ab(Loc0,Loc: integer; var a,b: integer);163 procedure Loc_to_ab(Loc0,Loc: Integer; var A,B: Integer); 164 164 {$IFDEF FPC} // freepascal 165 165 var 166 dx,dy: integer;166 dx,dy: Integer; 167 167 begin 168 168 dx:=((Loc mod G.lx *2 +Loc div G.lx and 1) 169 169 -(Loc0 mod G.lx *2 +Loc0 div G.lx and 1)+3*G.lx) mod (2*G.lx) -G.lx; 170 170 dy:=Loc div G.lx-Loc0 div G.lx; 171 a:=(dx+dy) div 2;172 b:=(dy-dx) div 2;171 A:=(dx+dy) div 2; 172 B:=(dy-dx) div 2; 173 173 end; 174 174 {$ELSE} // delphi … … 179 179 // calculate 180 180 push ecx 181 div byte ptr [G]181 div Byte ptr [G] 182 182 xor ebx,ebx 183 183 mov bl,ah // ebx:=Loc0 mod G.lx … … 185 185 and ecx,$000000FF // ecx:=Loc0 div G.lx 186 186 mov eax,edx 187 div byte ptr [G]187 div Byte ptr [G] 188 188 xor edx,edx 189 189 mov dl,ah // edx:=Loc mod G.lx … … 202 202 mov edx,dword ptr [G] 203 203 cmp eax,edx 204 jl @ a204 jl @A 205 205 sub eax,edx 206 206 sub eax,edx 207 207 jmp @ok 208 @ a:208 @A: 209 209 neg edx 210 210 cmp eax,edx … … 219 219 add eax,ebx 220 220 sar edx,1 // edx:=b 221 mov ebx,[ b]221 mov ebx,[B] 222 222 mov [ebx],edx 223 223 sar eax,1 // eax:=a 224 mov [ a],eax224 mov [A],eax 225 225 226 226 pop ebx … … 228 228 {$ENDIF} 229 229 230 procedure ab_to_V8( a,b: integer; var V8: integer);231 begin 232 assert((abs(a)<=1) and (abs(b)<=1) and ((a<>0) or (b<>0)));233 V8:=ab_v8[2* b+b+a];234 end; 235 236 procedure V8_to_ab(V8: integer; var a,b: integer);237 begin 238 a:=v8_a[V8]; b:=V8_b[V8];239 end; 240 241 procedure ab_to_V21( a,b: integer; var V21: integer);242 begin 243 V21:=( a+b+3) shl 2+(a-b+3) shr 1;244 end; 245 246 procedure V21_to_ab(V21: integer; var a,b: integer);247 var 248 dx,dy: integer;230 procedure ab_to_V8(A,B: Integer; var V8: Integer); 231 begin 232 Assert((abs(A)<=1) and (abs(B)<=1) and ((A<>0) or (B<>0))); 233 V8:=ab_v8[2*B+B+A]; 234 end; 235 236 procedure V8_to_ab(V8: Integer; var A,B: Integer); 237 begin 238 A:=v8_a[V8]; B:=V8_b[V8]; 239 end; 240 241 procedure ab_to_V21(A,B: Integer; var V21: Integer); 242 begin 243 V21:=(A+B+3) shl 2+(A-B+3) shr 1; 244 end; 245 246 procedure V21_to_ab(V21: Integer; var A,B: Integer); 247 var 248 dx,dy: Integer; 249 249 begin 250 250 dy:=V21 shr 2-3; 251 251 dx:=V21 and 3 shl 1 -3 + (dy+3) and 1; 252 a:=(dx+dy) div 2;253 b:=(dy-dx) div 2;254 end; 255 256 procedure V8_to_Loc(Loc0: integer; var VicinityLoc: TVicinity8Loc);257 var 258 x0,y0,lx: integer;252 A:=(dx+dy) div 2; 253 B:=(dy-dx) div 2; 254 end; 255 256 procedure V8_to_Loc(Loc0: Integer; var VicinityLoc: TVicinity8Loc); 257 var 258 x0,y0,lx: Integer; 259 259 begin 260 260 lx:=G.lx; 261 y0:= cardinal(Loc0)*decompose24 shr 24;261 y0:=Cardinal(Loc0)*decompose24 shr 24; 262 262 x0:=Loc0-y0*lx; // Loc0 mod lx; 263 263 VicinityLoc[1]:=Loc0+lx*2; … … 265 265 VicinityLoc[5]:=Loc0-lx*2; 266 266 VicinityLoc[7]:=Loc0+1; 267 inc(Loc0,y0 and 1);267 Inc(Loc0,y0 and 1); 268 268 VicinityLoc[0]:=Loc0+lx; 269 269 VicinityLoc[2]:=Loc0+lx-1; … … 276 276 if x0=0 then 277 277 begin 278 inc(VicinityLoc[3],lx);278 Inc(VicinityLoc[3],lx); 279 279 if y0 and 1=0 then 280 280 begin 281 inc(VicinityLoc[2],lx);282 inc(VicinityLoc[4],lx);281 Inc(VicinityLoc[2],lx); 282 Inc(VicinityLoc[4],lx); 283 283 end 284 284 end … … 286 286 else 287 287 begin 288 dec(VicinityLoc[7],lx);288 Dec(VicinityLoc[7],lx); 289 289 if y0 and 1=1 then 290 290 begin 291 dec(VicinityLoc[0],lx);292 dec(VicinityLoc[6],lx);291 Dec(VicinityLoc[0],lx); 292 Dec(VicinityLoc[6],lx); 293 293 end 294 294 end; … … 306 306 end; 307 307 308 procedure V21_to_Loc(Loc0: integer; var VicinityLoc: TVicinity21Loc);309 var 310 dx,dy,bit,y0,xComp,yComp,xComp0,xCompSwitch: integer;311 dst: ^ integer;312 begin 313 y0:= cardinal(Loc0)*decompose24 shr 24;308 procedure V21_to_Loc(Loc0: Integer; var VicinityLoc: TVicinity21Loc); 309 var 310 dx,dy,bit,y0,xComp,yComp,xComp0,xCompSwitch: Integer; 311 dst: ^Integer; 312 begin 313 y0:=Cardinal(Loc0)*decompose24 shr 24; 314 314 xComp0:=Loc0-y0*G.lx-1; // Loc0 mod G.lx -1 315 315 xCompSwitch:=xComp0-1+y0 and 1; 316 if xComp0<0 then inc(xComp0,G.lx);317 if xCompSwitch<0 then inc(xCompSwitch,G.lx);316 if xComp0<0 then Inc(xComp0,G.lx); 317 if xCompSwitch<0 then Inc(xCompSwitch,G.lx); 318 318 xCompSwitch:=xCompSwitch xor xComp0; 319 319 yComp:=G.lx*(y0-3); … … 329 329 if bit and $67F7F76<>0 then dst^:=xComp+yComp 330 330 else dst^:=-1; 331 inc(xComp);332 if xComp>=G.lx then dec(xComp, G.lx);333 inc(dst);331 Inc(xComp); 332 if xComp>=G.lx then Dec(xComp, G.lx); 333 Inc(dst); 334 334 bit:=bit shl 1; 335 335 end; 336 inc(yComp,G.lx);336 Inc(yComp,G.lx); 337 337 end 338 338 else 339 339 begin 340 340 for dx:=0 to 3 do 341 begin dst^:=-$1000; inc(dst); end;341 begin dst^:=-$1000; Inc(dst); end; 342 342 end 343 343 end; … … 345 345 346 346 procedure Init(NewGameData: TNewGameData); 347 {$IFDEF DEBUG}var Loc: integer;{$ENDIF}347 {$IFDEF DEBUG}var Loc: Integer;{$ENDIF} 348 348 begin 349 349 G:=NewGameData; 350 350 MapSize:=G.lx*G.ly; 351 351 decompose24:=(1 shl 24-1) div G.lx +1; 352 {$IFDEF DEBUG}for Loc:=0 to MapSize-1 do assert(cardinal(Loc)*decompose24 shr 24=cardinal(Loc div G.lx));{$ENDIF}353 end; 354 355 356 constructor TCustomAI.Create(Nation: integer);352 {$IFDEF DEBUG}for Loc:=0 to MapSize-1 do Assert(Cardinal(Loc)*decompose24 shr 24=Cardinal(Loc div G.lx));{$ENDIF} 353 end; 354 355 356 constructor TCustomAI.Create(Nation: Integer); 357 357 begin 358 358 inherited Create; 359 me:=Nation;360 RO:= pointer(G.RO[Nation]);361 Map:= pointer(RO.Map);362 MyUnit:= pointer(RO.Un);363 MyCity:= pointer(RO.City);364 MyModel:= pointer(RO.Model);359 Me:=Nation; 360 RO:=Pointer(G.RO[Nation]); 361 Map:=Pointer(RO.Map); 362 MyUnit:=Pointer(RO.Un); 363 MyCity:=Pointer(RO.City); 364 MyModel:=Pointer(RO.Model); 365 365 Opponent:=-1; 366 366 end; … … 368 368 destructor TCustomAI.Destroy; 369 369 begin 370 Server(sSetDebugMap, me,0,nodata^);371 end; 372 373 374 procedure TCustomAI.Process(Command: integer; var Data);375 var 376 Nation,NewResearch,NewGov,count,ad,cix,iix: integer;370 Server(sSetDebugMap,Me,0,nodata^); 371 end; 372 373 374 procedure TCustomAI.Process(Command: Integer; var Data); 375 var 376 Nation,NewResearch,NewGov,count,ad,cix,iix: Integer; 377 377 NegoTime: TNegoTime; 378 378 begin … … 380 380 cTurn, cContinue: 381 381 begin 382 if RO.Alive and (1 shl me)=0 then382 if RO.Alive and (1 shl Me)=0 then 383 383 begin // I'm dead, huhu 384 Server(sTurn, me,0,nodata^);385 exit384 Server(sTurn,Me,0,nodata^); 385 Exit 386 386 end; 387 387 if Command=cTurn then 388 388 begin 389 fillchar(cixStateImp, sizeof(cixStateImp), $FF);389 FillChar(cixStateImp, SizeOf(cixStateImp), $FF); 390 390 for cix:=0 to RO.nCity-1 do if MyCity[cix].Loc>=0 then 391 391 for iix:=imPalace to imSpacePort do … … 396 396 NewGov:=ChooseGovernment; 397 397 if NewGov>gAnarchy then 398 Server(sSetGovernment, me,NewGov,nodata^);398 Server(sSetGovernment,Me,NewGov,nodata^); 399 399 end; 400 HaveTurned:= false;400 HaveTurned:=False; 401 401 Contacted:=[]; 402 402 end; … … 405 405 if OnNegoRejected_CancelTreaty then 406 406 if RO.Treaty[Opponent]>=trPeace then 407 if Server(sCancelTreaty, me,0,nodata^)<rExecuted then408 assert(false)407 if Server(sCancelTreaty,Me,0,nodata^)<rExecuted then 408 Assert(False) 409 409 end 410 410 else UnwantedNego:=[]; … … 415 415 if RO.Government<>gAnarchy then 416 416 for Nation:=0 to nPl-1 do 417 if (Nation<> me) and (1 shl Nation and RO.Alive<>0)417 if (Nation<>Me) and (1 shl Nation and RO.Alive<>0) 418 418 and (RO.Treaty[Nation]>=trNone) 419 419 and not (Nation in Contacted) and not (Nation in UnwantedNego) 420 and (Server(scContact-sExecute + Nation shl 4, me, 0, nodata^)>=rExecuted) then420 and (Server(scContact-sExecute + Nation shl 4, Me, 0, nodata^)>=rExecuted) then 421 421 if WantNegotiation(Nation, NegoTime) then 422 422 begin 423 if Server(scContact + Nation shl 4, me, 0, nodata^)>=rExecuted then423 if Server(scContact + Nation shl 4, Me, 0, nodata^)>=rExecuted then 424 424 begin 425 include(Contacted, Nation);425 Include(Contacted, Nation); 426 426 Opponent:=Nation; 427 427 MyAction:=scContact; 428 exit;428 Exit; 429 429 end; 430 430 end 431 else include(UnwantedNego,Nation);431 else Include(UnwantedNego,Nation); 432 432 if NegoTime=BeginOfTurn then 433 433 begin 434 434 DoTurn; 435 HaveTurned:= true;435 HaveTurned:=True; 436 436 Contacted:=[]; 437 437 UnwantedNego:=[]; 438 438 end 439 else break;440 until false;439 else Break; 440 until False; 441 441 if RO.Happened and phTech<>0 then 442 442 begin … … 446 446 count:=0; 447 447 for ad:=0 to nAdv-1 do if AdvanceResearchable(ad) then 448 begin inc(count); if random(count)=0 then NewResearch:=ad end448 begin Inc(count); if random(count)=0 then NewResearch:=ad end 449 449 end; 450 Server(sSetResearch, me,NewResearch,nodata^)450 Server(sSetResearch,Me,NewResearch,nodata^) 451 451 end; 452 if ( me=1) and (RO.Turn=800) then452 if (Me=1) and (RO.Turn=800) then 453 453 begin 454 454 count:=0; 455 Server(sReload, me,0,count)455 Server(sReload,Me,0,count) 456 456 end 457 457 else if (RO.Turn>10) and (random(1000)=0) then 458 458 begin 459 459 count:=RO.Turn-10; 460 Server(sReload, me,0,count)460 Server(sReload,Me,0,count) 461 461 end 462 else if Server(sTurn, me,0,nodata^)<rExecuted then463 assert(false);462 else if Server(sTurn,Me,0,nodata^)<rExecuted then 463 Assert(False); 464 464 end; 465 465 scContact: 466 if WantNegotiation( integer(Data), EnemyCalled) then466 if WantNegotiation(Integer(Data), EnemyCalled) then 467 467 begin 468 if Server(scDipStart, me, 0, nodata^)<rExecuted then469 assert(false);470 Opponent:= integer(Data);468 if Server(scDipStart, Me, 0, nodata^)<rExecuted then 469 Assert(False); 470 Opponent:=Integer(Data); 471 471 MyAction:=scDipStart; 472 472 end 473 473 else 474 474 begin 475 if Server(scReject, me, 0, nodata^)<rExecuted then476 assert(false);475 if Server(scReject, Me, 0, nodata^)<rExecuted then 476 Assert(False); 477 477 end; 478 478 scDipStart, scDipNotice, scDipAccept, scDipCancelTreaty, scDipOffer, scDipBreak: … … 486 486 else begin MyAction:=scDipOffer; MyOffer.nDeliver:=0; MyOffer.nCost:=0; end; 487 487 DoNegotiation; 488 assert((MyAction=scDipNotice) or (MyAction=scDipAccept)488 Assert((MyAction=scDipNotice) or (MyAction=scDipAccept) 489 489 or (MyAction=scDipCancelTreaty) or (MyAction=scDipOffer) 490 490 or (MyAction=scDipBreak)); 491 if MyAction=scDipOffer then Server(MyAction, me, 0, MyOffer)492 else Server(MyAction, me, 0, nodata^);491 if MyAction=scDipOffer then Server(MyAction, Me, 0, MyOffer) 492 else Server(MyAction, Me, 0, nodata^); 493 493 end; 494 494 cShowEndContact: … … 515 515 516 516 procedure TCustomAI.OnBeforeEnemyAttack(UnitInfo: TUnitInfo; ToLoc, EndHealth, 517 EndHealthDef: integer);518 begin 519 end; 520 521 procedure TCustomAI.OnBeforeEnemyCapture(UnitInfo: TUnitInfo; ToLoc: integer);517 EndHealthDef: Integer); 518 begin 519 end; 520 521 procedure TCustomAI.OnBeforeEnemyCapture(UnitInfo: TUnitInfo; ToLoc: Integer); 522 522 begin 523 523 end; … … 531 531 end; 532 532 533 function TCustomAI.ChooseResearchAdvance: integer;534 begin 535 result:=-1536 end; 537 538 function TCustomAI.ChooseStealAdvance: integer;539 begin 540 result:=-1541 end; 542 543 function TCustomAI.ChooseGovernment: integer;544 begin 545 result:=gDespotism546 end; 547 548 function TCustomAI.WantNegotiation(Nation: integer; NegoTime: TNegoTime): boolean;549 begin 550 result:=false;551 end; 552 553 function TCustomAI.OnNegoRejected_CancelTreaty: boolean;554 begin 555 result:=false;533 function TCustomAI.ChooseResearchAdvance: Integer; 534 begin 535 Result:=-1 536 end; 537 538 function TCustomAI.ChooseStealAdvance: Integer; 539 begin 540 Result:=-1 541 end; 542 543 function TCustomAI.ChooseGovernment: Integer; 544 begin 545 Result:=gDespotism 546 end; 547 548 function TCustomAI.WantNegotiation(Nation: Integer; NegoTime: TNegoTime): Boolean; 549 begin 550 Result:=False; 551 end; 552 553 function TCustomAI.OnNegoRejected_CancelTreaty: Boolean; 554 begin 555 Result:=False; 556 556 end; 557 557 {$HINTS ON} … … 559 559 procedure TCustomAI.StealAdvance; 560 560 var 561 Steal, ad, count: integer;561 Steal, ad, count: Integer; 562 562 begin 563 563 Steal:=ChooseStealAdvance; … … 566 566 count:=0; 567 567 for ad:=0 to nAdv-1 do if AdvanceStealable(ad) then 568 begin inc(count); if random(count)=0 then Steal:=ad end568 begin Inc(count); if random(count)=0 then Steal:=ad end 569 569 end; 570 if Steal>=0 then Server(sStealTech, me,Steal,nodata^);570 if Steal>=0 then Server(sStealTech,Me,Steal,nodata^); 571 571 RO.Happened:=RO.Happened and not phStealTech 572 572 end; 573 573 574 function TCustomAI.IsResearched(Advance: integer): boolean;575 begin 576 result:= RO.Tech[Advance]>=tsApplicable577 end; 578 579 function TCustomAI.ResearchCost: integer;580 begin 581 Server(sGetTechCost, me,0,result)582 end; 583 584 function TCustomAI.ChangeAttitude(Nation, Attitude: integer): integer;585 begin 586 result:=Server(sSetAttitude+Nation shl 4,me,Attitude,nodata^)587 end; 588 589 function TCustomAI.Revolution: integer;590 begin 591 result:=Server(sRevolution,me,0,nodata^);592 end; 593 594 function TCustomAI.ChangeRates(Tax,Lux: integer): integer;595 begin 596 result:=Server(sSetRates,me,Tax div 10 and $f+Lux div 10 and $fshl 4,nodata^)597 end; 598 599 function TCustomAI.PrepareNewModel(Domain: integer): integer;600 begin 601 result:=Server(sCreateDevModel,me,Domain,nodata^);602 end; 603 604 function TCustomAI.SetNewModelFeature(F, Count: integer): integer;605 begin 606 result:=Server(sSetDevModelCap+Count shl 4,me,F,nodata^)607 end; 608 609 function TCustomAI.AdvanceResearchable(Advance: integer): boolean;610 begin 611 result:= Server(sSetResearch-sExecute,me,Advance,nodata^)>=rExecuted;612 end; 613 614 function TCustomAI.AdvanceStealable(Advance: integer): boolean;615 begin 616 result:= Server(sStealTech-sExecute,me,Advance,nodata^)>=rExecuted;617 end; 618 619 function TCustomAI.DebugMessage(Level: integer; Text: string): boolean;620 begin 621 Text:= copy('P'+char(48+me)+' '+Text,1,254);622 Server(sMessage, me,Level,pchar(Text)^);623 624 result:=true;574 function TCustomAI.IsResearched(Advance: Integer): Boolean; 575 begin 576 Result:= RO.Tech[Advance]>=tsApplicable 577 end; 578 579 function TCustomAI.ResearchCost: Integer; 580 begin 581 Server(sGetTechCost,Me,0,Result) 582 end; 583 584 function TCustomAI.ChangeAttitude(Nation, Attitude: Integer): Integer; 585 begin 586 Result:=Server(sSetAttitude+Nation shl 4,Me,Attitude,nodata^) 587 end; 588 589 function TCustomAI.Revolution: Integer; 590 begin 591 Result:=Server(sRevolution,Me,0,nodata^); 592 end; 593 594 function TCustomAI.ChangeRates(Tax,Lux: Integer): Integer; 595 begin 596 Result:=Server(sSetRates,Me,Tax div 10 and $F+Lux div 10 and $F shl 4,nodata^) 597 end; 598 599 function TCustomAI.PrepareNewModel(Domain: Integer): Integer; 600 begin 601 Result:=Server(sCreateDevModel,Me,Domain,nodata^); 602 end; 603 604 function TCustomAI.SetNewModelFeature(F, Count: Integer): Integer; 605 begin 606 Result:=Server(sSetDevModelCap+Count shl 4,Me,F,nodata^) 607 end; 608 609 function TCustomAI.AdvanceResearchable(Advance: Integer): Boolean; 610 begin 611 Result:= Server(sSetResearch-sExecute,Me,Advance,nodata^)>=rExecuted; 612 end; 613 614 function TCustomAI.AdvanceStealable(Advance: Integer): Boolean; 615 begin 616 Result:= Server(sStealTech-sExecute,Me,Advance,nodata^)>=rExecuted; 617 end; 618 619 function TCustomAI.DebugMessage(Level: Integer; Text: string): Boolean; 620 begin 621 Text:=Copy('P'+char(48+Me)+' '+Text,1,254); 622 Server(sMessage,Me,Level,PChar(Text)^); 623 624 Result:=True; 625 625 // always returns true so that it can be used like 626 626 // "assert(DebugMessage(...));" -> not compiled in release build 627 627 end; 628 628 629 function TCustomAI.SetDebugMap(var DebugMap): boolean;630 begin 631 Server(sSetDebugMap, me, 0, DebugMap);632 633 result:=true;629 function TCustomAI.SetDebugMap(var DebugMap): Boolean; 630 begin 631 Server(sSetDebugMap, Me, 0, DebugMap); 632 633 Result:=True; 634 634 // always returns true so that it can be used like 635 635 // "assert(SetDebugMap(...));" -> not compiled in release build 636 636 end; 637 637 638 procedure TCustomAI.Unit_FindMyDefender(Loc: integer; var uix: integer);639 begin 640 if Server(sGetDefender, me,Loc,uix)<rExecuted then uix:=-1641 end; 642 643 procedure TCustomAI.Unit_FindEnemyDefender(Loc: integer; var euix: integer);638 procedure TCustomAI.Unit_FindMyDefender(Loc: Integer; var uix: Integer); 639 begin 640 if Server(sGetDefender,Me,Loc,uix)<rExecuted then uix:=-1 641 end; 642 643 procedure TCustomAI.Unit_FindEnemyDefender(Loc: Integer; var euix: Integer); 644 644 begin 645 645 euix:=RO.nEnemyUn-1; 646 646 while (euix>=0) and (RO.EnemyUn[euix].Loc<>Loc) do 647 dec(euix);648 end; 649 650 function TCustomAI.Unit_Move(uix,ToLoc: integer): integer;651 var 652 Step: integer;653 DestinationReached: boolean;647 Dec(euix); 648 end; 649 650 function TCustomAI.Unit_Move(uix,ToLoc: Integer): Integer; 651 var 652 Step: Integer; 653 DestinationReached: Boolean; 654 654 Advice: TMoveAdviceData; 655 655 begin 656 assert((uix>=0) and (uix<RO.nUn) and (MyUnit[uix].Loc>=0)); // is a unit656 Assert((uix>=0) and (uix<RO.nUn) and (MyUnit[uix].Loc>=0)); // is a unit 657 657 {Loc_to_ab(MyUnit[uix].Loc,ToLoc,a,b); 658 assert((a<>0) or (b<>0));659 if ( a>=-1) and (a<=1) and (b>=-1) and (b<=1) then658 Assert((A<>0) or (B<>0)); 659 if (A>=-1) and (A<=1) and (B>=-1) and (B<=1) then 660 660 begin // move to adjacent tile 661 !!!problem: if move is invalid, return codes are not consistent with other branch (eNoWay)661 !!!problem: if Move is invalid, return codes are not consistent with other branch (eNoWay) 662 662 Advice.nStep:=1; 663 Advice.dx[0]:= a-b;664 Advice.dy[0]:= a+b;663 Advice.dx[0]:=A-B; 664 Advice.dy[0]:=A+B; 665 665 Advice.MoreTurns:=0; 666 666 Advice.MaxHostile_MovementLeft:=MyUnit[uix].Movement; 667 result:=eOK;667 Result:=eOK; 668 668 end 669 669 else} … … 672 672 Advice.MoreTurns:=9999; 673 673 Advice.MaxHostile_MovementLeft:=100; 674 result:=Server(sGetMoveAdvice,me,uix,Advice);674 Result:=Server(sGetMoveAdvice,Me,uix,Advice); 675 675 end; 676 if result=eOk then676 if Result=eOk then 677 677 begin 678 DestinationReached:= false;678 DestinationReached:=False; 679 679 Step:=0; 680 680 repeat 681 if result and (rExecuted or rUnitRemoved)=rExecuted then // check if destination reached681 if Result and (rExecuted or rUnitRemoved)=rExecuted then // check if destination reached 682 682 if (ToLoc>=0) and (Advice.MoreTurns=0) and (Step=Advice.nStep-1) 683 683 and ((Map[ToLoc] and (fUnit or fOwned)=fUnit) // attack … … 685 685 and ((MyModel[MyUnit[uix].mix].Domain<>dGround) // bombardment 686 686 or (MyModel[MyUnit[uix].mix].Flags and mdCivil<>0))) then // can't capture 687 begin DestinationReached:= true; break end // stop next to destination687 begin DestinationReached:=True; Break end // stop next to destination 688 688 else if Step=Advice.nStep then 689 DestinationReached:= true; // normal move -- stop at destination690 691 if (Step=Advice.nStep) or ( result<>eOK) and (result<>eLoaded) then692 break;693 694 result:=Server(sMoveUnit+(Advice.dx[Step] and 7) shl 4 +(Advice.dy[Step] and 7) shl 7,695 me,uix,nodata^);696 inc(Step);689 DestinationReached:=True; // normal move -- stop at destination 690 691 if (Step=Advice.nStep) or (Result<>eOK) and (Result<>eLoaded) then 692 Break; 693 694 Result:=Server(sMoveUnit+(Advice.dx[Step] and 7) shl 4 +(Advice.dy[Step] and 7) shl 7, 695 Me,uix,nodata^); 696 Inc(Step); 697 697 if RO.Happened and phStealTech<>0 then StealAdvance; 698 until false;698 until False; 699 699 if DestinationReached then 700 700 if Advice.nStep=25 then 701 result:=Unit_Move(uix,ToLoc) // Shinkansen701 Result:=Unit_Move(uix,ToLoc) // Shinkansen 702 702 else if Advice.MoreTurns=0 then 703 result:=result or rLocationReached704 else result:=result or rMoreTurns;705 end 706 end; 707 708 function TCustomAI.Unit_Step(uix,ToLoc: integer): integer;709 var 710 a,b: integer;711 begin 712 Loc_to_ab(MyUnit[uix].Loc, ToLoc, a, b);713 assert(((a<>0) or (b<>0)) and (a>=-1) and (a<=1) and (b>=-1) and (b<=1));714 result:=Server(sMoveUnit+((a-b) and 7) shl 4 +((a+b) and 7) shl 7, me, uix, nodata^);703 Result:=Result or rLocationReached 704 else Result:=Result or rMoreTurns; 705 end 706 end; 707 708 function TCustomAI.Unit_Step(uix,ToLoc: Integer): Integer; 709 var 710 A,B: Integer; 711 begin 712 Loc_to_ab(MyUnit[uix].Loc, ToLoc, A, B); 713 Assert(((A<>0) or (B<>0)) and (A>=-1) and (A<=1) and (B>=-1) and (B<=1)); 714 Result:=Server(sMoveUnit+((A-B) and 7) shl 4 +((A+B) and 7) shl 7, Me, uix, nodata^); 715 715 if RO.Happened and phStealTech<>0 then StealAdvance; 716 716 end; 717 717 718 function TCustomAI.Unit_Attack(uix,ToLoc: integer): integer;719 var 720 a,b: integer;721 begin 722 assert((uix>=0) and (uix<RO.nUn) and (MyUnit[uix].Loc>=0) // is a unit718 function TCustomAI.Unit_Attack(uix,ToLoc: Integer): Integer; 719 var 720 A,B: Integer; 721 begin 722 Assert((uix>=0) and (uix<RO.nUn) and (MyUnit[uix].Loc>=0) // is a unit 723 723 and ((Map[ToLoc] and (fUnit or fOwned)=fUnit) // is an attack 724 724 or (Map[ToLoc] and (fCity or fOwned)=fCity) 725 725 and (MyModel[MyUnit[uix].mix].Domain<>dGround))); // is a bombardment 726 Loc_to_ab(MyUnit[uix].Loc,ToLoc, a,b);727 assert(((a<>0) or (b<>0)) and (a>=-1) and (a<=1) and (b>=-1) and (b<=1)); // attack to adjacent tile728 result:=Server(sMoveUnit+(a-b) and 7 shl 4 +(a+b) and 7 shl 7,me,uix,nodata^);729 end; 730 731 function TCustomAI.Unit_DoMission(uix,MissionType,ToLoc: integer): integer;732 var 733 a,b: integer;734 begin 735 result:=Server(sSetSpyMission + MissionType shl 4,me,0,nodata^);736 if result>=rExecuted then726 Loc_to_ab(MyUnit[uix].Loc,ToLoc,A,B); 727 Assert(((A<>0) or (B<>0)) and (A>=-1) and (A<=1) and (B>=-1) and (B<=1)); // attack to adjacent tile 728 Result:=Server(sMoveUnit+(A-B) and 7 shl 4 +(A+B) and 7 shl 7,Me,uix,nodata^); 729 end; 730 731 function TCustomAI.Unit_DoMission(uix,MissionType,ToLoc: Integer): Integer; 732 var 733 A,B: Integer; 734 begin 735 Result:=Server(sSetSpyMission + MissionType shl 4,Me,0,nodata^); 736 if Result>=rExecuted then 737 737 begin 738 assert((uix>=0) and (uix<RO.nUn) and (MyUnit[uix].Loc>=0) // is a unit738 Assert((uix>=0) and (uix<RO.nUn) and (MyUnit[uix].Loc>=0) // is a unit 739 739 and (MyModel[MyUnit[uix].mix].Kind=mkDiplomat)); // is a commando 740 Loc_to_ab(MyUnit[uix].Loc,ToLoc, a,b);741 assert(((a<>0) or (b<>0)) and (a>=-1) and (a<=1) and (b>=-1) and (b<=1)); // city must be adjacent742 result:=Server(sMoveUnit-sExecute+(a-b) and 7 shl 4 +(a+b) and 7 shl 7,me,uix,nodata^);743 if result=eMissionDone then744 result:=Server(sMoveUnit+(a-b) and 7 shl 4 +(a+b) and 7 shl 7,me,uix,nodata^)745 else if ( result<>eNoTime_Move) and (result<>eTreaty) and (result<>eNoTurn) then746 result:=eInvalid // not a special commando mission!747 end 748 end; 749 750 function TCustomAI.Unit_MoveForecast(uix,ToLoc: integer;751 var RemainingMovement: integer): boolean;740 Loc_to_ab(MyUnit[uix].Loc,ToLoc,A,B); 741 Assert(((A<>0) or (B<>0)) and (A>=-1) and (A<=1) and (B>=-1) and (B<=1)); // city must be adjacent 742 Result:=Server(sMoveUnit-sExecute+(A-B) and 7 shl 4 +(A+B) and 7 shl 7,Me,uix,nodata^); 743 if Result=eMissionDone then 744 Result:=Server(sMoveUnit+(A-B) and 7 shl 4 +(A+B) and 7 shl 7,Me,uix,nodata^) 745 else if (Result<>eNoTime_Move) and (Result<>eTreaty) and (Result<>eNoTurn) then 746 Result:=eInvalid // not a special commando mission! 747 end 748 end; 749 750 function TCustomAI.Unit_MoveForecast(uix,ToLoc: Integer; 751 var RemainingMovement: Integer): Boolean; 752 752 var 753 753 Advice: TMoveAdviceData; 754 754 begin 755 assert((uix>=0) and (uix<RO.nUn) and (MyUnit[uix].Loc>=0)); // is a unit755 Assert((uix>=0) and (uix<RO.nUn) and (MyUnit[uix].Loc>=0)); // is a unit 756 756 Advice.ToLoc:=ToLoc; 757 757 Advice.MoreTurns:=0; 758 758 Advice.MaxHostile_MovementLeft:=100; 759 if Server(sGetMoveAdvice, me,uix,Advice)=eOk then759 if Server(sGetMoveAdvice,Me,uix,Advice)=eOk then 760 760 begin 761 761 RemainingMovement:=Advice.MaxHostile_MovementLeft; 762 result:=true762 Result:=True 763 763 end 764 764 else 765 765 begin 766 766 RemainingMovement:=-1; 767 result:=false768 end 769 end; 770 771 function TCustomAI.Unit_AttackForecast(uix,ToLoc,AttackMovement: integer;772 var RemainingHealth: integer): boolean;767 Result:=False 768 end 769 end; 770 771 function TCustomAI.Unit_AttackForecast(uix,ToLoc,AttackMovement: Integer; 772 var RemainingHealth: Integer): Boolean; 773 773 var 774 774 BattleForecast: TBattleForecast; 775 775 begin 776 assert((uix>=0) and (uix<RO.nUn) and (MyUnit[uix].Loc>=0) // is a unit776 Assert((uix>=0) and (uix<RO.nUn) and (MyUnit[uix].Loc>=0) // is a unit 777 777 and (Map[ToLoc] and (fUnit or fOwned)=fUnit)); // is an attack 778 778 RemainingHealth:=-$100; 779 result:=false;779 Result:=False; 780 780 if AttackMovement>=0 then with MyUnit[uix] do 781 781 begin 782 BattleForecast.pAtt:= me;782 BattleForecast.pAtt:=Me; 783 783 BattleForecast.mixAtt:=mix; 784 784 BattleForecast.HealthAtt:=Health; … … 786 786 BattleForecast.FlagsAtt:=Flags; 787 787 BattleForecast.Movement:=AttackMovement; 788 if Server(sGetBattleForecast, me,ToLoc,BattleForecast)>=rExecuted then788 if Server(sGetBattleForecast,Me,ToLoc,BattleForecast)>=rExecuted then 789 789 begin 790 790 if BattleForecast.EndHealthAtt>0 then 791 791 RemainingHealth:=BattleForecast.EndHealthAtt 792 792 else RemainingHealth:=-BattleForecast.EndHealthDef; 793 result:=true793 Result:=True 794 794 end 795 795 end 796 796 end; 797 797 798 function TCustomAI.Unit_DefenseForecast(euix,ToLoc: integer;799 var RemainingHealth: integer): boolean;798 function TCustomAI.Unit_DefenseForecast(euix,ToLoc: Integer; 799 var RemainingHealth: Integer): Boolean; 800 800 var 801 801 BattleForecast: TBattleForecast; 802 802 begin 803 assert((euix>=0) and (euix<RO.nEnemyUn) and (RO.EnemyUn[euix].Loc>=0) // is an enemy unit803 Assert((euix>=0) and (euix<RO.nEnemyUn) and (RO.EnemyUn[euix].Loc>=0) // is an enemy unit 804 804 and (Map[ToLoc] and (fUnit or fOwned)=(fUnit or fOwned))); // is an attack 805 805 RemainingHealth:=$100; 806 result:=false;806 Result:=False; 807 807 with RO.EnemyUn[euix] do 808 808 begin … … 813 813 BattleForecast.FlagsAtt:=Flags; 814 814 BattleForecast.Movement:=100; 815 if Server(sGetBattleForecast, me,ToLoc,BattleForecast)>=rExecuted then815 if Server(sGetBattleForecast,Me,ToLoc,BattleForecast)>=rExecuted then 816 816 begin 817 817 if BattleForecast.EndHealthDef>0 then 818 818 RemainingHealth:=BattleForecast.EndHealthDef 819 819 else RemainingHealth:=-BattleForecast.EndHealthAtt; 820 result:=true820 Result:=True 821 821 end 822 822 end 823 823 end; 824 824 825 function TCustomAI.Unit_Disband(uix: integer): integer;826 begin 827 result:=Server(sRemoveUnit,me,uix,nodata^)828 end; 829 830 function TCustomAI.Unit_StartJob(uix,NewJob: integer): integer;831 begin 832 result:=Server(sStartJob+NewJob shl 4,me,uix,nodata^)833 end; 834 835 function TCustomAI.Unit_SetHomeHere(uix: integer): integer;836 begin 837 result:=Server(sSetUnitHome,me,uix,nodata^)838 end; 839 840 function TCustomAI.Unit_Load(uix: integer): integer;841 begin 842 result:=Server(sLoadUnit,me,uix,nodata^)843 end; 844 845 function TCustomAI.Unit_Unload(uix: integer): integer;846 begin 847 result:=Server(sUnloadUnit,me,uix,nodata^)848 end; 849 850 function TCustomAI.Unit_AddToCity(uix: integer): integer;851 begin 852 result:=Server(sAddToCity,me,uix,nodata^)853 end; 854 855 856 procedure TCustomAI.City_FindMyCity(Loc: integer; var cix: integer);825 function TCustomAI.Unit_Disband(uix: Integer): Integer; 826 begin 827 Result:=Server(sRemoveUnit,Me,uix,nodata^) 828 end; 829 830 function TCustomAI.Unit_StartJob(uix,NewJob: Integer): Integer; 831 begin 832 Result:=Server(sStartJob+NewJob shl 4,Me,uix,nodata^) 833 end; 834 835 function TCustomAI.Unit_SetHomeHere(uix: Integer): Integer; 836 begin 837 Result:=Server(sSetUnitHome,Me,uix,nodata^) 838 end; 839 840 function TCustomAI.Unit_Load(uix: Integer): Integer; 841 begin 842 Result:=Server(sLoadUnit,Me,uix,nodata^) 843 end; 844 845 function TCustomAI.Unit_Unload(uix: Integer): Integer; 846 begin 847 Result:=Server(sUnloadUnit,Me,uix,nodata^) 848 end; 849 850 function TCustomAI.Unit_AddToCity(uix: Integer): Integer; 851 begin 852 Result:=Server(sAddToCity,Me,uix,nodata^) 853 end; 854 855 856 procedure TCustomAI.City_FindMyCity(Loc: Integer; var cix: Integer); 857 857 begin 858 858 if Map[Loc] and (fCity or fOwned)<>fCity or fOwned then … … 862 862 cix:=RO.nCity-1; 863 863 while (cix>=0) and (MyCity[cix].Loc<>Loc) do 864 dec(cix);865 end 866 end; 867 868 procedure TCustomAI.City_FindEnemyCity(Loc: integer; var ecix: integer);864 Dec(cix); 865 end 866 end; 867 868 procedure TCustomAI.City_FindEnemyCity(Loc: Integer; var ecix: Integer); 869 869 begin 870 870 if Map[Loc] and (fCity or fOwned)<>fCity then … … 874 874 ecix:=RO.nEnemyCity-1; 875 875 while (ecix>=0) and (RO.EnemyCity[ecix].Loc<>Loc) do 876 dec(ecix);877 end 878 end; 879 880 function TCustomAI.City_HasProject(cix: integer): boolean;881 begin 882 result:= MyCity[cix].Project and (cpImp+cpIndex)<>cpImp+imTrGoods883 end; 884 885 function TCustomAI.City_CurrentImprovementProject(cix: integer): integer;886 begin 887 if MyCity[cix].Project and cpImp=0 then result:=-1876 Dec(ecix); 877 end 878 end; 879 880 function TCustomAI.City_HasProject(cix: Integer): Boolean; 881 begin 882 Result:= MyCity[cix].Project and (cpImp+cpIndex)<>cpImp+imTrGoods 883 end; 884 885 function TCustomAI.City_CurrentImprovementProject(cix: Integer): Integer; 886 begin 887 if MyCity[cix].Project and cpImp=0 then Result:=-1 888 888 else 889 889 begin 890 result:=MyCity[cix].Project and cpIndex;891 if result=imTrGoods then result:=-1892 end 893 end; 894 895 function TCustomAI.City_CurrentUnitProject(cix: integer): integer;896 begin 897 if MyCity[cix].Project and cpImp<>0 then result:=-1898 else result:=MyCity[cix].Project and cpIndex;899 end; 900 901 function TCustomAI.City_GetTileInfo(cix,TileLoc: integer; var TileInfo: TTileInfo): integer;890 Result:=MyCity[cix].Project and cpIndex; 891 if Result=imTrGoods then Result:=-1 892 end 893 end; 894 895 function TCustomAI.City_CurrentUnitProject(cix: Integer): Integer; 896 begin 897 if MyCity[cix].Project and cpImp<>0 then Result:=-1 898 else Result:=MyCity[cix].Project and cpIndex; 899 end; 900 901 function TCustomAI.City_GetTileInfo(cix,TileLoc: Integer; var TileInfo: TTileInfo): Integer; 902 902 begin 903 903 TileInfo.ExplCity:=cix; 904 result:=Server(sGetHypoCityTileInfo,me,TileLoc,TileInfo)905 end; 906 907 function TCustomAI.City_GetReport(cix: integer; var Report: TCityReport): integer;904 Result:=Server(sGetHypoCityTileInfo,Me,TileLoc,TileInfo) 905 end; 906 907 function TCustomAI.City_GetReport(cix: Integer; var Report: TCityReport): Integer; 908 908 begin 909 909 Report.HypoTiles:=-1; 910 910 Report.HypoTax:=-1; 911 911 Report.HypoLux:=-1; 912 result:=Server(sGetCityReport,me,cix,Report)913 end; 914 915 function TCustomAI.City_GetHypoReport(cix, HypoTiles, HypoTax, HypoLux: integer;916 var Report: TCityReport): integer;912 Result:=Server(sGetCityReport,Me,cix,Report) 913 end; 914 915 function TCustomAI.City_GetHypoReport(cix, HypoTiles, HypoTax, HypoLux: Integer; 916 var Report: TCityReport): Integer; 917 917 begin 918 918 Report.HypoTiles:=HypoTiles; 919 919 Report.HypoTax:=HypoTax; 920 920 Report.HypoLux:=HypoLux; 921 result:=Server(sGetCityReport,me,cix,Report)922 end; 923 924 function TCustomAI.City_GetAreaInfo(cix: integer; var AreaInfo: TCityAreaInfo): integer;925 begin 926 result:=Server(sGetCityAreaInfo,me,cix,AreaInfo)927 end; 928 929 function TCustomAI.City_StartUnitProduction(cix,mix: integer): integer;930 begin 931 result:=Server(sSetCityProject,me,cix,mix)932 end; 933 934 function TCustomAI.City_StartEmigration(cix,mix: integer;935 AllowDisbandCity, AsConscripts: boolean): integer;936 var 937 NewProject: integer;921 Result:=Server(sGetCityReport,Me,cix,Report) 922 end; 923 924 function TCustomAI.City_GetAreaInfo(cix: Integer; var AreaInfo: TCityAreaInfo): Integer; 925 begin 926 Result:=Server(sGetCityAreaInfo,Me,cix,AreaInfo) 927 end; 928 929 function TCustomAI.City_StartUnitProduction(cix,mix: Integer): Integer; 930 begin 931 Result:=Server(sSetCityProject,Me,cix,mix) 932 end; 933 934 function TCustomAI.City_StartEmigration(cix,mix: Integer; 935 AllowDisbandCity, AsConscripts: Boolean): Integer; 936 var 937 NewProject: Integer; 938 938 begin 939 939 NewProject:=mix; 940 940 if AllowDisbandCity then NewProject:=NewProject or cpDisbandCity; 941 941 if AsConscripts then NewProject:=NewProject or cpConscripts; 942 result:=Server(sSetCityProject,me,cix,NewProject)943 end; 944 945 function TCustomAI.City_StartImprovement(cix,iix: integer): integer;946 var 947 NewProject: integer;942 Result:=Server(sSetCityProject,Me,cix,NewProject) 943 end; 944 945 function TCustomAI.City_StartImprovement(cix,iix: Integer): Integer; 946 var 947 NewProject: Integer; 948 948 begin 949 949 NewProject:=iix+cpImp; 950 result:=Server(sSetCityProject,me,cix,NewProject)951 end; 952 953 function TCustomAI.City_Improvable(cix,iix: integer): boolean;954 var 955 NewProject: integer;950 Result:=Server(sSetCityProject,Me,cix,NewProject) 951 end; 952 953 function TCustomAI.City_Improvable(cix,iix: Integer): Boolean; 954 var 955 NewProject: Integer; 956 956 begin 957 957 NewProject:=iix+cpImp; 958 result:= Server(sSetCityProject-sExecute,me,cix,NewProject)>=rExecuted;959 end; 960 961 function TCustomAI.City_StopProduction(cix: integer): integer;962 var 963 NewProject: integer;958 Result:= Server(sSetCityProject-sExecute,Me,cix,NewProject)>=rExecuted; 959 end; 960 961 function TCustomAI.City_StopProduction(cix: Integer): Integer; 962 var 963 NewProject: Integer; 964 964 begin 965 965 NewProject:=imTrGoods+cpImp; 966 result:=Server(sSetCityProject,me,cix,NewProject)967 end; 968 969 function TCustomAI.City_BuyProject(cix: integer): integer;970 begin 971 result:=Server(sBuyCityProject,me,cix,nodata^)972 end; 973 974 function TCustomAI.City_SellImprovement(cix,iix: integer): integer;975 begin 976 result:=Server(sSellCityImprovement,me,cix,iix)977 end; 978 979 function TCustomAI.City_RebuildImprovement(cix,iix: integer): integer;980 begin 981 result:=Server(sRebuildCityImprovement,me,cix,iix)982 end; 983 984 function TCustomAI.City_SetTiles(cix,NewTiles: integer): integer;985 begin 986 result:=Server(sSetCityTiles,me,cix,NewTiles)966 Result:=Server(sSetCityProject,Me,cix,NewProject) 967 end; 968 969 function TCustomAI.City_BuyProject(cix: Integer): Integer; 970 begin 971 Result:=Server(sBuyCityProject,Me,cix,nodata^) 972 end; 973 974 function TCustomAI.City_SellImprovement(cix,iix: Integer): Integer; 975 begin 976 Result:=Server(sSellCityImprovement,Me,cix,iix) 977 end; 978 979 function TCustomAI.City_RebuildImprovement(cix,iix: Integer): Integer; 980 begin 981 Result:=Server(sRebuildCityImprovement,Me,cix,iix) 982 end; 983 984 function TCustomAI.City_SetTiles(cix,NewTiles: Integer): Integer; 985 begin 986 Result:=Server(sSetCityTiles,Me,cix,NewTiles) 987 987 end; 988 988 989 989 990 990 // negotiation 991 function TCustomAI.Nego_CheckMyAction: integer;992 begin 993 assert(Opponent>=0); // only allowed in negotiation mode994 assert((MyAction=scDipNotice) or (MyAction=scDipAccept)991 function TCustomAI.Nego_CheckMyAction: Integer; 992 begin 993 Assert(Opponent>=0); // only allowed in negotiation mode 994 Assert((MyAction=scDipNotice) or (MyAction=scDipAccept) 995 995 or (MyAction=scDipCancelTreaty) or (MyAction=scDipOffer) 996 996 or (MyAction=scDipBreak)); 997 if MyAction=scDipOffer then result:=Server(MyAction-sExecute, me, 0, MyOffer)998 else result:=Server(MyAction-sExecute, me, 0, nodata^);997 if MyAction=scDipOffer then Result:=Server(MyAction-sExecute, Me, 0, MyOffer) 998 else Result:=Server(MyAction-sExecute, Me, 0, nodata^); 999 999 end; 1000 1000 1001 1001 1002 1002 initialization 1003 nodata:= pointer(0);1003 nodata:=Pointer(0); 1004 1004 RWDataSize:=0; 1005 1005 -
branches/highdpi/AI/StdAI/Pile.pas
r303 r465 8 8 interface 9 9 10 procedure Create(Size: integer);10 procedure Create(Size: Integer); 11 11 procedure Free; 12 12 procedure Empty; 13 function Put(Item, Value: integer): boolean;14 function TestPut(Item, Value: integer): boolean;15 function Get(var Item, Value: integer): boolean;13 function Put(Item, Value: Integer): Boolean; 14 function TestPut(Item, Value: Integer): Boolean; 15 function Get(var Item, Value: Integer): Boolean; 16 16 17 17 … … 23 23 type 24 24 TheapItem = record 25 Item: integer;26 Value: integer;25 Item: Integer; 26 Value: Integer; 27 27 end; 28 28 29 29 var 30 30 bh: array[0..MaxSize - 1] of TheapItem; 31 Ix: array[0..MaxSize - 1] of integer;32 n, CurrentSize: integer;33 {$IFDEF DEBUG}InUse: boolean;{$ENDIF}31 Ix: array[0..MaxSize - 1] of Integer; 32 N, CurrentSize: Integer; 33 {$IFDEF DEBUG}InUse: Boolean;{$ENDIF} 34 34 35 35 36 procedure Create(Size: integer);36 procedure Create(Size: Integer); 37 37 begin 38 38 {$IFDEF DEBUG} 39 assert(not InUse, 'Pile is a single instance class, ' +39 Assert(not InUse, 'Pile is a single instance class, ' + 40 40 'no multiple usage possible. Always call Pile.Free after use.'); 41 41 {$ENDIF} 42 assert(Size <= MaxSize);43 if ( n<> 0) or (Size > CurrentSize) then42 Assert(Size <= MaxSize); 43 if (N <> 0) or (Size > CurrentSize) then 44 44 begin 45 FillChar(Ix, Size * sizeOf( integer), 255);46 n:= 0;45 FillChar(Ix, Size * sizeOf(Integer), 255); 46 N := 0; 47 47 end; 48 48 CurrentSize := Size; … … 55 55 begin 56 56 {$IFDEF DEBUG} 57 assert(InUse);57 Assert(InUse); 58 58 InUse := False; 59 59 {$ENDIF} … … 62 62 procedure Empty; 63 63 begin 64 if n<> 0 then64 if N <> 0 then 65 65 begin 66 FillChar(Ix, CurrentSize * sizeOf( integer), 255);67 n:= 0;66 FillChar(Ix, CurrentSize * sizeOf(Integer), 255); 67 N := 0; 68 68 end; 69 69 end; 70 70 71 71 //Parent(i) = (i-1)/2. 72 function Put(Item, Value: integer): boolean; //O(lg(n))72 function Put(Item, Value: Integer): Boolean; //O(lg(n)) 73 73 var 74 i, j: integer;74 I, J: Integer; 75 75 begin 76 assert(Item < CurrentSize);77 i:= Ix[Item];78 if i>= 0 then76 Assert(Item < CurrentSize); 77 I := Ix[Item]; 78 if I >= 0 then 79 79 begin 80 if bh[ i].Value <= Value then80 if bh[I].Value <= Value then 81 81 begin 82 82 Result := False; 83 exit;83 Exit; 84 84 end; 85 85 end 86 86 else 87 87 begin 88 i := n;89 Inc( n);88 I := N; 89 Inc(N); 90 90 end; 91 91 92 while i> 0 do92 while I > 0 do 93 93 begin 94 j := (i- 1) shr 1; //Parent(i) = (i-1)/295 if Value >= bh[ j].Value then96 break;97 bh[ i] := bh[j];98 Ix[bh[ i].Item] := i;99 i := j;94 J := (I - 1) shr 1; //Parent(i) = (i-1)/2 95 if Value >= bh[J].Value then 96 Break; 97 bh[I] := bh[J]; 98 Ix[bh[I].Item] := I; 99 I := J; 100 100 end; 101 101 // Insert the new Item at the insertion point found. 102 bh[ i].Value := Value;103 bh[ i].Item := Item;104 Ix[bh[ i].Item] := i;102 bh[I].Value := Value; 103 bh[I].Item := Item; 104 Ix[bh[I].Item] := I; 105 105 Result := True; 106 106 end; 107 107 108 function TestPut(Item, Value: integer): boolean;108 function TestPut(Item, Value: Integer): Boolean; 109 109 var 110 i: integer;110 I: Integer; 111 111 begin 112 assert(Item < CurrentSize);113 i:= Ix[Item];114 Result := ( i < 0) or (bh[i].Value > Value);112 Assert(Item < CurrentSize); 113 I := Ix[Item]; 114 Result := (I < 0) or (bh[I].Value > Value); 115 115 end; 116 116 117 117 //Left(i) = 2*i+1. 118 118 //Right(i) = 2*i+2 => Left(i)+1 119 function Get(var Item, Value: integer): boolean; //O(lg(n))119 function Get(var Item, Value: Integer): Boolean; //O(lg(n)) 120 120 var 121 i, j: integer;122 last: TheapItem;121 I, J: Integer; 122 Last: TheapItem; 123 123 begin 124 if n= 0 then124 if N = 0 then 125 125 begin 126 126 Result := False; 127 exit;127 Exit; 128 128 end; 129 129 … … 133 133 Ix[Item] := -1; 134 134 135 Dec( n);136 if n> 0 then135 Dec(N); 136 if N > 0 then 137 137 begin 138 last := bh[n];139 i:= 0;140 j:= 1;141 while j < ndo138 Last := bh[N]; 139 I := 0; 140 J := 1; 141 while J < N do 142 142 begin 143 143 // Right(i) = Left(i)+1 144 if ( j < n - 1) and (bh[j].Value > bh[j+ 1].Value) then145 Inc( j);146 if last.Value <= bh[j].Value then147 break;144 if (J < N - 1) and (bh[J].Value > bh[J + 1].Value) then 145 Inc(J); 146 if Last.Value <= bh[J].Value then 147 Break; 148 148 149 bh[ i] := bh[j];150 Ix[bh[ i].Item] := i;151 i := j;152 j := jshl 1 + 1; //Left(j) = 2*j+1149 bh[I] := bh[J]; 150 Ix[bh[I].Item] := I; 151 I := J; 152 J := J shl 1 + 1; //Left(j) = 2*j+1 153 153 end; 154 154 155 155 // Insert the root in the correct place in the heap. 156 bh[ i] := last;157 Ix[ last.Item] := i;156 bh[I] := Last; 157 Ix[Last.Item] := I; 158 158 end; 159 159 Result := True; … … 161 161 162 162 initialization 163 n:= 0;163 N := 0; 164 164 CurrentSize := 0; 165 165 {$IFDEF DEBUG} -
branches/highdpi/AI/StdAI/Protocol.pas
r349 r465 916 916 Cost: Integer; 917 917 Maint: Integer; 918 Expiration: integer;918 Expiration: Integer; 919 919 end 920 920 = ((Kind: ikWonder; Preq: adMathematics; Cost: 400; Maint: 0; … … 1120 1120 Strength: Integer; 1121 1121 Trans: Integer; 1122 Cost: integer;1122 Cost: Integer; 1123 1123 end 1124 1124 = (((Preq: adWarriorCode; Strength: 4; Trans: 0; Cost: 3), … … 1510 1510 TGetCityData = record 1511 1511 Owner: Integer; 1512 c: TCity;1512 C: TCity; 1513 1513 end; 1514 1514 … … 1591 1591 TCreateUnitData = record 1592 1592 Loc: Integer; 1593 p: Integer;1593 P: Integer; 1594 1594 mix: Integer; 1595 1595 end; … … 1600 1600 TOwnerList = array [0 .. INFIN] of ShortInt; 1601 1601 TByteList = array [0 .. INFIN] of Byte; 1602 TIntList = array [0 .. INFIN] of integer;1602 TIntList = array [0 .. INFIN] of Integer; 1603 1603 TCityList = array [0 .. INFIN] of TCity; 1604 1604 TUnList = array [0 .. INFIN] of TUn; … … 1761 1761 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))); 1762 1762 1763 SpecialModelPreq: array [0 .. nSpecialModel - 1] of integer = (preNone,1763 SpecialModelPreq: array [0 .. nSpecialModel - 1] of Integer = (preNone, 1764 1764 adExplosives, preNone, preNone, (* adWri, *) adIntelligence, adTrade, 1765 1765 (* adTheCorporation,adHorsebackRiding,adAutomobile,adNavigation, … … 1770 1770 DelphiRandSeed: Integer; 1771 1771 1772 procedure MakeUnitInfo( p: Integer; const u: TUn; var ui: TUnitInfo);1773 procedure MakeModelInfo( p, mix: Integer; const m: TModel; var mi: TModelInfo);1772 procedure MakeUnitInfo(P: Integer; const U: TUn; var ui: TUnitInfo); 1773 procedure MakeModelInfo(P, mix: Integer; const M: TModel; var mi: TModelInfo); 1774 1774 function IsSameModel(const mi1, mi2: TModelInfo): Boolean; 1775 1775 function SpecialTile(Loc, TerrType, lx: Integer): Integer; … … 1781 1781 implementation 1782 1782 1783 procedure MakeUnitInfo( p: Integer; const u: TUn; var ui: TUnitInfo);1783 procedure MakeUnitInfo(P: Integer; const U: TUn; var ui: TUnitInfo); 1784 1784 begin 1785 ui.Owner := p;1786 ui.Loc := u.Loc;1787 ui.Health := u.Health;1788 ui.Fuel := u.Fuel;1789 ui.Job := u.Job;1790 ui.Exp := u.Exp;1791 ui.Load := u.TroopLoad + u.AirLoad;1792 ui.mix := u.mix;1793 ui.Flags := u.Flags;1785 ui.Owner := P; 1786 ui.Loc := U.Loc; 1787 ui.Health := U.Health; 1788 ui.Fuel := U.Fuel; 1789 ui.Job := U.Job; 1790 ui.Exp := U.Exp; 1791 ui.Load := U.TroopLoad + U.AirLoad; 1792 ui.mix := U.mix; 1793 ui.Flags := U.Flags; 1794 1794 end; 1795 1795 1796 procedure MakeModelInfo( p, mix: Integer; const m: TModel; var mi: TModelInfo);1796 procedure MakeModelInfo(P, mix: Integer; const M: TModel; var mi: TModelInfo); 1797 1797 var 1798 i: Integer;1798 I: Integer; 1799 1799 begin 1800 mi.Owner := p;1800 mi.Owner := P; 1801 1801 mi.mix := mix; 1802 mi.ID := m.ID;1803 mi.Domain := m.Domain;1804 if m.Kind = mkEnemyDeveloped then1802 mi.ID := M.ID; 1803 mi.Domain := M.Domain; 1804 if M.Kind = mkEnemyDeveloped then 1805 1805 mi.Kind := mkSelfDeveloped // important for IsSameModel() 1806 1806 else 1807 mi.Kind := m.Kind;1808 mi.Attack := m.Attack;1809 mi.Defense := m.Defense;1810 mi.Speed := m.Speed;1811 mi.Cost := m.Cost;1807 mi.Kind := M.Kind; 1808 mi.Attack := M.Attack; 1809 mi.Defense := M.Defense; 1810 mi.Speed := M.Speed; 1811 mi.Cost := M.Cost; 1812 1812 if mi.Domain = dAir then 1813 1813 begin 1814 mi.TTrans := m.Cap[mcAirTrans] * m.MTrans;1815 mi.ATrans_Fuel := m.Cap[mcFuel];1814 mi.TTrans := M.Cap[mcAirTrans] * M.MTrans; 1815 mi.ATrans_Fuel := M.Cap[mcFuel]; 1816 1816 end 1817 1817 else 1818 1818 begin 1819 mi.TTrans := m.Cap[mcSeaTrans] * m.MTrans;1820 mi.ATrans_Fuel := m.Cap[mcCarrier] * m.MTrans;1821 end; 1822 mi.Bombs := m.Cap[mcBombs] * m.MStrength * 2;1819 mi.TTrans := M.Cap[mcSeaTrans] * M.MTrans; 1820 mi.ATrans_Fuel := M.Cap[mcCarrier] * M.MTrans; 1821 end; 1822 mi.Bombs := M.Cap[mcBombs] * M.MStrength * 2; 1823 1823 mi.Cap := 0; 1824 for i:= mcFirstNonCap to nFeature - 1 do1825 if m.Cap[i] > 0 then1826 mi.Cap := mi.Cap or (1 shl ( i- mcFirstNonCap));1824 for I := mcFirstNonCap to nFeature - 1 do 1825 if M.Cap[I] > 0 then 1826 mi.Cap := mi.Cap or (1 shl (I - mcFirstNonCap)); 1827 1827 mi.MaxUpgrade := 0; 1828 for i:= 1 to nUpgrade - 1 do1829 if m.Upgrades and (1 shl i) <> 0 then1830 mi.MaxUpgrade := i;1831 mi.Weight := m.Weight;1828 for I := 1 to nUpgrade - 1 do 1829 if M.Upgrades and (1 shl I) <> 0 then 1830 mi.MaxUpgrade := I; 1831 mi.Weight := M.Weight; 1832 1832 mi.Lost := 0; 1833 1833 end; … … 1841 1841 Compare1 := @mi1; 1842 1842 Compare2 := @mi2; 1843 result := (Compare1[1] and $FFFF0000 = Compare2[1] and $FFFF0000) and1843 Result := (Compare1[1] and $FFFF0000 = Compare2[1] and $FFFF0000) and 1844 1844 (Compare1[2] = Compare2[2]) and (Compare1[3] = Compare2[3]) and 1845 1845 (Compare1[4] = Compare2[4]) and (Compare1[5] = Compare2[5]) … … 1848 1848 function SpecialTile(Loc, TerrType, lx: Integer): Integer; 1849 1849 var 1850 x, y, qx, qy, a: Integer;1850 X, Y, qx, qy, A: Integer; 1851 1851 begin 1852 1852 if TerrType = fOcean then 1853 result := 01853 Result := 0 1854 1854 else 1855 1855 begin 1856 y:= Loc div lx;1857 x := Loc - y* lx;1856 Y := Loc div lx; 1857 X := Loc - Y * lx; 1858 1858 if TerrType = fGrass then { formula for productive grassland } 1859 if Odd((lymax + x - y shr 1) shr 1 + x + (y+ 1) shr 1) then1860 result := 11859 if Odd((lymax + X - Y shr 1) shr 1 + X + (Y + 1) shr 1) then 1860 Result := 1 1861 1861 else 1862 result := 01862 Result := 0 1863 1863 else { formula for special resources } 1864 1864 begin 1865 a := 4 * x - y+ 9980;1866 qx := adiv 10;1867 if (qx * 10 = a) and (qx and 3 <> 0) then1865 A := 4 * X - Y + 9980; 1866 qx := A div 10; 1867 if (qx * 10 = A) and (qx and 3 <> 0) then 1868 1868 begin 1869 qy := ( y + x) div 5;1869 qy := (Y + X) div 5; 1870 1870 if qy and 3 <> qx shr 2 and 1 * 2 then 1871 1871 if (TerrType = fArctic) or (TerrType = fSwamp) then 1872 result := 11872 Result := 1 1873 1873 else if TerrType = fShore then 1874 1874 begin 1875 1875 if (qx + qy) and 1 = 0 then 1876 1876 if qx and 3 = 2 then 1877 result := 21877 Result := 2 1878 1878 else 1879 result := 11879 Result := 1 1880 1880 else 1881 result := 01881 Result := 0 1882 1882 end 1883 1883 else 1884 result := (qx + qy) and 1 + 11884 Result := (qx + qy) and 1 + 1 1885 1885 else 1886 result := 0;1886 Result := 0; 1887 1887 end 1888 1888 else 1889 result := 0;1889 Result := 0; 1890 1890 end 1891 1891 end; -
branches/highdpi/AI/StdAI/StdAI.ai.txt
r124 r465 5 5 #PATH_WIN32 StdAI-win32.dll 6 6 #PATH_WIN64 StdAI-win64.dll 7 #PATH_LINUX32 libstdai-i386.so 8 #PATH_LINUX64 libstdai-amd64.so 7 #PATH_LINUX_I386 libstdai-i386.so 8 #PATH_LINUX_AMD64 libstdai-amd64.so 9 #PATH_LINUX_ARM32 libstdai-arm32.so 10 #PATH_LINUX_ARM64 libstdai-arm64.so 9 11 #CREDITS Standard AI by Steffen Gerlach. -
branches/highdpi/AI/StdAI/StdAI.lpr
r303 r465 12 12 var 13 13 AIList: array[0..nPl - 1] of TCustomAI; 14 Defender: integer;14 Defender: Integer; 15 15 16 16 17 procedure Client(Command, Player: integer; var Data); stdcall;17 procedure Client(Command, Player: Integer; var Data); stdcall; 18 18 var 19 p, y0, ToLoc: integer;19 P, y0, ToLoc: Integer; 20 20 UnitInfo: TUnitInfo; 21 21 begin … … 32 32 {$ENDIF} 33 33 CustomAI.Init(TNewGameData(Data)); 34 for p:= nPl - 1 downto 0 do35 if G.RO[ p] <> nil then34 for P := nPl - 1 downto 0 do 35 if G.RO[P] <> nil then 36 36 begin 37 AIList[ p] := TAI.Create(p);38 AIList[ p].SetDataDefaults;37 AIList[P] := TAI.Create(P); 38 AIList[P].SetDataDefaults; 39 39 end 40 40 else 41 AIList[ p] := nil;41 AIList[P] := nil; 42 42 Defender := -1; 43 43 end; 44 44 cGetReady: 45 for p:= nPl - 1 downto 0 do46 if AIList[ p] <> nil then47 AIList[ p].SetDataRandom;45 for P := nPl - 1 downto 0 do 46 if AIList[P] <> nil then 47 AIList[P].SetDataRandom; 48 48 cBreakGame: 49 for p:= 0 to nPl - 1 do50 if AIList[ p] <> nil then51 AIList[ p].Free;49 for P := 0 to nPl - 1 do 50 if AIList[P] <> nil then 51 AIList[P].Free; 52 52 53 53 cTurn, cContinue, scContact..scDipBreak, cShowEndContact: -
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.
