Changeset 148 for trunk/UGame.pas
- Timestamp:
- Nov 12, 2017, 11:06:20 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/UGame.pas
r147 r148 71 71 function GetAvialPower: Integer; 72 72 function GetAttackPower: Integer; 73 function ToString: ansistring; override; 73 74 constructor Create; 74 75 destructor Destroy; override; … … 267 268 TPlayerMode = (pmHuman, pmComputer); 268 269 TComputerAgressivity = (caLow, caMedium, caHigh); 270 TComputer = class; 271 TUnitMove = class; 269 272 270 273 { TPlayer } … … 274 277 FClient: TClient; 275 278 FGame: TGame; 279 FMode: TPlayerMode; 276 280 procedure SetClient(AValue: TClient); 277 281 procedure SetGame(AValue: TGame); 282 procedure Attack(var AttackPower, DefendPower: Integer); 283 procedure ClearMovesFromCell(Cell: TCell); 284 procedure MoveAll; 285 procedure CheckCounterMove(Move: TUnitMove); 286 procedure SetMode(AValue: TPlayerMode); 287 function SetMove(CellFrom, CellTo: TCell; Power: Integer; Confirmation: Boolean = True): TUnitMove; 288 procedure UpdateRepeatMoves; 278 289 public 279 290 Id: Integer; 280 291 Name: string; 281 292 Color: TColor; 282 Mode: TPlayerMode;283 293 TotalUnits: Integer; 284 294 TotalCells: Integer; … … 291 301 Agressivity: TComputerAgressivity; 292 302 TurnStats: TGameTurnStats; 303 Moves: TUnitMoves; 304 Computer: TComputer; 293 305 procedure Clear; 294 306 procedure LoadFromNode(Node: TDOMNode); … … 300 312 property Game: TGame read FGame write SetGame; 301 313 property Client: TClient read FClient write SetClient; 302 end;303 304 305 { TComputer }314 property Mode: TPlayerMode read FMode write SetMode; 315 end; 316 317 { TComputer } 306 318 307 319 TComputer = class … … 309 321 //Targets: TFPGObjectList<TPlayer>; 310 322 CellProcessDirection: Boolean; 323 Player: TPlayer; 311 324 procedure AttackNeutral; 312 325 procedure AttackPlayers; … … 358 371 TUnitMoves = class(TFPGObjectList<TUnitMove>) 359 372 Game: TGame; 373 function SearchByFromTo(CellFrom, CellTo: TCell): TUnitMove; 360 374 procedure LoadFromNode(Node: TDOMNode); 361 375 procedure SaveToNode(Node: TDOMNode); … … 390 404 TMoveEvent = procedure(CellFrom, CellTo: TCell; var CountOnce, CountRepeat: Integer; 391 405 Update: Boolean; var Confirm: Boolean) of object; 406 TMoveUpdatedEvent = procedure(UnitMove: TUnitMove) of object; 407 392 408 TWinEvent = procedure(Player: TPlayer) of object; 393 409 TGrowAmount = (gaByOne, gaBySquareRoot); … … 401 417 FMapType: TMapType; 402 418 FOnMove: TMoveEvent; 419 FOnMoveUpdated: TMoveUpdatedEvent; 403 420 FOnNewTurn: TNotifyEvent; 404 421 FOnPlayerChange: TNotifyEvent; … … 407 424 LoadedImageFileName: string; 408 425 ProbabilityMatrix: array of array of Single; 409 procedure Attack(var AttackPower, DefendPower: Integer);410 procedure MoveAll(Player: TPlayer);411 procedure ClearMovesFromCell(Cell: TCell);412 426 procedure RecordTurnStats; 413 427 procedure SetMapType(AValue: TMapType); 414 function SetMove(CellFrom, CellTo: TCell; Power: Integer; Confirmation: Boolean = True): TUnitMove;415 428 procedure SetRunning(AValue: Boolean); 416 procedure UpdateRepeatMoves(Player: TPlayer);417 procedure CheckCounterMove(Move: TUnitMove);418 429 function SearchDifferentCellArea(List: TCells; SourceArea, DestArea: TMapArea): TCell; 419 430 procedure BuildTerrain; … … 437 448 CityPercentage: Integer; 438 449 CurrentPlayer: TPlayer; 439 Moves: TUnitMoves;440 450 TurnCounter: Integer; 441 451 WinObjective: TWinObjective; … … 464 474 published 465 475 property OnMove: TMoveEvent read FOnMove write FOnMove; 476 property OnMoveUpdated: TMoveUpdatedEvent read FOnMoveUpdated write FOnMoveUpdated; 466 477 property OnWin: TWinEvent read FOnWin write FOnWin; 467 478 property OnNewTurn: TNotifyEvent read FOnNewTurn write FOnNewTurn; … … 990 1001 // Draw arrows 991 1002 Pen.Color := clCream; 992 for I := 0 to Game.Moves.Count - 1 do begin993 Move := TUnitMove( Game.Moves[I]);1003 for I := 0 to Player.Moves.Count - 1 do begin 1004 Move := TUnitMove(Player.Moves[I]); 994 1005 PosFrom := Player.Game.Map.CellToPos(Move.CellFrom); 995 1006 PosTo := Player.Game.Map.CellToPos(Move.CellTo); … … 1191 1202 1192 1203 { TUnitMoves } 1204 1205 function TUnitMoves.SearchByFromTo(CellFrom, CellTo: TCell): TUnitMove; 1206 var 1207 UnitMove: TUnitMove; 1208 begin 1209 Result := nil; 1210 for UnitMove in Self do 1211 if (UnitMove.CellFrom = CellFrom) and (UnitMove.CellTo = CellTo) then begin 1212 Result := UnitMove; 1213 Break; 1214 end; 1215 end; 1193 1216 1194 1217 procedure TUnitMoves.LoadFromNode(Node: TDOMNode); … … 1823 1846 function TCell.GetAvialPower: Integer; 1824 1847 var 1825 I: Integer;1848 UnitMove: TUnitMove; 1826 1849 begin 1827 1850 Result := Power; 1828 for I := 0 to MovesFrom.Count - 1 do 1829 Result := Result - TUnitMove(MovesFrom[I]).CountOnce; 1830 if Result < 0 then Result := 0; 1851 for UnitMove in MovesFrom do 1852 Result := Result - UnitMove.CountOnce; 1853 if Result < 0 then raise Exception.Create('Unit move power mismatch. Cell power is ' + 1854 IntToStr(Power) + ' but ' + IntToStr(- (Result - Power)) + ' moved away.'); 1831 1855 end; 1832 1856 … … 1838 1862 for I := 0 to MovesTo.Count - 1 do 1839 1863 Result := Result + TUnitMove(MovesTo[I]).CountOnce; 1864 end; 1865 1866 function TCell.ToString: ansistring; 1867 begin 1868 Result := IntToStr(Id); 1840 1869 end; 1841 1870 … … 1912 1941 if FGame = AValue then Exit; 1913 1942 FGame := AValue; 1943 Moves.Game := AValue; 1944 Computer.Game := AValue; 1914 1945 end; 1915 1946 … … 1917 1948 begin 1918 1949 TurnStats.Clear; 1950 Moves.Clear; 1919 1951 end; 1920 1952 … … 1946 1978 end; 1947 1979 with Node do begin 1980 NewNode := FindNode('UnitMoves'); 1981 if Assigned(NewNode) then 1982 Moves.LoadFromNode(NewNode); 1983 end; 1984 with Node do begin 1948 1985 NewNode := FindNode('TurnStats'); 1949 1986 if Assigned(NewNode) then … … 1971 2008 end; 1972 2009 with Node do begin 2010 NewNode := OwnerDocument.CreateElement('UnitMoves'); 2011 AppendChild(NewNode); 2012 Moves.SaveToNode(NewNode); 2013 end; 2014 with Node do begin 1973 2015 NewNode := OwnerDocument.CreateElement('TurnStats'); 1974 2016 AppendChild(NewNode); … … 1997 2039 AttackPower: Integer; 1998 2040 TotalAttackPower: Integer; 1999 I: Integer;2000 C: Integer;2001 2041 CanAttack: Integer; 2002 2042 TargetCells: TCells; 2043 Cell: TCell; 2044 NeighborCell: TCell; 2003 2045 const 2004 2046 AttackDiff = 1; … … 2009 2051 2010 2052 // Get list of all attack target cells 2011 for C := 0 to AllCells.Count - 1do2012 with TCell(AllCells[C])do begin2053 for Cell in AllCells do 2054 with Cell do begin 2013 2055 if (Terrain <> ttVoid) and (Player = nil) then begin 2014 2056 CanAttack := 0; 2015 for I := 0 to Neighbors.Count - 1do2016 if (TCell(Neighbors[I]).Player = Game.CurrentPlayer)then begin2057 for NeighborCell in Neighbors do 2058 if NeighborCell.Player = Game.CurrentPlayer then begin 2017 2059 Inc(CanAttack); 2018 2060 end; 2019 if CanAttack > 0 then TargetCells.Add( AllCells[C]);2061 if CanAttack > 0 then TargetCells.Add(Cell); 2020 2062 end; 2021 2063 end; … … 2025 2067 TargetCells.Sort(CellCompare); 2026 2068 2027 for C := 0 to TargetCells.Count - 1do2028 with TCell(TargetCells[C])do begin2069 for Cell in TargetCells do 2070 with Cell do begin 2029 2071 // Attack to not owned cell yet 2030 2072 // Count own possible power 2031 2073 TotalPower := 0; 2032 for I := 0 to Neighbors.Count - 1do2033 if (TCell(Neighbors[I]).Player = Game.CurrentPlayer) then begin2034 TotalPower := TotalPower + TCell(Neighbors[I]).GetAvialPower;2035 end; 2074 for NeighborCell in Neighbors do 2075 if NeighborCell.Player = Game.CurrentPlayer then 2076 TotalPower := TotalPower + NeighborCell.GetAvialPower; 2077 2036 2078 // Attack if target is weaker 2037 2079 if TotalPower >= (Power + AttackDiff) then begin 2038 2080 TotalAttackPower := 0; 2039 for I := 0 to Neighbors.Count - 1do2040 if (TCell(Neighbors[I]).Player = Game.CurrentPlayer)then begin2081 for NeighborCell in Neighbors do 2082 if NeighborCell.Player = Game.CurrentPlayer then begin 2041 2083 // Use only necessary power 2042 2084 AttackPower := Power - TotalAttackPower + AttackDiff; 2043 if TCell(Neighbors[I]).GetAvialPower < AttackPower then2044 AttackPower := TCell(Neighbors[I]).GetAvialPower;2045 Game.SetMove(Tcell(Neighbors[I]), TCell(TargetCells[C]), AttackPower, False);2085 if NeighborCell.GetAvialPower < AttackPower then 2086 AttackPower := NeighborCell.GetAvialPower; 2087 Self.Player.SetMove(NeighborCell, Cell, AttackPower, False); 2046 2088 TotalAttackPower := TotalAttackPower + AttackPower; 2047 2089 end; … … 2049 2091 end; 2050 2092 2051 TargetCells.Free;2093 FreeAndNil(TargetCells); 2052 2094 end; 2053 2095 … … 2058 2100 AttackPower: Integer; 2059 2101 TotalAttackPower: Integer; 2060 I: Integer;2061 C: Integer;2062 2102 CanAttack: Integer; 2063 2103 TargetCells: TCells; 2104 TargetCell: TCell; 2105 NeighborCell: TCell; 2064 2106 begin 2065 2107 if Game.CurrentPlayer.Defensive then Exit; … … 2070 2112 2071 2113 // Get list of all attack target cells 2072 for C := 0 to AllCells.Count - 1 do2073 with TCell(AllCells[C]) do begin2074 if (Terrain <> ttVoid) and (Player <> Game.CurrentPlayer) and (Player <> nil) then begin2114 for TargetCell in AllCells do begin 2115 if (TargetCell.Terrain <> ttVoid) and (TargetCell.Player <> Player) and 2116 (TargetCell.Player <> nil) then begin 2075 2117 CanAttack := 0; 2076 for I := 0 to Neighbors.Count - 1do2077 if (TCell(Neighbors[I]).Player = Game.CurrentPlayer)then begin2118 for NeighborCell in TargetCell.Neighbors do 2119 if NeighborCell.Player = Player then begin 2078 2120 Inc(CanAttack); 2079 2121 end; 2080 if CanAttack > 0 then TargetCells.Add( AllCells[C]);2122 if CanAttack > 0 then TargetCells.Add(TargetCell); 2081 2123 end; 2082 2124 end; … … 2086 2128 TargetCells.Sort(CellCompareDescending); 2087 2129 2088 for C := 0 to TargetCells.Count - 1 do 2089 with TCell(TargetCells[C]) do begin 2130 for TargetCell in TargetCells do begin 2090 2131 // Attack to not owned cell yet 2091 2132 // Count own possible power 2092 2133 TotalPower := 0; 2093 for I := 0 to Neighbors.Count - 1do2094 if (TCell(Neighbors[I]).Player = Game.CurrentPlayer)then begin2095 TotalPower := TotalPower + TCell(Neighbors[I]).GetAvialPower;2134 for NeighborCell in TargetCell.Neighbors do 2135 if NeighborCell.Player = Player then begin 2136 TotalPower := TotalPower + NeighborCell.GetAvialPower; 2096 2137 end; 2097 2138 // Attack if target is weaker 2098 if Game.AttackProbability(TotalPower, Power) >= ComputerAggroProbability[Game.CurrentPlayer.Agressivity] then begin 2139 if Game.AttackProbability(TotalPower, TargetCell.Power) >= 2140 ComputerAggroProbability[Player.Agressivity] then begin 2099 2141 // Try to limit total attacking power to necessary minimum 2100 while Game.AttackProbability(TotalPower - 1, Power) >= ComputerAggroProbability[Game.CurrentPlayer.Agressivity] do 2142 while Game.AttackProbability(TotalPower - 1, TargetCell.Power) >= 2143 ComputerAggroProbability[Player.Agressivity] do 2101 2144 Dec(TotalPower); 2102 2145 2103 2146 // Collect required attack units from our cells 2104 2147 TotalAttackPower := 0; 2105 for I := 0 to Neighbors.Count - 1do2106 if (TCell(Neighbors[I]).Player = Game.CurrentPlayer)then begin2148 for NeighborCell in TargetCell.Neighbors do 2149 if NeighborCell.Player = Player then begin 2107 2150 // Use only necessary power 2108 2151 AttackPower := TotalPower - TotalAttackPower; 2109 if TCell(Neighbors[I]).GetAvialPower < AttackPower then2110 AttackPower := TCell(Neighbors[I]).GetAvialPower;2111 Game.SetMove(TCell(Neighbors[I]), TCell(TargetCells[C]), AttackPower, False);2152 if NeighborCell.GetAvialPower < AttackPower then 2153 AttackPower := NeighborCell.GetAvialPower; 2154 Self.Player.SetMove(NeighborCell, TargetCell, AttackPower, False); 2112 2155 TotalAttackPower := TotalAttackPower + AttackPower; 2113 2156 if TotalAttackPower >= TotalPower then Break; … … 2116 2159 end; 2117 2160 2118 TargetCells.Free;2161 FreeAndNil(TargetCells); 2119 2162 end; 2120 2163 … … 2185 2228 if (TCell(TargetCells[C]).GetAvialPower + TCell(TargetCells[C]).GetAttackPower + MovedPower) > Game.Map.MaxPower then 2186 2229 MovedPower := Game.Map.MaxPower - TCell(TargetCells[C]).GetAvialPower - TCell(TargetCells[C]).GetAttackPower; 2187 Game.SetMove(TCell(Neighbors[I]), TCell(TargetCells[C]), MovedPower, False);2230 Player.SetMove(TCell(Neighbors[I]), TCell(TargetCells[C]), MovedPower, False); 2188 2231 end; 2189 2232 end; … … 2195 2238 2196 2239 // Use source cells NewTargetCells as new TargetCells 2197 TargetCells.Free;2240 FreeAndNil(TargetCells); 2198 2241 TargetCells := NewTargetCells; 2199 2242 NewTargetCells := TCells.Create; … … 2201 2244 end; 2202 2245 2203 TargetCells.Free;2204 NewTargetCells.Free;2246 FreeAndNil(TargetCells); 2247 FreeAndNil(NewTargetCells); 2205 2248 end; 2206 2249 … … 2211 2254 begin 2212 2255 // If available power remains then use all for existed unit moves 2213 for I := 0 to Game.Moves.Count - 1 do2214 with TUnitMove( Game.Moves[I]) do begin2256 for I := 0 to Player.Moves.Count - 1 do 2257 with TUnitMove(Player.Moves[I]) do begin 2215 2258 if CellFrom.GetAvialPower > 0 then begin 2216 2259 AvailPower := CellFrom.GetAvialPower; … … 2266 2309 TUnitMove(MovesTo[I]).Free; 2267 2310 for I := 0 to Neighbors.Count - 1 do 2268 if (TCell(Neighbors[I]).Player = Game.CurrentPlayer) and (AttackersCount(TCell(Neighbors[I])) = 0) then begin 2269 2270 Game.SetMove(TCell(BorderCells[C]), TCell(Neighbors[I]), GetAvialPower, False); 2311 if (TCell(Neighbors[I]).Player = Player) and (AttackersCount(TCell(Neighbors[I])) = 0) then begin 2312 Player.SetMove(TCell(BorderCells[C]), TCell(Neighbors[I]), GetAvialPower, False); 2271 2313 Break; 2272 2314 end; … … 2274 2316 end; 2275 2317 2276 BorderCells.Free;2318 FreeAndNil(BorderCells); 2277 2319 end; 2278 2320 … … 2302 2344 for I := SelectedCell.MovesFrom.Count - 1 downto 0 do 2303 2345 TUnitMove(SelectedCell.MovesFrom[I]).Free; 2304 Game. SetMove(SelectedCell, NewSelectedCell, SelectedCell.Power, False);2346 Game.CurrentPlayer.SetMove(SelectedCell, NewSelectedCell, SelectedCell.Power, False); 2305 2347 SelectedCell := nil; 2306 2348 end else … … 2310 2352 for I := SelectedCell.MovesFrom.Count - 1 downto 0 do 2311 2353 TUnitMove(SelectedCell.MovesFrom[I]).Free; 2312 UnitMove := Game. SetMove(SelectedCell, NewSelectedCell, SelectedCell.Power, False);2354 UnitMove := Game.CurrentPlayer.SetMove(SelectedCell, NewSelectedCell, SelectedCell.Power, False); 2313 2355 if Assigned(UnitMove) then 2314 2356 UnitMove.CountRepeat := Player.Game.Map.MaxPower; … … 2316 2358 else SelectedCell := nil; 2317 2359 end else begin 2318 Game. SetMove(SelectedCell, NewSelectedCell, SelectedCell.Power);2360 Game.CurrentPlayer.SetMove(SelectedCell, NewSelectedCell, SelectedCell.Power); 2319 2361 SelectedCell := nil; 2320 2362 end; … … 2354 2396 constructor TPlayer.Create; 2355 2397 begin 2398 Moves := TUnitMoves.Create; 2356 2399 StartUnits := DefaultPlayerStartUnits; 2357 2400 StartCell := nil; … … 2359 2402 PlayerMap.Player := Self; 2360 2403 TurnStats := TGameTurnStats.Create; 2404 Computer := TComputer.Create; 2405 Computer.Player := Self; 2361 2406 end; 2362 2407 2363 2408 destructor TPlayer.Destroy; 2364 2409 begin 2410 FreeAndNil(Computer); 2365 2411 FreeAndNil(TurnStats); 2366 2412 FreeAndNil(PlayerMap); 2413 FreeAndNil(Moves); 2367 2414 inherited Destroy; 2368 2415 end; … … 2390 2437 end; 2391 2438 2392 procedure T Game.Attack(var AttackPower, DefendPower: Integer);2439 procedure TPlayer.Attack(var AttackPower, DefendPower: Integer); 2393 2440 var 2394 2441 AttackerDiceCount: Integer; … … 2433 2480 else Dec(AttackPower); 2434 2481 end; 2435 AttackRolls.Free;2436 DefendRolls.Free;2482 FreeAndNil(AttackRolls); 2483 FreeAndNil(DefendRolls); 2437 2484 end; 2438 2485 … … 2495 2542 end; 2496 2543 2497 procedure T Game.MoveAll(Player: TPlayer);2544 procedure TPlayer.MoveAll; 2498 2545 var 2499 2546 I: Integer; … … 2501 2548 DefenderPower: Integer; 2502 2549 UnitCount: Integer; 2503 begin 2504 I := 0; 2505 while I < Moves.Countdo2506 with TUnitMove(Moves[I])do begin2550 UnitMove: TUnitMove; 2551 begin 2552 for UnitMove in Moves do 2553 with UnitMove do begin 2507 2554 if CountOnce > 0 then begin 2508 if CellFrom.Player = Playerthen begin2555 if CellFrom.Player = Self then begin 2509 2556 UnitCount := CountOnce; 2510 2557 if CountOnce > CellFrom.Power then 2511 2558 UnitCount := CellFrom.Power; 2512 if CellTo.Player = Playerthen begin2559 if CellTo.Player = Self then begin 2513 2560 // Inner move 2514 2561 CellTo.Power := CellTo.Power + UnitCount; … … 2520 2567 // Attacker wins with possible loses 2521 2568 ClearMovesFromCell(CellTo); 2522 CellTo.Player := Player;2569 CellTo.Player := Self; 2523 2570 CellTo.Power := AttackerPower; 2524 2571 end else … … 2533 2580 end; 2534 2581 end; 2535 Inc(I);2536 2582 end; 2537 2583 // Remove empty moves 2538 2584 for I := Moves.Count - 1 downto 0 do 2539 if (TUnitMove(Moves[I]).CellFrom.Player = Player) and2585 if (TUnitMove(Moves[I]).CellFrom.Player = Self) and 2540 2586 (TUnitMove(Moves[I]).CountOnce = 0) and (TUnitMove(Moves[I]).CountRepeat = 0) then 2541 2587 Moves.Delete(I); 2542 2588 end; 2543 2589 2544 procedure TGame.ClearMovesFromCell(Cell: TCell); 2545 var 2546 I: Integer; 2547 begin 2548 for I := Moves.Count - 1 downto 0 do 2549 if TUnitMove(Moves[I]).CellFrom = Cell then 2550 Moves.Delete(I); 2590 procedure TPlayer.ClearMovesFromCell(Cell: TCell); 2591 var 2592 I: Integer; 2593 begin 2594 if Assigned(Cell.Player) then 2595 for I := Cell.Player.Moves.Count - 1 downto 0 do 2596 if TUnitMove(Cell.Player.Moves[I]).CellFrom = Cell then 2597 Cell.Player.Moves.Delete(I); 2551 2598 end; 2552 2599 … … 2566 2613 end; 2567 2614 Map.Assign(OldMap); 2568 OldMap.Free;2615 FreeAndNil(OldMap); 2569 2616 FMapType := AValue; 2570 2617 end; 2571 2618 2572 function T Game.SetMove(CellFrom, CellTo: TCell; Power: Integer; Confirmation: Boolean = True): TUnitMove;2619 function TPlayer.SetMove(CellFrom, CellTo: TCell; Power: Integer; Confirmation: Boolean = True): TUnitMove; 2573 2620 var 2574 2621 NewMove: TUnitMove; 2575 OldMove: TUnitMove;2576 2622 I: Integer; 2577 2623 CountOnce: Integer; … … 2581 2627 I := 0; 2582 2628 Confirm := True; 2583 while (I < Moves.Count) and ((TUnitMove(Moves[I]).CellFrom <> CellFrom) or 2584 (TUnitMove(Moves[I]).CellTo <> CellTo)) do Inc(I); 2585 if I < Moves.Count then OldMove := TUnitMove(Moves[I]) 2586 else OldMove := nil; 2587 Result := OldMove; 2588 if Assigned(OldMove) then begin 2589 CountOnce := OldMove.CountOnce; 2590 CountRepeat := OldMove.CountRepeat; 2591 if Assigned(CurrentPlayer) and Confirmation and 2592 Assigned(FOnMove) then FOnMove(CellFrom, CellTo, CountOnce, CountRepeat, True, Confirm); 2629 Result := Moves.SearchByFromTo(CellFrom, CellTo); 2630 2631 if Assigned(Result) then begin 2632 CountOnce := Result.CountOnce; 2633 CountRepeat := Result.CountRepeat; 2634 if (Mode = pmHuman) and Confirmation and 2635 Assigned(Game.FOnMove) then Game.FOnMove(CellFrom, CellTo, CountOnce, CountRepeat, True, Confirm); 2593 2636 end else begin 2594 2637 CountOnce := Power; 2595 2638 CountRepeat := 0; 2596 if Assigned(CurrentPlayer) and Confirmation and2597 Assigned( FOnMove) thenFOnMove(CellFrom, CellTo, CountOnce, CountRepeat, False, Confirm);2639 if (Mode = pmHuman) and Confirmation and 2640 Assigned(Game.FOnMove) then Game.FOnMove(CellFrom, CellTo, CountOnce, CountRepeat, False, Confirm); 2598 2641 end; 2599 2642 if Confirm then begin 2600 if Assigned( OldMove) then begin2643 if Assigned(Result) then begin 2601 2644 // Already have such move 2602 2645 if (CountOnce = 0) and (CountRepeat = 0) then Moves.Delete(I) 2603 2646 else begin 2604 OldMove.CountOnce := CountOnce;2605 OldMove.CountRepeat := CountRepeat;2606 CheckCounterMove( OldMove);2647 Result.CountOnce := CountOnce; 2648 Result.CountRepeat := CountRepeat; 2649 CheckCounterMove(Result); 2607 2650 end; 2608 2651 end else begin … … 2619 2662 end; 2620 2663 end; 2664 if Assigned(Game.FOnMoveUpdated) then Game.FOnMoveUpdated(Result); 2621 2665 end; 2622 2666 end; … … 2639 2683 end; 2640 2684 2641 procedure T Game.UpdateRepeatMoves(Player: TPlayer);2642 var 2643 I: Integer;2644 begin 2645 for I := 0 to Moves.Count - 1do2646 with TUnitMove(Moves[I])do begin2647 if CellFrom.Player = Playerthen2685 procedure TPlayer.UpdateRepeatMoves; 2686 var 2687 Move: TUnitMove; 2688 begin 2689 for Move in Moves do 2690 with Move do begin 2691 if CellFrom.Player = Self then 2648 2692 if CountRepeat <= CellFrom.GetAvialPower then 2649 2693 CountOnce := CountRepeat … … 2652 2696 end; 2653 2697 2654 procedure TGame.CheckCounterMove(Move: TUnitMove); 2655 var 2656 I: Integer; 2698 procedure TPlayer.CheckCounterMove(Move: TUnitMove); 2699 var 2657 2700 CounterMove: TUnitMove; 2658 2701 begin 2659 I := 0; 2660 while (I < Moves.Count) and ((TUnitMove(Moves[I]).CellTo <> Move.CellFrom) or 2661 (TUnitMove(Moves[I]).CellFrom <> Move.CellTo)) do Inc(I); 2662 if I < Moves.Count then CounterMove := TUnitMove(Moves[I]) 2663 else CounterMove := nil; 2702 CounterMove := Moves.SearchByFromTo(Move.CellTo, Move.CellFrom); 2664 2703 if Assigned(CounterMove) then begin 2665 2704 // For now, just remove counter move 2666 2705 Moves.Remove(CounterMove); 2667 2706 end; 2707 end; 2708 2709 procedure TPlayer.SetMode(AValue: TPlayerMode); 2710 begin 2711 if FMode = AValue then Exit; 2712 FMode := AValue; 2668 2713 end; 2669 2714 … … 2704 2749 end; 2705 2750 2706 NewListVoid.Free;2707 NewList.Free;2751 FreeAndNil(NewListVoid); 2752 FreeAndNil(NewList); 2708 2753 end; 2709 2754 … … 2793 2838 2794 2839 end; 2795 List.Free;2796 BorderList.Free;2840 FreeAndNil(List); 2841 FreeAndNil(BorderList); 2797 2842 end; 2798 2843 … … 2998 3043 InitClients; 2999 3044 3000 NewNode := FindNode('UnitMoves');3001 if Assigned(NewNode) then3002 Moves.LoadFromNode(NewNode);3003 3004 3045 Map.Cells.FixRefId; 3005 3046 … … 3011 3052 end; 3012 3053 finally 3013 Doc.Free;3054 FreeAndNil(Doc); 3014 3055 end; 3015 3056 end; … … 3049 3090 AppendChild(NewNode); 3050 3091 Players.SaveToNode(NewNode); 3051 3052 NewNode := OwnerDocument.CreateElement('UnitMoves');3053 AppendChild(NewNode);3054 Moves.SaveToNode(NewNode);3055 3092 end; 3056 3093 ForceDirectoriesUTF8(ExtractFileDir(FileName)); 3057 3094 WriteXMLFile(Doc, FileName); 3058 3095 finally 3059 Doc.Free;3096 FreeAndNil(Doc); 3060 3097 end; 3061 3098 end; … … 3127 3164 begin 3128 3165 //TODO CurrentPlayer.View.SelectedCell := nil; 3129 MoveAll(CurrentPlayer);3166 CurrentPlayer.MoveAll; 3130 3167 Map.Grow(CurrentPlayer); 3131 UpdateRepeatMoves(CurrentPlayer);3168 CurrentPlayer.UpdateRepeatMoves; 3132 3169 ComputePlayerStats; 3133 3170 PrevPlayer := CurrentPlayer; … … 3183 3220 constructor TGame.Create; 3184 3221 begin 3185 Moves := TUnitMoves.Create;3186 Moves.Game := Self;3187 3222 Map := TMap.Create; 3188 3223 Players := TPlayers.Create; … … 3208 3243 begin 3209 3244 FreeAndNil(Clients); 3210 FreeAndNil(Moves);3211 3245 FreeAndNil(Players); 3212 3246 FreeAndNil(Map); … … 3223 3257 FileName := SNewGameFile; 3224 3258 TurnCounter := 1; 3225 Moves.Clear;3226 3259 3227 3260 BuildTerrain; … … 3322 3355 // Draw arrows 3323 3356 Pen.Color := clCream; 3324 for I := 0 to Game. Moves.Count - 1 do begin3325 Move := TUnitMove(Game. Moves[I]);3357 for I := 0 to Game.CurrentPlayer.Moves.Count - 1 do begin 3358 Move := TUnitMove(Game.CurrentPlayer.Moves[I]); 3326 3359 PosFrom := CellToPos(Move.CellFrom); 3327 3360 PosTo := CellToPos(Move.CellTo);
Note:
See TracChangeset
for help on using the changeset viewer.