Changeset 265 for trunk/UPlayer.pas
- Timestamp:
- Jan 15, 2019, 1:03:40 AM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/UPlayer.pas
r262 r265 6 6 7 7 uses 8 Classes, SysUtils, Graphics, UMap, DOM, fgl, XMLConf, 9 U XMLUtils, Math, UGeometry;8 Classes, SysUtils, Graphics, UMap, DOM, fgl, XMLConf, UXMLUtils, Math, 9 UGeometry, UUnit; 10 10 11 11 type … … 96 96 FMode: TPlayerMode; 97 97 FOnMove: TMoveEvent; 98 procedure MoveUnit(UnitMove: TUnitMove); 98 99 procedure SetGame(AValue: TObject); // TGame 99 100 procedure Attack(var AttackPower, DefendPower: Integer); … … 118 119 TurnStats: TGameTurnStats; 119 120 Moves: TUnitMoves; 121 Units: TUnits; 120 122 procedure ReduceMovesPower; 121 123 procedure RemoveInvalidMoves; … … 148 150 public 149 151 Game: TObject; //TGame; 150 New PlayerId: Integer;152 NewId: Integer; 151 153 function FindById(Id: Integer): TPlayer; 152 154 procedure New(Name: string; Color: TColor; Mode: TPlayerMode); 153 function GetNew PlayerId: Integer;155 function GetNewId: Integer; 154 156 procedure LoadFromNode(Node: TDOMNode); 155 157 procedure SaveToNode(Node: TDOMNode); … … 259 261 UnitMove: TUnitMove; 260 262 begin 261 Result := MapCell.Power; 263 if Assigned(MapCell.OneUnit) then Result := MapCell.OneUnit.Power 264 else Result := 0; 262 265 for UnitMove in MovesFrom do 263 266 Result := Result - UnitMove.CountOnce; … … 433 436 with TPlayerCell(Cells[I]) do begin 434 437 for J := 0 to MapCell.Neighbors.Count - 1 do 435 ConnectTo(T Cell(MapCell.Neighbors[J]).PlayerCell);438 ConnectTo(TPlayerCell(TCell(MapCell.Neighbors[J]).PlayerCell)); 436 439 end; 437 440 end; … … 511 514 NewPlayer.Color := Color; 512 515 NewPlayer.Mode := Mode; 513 NewPlayer.Id := GetNew PlayerId;516 NewPlayer.Id := GetNewId; 514 517 if Mode = pmComputer then 515 518 NewPlayer.Agressivity := caMedium; … … 517 520 end; 518 521 519 function TPlayers.GetNew PlayerId: Integer;520 begin 521 Result := New PlayerId;522 Inc(New PlayerId);522 function TPlayers.GetNewId: Integer; 523 begin 524 Result := NewId; 525 Inc(NewId); 523 526 end; 524 527 … … 554 557 begin 555 558 inherited; 556 New PlayerId := 1;559 NewId := 1; 557 560 end; 558 561 … … 579 582 Items[I].Game := Game; 580 583 end; 581 New PlayerId := Source.NewPlayerId;584 NewId := Source.NewId; 582 585 end; 583 586 … … 589 592 with Config do begin 590 593 NewCount := GetValue(DOMString(Path + '/Count'), -1); 591 New PlayerId := 1;592 if NewCount >= 2then begin594 NewId := 1; 595 if NewCount >= MinPlayerCount then begin 593 596 Self.Clear; 594 597 Count := NewCount; 595 598 for I := 0 to Count - 1 do begin 596 599 Items[I] := TPlayer.Create; 597 Items[I].Id := GetNew PlayerId;600 Items[I].Id := GetNewId; 598 601 Items[I].Game := Game; 599 602 Items[I].LoadConfig(Config, Path + '/Player' + IntToStr(I)); … … 683 686 684 687 procedure TUnitMove.SetCellFrom(AValue: TPlayerCell); 688 var 689 OldValue: TPlayerCell; 685 690 begin 686 691 if FCellFrom = AValue then Exit; 687 if Assigned(AValue) and not Assigned(FCellFrom) then begin 688 if AValue.MovesFrom.IndexOf(Self) = -1 then 689 AValue.MovesFrom.Add(Self) 692 OldValue := FCellFrom; 693 FCellFrom := nil; 694 if Assigned(OldValue) then begin 695 if OldValue.MovesFrom.IndexOf(Self) <> -1 then 696 OldValue.MovesFrom.Remove(Self) 697 else raise Exception.Create('Unit move not found'); 698 end; 699 FCellFrom := AValue; 700 if Assigned(FCellFrom) then begin 701 if FCellFrom.MovesFrom.IndexOf(Self) = -1 then 702 FCellFrom.MovesFrom.Add(Self) 690 703 else raise Exception.Create('Unit move already exists'); 691 704 end else 692 if not Assigned(AValue) and Assigned(FCellFrom) then begin 693 if FCellFrom.MovesFrom.IndexOf(Self) <> -1 then 694 FCellFrom.MovesFrom.Remove(Self) 705 end; 706 707 procedure TUnitMove.SetCellTo(AValue: TPlayerCell); 708 var 709 OldValue: TPlayerCell; 710 begin 711 if FCellTo = AValue then Exit; 712 OldValue := FCellTo; 713 FCellTo := nil; 714 if Assigned(OldValue) then begin 715 if OldValue.MovesTo.IndexOf(Self) <> -1 then 716 OldValue.MovesTo.Remove(Self) 695 717 else raise Exception.Create('Unit move not found'); 696 718 end; 697 FCellFrom := AValue; 698 end; 699 700 procedure TUnitMove.SetCellTo(AValue: TPlayerCell); 701 begin 702 if FCellTo = AValue then Exit; 703 if Assigned(AValue) and not Assigned(FCellTo) then begin 704 AValue.MovesTo.Add(Self); 719 FCellTo := AValue; 720 if Assigned(FCellTo) then begin 721 if FCellTo.MovesTo.IndexOf(Self) = -1 then 722 FCellTo.MovesTo.Add(Self) 723 else raise Exception.Create('Unit move already exists'); 705 724 end else 706 if not Assigned(AValue) and Assigned(FCellTo) then begin707 FCellTo.MovesTo.Remove(Self);708 end;709 FCellTo := AValue;710 725 end; 711 726 … … 829 844 constructor TPlayer.Create; 830 845 begin 846 Units := TUnits.Create(False); 831 847 Moves := TUnitMoves.Create; 832 848 Moves.Player := Self; … … 844 860 FreeAndNil(PlayerMap); 845 861 FreeAndNil(Moves); 862 FreeAndNil(Units); 846 863 inherited Destroy; 847 864 end; … … 937 954 938 955 function CellCompare(const Item1, Item2: TPlayerCell): Integer; 939 begin 940 if Item1.MapCell.Power > Item2.MapCell.Power then Result := 1 941 else if Item1.MapCell.Power < Item2.MapCell.Power then Result := -1 956 var 957 Stack1, Stack2: Integer; 958 begin 959 if Assigned(Item1.MapCell.OneUnit) then Stack1 := Item1.MapCell.OneUnit.Power 960 else Stack1 := 0; 961 if Assigned(Item2.MapCell.OneUnit) then Stack2 := Item2.MapCell.OneUnit.Power 962 else Stack2 := 0; 963 if Stack1 > Stack1 then Result := 1 964 else if Stack1 < Stack2 then Result := -1 942 965 else Result := 0; 943 966 end; 944 967 945 968 function CellCompareDescending(const Item1, Item2: TPlayerCell): Integer; 946 begin 947 if Item1.MapCell.Power > Item2.MapCell.Power then Result := -1 948 else if Item1.MapCell.Power < Item2.MapCell.Power then Result := 1 969 var 970 Stack1, Stack2: Integer; 971 begin 972 if Assigned(Item1.MapCell.OneUnit) then Stack1 := Item1.MapCell.OneUnit.Power 973 else Stack1 := 0; 974 if Assigned(Item2.MapCell.OneUnit) then Stack2 := Item2.MapCell.OneUnit.Power 975 else Stack2 := 0; 976 if Stack1 > Stack2 then Result := -1 977 else if Stack1 < Stack2 then Result := 1 949 978 else Result := 0; 950 979 end; 951 980 952 procedure TPlayer.Move All;981 procedure TPlayer.MoveUnit(UnitMove: TUnitMove); 953 982 var 954 983 AttackerPower: Integer; 955 984 DefenderPower: Integer; 956 985 UnitCount: Integer; 986 begin 987 with UnitMove do begin 988 UnitCount := CountOnce; 989 if CountOnce > CellFrom.MapCell.OneUnit.Power then 990 UnitCount := CellFrom.MapCell.OneUnit.Power; 991 CountOnce := 0; 992 if not Assigned(CellTo.MapCell.OneUnit) then begin 993 CellTo.MapCell.OneUnit := TGame(Game).Units.AddNew(CellFrom.MapCell.OneUnit.Kind, 0); 994 CellTo.MapCell.Player := Self; 995 end; 996 997 if CellTo.MapCell.OneUnit.Player = Self then begin 998 // Inner move 999 CellTo.MapCell.OneUnit.Power := CellTo.MapCell.OneUnit.Power + UnitCount; 1000 end else begin 1001 AttackerPower := UnitCount; 1002 if Assigned(CellTo.MapCell.OneUnit) then 1003 DefenderPower := CellTo.MapCell.OneUnit.Power 1004 else DefenderPower := 0; 1005 Attack(AttackerPower, DefenderPower); 1006 if DefenderPower = 0 then begin 1007 // Attacker wins with possible loses 1008 ClearMovesFromCell(CellTo); 1009 CellTo.MapCell.Player := Self; 1010 CellTo.MapCell.OneUnit.Player := Self; 1011 CellTo.MapCell.OneUnit.Power := AttackerPower; 1012 end else 1013 if AttackerPower = 0 then begin 1014 // Defender wins with possible loses 1015 CellTo.MapCell.OneUnit.Power := DefenderPower; 1016 end else 1017 raise Exception.Create(SUnfinishedBattle); 1018 end; 1019 CellFrom.MapCell.OneUnit.Power := CellFrom.MapCell.OneUnit.Power - UnitCount; 1020 end; 1021 end; 1022 1023 procedure TPlayer.MoveAll; 1024 var 957 1025 UnitMove: TUnitMove; 958 1026 begin 959 1027 for UnitMove in Moves do 960 with UnitMove do begin1028 with UnitMove do 961 1029 if CountOnce > 0 then begin 962 1030 if CellFrom.MapCell.Player = Self then begin 963 UnitCount := CountOnce; 964 if CountOnce > CellFrom.MapCell.Power then 965 UnitCount := CellFrom.MapCell.Power; 966 CountOnce := 0; 967 if CellTo.MapCell.Player = Self then begin 968 // Inner move 969 CellTo.MapCell.Power := CellTo.MapCell.Power + UnitCount; 970 end else begin 971 AttackerPower := UnitCount; 972 DefenderPower := CellTo.MapCell.Power; 973 Attack(AttackerPower, DefenderPower); 974 if DefenderPower = 0 then begin 975 // Attacker wins with possible loses 976 ClearMovesFromCell(CellTo); 977 CellTo.MapCell.Player := Self; 978 CellTo.MapCell.Power := AttackerPower; 979 end else 980 if AttackerPower = 0 then begin 981 // Defender wins with possible loses 982 CellTo.MapCell.Power := DefenderPower; 983 end else 984 raise Exception.Create(SUnfinishedBattle); 985 end; 986 CellFrom.MapCell.Power := CellFrom.MapCell.Power - UnitCount; 987 end; 1031 MoveUnit(UnitMove); 988 1032 end; 989 1033 end; … … 1020 1064 var 1021 1065 I: Integer; 1022 begin 1023 for I := Cell.MovesFrom.Count - 1 downto 0 do 1024 Cell.MovesFrom.Delete(I); 1066 OtherPlayerCell: TPlayerCell; 1067 begin 1068 if Assigned(Cell.MapCell.Player) then 1069 with TPlayer(Cell.MapCell.Player) do begin 1070 OtherPlayerCell := PlayerMap.Cells.SearchCell(Cell.MapCell); 1071 if Assigned(OtherPlayerCell) then begin 1072 for I := OtherPlayerCell.MovesFrom.Count - 1 downto 0 do 1073 Moves.Remove(OtherPlayerCell.MovesFrom[I]); 1074 end; 1075 end; 1025 1076 end; 1026 1077 … … 1082 1133 var 1083 1134 Move: TUnitMove; 1135 AvailPower: Integer; 1084 1136 begin 1085 1137 for Move in Moves do 1086 1138 with Move do begin 1087 if CellFrom.MapCell.Player = Self then 1088 if CountRepeat <= CellFrom.GetAvialPower then 1139 if CellFrom.MapCell.Player = Self then begin 1140 AvailPower := CellFrom.GetAvialPower + Move.CountOnce; 1141 if CountRepeat <= AvailPower then 1089 1142 CountOnce := CountRepeat 1090 else CountOnce := CellFrom.GetAvialPower; 1143 else CountOnce := AvailPower; 1144 end; 1091 1145 end; 1092 1146 RemoveEmptyUnitMoves; … … 1097 1151 I: Integer; 1098 1152 begin 1099 if TGame(Game). EmptyCellsNeutral then1153 if TGame(Game).GameSystem.EmptyCellsNeutral then 1100 1154 for I := 0 to PlayerMap.Cells.Count - 1 do 1101 1155 with TPlayerCell(PlayerMap.Cells[I]) do begin 1102 if MapCell. Power = 0 then MapCell.Player := nil;1156 if MapCell.OneUnit.Power = 0 then MapCell.Player := nil; 1103 1157 end; 1104 1158 end; … … 1108 1162 I: Integer; 1109 1163 begin 1110 // Remove empty moves1111 1164 for I := Moves.Count - 1 downto 0 do 1112 1165 if (TUnitMove(Moves[I]).CellFrom.MapCell.Player = Self) and … … 1168 1221 with TGame(Game).Map do 1169 1222 for I := 0 to Cells.Count - 1 do 1170 with Cells[I]do begin1223 with TCell(Cells[I]) do begin 1171 1224 if (Player = Self) and ((TGame(Game).GrowCells = gcPlayerAll) or 1172 1225 ((TGame(Game).GrowCells = gcPlayerCities) and (Terrain = ttCity))) then begin 1173 if Power < MaxPower then begin1226 if OneUnit.Power < MaxPower then begin 1174 1227 // Increase units count 1175 1228 Addition := 0; … … 1178 1231 end else 1179 1232 if TGame(Game).GrowAmount = gaBySquareRoot then begin 1180 Addition := Trunc(Sqrt( Power));1233 Addition := Trunc(Sqrt(OneUnit.Power)); 1181 1234 if Addition = 0 then Addition := 1; 1182 1235 end; 1183 Power := Min(Power + Addition, MaxPower);1236 OneUnit.Power := Min(OneUnit.Power + Addition, MaxPower); 1184 1237 end else 1185 if Power > MaxPower then begin1238 if OneUnit.Power > MaxPower then begin 1186 1239 // Reduce units count 1187 1240 // If cell has more then MaxPower units then additional units dies 1188 1241 // in twice of squeare root of unites over MaxPower 1189 Dies := 2 * Trunc(Sqrt( Power - MaxPower));1190 Power := Max(Power - Dies, 0);1242 Dies := 2 * Trunc(Sqrt(OneUnit.Power - MaxPower)); 1243 OneUnit.Power := Max(OneUnit.Power - Dies, 0); 1191 1244 end; 1192 1245 end;
Note:
See TracChangeset
for help on using the changeset viewer.