Changeset 79 for trunk/UGame.pas


Ignore:
Timestamp:
Nov 4, 2014, 8:57:21 AM (10 years ago)
Author:
chronos
Message:
  • Removed: Useless old method GetCellNeighbors. Cell neigbours can be now accessed directly.
  • Modified: Optimized canvas TextOut to not move pointer after text displaying.
  • Fixed: Computer inner moves were calculated incorrectly multiple times for same cells. This was slowing down calculation in particular for large maps.
  • Added: Used PersistentForm component to keep forms position and size. So far it not supports xmlconfig class.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/UGame.pas

    r78 r79  
    77uses
    88  Classes, SysUtils, ExtCtrls, Graphics, Contnrs, XMLConf, XMLRead, XMLWrite,
    9   DOM, Math, FileUtil, UXMLUtils, Dialogs, Types;
     9  DOM, Math, FileUtil, UXMLUtils, Dialogs, Types, LCLType, LCLIntf;
    1010
    1111const
     
    105105    property DestRect: TRect read FDestRect write SetDestRect;
    106106    property Zoom: Double read FZoom write SetZoom;
     107  end;
     108
     109  { TCanvasEx }
     110
     111  TCanvasEx = class(TCanvas)
     112    procedure TextOutEx(X,Y: Integer; const Text: string; MovePen: Boolean = True);
    107113  end;
    108114
     
    144150    constructor Create; virtual;
    145151    destructor Destroy; override;
    146     function GetCellNeighbors(Cell: TCell): TCellArray; virtual;
    147152    procedure Paint(Canvas: TCanvas; View: TView); virtual;
    148153    function GetPixelRect: TRect; virtual;
     
    436441end;
    437442
     443{ TCanvasEx }
     444
     445procedure TCanvasEx.TextOutEx(X, Y: Integer; const Text: string;
     446  MovePen: Boolean);
     447var
     448  Flags : Cardinal;
     449begin
     450  Changing;
     451  RequiredState([csHandleValid, csFontValid, csBrushValid]);
     452  Flags := 0;
     453  if TextStyle.Opaque then
     454    Flags := ETO_Opaque;
     455  ExtUTF8Out(Handle, X, Y, Flags, nil, PChar(Text), Length(Text), nil);
     456  if MovePen then MoveTo(X + TextWidth(Text), Y);
     457  Changed;
     458end;
     459
    438460{ TCells }
    439461
     
    956978    Brush.Style := bsSolid;
    957979    Polygon(Points, False, 0, Length(Points));
     980
     981    // Show cell text
    958982    Pen.Style := psSolid;
    959983    Font.Color := clWhite;
     
    962986    TextPos := View.CellToCanvasPos(Pos);
    963987    TextSize := TextExtent(Text);
    964     TextOut(Round(TextPos.X) - TextSize.cx div 2, Round(TextPos.Y) - TextSize.cy div 2, Text);
     988    TCanvasEx(Canvas).TextOutEx(Round(TextPos.X) - TextSize.cx div 2,
     989      Round(TextPos.Y) - TextSize.cy div 2, Text, False);
    965990  end;
    966991end;
     
    10191044  FreeAndNil(Cells);
    10201045  inherited Destroy;
    1021 end;
    1022 
    1023 function TMap.GetCellNeighbors(Cell: TCell): TCellArray;
    1024 var
    1025   I: Integer;
    1026 begin
    1027   SetLength(Result, Cell.Neighbors.Count);
    1028   for I := 0 to Length(Result) - 1 do
    1029     Result[I] := TCell(Cell.Neighbors[I]);
    10301046end;
    10311047
     
    14111427var
    14121428  AllCells: TCells;
    1413   Cells, Cells2: TCellArray;
    14141429  TotalPower: Integer;
    14151430  AttackPower: Integer;
     
    14171432  I, J: Integer;
    14181433  C: Integer;
    1419   CanAttack, CanAttack2: Integer;
     1434  CanAttack: Integer;
    14201435  TargetCells: TCells;
    14211436  S: string;
     
    14311446  with TCell(AllCells[C]) do begin
    14321447    if (Terrain <> ttVoid) and (Player = nil) then begin
    1433       Cells := Game.Map.GetCellNeighbors(TCell(AllCells[C]));
    14341448      CanAttack := 0;
    1435       for I := 0 to Length(Cells) - 1 do
    1436       if (Cells[I].Player = Game.CurrentPlayer) then begin
     1449      for I := 0 to Neighbors.Count - 1 do
     1450      if (TCell(Neighbors[I]).Player = Game.CurrentPlayer) then begin
    14371451        Inc(CanAttack);
    14381452      end;
     
    14491463      // Attack to not owned cell yet
    14501464      // Count own possible power
    1451       Cells := Game.Map.GetCellNeighbors(TCell(TargetCells[C]));
    14521465      TotalPower := 0;
    1453       for I := 0 to Length(Cells) - 1 do
    1454       if (Cells[I].Player = Game.CurrentPlayer) then begin
    1455         TotalPower := TotalPower + Cells[I].GetAvialPower;
     1466      for I := 0 to Neighbors.Count - 1 do
     1467      if (TCell(Neighbors[I]).Player = Game.CurrentPlayer) then begin
     1468        TotalPower := TotalPower + TCell(Neighbors[I]).GetAvialPower;
    14561469      end;
    14571470      // Attack if target is weaker
    14581471      if TotalPower >= (Power + AttackDiff) then begin
    14591472        TotalAttackPower := 0;
    1460         for I := 0 to Length(Cells) - 1 do
    1461         if (Cells[I].Player = Game.CurrentPlayer) then begin
     1473        for I := 0 to Neighbors.Count - 1 do
     1474        if (TCell(Neighbors[I]).Player = Game.CurrentPlayer) then begin
    14621475          // Use only necessary power
    14631476          AttackPower := Power - TotalAttackPower + AttackDiff;
    1464           if Cells[I].GetAvialPower < AttackPower then
    1465             AttackPower := Cells[I].GetAvialPower;
    1466           Game.SetMove(Cells[I], TCell(TargetCells[C]), AttackPower);
     1477          if TCell(Neighbors[I]).GetAvialPower < AttackPower then
     1478            AttackPower := TCell(Neighbors[I]).GetAvialPower;
     1479          Game.SetMove(Tcell(Neighbors[I]), TCell(TargetCells[C]), AttackPower);
    14671480          TotalAttackPower := TotalAttackPower + AttackPower;
    14681481        end;
     
    14761489var
    14771490  AllCells: TCells;
    1478   Cells, Cells2: TCellArray;
    14791491  TotalPower: Integer;
    14801492  AttackPower: Integer;
     
    14821494  I, J: Integer;
    14831495  C: Integer;
    1484   CanAttack, CanAttack2: Integer;
     1496  CanAttack: Integer;
    14851497  TargetCells: TCells;
    14861498  S: string;
     
    14961508  with TCell(AllCells[C]) do begin
    14971509    if (Terrain <> ttVoid) and (Player <> Game.CurrentPlayer) and (Player <> nil) then begin
    1498       Cells := Game.Map.GetCellNeighbors(TCell(AllCells[C]));
    14991510      CanAttack := 0;
    1500       for I := 0 to Length(Cells) - 1 do
    1501       if (Cells[I].Player = Game.CurrentPlayer) then begin
     1511      for I := 0 to Neighbors.Count - 1 do
     1512      if (TCell(Neighbors[I]).Player = Game.CurrentPlayer) then begin
    15021513        Inc(CanAttack);
    15031514      end;
     
    15141525      // Attack to not owned cell yet
    15151526      // Count own possible power
    1516       Cells := Game.Map.GetCellNeighbors(TCell(TargetCells[C]));
    15171527      TotalPower := 0;
    1518       for I := 0 to Length(Cells) - 1 do
    1519       if (Cells[I].Player = Game.CurrentPlayer) then begin
    1520         TotalPower := TotalPower + Cells[I].GetAvialPower;
     1528      for I := 0 to Neighbors.Count - 1 do
     1529      if (TCell(Neighbors[I]).Player = Game.CurrentPlayer) then begin
     1530        TotalPower := TotalPower + TCell(Neighbors[I]).GetAvialPower;
    15211531      end;
    15221532      // Attack if target is weaker
    15231533      if TotalPower >= (Power + AttackDiff) then begin
    15241534        TotalAttackPower := 0;
    1525         for I := 0 to Length(Cells) - 1 do
    1526         if (Cells[I].Player = Game.CurrentPlayer) then begin
     1535        for I := 0 to Neighbors.Count - 1 do
     1536        if (TCell(Neighbors[I]).Player = Game.CurrentPlayer) then begin
    15271537          // Use only necessary power
    15281538          AttackPower := Power - TotalAttackPower + AttackDiff;
    1529           if Cells[I].GetAvialPower < AttackPower then
    1530             AttackPower := Cells[I].GetAvialPower;
    1531           Game.SetMove(Cells[I], TCell(TargetCells[C]), AttackPower);
     1539          if TCell(Neighbors[I]).GetAvialPower < AttackPower then
     1540            AttackPower := TCell(Neighbors[I]).GetAvialPower;
     1541          Game.SetMove(TCell(Neighbors[I]), TCell(TargetCells[C]), AttackPower);
    15321542          TotalAttackPower := TotalAttackPower + AttackPower;
    15331543        end;
     
    15411551var
    15421552  AllCells: TCells;
    1543   Cells, Cells2: TCellArray;
    15441553  I, J: Integer;
    15451554  C: Integer;
    1546   CanAttack, CanAttack2: Integer;
     1555  CanAttack: Integer;
    15471556  TargetCells: TCells;
    15481557  NewTargetCells: TCells;
     1558  Cells2: TCells;
    15491559begin
    15501560  // We need to move available power to borders to be available for attacks
     
    15601570  with TCell(AllCells[C]) do begin
    15611571    if (Player <> Game.CurrentPlayer) and (Player <> nil) and (Terrain <> ttVoid) then begin
    1562       Cells := Game.Map.GetCellNeighbors(TCell(AllCells[C]));
    15631572      CanAttack := 0;
    1564       for I := 0 to Length(Cells) - 1 do
    1565       if ((Cells[I].Player = Game.CurrentPlayer) or (Cells[I].Player = nil)) and (Cells[I].Terrain <> ttVoid) then begin
     1573      for I := 0 to Neighbors.Count - 1 do
     1574      if ((TCell(Neighbors[I]).Player = Game.CurrentPlayer) or
     1575      (TCell(Neighbors[I]).Player = nil)) and (TCell(Neighbors[I]).Terrain <> ttVoid) then begin
    15661576        Inc(CanAttack);
    15671577      end;
     
    15831593    for C := 0 to TargetCells.Count - 1 do
    15841594    with TCell(TargetCells[C]) do begin
    1585       Cells := Game.Map.GetCellNeighbors(TCell(TargetCells[C]));
    1586       for I := 0 to Length(Cells) - 1 do begin
    1587         if (Cells[I].Terrain <> ttVoid) and (not Cells[I].Mark) then begin
     1595      for I := 0 to Neighbors.Count - 1 do begin
     1596        if (TCell(Neighbors[I]).Terrain <> ttVoid) and (not TCell(Neighbors[I]).Mark) then begin
    15881597          if (TCell(TargetCells[C]).Player = Game.CurrentPlayer) and
    1589           (Cells[I].Player = Game.CurrentPlayer) then begin
     1598          (TCell(Neighbors[I]).Player = Game.CurrentPlayer) then begin
    15901599            // Do not take units from front line
    1591             Cells2 := Game.Map.GetCellNeighbors(TCell(Cells[I]));
     1600            Cells2 := TCell(Neighbors[I]).Neighbors;
    15921601            CanAttack := 0;
    1593             for J := 0 to Length(Cells2) - 1 do
    1594             if ((Cells2[J].Player <> Game.CurrentPlayer) or (Cells2[J].Player = nil))
    1595             and (Cells2[J].Terrain <> ttVoid) then begin
     1602            for J := 0 to Cells2.Count - 1 do
     1603            if ((TCell(Cells2[J]).Player <> Game.CurrentPlayer) or (TCell(Cells2[J]).Player = nil))
     1604            and (TCell(Cells2[J]).Terrain <> ttVoid) then begin
    15961605              Inc(CanAttack);
    15971606            end;
    15981607            if CanAttack = 0 then
    1599               Game.SetMove(Cells[I], TCell(TargetCells[C]), Cells[I].GetAvialPower);
     1608              Game.SetMove(TCell(Neighbors[I]), TCell(TargetCells[C]), TCell(Neighbors[I]).GetAvialPower);
    16001609          end;
    1601           TCell(TargetCells[C]).Mark := True;
    1602           NewTargetCells.Add(Cells[I]);
     1610          TCell(Neighbors[I]).Mark := True;
     1611          NewTargetCells.Add(TCell(Neighbors[I]));
    16031612        end;
    16041613      end;
     
    16061615
    16071616    // Use source cells NewTargetCells as new TargetCells
    1608     TargetCells.Count := NewTargetCells.Count;
    1609     for C := 0 to TargetCells.Count - 1 do
    1610       TargetCells[C] := NewTargetCells[C];
     1617    TargetCells.Free;
     1618    TargetCells := NewTargetCells;
     1619    NewTargetCells := TCells.Create;
     1620    NewTargetCells.OwnsObjects := False;
    16111621  end;
    16121622
Note: See TracChangeset for help on using the changeset viewer.