⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sandque.pas

📁 模拟2维沙堆效果
💻 PAS
字号:
unit SandQue;
// A generic queue, used to store sand grains

interface

type
  PQueueElem = ^TQueueElem;  // Generic element holding user item
  TQueueElem = record
    Item: Pointer;           // The stored user-defined item
    Next: PQueueElem;        // Next element
  end;

  TQueue = class
  public
    Size: Longint;   // We want to be able to store a LOT of grains
    constructor Create;
    destructor Destroy; override;
    procedure Enqueue(Itm: Pointer);
    function Dequeue(var Itm: Pointer): Boolean;
    function Peek(Idx: Word; var Itm: Pointer): Boolean;
  private
    Top, Bottom, Current: PQueueElem;
    Position: Word;
  end;

implementation

{----------------------- TQueue -----------------------}

constructor TQueue.Create;
begin
  inherited Create;
  Size := 0;                 // Queue is empty
  Position := 0;
  Top := nil;
  Bottom := nil;
  Current := nil;
end;


destructor TQueue.Destroy;
var
  Itm: Pointer;
begin
  { Remove any remaining elements before destroying the queue.
    Note that user items are NOT disposed as TQueue doesn't know their
    types. Therefore user should always empty the queue himself and
    dispose the items before destroying the queue. }
  while Size > 0 do
    Dequeue(Itm);
  inherited Destroy;
end;


procedure TQueue.Enqueue(Itm: Pointer);
var
  P: PQueueElem;             // We need a record for the user item
begin
  New(P);
  P^.Item := Itm;
  P^.Next := nil;
  if Size = 0 then
  begin
    Top := P;
    Bottom := P;
    Current := P;
  end;
  Bottom^.Next := P;
  Bottom := P;
  Inc(Position);
  Inc(Size);
end;


function TQueue.Dequeue(var Itm: Pointer): Boolean;
var
  P: PQueueElem;
begin
  Dequeue := False;
  if Size > 0 then           // Same as: if Top <> NIL
  begin
    Itm := Top^.Item;
    P := Top;
    Top := Top^.Next;
    if Current = Itm then
    begin
      Current := Top;
      if Top = nil then
        Position := 0
      else
        Position := 1;
    end
    else
      Dec(Position);
    Dispose(P);
    Dec(Size);
    Dequeue := True;
  end;
end;


function TQueue.Peek(Idx: Word; var Itm: Pointer): Boolean;
var
  P: PQueueElem;
  I: Word;
begin
  Itm := nil;
  Peek := False;

  if Idx <= Size then        // Does the element exist?
  begin
    if Position <= Idx then
    begin
      P := Current;          // Traverse from current position
      for I := 1 to Idx-Position do
        P := P^.Next;
    end
    else
    begin
      P := Top;              // Traverse from start
      for I := 1 to Idx-1 do
        P := P^.Next;
    end;

    Itm := P^.Item;
    Current := P;
    Position := Idx;
    Peek := True;
  end;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -