Changeset 30


Ignore:
Timestamp:
Oct 12, 2019, 9:35:25 PM (5 years ago)
Author:
chronos
Message:
  • Modified: Simplified moved board area calculation.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/UGame.pas

    r29 r30  
    2323
    2424  TTiles = class(TFPGObjectList<TTile>)
     25  end;
     26
     27  { TArea }
     28
     29  TArea = record
     30    P1, P2: TPoint;
     31    function Increment: TPoint;
     32    function Create(P1, P2: TPoint): TArea; overload;
     33    function Create(X1, Y1, X2, Y2: Integer): TArea; overload;
    2534  end;
    2635
     
    6776    procedure Win;
    6877    function FillRandomTile(Value4Change: Double = 0.1): Integer;
     78    function GetMoveArea(Direction: TDirection): TArea;
    6979  public
    7080    Board: TBoard;
     
    112122implementation
    113123
     124{ TArea }
     125
     126function TArea.Increment: TPoint;
     127begin
     128  Result := Point(Sign(P2.X - P1.X), Sign(P2.Y - P1.Y));
     129end;
     130
     131function TArea.Create(P1, P2: TPoint): TArea;
     132begin
     133  Result.P1 := P1;
     134  Result.P2 := P2;
     135end;
     136
     137function TArea.Create(X1, Y1, X2, Y2: Integer): TArea;
     138begin
     139  Result.P1 := Point(X1, Y1);
     140  Result.P2 := Point(X2, Y2);
     141end;
     142
    114143{ TBoard }
    115144
     
    302331end;
    303332
     333function TGame.GetMoveArea(Direction: TDirection): TArea;
     334begin
     335  case Direction of
     336    drLeft: begin
     337      Result := TArea.Create(1, 0, Board.Size.X - 1, Board.Size.Y - 1);
     338    end;
     339    drUp: begin
     340      Result := TArea.Create(0, 1, Board.Size.X - 1, Board.Size.Y - 1);
     341    end;
     342    drRight: begin
     343      Result := TArea.Create(Board.Size.X - 2, 0, 0, Board.Size.Y - 1);
     344    end;
     345    drDown: begin
     346      Result := TArea.Create(0, Board.Size.Y - 2, Board.Size.X - 1, 0);
     347    end;
     348  end;
     349end;
     350
    304351function TGame.CanMove: Boolean;
    305352begin
     
    439486function TGame.CanMergeDirection(Direction: TDirection): Boolean;
    440487var
    441   StartPoint: TPoint;
    442   AreaSize: TPoint;
    443   Increment: TPoint;
    444488  P: TPoint;
    445489  PNew: TPoint;
    446   PI: TPoint;
    447490  I: Integer;
     491  Area: TArea;
    448492begin
    449493  Result := False;
    450   case Direction of
    451     drLeft: begin
    452       StartPoint := Point(1, 0);
    453       AreaSize := Point(Board.Size.X - 2, Board.Size.Y - 1);
    454       Increment := Point(1, 1);
    455     end;
    456     drUp: begin
    457       StartPoint := Point(0, 1);
    458       AreaSize := Point(Board.Size.X - 1, Board.Size.Y - 2);
    459       Increment := Point(1, 1);
    460     end;
    461     drRight: begin
    462       StartPoint := Point(Board.Size.X - 2, 0);
    463       AreaSize := Point(Board.Size.X - 2, Board.Size.Y - 1);
    464       Increment := Point(-1, 1);
    465     end;
    466     drDown: begin
    467       StartPoint := Point(0, Board.Size.Y - 2);
    468       AreaSize := Point(Board.Size.X - 1, Board.Size.Y - 2);
    469       Increment := Point(1, -1);
    470     end;
    471   end;
    472 
     494  Area := GetMoveArea(Direction);
    473495  for I := 0 to Max(Board.Size.X, Board.Size.Y) - 1 do begin
    474     PI.Y := 0;
    475     while PI.Y <= AreaSize.Y do begin
    476       PI.X := 0;
    477       while PI.X <= AreaSize.X do begin
    478         P := Point(StartPoint.X + PI.X * Increment.X, StartPoint.Y + PI.Y * Increment.Y);
    479         PNew.X := P.X + DirectionDiff[Direction].X;
    480         PNew.Y := P.Y + DirectionDiff[Direction].Y;
     496    P := Area.P1;
     497    while P.Y <> Area.P2.Y do begin
     498      P.X := Area.P1.X;
     499      while P.X <> Area.P2.X do begin
     500        PNew := P + DirectionDiff[Direction];
    481501        if IsValidPos(PNew) then begin
    482502          if (Board.Tiles[PNew.Y, PNew.X].Value = 0) then begin
     
    490510            end;
    491511          end;
    492           P.X := PNew.X;
    493           P.Y := PNew.Y;
    494           PNew.X := P.X + DirectionDiff[Direction].X;
    495           PNew.Y := P.Y + DirectionDiff[Direction].Y;
    496512        end;
    497         Inc(PI.X);
     513        Inc(P.X, Area.Increment.Y);
    498514      end;
    499515      if Result then Break;
    500       Inc(PI.Y);
     516      Inc(P.Y, Area.Increment.Y);
    501517    end;
    502518  end;
     
    505521function TGame.CanMoveDirection(Direction: TDirection): Boolean;
    506522var
    507   StartPoint: TPoint;
    508   AreaSize: TPoint;
    509   Increment: TPoint;
    510523  P: TPoint;
    511524  PNew: TPoint;
    512   PI: TPoint;
     525  Area: TArea;
    513526begin
    514527  Result := False;
    515   case Direction of
    516     drLeft: begin
    517       StartPoint := Point(1, 0);
    518       AreaSize := Point(Board.Size.X - 2, Board.Size.Y - 1);
    519       Increment := Point(1, 1);
    520     end;
    521     drUp: begin
    522       StartPoint := Point(0, 1);
    523       AreaSize := Point(Board.Size.X - 1, Board.Size.Y - 2);
    524       Increment := Point(1, 1);
    525     end;
    526     drRight: begin
    527       StartPoint := Point(Board.Size.X - 2, 0);
    528       AreaSize := Point(Board.Size.X - 2, Board.Size.Y - 1);
    529       Increment := Point(-1, 1);
    530     end;
    531     drDown: begin
    532       StartPoint := Point(0, Board.Size.Y - 2);
    533       AreaSize := Point(Board.Size.X - 1, Board.Size.Y - 2);
    534       Increment := Point(1, -1);
    535     end;
    536   end;
    537 
    538   PI.Y := 0;
    539   while PI.Y <= AreaSize.Y do begin
    540     PI.X := 0;
    541     while PI.X <= AreaSize.X do begin
    542       P := Point(StartPoint.X + PI.X * Increment.X, StartPoint.Y + PI.Y * Increment.Y);
    543       PNew.X := P.X + DirectionDiff[Direction].X;
    544       PNew.Y := P.Y + DirectionDiff[Direction].Y;
     528  Area := GetMoveArea(Direction);
     529  P := Area.P1;
     530  while P.Y <> Area.P2.Y + Area.Increment.Y do begin
     531    P.X := Area.P1.X;
     532    while P.X <> Area.P2.X + Area.Increment.X do begin
     533      PNew := P + DirectionDiff[Direction];
    545534      if IsValidPos(PNew) then begin
    546535        if (Board.Tiles[P.Y, P.X].Value <> 0) then begin
     
    551540          end;
    552541        end;
    553         P.X := PNew.X;
    554         P.Y := PNew.Y;
    555         PNew.X := P.X + DirectionDiff[Direction].X;
    556         PNew.Y := P.Y + DirectionDiff[Direction].Y;
    557542      end;
    558       Inc(PI.X);
     543      Inc(P.X, Area.Increment.X);
    559544    end;
    560545    if Result then Break;
    561     Inc(PI.Y);
     546    Inc(P.Y, Area.Increment.Y);
    562547  end;
    563548end;
     
    565550procedure TGame.MoveAll(Direction: TDirection);
    566551var
    567   StartPoint: TPoint;
    568   AreaSize: TPoint;
    569   Increment: TPoint;
    570   MoveDirection: TPoint;
    571552  P: TPoint;
    572553  PNew: TPoint;
    573   PI: TPoint;
    574554  X, Y: Integer;
    575555  I: Integer;
     
    578558  Time: TDateTime;
    579559  Part: Double;
     560  Area: TArea;
    580561begin
    581562  if not CanMoveDirection(Direction) then Exit;
     
    583564  FBoardUndo.Assign(Board);
    584565  FCanUndo := True;
    585   //Diff := DirectionDiff[Direction];
    586   case Direction of
    587     drLeft: begin
    588       StartPoint := Point(1, 0);
    589       AreaSize := Point(Board.Size.X - 2, Board.Size.Y - 1);
    590       Increment := Point(1, 1);
    591       MoveDirection := Point(-1, 0);
    592     end;
    593     drUp: begin
    594       StartPoint := Point(0, 1);
    595       AreaSize := Point(Board.Size.X - 1, Board.Size.Y - 2);
    596       Increment := Point(1, 1);
    597       MoveDirection := Point(0, -1);
    598     end;
    599     drRight: begin
    600       StartPoint := Point(Board.Size.X - 2, 0);
    601       AreaSize := Point(Board.Size.X - 2, Board.Size.Y - 1);
    602       Increment := Point(-1, 1);
    603       MoveDirection := Point(1, 0);
    604     end;
    605     drDown: begin
    606       StartPoint := Point(0, Board.Size.Y - 2);
    607       AreaSize := Point(Board.Size.X - 1, Board.Size.Y - 2);
    608       Increment := Point(1, -1);
    609       MoveDirection := Point(0, 1);
    610     end;
    611   end;
     566  Area := GetMoveArea(Direction);
    612567  Board.ClearMerged;
    613568  for I := 0 to Max(Board.Size.X, Board.Size.Y) - 1 do begin
    614     PI.Y := 0;
    615569    for Y := 0 to Board.Size.Y - 1 do
    616570      for X := 0 to Board.Size.X - 1 do begin
     
    619573      end;
    620574
    621     while PI.Y <= AreaSize.Y do begin
    622       PI.X := 0;
    623       while PI.X <= AreaSize.X do begin
    624         P := Point(StartPoint.X + PI.X * Increment.X, StartPoint.Y + PI.Y * Increment.Y);
    625         PNew.X := P.X + DirectionDiff[Direction].X;
    626         PNew.Y := P.Y + DirectionDiff[Direction].Y;
     575    P := Area.P1;
     576    while P.Y <> Area.P2.Y + Area.Increment.Y do begin
     577      P.X := Area.P1.X;
     578      while P.X <> Area.P2.X + Area.Increment.X do begin
     579        PNew := P + DirectionDiff[Direction];
    627580        if IsValidPos(PNew) then begin
    628581          if (Board.Tiles[P.Y, P.X].NewValue <> 0) then begin
     
    644597            end;
    645598          end;
    646           P.X := PNew.X;
    647           P.Y := PNew.Y;
    648           PNew.X := P.X + DirectionDiff[Direction].X;
    649           PNew.Y := P.Y + DirectionDiff[Direction].Y;
    650599        end;
    651         Inc(PI.X);
     600        Inc(P.X, Area.Increment.X);
    652601      end;
    653       Inc(PI.Y);
     602      Inc(P.Y, Area.Increment.Y);
    654603    end;
    655604
     
    665614        for X := 0 to Board.Size.X - 1 do begin
    666615          if Board.Tiles[Y, X].Moving then
    667             Board.Tiles[Y, X].Shift := Point(Trunc(Part * MoveDirection.X * 100),
    668               Trunc(Part * MoveDirection.Y * 100));
     616            Board.Tiles[Y, X].Shift := Point(Trunc(Part * DirectionDiff[Direction].X * 100),
     617              Trunc(Part * DirectionDiff[Direction].Y * 100));
    669618        end;
    670619      DoChange;
Note: See TracChangeset for help on using the changeset viewer.