Changeset 143 for trunk/GameServer.pas
- Timestamp:
- May 8, 2018, 4:37:34 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/GameServer.pas
r133 r143 7 7 8 8 uses 9 Protocol, Database, dynlibs, Platform, dateutils ;9 Protocol, Database, dynlibs, Platform, dateutils, fgl, FileUtil, Graphics; 10 10 11 11 const … … 50 50 51 51 maxBrain = 255; 52 bixNoTerm = 0;53 bixSuper_Virtual = 1;54 bixTerm = 2;55 bixRandom = 3;56 bixFirstAI = 4;57 52 58 53 type 59 54 TNotifyFunction = procedure(ID: integer); 60 55 61 TBrainInfo = record 62 FileName, DLLName, Name, Credits: string; { filename and full name } 56 TBrainType = (btNoTerm, btSuperVirtual, btTerm, btRandom, btAI); 57 58 { TBrain } 59 60 TBrain = class 61 FileName: string; 62 DLLName: string; 63 Name: string; 64 Credits: string; { filename and full name } 63 65 hm: TLibHandle; { module handle } 64 Flags, ServerVersion, DataVersion, DataSize: integer; 66 Flags: Integer; 67 ServerVersion: Integer; 68 DataVersion: Integer; 69 DataSize: Integer; 65 70 Client: TClientCall; { client function address } 66 Initialized: boolean; 71 Initialized: Boolean; 72 Kind: TBrainType; 73 Picture: TBitmap; 74 procedure LoadFromFile(AIFileName: string); 75 constructor Create; 76 destructor Destroy; override; 77 end; 78 79 { TBrains } 80 81 TBrains = class(TFPGObjectList<TBrain>) 82 function AddNew: TBrain; 83 function GetKindCount(Kind: TBrainType): Integer; 84 procedure GetByKind(Kind: TBrainType; Brains: TBrains); 67 85 end; 68 86 … … 75 93 // READ ONLY 76 94 DotNetClient: TClientCall; 77 bixBeginner, // AI to use for beginner level 78 nBrain: integer; { number of brains available } 79 Brain: array [-1 .. maxBrain - 1] of TBrainInfo; { available brains } 95 Brains: TBrains; // { available brains } 80 96 NotifyMessage: string; 97 98 BrainNoTerm: TBrain; 99 BrainSuperVirtual: TBrain; 100 BrainTerm: TBrain; 101 BrainRandom: TBrain; 102 BrainBeginner: TBrain; // AI to use for beginner level 81 103 82 104 procedure Init(NotifyFunction: TNotifyFunction); … … 145 167 HandoverStack[nHandoverStack + 1] := Command; 146 168 inc(nHandoverStack, 2); 147 Brain [bix[p]].Client(Command, p, Data);169 Brains[bix[p]].Client(Command, p, Data); 148 170 dec(nHandoverStack, 2); 149 171 {$ELSE} … … 165 187 HandoverStack[nHandoverStack + 1] := Command; 166 188 inc(nHandoverStack, 2); 167 Brain [bix].Client(Command, -1, Data);189 Brains[bix].Client(Command, -1, Data); 168 190 dec(nHandoverStack, 2); 169 191 {$ELSE} … … 179 201 procedure Init(NotifyFunction: TNotifyFunction); 180 202 var 181 i: integer;182 203 f: TSearchRec; 183 T: TextFile;184 s: string;185 Key: string;186 Value: string;187 204 BasePath: string; 188 AIFileName: string;205 NewBrain: TBrain; 189 206 begin 190 207 Notify := NotifyFunction; … … 192 209 193 210 { get available brains } 194 Brain[bixNoTerm].FileName := ':AIT'; 195 Brain[bixNoTerm].Flags := 0; 196 Brain[bixNoTerm].Initialized := false; 197 Brain[bixSuper_Virtual].FileName := ':Supervisor'; 198 Brain[bixSuper_Virtual].Flags := 0; 199 Brain[bixSuper_Virtual].Initialized := false; 200 Brain[bixTerm].FileName := ':StdIntf'; 201 Brain[bixTerm].Flags := fMultiple; 202 Brain[bixTerm].Initialized := false; 203 Brain[bixTerm].ServerVersion := Version; 204 Brain[bixRandom].FileName := ':Random'; 205 Brain[bixRandom].Flags := fMultiple; 206 Brain[bixRandom].Initialized := false; 207 nBrain := bixFirstAI; 208 bixBeginner := bixFirstAI; 211 Brains := TBrains.Create; 212 BrainNoTerm := Brains.AddNew; 213 BrainNoTerm.FileName := ':AIT'; 214 BrainNoTerm.Flags := 0; 215 BrainNoTerm.Initialized := false; 216 BrainNoTerm.Kind := btNoTerm; 217 BrainSuperVirtual := Brains.AddNew; 218 BrainSuperVirtual.FileName := ':Supervisor'; 219 BrainSuperVirtual.Flags := 0; 220 BrainSuperVirtual.Initialized := false; 221 BrainSuperVirtual.Kind := btSuperVirtual; 222 BrainTerm := Brains.AddNew; 223 BrainTerm.FileName := ':StdIntf'; 224 BrainTerm.Flags := fMultiple; 225 BrainTerm.Initialized := false; 226 BrainTerm.ServerVersion := Version; 227 BrainTerm.Kind := btTerm; 228 BrainRandom := Brains.AddNew; 229 BrainRandom.FileName := ':Random'; 230 BrainRandom.Flags := fMultiple; 231 BrainRandom.Initialized := false; 232 BrainRandom.Kind := btRandom; 233 234 BrainBeginner := nil; 235 209 236 if FindFirst(HomeDir + 'AI' + DirectorySeparator + '*', faDirectory or faArchive or faReadOnly, f) = 0 then 210 237 repeat 211 238 BasePath := HomeDir + 'AI' + DirectorySeparator + f.Name; 212 239 if (f.Name <> '.') and (f.Name <> '..') and DirectoryExists(BasePath) then begin 213 with Brain[nBrain] do begin 214 FileName := f.Name; 215 DLLName := BasePath + DirectorySeparator + FileName + '.dll'; 216 AIFileName := BasePath + DirectorySeparator + f.Name + '.ai.txt'; 217 Name := f.Name; 218 Credits := ''; 219 Flags := fMultiple; 220 Client := nil; 221 Initialized := false; 222 ServerVersion := 0; 223 if not FileExists(AIFileName) then 224 raise Exception.Create(Format('AI specification file %s not found', [AIFileName])); 225 AssignFile(T, AIFileName); 226 Reset(T); 227 while not EOF(T) do 228 begin 229 ReadLn(T, s); 230 s := trim(s); 231 if Pos(' ', S) > 0 then begin 232 Key := Copy(S, 1, Pos(' ', S) - 1); 233 Value := Trim(Copy(S, Pos(' ', S) + 1, Length(S))); 234 end else begin 235 Key := S; 236 Value := ''; 237 end; 238 if Key = '#NAME' then 239 Name := Value 240 else if Key = '#.NET' then 241 Flags := Flags or fDotNet 242 else if Key = '#BEGINNER' then 243 bixBeginner := nBrain 244 else if Key = '#PATH' then 245 DLLName := BasePath + DirectorySeparator + Value 246 {$IFDEF WINDOWS}{$IFDEF CPU32} 247 else if Key = '#PATH_WIN32' then 248 DLLName := BasePath + DirectorySeparator + Value 249 {$ENDIF}{$ENDIF} 250 {$IFDEF WINDOWS}{$IFDEF CPU64} 251 else if Key = '#PATH_WIN64' then 252 DLLName := BasePath + DirectorySeparator + Value 253 {$ENDIF}{$ENDIF} 254 {$IFDEF LINUX}{$IFDEF CPU32} 255 else if Key = '#PATH_LINUX32' then 256 DLLName := BasePath + DirectorySeparator + Value 257 {$ENDIF}{$ENDIF} 258 {$IFDEF LINUX}{$IFDEF CPU64} 259 else if Key = '#PATH_LINUX64' then 260 DLLName := BasePath + DirectorySeparator + Value 261 {$ENDIF}{$ENDIF} 262 else if Key = '#GAMEVERSION' then 263 for i := 1 to Length(Value) do 264 case Value[i] of 265 '0' .. '9': 266 ServerVersion := ServerVersion and $FFFF00 + ServerVersion and 267 $FF * 10 + ord(Value[i]) - 48; 268 '.': 269 ServerVersion := ServerVersion shl 8; 270 end 271 else if Key = '#CREDITS' then 272 Credits := Value 273 end; 274 CloseFile(T); 275 end; 276 if (Brain[nBrain].ServerVersion >= FirstAICompatibleVersion) and 277 (Brain[nBrain].ServerVersion <= Version) and 278 ((Brain[nBrain].Flags and fDotNet = 0) or (@DotNetClient <> nil)) then 279 inc(nBrain); 240 NewBrain := Brains.AddNew; 241 NewBrain.Kind := btAI; 242 NewBrain.LoadFromFile(BasePath + DirectorySeparator + F.Name + '.ai.txt'); 243 if (NewBrain.ServerVersion >= FirstAICompatibleVersion) and 244 (NewBrain.ServerVersion <= Version) and 245 ((NewBrain.Flags and fDotNet = 0) or (@DotNetClient <> nil)) then begin 246 end else Brains.Delete(Brains.Count - 1); 280 247 end; 281 248 until FindNext(f) <> 0; 282 249 FindClose(F); 283 250 284 if nBrain= 0 then251 if Brains.GetKindCount(btAI) = 0 then 285 252 raise Exception.Create(Format('No AI libraries found in directory %s', [HomeDir + 'AI'])); 286 253 end; … … 288 255 procedure Done; 289 256 var 290 i: integer;257 I: Integer; 291 258 begin 292 for i := 0 to nBrain- 1 do293 if Brain[i].Initialized then294 begin295 CallClient( i, cReleaseModule, nil^);296 if ( i >= bixFirstAI) and (Brain[i].Flags and fDotNet= 0) then297 FreeLibrary( Brain[i].hm);259 for I := 0 to Brains.Count - 1 do 260 with Brains[I] do 261 if Initialized then begin 262 CallClient(I, cReleaseModule, nil^); 263 if (Kind = btAI) and ((Flags and fDotNet) = 0) then 264 FreeLibrary(hm); 298 265 end; 266 Brains.Free; 299 267 end; 300 268 … … 327 295 procedure PutMessage(Level: integer; Text: string); 328 296 begin 329 Brain [bix[0]].Client(cDebugMessage, Level, pchar(Text)^);297 Brains[bix[0]].Client(cDebugMessage, Level, pchar(Text)^); 330 298 end; 331 299 … … 362 330 LastClientTime := T; 363 331 PutMessage(1 shl 16 + 2, Format('CLIENT: calling %d (%s)', 364 [CCPlayer, Brain [bix[CCPlayer]].Name]));332 [CCPlayer, Brains[bix[CCPlayer]].Name])); 365 333 if CCCommand = cTurn then 366 334 for p := 0 to nPl - 1 do … … 371 339 CCPlayer := -1; 372 340 CallPlayer(CCCommand, p, CCData); 373 if (Mode = moPlaying) and (Brain [bix[p]].Flags and aiThreaded = 0) and341 if (Mode = moPlaying) and (Brains[bix[p]].Flags and aiThreaded = 0) and 374 342 (CCPlayer < 0) then 375 343 begin … … 449 417 end; 450 418 // log data changes 451 if Brain [bix[p]].DataSize > 0 then419 if Brains[bix[p]].DataSize > 0 then 452 420 begin 453 421 CL.PutDataChanges(sIntDataChange, p, SavedData[p], RW[p].Data, 454 Brain [bix[p]].DataSize);455 move(RW[p].Data^, SavedData[p]^, Brain [bix[p]].DataSize * 4);422 Brains[bix[p]].DataSize); 423 move(RW[p].Data^, SavedData[p]^, Brains[bix[p]].DataSize * 4); 456 424 end 457 425 end; … … 477 445 with RW[p].EnemyCity[ix] do 478 446 SavedStatus := Status; 479 if Brain [bix[p]].DataSize > 0 then480 move(RW[p].Data^, SavedData[p]^, Brain [bix[p]].DataSize * 4);447 if Brains[bix[p]].DataSize > 0 then 448 move(RW[p].Data^, SavedData[p]^, Brains[bix[p]].DataSize * 4); 481 449 end; 482 450 end; … … 507 475 result := true; 508 476 if RW[p].Data <> nil then 509 for ix := 0 to Brain [bix[p]].DataSize - 1 do477 for ix := 0 to Brains[bix[p]].DataSize - 1 do 510 478 if PDWortList(SavedData[p])[ix] <> PDWortList(RW[p].Data)[ix] then 511 479 result := true … … 516 484 InitModuleData: TInitModuleData; 517 485 begin 518 assert(bix <> bixSuper_Virtual); 519 with Brain[bix] do 520 begin 486 assert(Brains[bix].Kind <> btSuperVirtual); 487 with Brains[bix] do begin 521 488 if Initialized then 522 489 exit; 523 if bix >= bixFirstAI then490 if Kind = btAI then 524 491 begin { get client function } 525 492 Notify(ntInitModule + bix); … … 635 602 nLocal := 0; 636 603 for i := 0 to nPl - 1 do 637 if bix[i] = bixTermthen604 if (bix[i] <> -1) and (Brains[bix[i]].Kind = btTerm) then 638 605 inc(nLocal); 639 606 if Difficulty[0] = 0 then … … 683 650 else 684 651 begin 685 if bixView[i] >= bixRandomthen686 s := Brain [bix[i]].FileName687 else 688 s := Brain [bixView[i]].FileName;652 if Brains[bixView[i]].Kind in [btRandom, btAI] then 653 s := Brains[bix[i]].FileName 654 else 655 s := Brains[bixView[i]].FileName; 689 656 move(zero, s[Length(s) + 1], 4); 690 657 LogFile.write(s, (Length(s) div 4 + 1) * 4); … … 715 682 Path: shortstring; 716 683 BrainUsed: Set of 0 .. 254; { used brains } 684 AIBrains: TBrains; 717 685 begin 718 for p1 := 0 to nPl - 1 do 719 begin 720 if bixView[p1] = bixSuper_Virtual then 721 bix[p1] := bixTerm // supervisor and local human use same module 722 else if bixView[p1] = bixRandom then 723 if nBrain <= bixFirstAI then 686 for p1 := 0 to nPl - 1 do begin 687 if (bixView[p1] <> -1) and (Brains[bixView[p1]].Kind = btSuperVirtual) then 688 bix[p1] := Brains.IndexOf(BrainTerm) // supervisor and local human use same module 689 else if (bixView[p1] <> -1) and (Brains[bixView[p1]].Kind = btRandom) then 690 if Brains.GetKindCount(btAI) = 0 then 724 691 bix[p1] := -1 725 else 726 bix[p1] := bixFirstAI + Delphirandom(nBrain - bixFirstAI) 692 else begin 693 AIBrains := TBrains.Create(False); 694 bix[p1] := Brains.IndexOf(AIBrains[DelphiRandom(AIBrains.Count)]); 695 AIBrains.Free; 696 end 727 697 else 728 698 bix[p1] := bixView[p1]; … … 731 701 end; 732 702 733 if bix[0] <> bixNoTerm then703 if Brains[bix[0]].Kind <> btNoTerm then 734 704 Notify(ntInitLocalHuman); 735 705 BrainUsed := []; … … 737 707 if (bix[p] >= 0) and ((Mode <> moMovie) or (p = 0)) then 738 708 begin { initiate selected control module } 739 AIInfo[p] := Brain [bix[p]].Name + #0;709 AIInfo[p] := Brains[bix[p]].Name + #0; 740 710 InitBrain(bix[p]); 741 711 if Mode = moPlaying then 742 712 begin // new game, this data version is original 743 OriginalDataVersion[p] := Brain [bix[p]].DataVersion;713 OriginalDataVersion[p] := Brains[bix[p]].DataVersion; 744 714 ProcessClientData[p] := true; 745 715 end 746 716 else // loading game, compare with data version read from file 747 717 ProcessClientData[p] := ProcessClientData[p] and 748 (OriginalDataVersion[p] = Brain [bix[p]].DataVersion);749 if @Brain [bix[p]].Client = nil then // client function not found750 if bix[0] = bixNoTerm then718 (OriginalDataVersion[p] = Brains[bix[p]].DataVersion); 719 if @Brains[bix[p]].Client = nil then // client function not found 720 if Brains[bix[0]].Kind = btNoTerm then 751 721 bix[p] := -1 752 722 else 753 723 begin 754 bix[p] := bixTerm;724 bix[p] := Brains.IndexOf(BrainTerm); 755 725 OriginalDataVersion[p] := -1; 756 726 ProcessClientData[p] := false; … … 773 743 if Mode <> moMovie then 774 744 inc(GWatching, 1 shl p1); 775 if bix[p1] >= bixFirstAI then745 if Brains[bix[p1]].Kind = btAI then 776 746 inc(GAI, 1 shl p1); 777 747 if Difficulty[p1] > 0 then … … 780 750 inc(nAlive); 781 751 end; 782 ServerVersion[p1] := Brain [bix[p1]].ServerVersion;752 ServerVersion[p1] := Brains[bix[p1]].ServerVersion; 783 753 end; 784 WinOnAlone := ( bix[0] = bixNoTerm) and (nAlive > 1);754 WinOnAlone := (Brains[bix[0]].Kind = btNoTerm) and (nAlive > 1); 785 755 GWinner := 0; 786 756 GColdWarStart := -ColdWarTurns - 1; … … 817 787 OracleIncome := 0; 818 788 819 if Brain [bix[p]].DataSize > 0 then789 if Brains[bix[p]].DataSize > 0 then 820 790 begin 821 GetMem(SavedData[p], Brain [bix[p]].DataSize * 4);822 GetMem(Data, Brain [bix[p]].DataSize * 4);823 FillChar(SavedData[p]^, Brain [bix[p]].DataSize * 4, 0);824 FillChar(Data^, Brain [bix[p]].DataSize * 4, 0);791 GetMem(SavedData[p], Brains[bix[p]].DataSize * 4); 792 GetMem(Data, Brains[bix[p]].DataSize * 4); 793 FillChar(SavedData[p]^, Brains[bix[p]].DataSize * 4, 0); 794 FillChar(Data^, Brains[bix[p]].DataSize * 4, 0); 825 795 end 826 796 else … … 839 809 for i := 0 to nStat - 1 do 840 810 GetMem(Stat[i, p], 4 * (MaxTurn + 1)); 841 if Brain [bix[p]].Flags and fDotNet <> 0 then811 if Brains[bix[p]].Flags and fDotNet <> 0 then 842 812 begin 843 813 GetMem(RW[p].DefaultDebugMap, MapSize * 4); … … 865 835 Human := 0; 866 836 for p1 := 0 to nPl - 1 do 867 if bix[p1] = bixTerm then837 if Brains[bix[p1]].Kind = btTerm then 868 838 inc(Human, 1 shl p1); 869 839 InitMapGame(Human); … … 876 846 877 847 pTurn := -1; 878 if bix[0] <> bixNoTerm then848 if Brains[bix[0]].Kind <> btNoTerm then 879 849 Notify(ntInitLocalHuman); 880 850 Game.lx := lx; … … 887 857 // move(Difficulty,GameEx.Difficulty,SizeOf(Difficulty)); 888 858 AICredits := ''; 889 for i := 0 to nBrain - 1 do 890 if Brain[i].Initialized then 859 for i := 0 to Brains.Count - 1 do 860 with Brains[I] do begin 861 if Initialized then 891 862 if i in BrainUsed then 892 863 begin 893 if i >= bixFirstAI then864 if Kind = btAI then 894 865 Notify(ntInitPlayers); 895 866 for p := 0 to nPl - 1 do … … 899 870 else 900 871 Game.RO[p] := nil; 901 if ( i = bixTerm) and (Difficulty[0] = 0) and (bix[p] >= 0) then872 if (Kind = btTerm) and (Difficulty[0] = 0) and (bix[p] >= 0) then 902 873 Game.SuperVisorRO[p] := @RW[p] 903 874 else 904 875 Game.SuperVisorRO[p] := nil; 905 876 end; 906 if Brain[i].Flags and fDotNet > 0 then877 if Flags and fDotNet > 0 then 907 878 begin 908 Path := Brain[i].DLLName;879 Path := DLLName; 909 880 move(Path[1], Game.AssemblyPath, Length(Path)); 910 881 Game.AssemblyPath[Length(Path)] := #0; … … 920 891 CallClient(i, cNewGame, Game); 921 892 end; 922 if ( i >= bixFirstAI) and (Brain[i].Credits <> '') then893 if (Kind = btAI) and (Credits <> '') then 923 894 if AICredits = '' then 924 AICredits := Brain[i].Credits895 AICredits := Credits 925 896 else 926 AICredits := AICredits + '\' + Brain[i].Credits897 AICredits := AICredits + '\' + Credits; 927 898 end 928 899 else 929 900 begin { module no longer used -- unload } 930 901 CallClient(i, cReleaseModule, nil^); 931 if i >= bixFirstAI then902 if Kind = btAI then 932 903 begin 933 if Brain[i].Flags and fDotNet = 0 then934 FreeLibrary( Brain[i].hm);935 Brain[i].Client := nil;904 if Flags and fDotNet = 0 then 905 FreeLibrary(hm); 906 Client := nil; 936 907 end; 937 Brain[i].Initialized := false; 938 end; 908 Initialized := false; 909 end; 910 end; 939 911 AICredits := AICredits + #0; 940 912 941 if bix[0] <> bixNoTerm then913 if Brains[bix[0]].Kind <> btNoTerm then 942 914 begin 943 915 // uni ai? 944 916 bixUni := -1; 945 917 for p1 := 0 to nPl - 1 do 946 if bix[p1] >= bixFirstAIthen918 if (bix[p1] <> - 1) and (Brains[bix[p1]].Kind = btAI) then 947 919 if bixUni = -1 then 948 920 bixUni := bix[p1] … … 950 922 bixUni := -2; 951 923 for p1 := 0 to nPl - 1 do 952 if bix[p1] >= bixFirstAIthen924 if (bix[p1] <> -1) and (Brains[bix[p1]].Kind = btAI) then 953 925 begin 954 926 if bixUni = -2 then 955 NotifyMessage := Brain [bix[p1]].FileName927 NotifyMessage := Brains[bix[p1]].FileName 956 928 else 957 929 NotifyMessage := ''; … … 1159 1131 LogFile.read(d, 4); { behavior } 1160 1132 LogFile.read(Difficulty[p1], 4); 1161 j := nBrain- 1;1162 while (j >= 0) and (AnsiCompareFileName(Brain [j].FileName, s) <> 0) do1133 j := Brains.Count - 1; 1134 while (j >= 0) and (AnsiCompareFileName(Brains[j].FileName, s) <> 0) do 1163 1135 dec(j); 1164 1136 if j < 0 then … … 1167 1139 NotifyMessage := s; 1168 1140 Notify(ntAIError); 1169 j := bixTerm;1141 j := Brains.IndexOf(BrainTerm); 1170 1142 end 1171 1143 else 1172 1144 ProcessClientData[p1] := true; 1173 if j = bixNoTerm then1174 j := bixSuper_Virtual;1145 if Brains[j].Kind = btNoTerm then 1146 j := Brains.IndexOf(BrainSuperVirtual); 1175 1147 // crashed tournament -- load as supervisor 1176 1148 bixView[p1] := j; … … 1205 1177 if MovieMode then 1206 1178 begin 1207 Brain [bix[0]].Client(cShowGame, 0, nil^);1179 Brains[bix[0]].Client(cShowGame, 0, nil^); 1208 1180 Notify(ntBackOff); 1209 1181 end … … 1257 1229 {$IFDEF TEXTLOG}LoadPos0 := CL.State.LoadPos; {$ENDIF} 1258 1230 if ProcessClientData[p1] then 1259 CL.GetDataChanges(RW[p1].Data, Brain [bix[p1]].DataSize)1231 CL.GetDataChanges(RW[p1].Data, Brains[bix[p1]].DataSize) 1260 1232 else 1261 1233 CL.GetDataChanges(nil, 0); … … 1281 1253 begin 1282 1254 Notify(ntBackOn); 1283 Brain [bix[0]].Client(cBreakGame, -1, nil^);1255 Brains[bix[0]].Client(cBreakGame, -1, nil^); 1284 1256 EndGame; 1285 1257 Notify(ntStartGo); … … 1326 1298 Notify(ntLoadError); 1327 1299 end; 1328 Brain [bix[0]].Client(cShowGame, 0, nil^);1300 Brains[bix[0]].Client(cShowGame, 0, nil^); 1329 1301 Notify(ntBackOff); 1330 1302 Inform(pTurn); … … 1397 1369 nLogOpened := -1; 1398 1370 LastEndClientCommand := -1; 1399 Brain [bix[0]].Client(cShowGame, 0, nil^);1371 Brains[bix[0]].Client(cShowGame, 0, nil^); 1400 1372 Notify(ntBackOff); 1401 1373 Inform(pTurn); … … 1405 1377 procedure DirectHelp(Command: integer); 1406 1378 begin 1407 InitBrain( bixTerm);1408 Brain [bixTerm].Client(Command, -1, nil^);1379 InitBrain(Brains.IndexOf(BrainTerm)); 1380 BrainTerm.Client(Command, -1, nil^); 1409 1381 AICredits := #0; 1410 1382 end; … … 1422 1394 MapSize := lx * ly; 1423 1395 LandMass := NewLandMass; 1424 bix[0] := bixTerm;1396 bix[0] := Brains.IndexOf(BrainTerm); 1425 1397 Difficulty[0] := 0; 1426 InitBrain( bixTerm);1398 InitBrain(Brains.IndexOf(BrainTerm)); 1427 1399 1428 1400 DelphiRandomize; … … 1446 1418 Game.Difficulty[p1] := -1 1447 1419 end; 1448 Brain [bixTerm].Client(cNewMap, -1, Game);1420 BrainTerm.Client(cNewMap, -1, Game); 1449 1421 1450 1422 DiscoverAll(0, lObserveSuper); 1451 1423 Notify(ntEndInfo); 1452 Brain [bix[0]].Client(cShowGame, 0, nil^);1424 Brains[bix[0]].Client(cShowGame, 0, nil^); 1453 1425 Notify(ntBackOff); 1454 1426 ChangeClientWhenDone(cEditMap, 0, nil^, 0) … … 1905 1877 then { supervisor - all tiles visible } 1906 1878 begin 1907 if ( bix[pTurn] <> bixNoTerm) and1879 if (Brains[bix[pTurn]].Kind <> btNoTerm) and 1908 1880 ((Difficulty[pTurn] > 0) or (Mode > moLoading_Fast)) then 1909 1881 DiscoverAll(pTurn, lObserveSuper) … … 2102 2074 ShowMove.Flags := ShowMove.Flags or umShipLoading; 2103 2075 for p1 := 0 to nPl - 1 do 2104 if (1 shl p1 and GWatching <> 0) and ((p1 <> p) or ( bix[p1] = bixTerm))2076 if (1 shl p1 and GWatching <> 0) and ((p1 <> p) or (Brains[bix[p1]].Kind = btTerm)) 2105 2077 then 2106 2078 begin … … 2273 2245 if Mode >= moMovie then { show after-move in interface modules } 2274 2246 for p1 := 0 to nPl - 1 do 2275 if (1 shl p1 and GWatching <> 0) and ((p1 <> p) or ( bix[p1] = bixTerm))2247 if (1 shl p1 and GWatching <> 0) and ((p1 <> p) or (Brains[bix[p1]].Kind = btTerm)) 2276 2248 then 2277 2249 begin … … 2381 2353 if Mode >= moMovie then { show attack in interface modules } 2382 2354 for p1 := 0 to nPl - 1 do 2383 if (1 shl p1 and GWatching <> 0) and ((p1 <> p) or ( bix[p1] = bixTerm))2355 if (1 shl p1 and GWatching <> 0) and ((p1 <> p) or (Brains[bix[p1]].Kind = btTerm)) 2384 2356 then 2385 2357 begin … … 2543 2515 Lost := Destroyed[p, Owner, mix]; 2544 2516 for p1 := 0 to nPl - 1 do { show after-attack in interface modules } 2545 if (1 shl p1 and GWatching <> 0) and ((p1 <> p) or ( bix[p1] = bixTerm))2517 if (1 shl p1 and GWatching <> 0) and ((p1 <> p) or (Brains[bix[p1]].Kind = btTerm)) 2546 2518 then 2547 2519 begin … … 2807 2779 } 2808 2780 sMessage: 2809 Brain [bix[0]].Client(cDebugMessage, Subject, Data);2781 Brains[bix[0]].Client(cDebugMessage, Subject, Data); 2810 2782 2811 2783 sSetDebugMap: … … 2824 2796 2825 2797 sRefreshDebugMap: 2826 Brain [bix[0]].Client(cRefreshDebugMap, -1, Player);2798 Brains[bix[0]].Client(cRefreshDebugMap, -1, Player); 2827 2799 2828 2800 sGetChart .. sGetChart + (nStat - 1) shl 4: … … 3121 3093 AllHumansDead := true; 3122 3094 for p1 := 0 to nPl - 1 do 3123 if (1 shl p1 and GAlive <> 0) and ( bix[p1] = bixTerm) then3095 if (1 shl p1 and GAlive <> 0) and (Brains[bix[p1]].Kind = btTerm) then 3124 3096 AllHumansDead := false; 3125 3097 if (pDipActive >= 0) // still in negotiation mode … … 3238 3210 if Command = sReload then 3239 3211 begin 3240 ok := (Difficulty[0] = 0) and ( bix[0] <> bixNoTerm) and3212 ok := (Difficulty[0] = 0) and (Brains[bix[0]].Kind <> btNoTerm) and 3241 3213 (integer(Data) >= 0) and (integer(Data) < GTurn); 3242 3214 for p1 := 1 to nPl - 1 do 3243 if bix[p1] = bixTerm then3215 if Brains[bix[p1]].Kind = btTerm then 3244 3216 ok := false; 3245 3217 // allow reload in AI-only games only … … 3251 3223 if (Command = sBreak) or (Command = sResign) then 3252 3224 Notify(ntBackOn); 3253 for i := 0 to nBrain- 1 do3254 if Brain [i].Initialized then3225 for i := 0 to Brains.Count - 1 do 3226 if Brains[i].Initialized then 3255 3227 begin 3256 if i >= bixFirstAI then3228 if Brains[i].Kind = btAI then 3257 3229 Notify(ntDeinitModule + i); 3258 3230 CallClient(i, cBreakGame, nil^); … … 3289 3261 SaveMap(MapFileName); 3290 3262 Notify(ntBackOn); 3291 Brain [bixTerm].Client(cBreakGame, -1, nil^);3263 BrainTerm.Client(cBreakGame, -1, nil^); 3292 3264 ReleaseMapEditor; 3293 3265 if Command = sSaveMap then … … 3469 3441 pTarget := p1; 3470 3442 Action := Command; 3471 Brain [bix[0]].Client(cShowNego, 1 shl 16 + 3, ShowNegoData);3443 Brains[bix[0]].Client(cShowNego, 1 shl 16 + 3, ShowNegoData); 3472 3444 end; 3473 3445 pDipActive := p1; … … 3570 3542 Action := Command; 3571 3543 Offer := TOffer(Data); 3572 Brain [bix[0]].Client(cShowNego, 1 shl 16 + 3, ShowNegoData);3544 Brains[bix[0]].Client(cShowNego, 1 shl 16 + 3, ShowNegoData); 3573 3545 end; 3574 3546 LastOffer := TOffer(Data); … … 4507 4479 end; { <<<server } 4508 4480 4481 { TBrain } 4482 4483 procedure TBrain.LoadFromFile(AIFileName: string); 4484 var 4485 T: Text; 4486 Key: string; 4487 Value: string; 4488 S: string; 4489 BasePath: string; 4490 I: Integer; 4491 begin 4492 BasePath := ExtractFileDir(AIFileName); 4493 FileName := ExtractFileName(ExtractFileNameWithoutExt(ExtractFileNameWithoutExt(AIFileName))); 4494 Name := FileName; 4495 DLLName := BasePath + DirectorySeparator + Name + '.dll'; 4496 Credits := ''; 4497 Flags := fMultiple; 4498 Client := nil; 4499 Initialized := false; 4500 ServerVersion := 0; 4501 if not FileExists(AIFileName) then 4502 raise Exception.Create(Format('AI specification file %s not found', [AIFileName])); 4503 AssignFile(T, AIFileName); 4504 Reset(T); 4505 while not EOF(T) do 4506 begin 4507 ReadLn(T, s); 4508 s := trim(s); 4509 if Pos(' ', S) > 0 then begin 4510 Key := Copy(S, 1, Pos(' ', S) - 1); 4511 Value := Trim(Copy(S, Pos(' ', S) + 1, Length(S))); 4512 end else begin 4513 Key := S; 4514 Value := ''; 4515 end; 4516 if Key = '#NAME' then 4517 Name := Value 4518 else if Key = '#.NET' then 4519 Flags := Flags or fDotNet 4520 else if Key = '#BEGINNER' then 4521 BrainBeginner := Self 4522 else if Key = '#PATH' then 4523 DLLName := BasePath + DirectorySeparator + Value 4524 {$IFDEF WINDOWS}{$IFDEF CPU32} 4525 else if Key = '#PATH_WIN32' then 4526 DLLName := BasePath + DirectorySeparator + Value 4527 {$ENDIF}{$ENDIF} 4528 {$IFDEF WINDOWS}{$IFDEF CPU64} 4529 else if Key = '#PATH_WIN64' then 4530 DLLName := BasePath + DirectorySeparator + Value 4531 {$ENDIF}{$ENDIF} 4532 {$IFDEF LINUX}{$IFDEF CPU32} 4533 else if Key = '#PATH_LINUX32' then 4534 DLLName := BasePath + DirectorySeparator + Value 4535 {$ENDIF}{$ENDIF} 4536 {$IFDEF LINUX}{$IFDEF CPU64} 4537 else if Key = '#PATH_LINUX64' then 4538 DLLName := BasePath + DirectorySeparator + Value 4539 {$ENDIF}{$ENDIF} 4540 else if Key = '#GAMEVERSION' then 4541 for i := 1 to Length(Value) do 4542 case Value[i] of 4543 '0' .. '9': 4544 ServerVersion := ServerVersion and $FFFF00 + ServerVersion and 4545 $FF * 10 + ord(Value[i]) - 48; 4546 '.': 4547 ServerVersion := ServerVersion shl 8; 4548 end 4549 else if Key = '#CREDITS' then 4550 Credits := Value; 4551 end; 4552 CloseFile(T); 4553 end; 4554 4555 constructor TBrain.Create; 4556 begin 4557 Picture := nil; 4558 end; 4559 4560 destructor TBrain.Destroy; 4561 begin 4562 if Assigned(Picture) then Picture.Free; 4563 inherited Destroy; 4564 end; 4565 4566 { TBrains } 4567 4568 function TBrains.AddNew: TBrain; 4569 begin 4570 Result := TBrain.Create; 4571 Add(Result); 4572 end; 4573 4574 function TBrains.GetKindCount(Kind: TBrainType): Integer; 4575 var 4576 I: Integer; 4577 begin 4578 Result := 0; 4579 for I := 0 to Count - 1 do 4580 if Items[I].Kind = Kind then Inc(Result); 4581 end; 4582 4583 procedure TBrains.GetByKind(Kind: TBrainType; Brains: TBrains); 4584 var 4585 I: Integer; 4586 begin 4587 Brains.Clear; 4588 for I := 0 to Count - 1 do 4589 if Items[I].Kind = Kind then Brains.Add(Items[I]); 4590 end; 4591 4509 4592 initialization 4510 4593
Note:
See TracChangeset
for help on using the changeset viewer.