source: tags/1.2.0/AI/StdAI/Pile.pas

Last change on this file was 160, checked in by chronos, 5 years ago
  • Added: StdAI from original game. Previously used only AI dev kit.
File size: 2.9 KB
Line 
1{single instance priority queue
2main parts contributed by Rassim Eminli}
3
4{$INCLUDE Switches.inc}
5
6unit Pile;
7
8interface
9
10procedure Create(Size: integer);
11procedure Free;
12procedure Empty;
13function Put(Item, Value: integer): boolean;
14function TestPut(Item, Value: integer): boolean;
15function Get(var Item, Value: integer): boolean;
16
17
18implementation
19
20const
21MaxSize=9600;
22
23type
24TheapItem = record
25 Item: integer;
26 Value: integer;
27end;
28
29var
30bh: array[0..MaxSize-1] of TheapItem;
31Ix: array[0..MaxSize-1] of integer;
32n, CurrentSize: integer;
33{$IFDEF DEBUG}InUse: boolean;{$ENDIF}
34
35
36procedure Create(Size: integer);
37begin
38 {$IFDEF DEBUG}assert(not InUse, 'Pile is a single instance class, '
39 +'no multiple usage possible. Always call Pile.Free after use.');{$ENDIF}
40 assert(Size<=MaxSize);
41 if (n <> 0) or (Size > CurrentSize) then
42 begin
43 FillChar(Ix, Size*sizeOf(integer), 255);
44 n := 0;
45 end;
46 CurrentSize := Size;
47 {$IFDEF DEBUG}InUse:=true;{$ENDIF}
48end;
49
50procedure Free;
51begin
52 {$IFDEF DEBUG}assert(InUse);InUse:=false;{$ENDIF}
53end;
54
55procedure Empty;
56begin
57 if n <> 0 then
58 begin
59 FillChar(Ix, CurrentSize*sizeOf(integer), 255);
60 n := 0;
61 end;
62end;
63
64//Parent(i) = (i-1)/2.
65function Put(Item, Value: integer): boolean; //O(lg(n))
66var
67 i, j: integer;
68begin
69 assert(Item<CurrentSize);
70 i := Ix[Item];
71 if i >= 0 then
72 begin
73 if bh[i].Value <= Value then
74 begin
75 result := False;
76 exit;
77 end;
78 end
79 else
80 begin
81 i := n;
82 Inc(n);
83 end;
84
85 while i > 0 do
86 begin
87 j := (i-1) shr 1; //Parent(i) = (i-1)/2
88 if Value >= bh[j].Value then break;
89 bh[i] := bh[j];
90 Ix[bh[i].Item] := i;
91 i := j;
92 end;
93 // Insert the new Item at the insertion point found.
94 bh[i].Value := Value;
95 bh[i].Item := Item;
96 Ix[bh[i].Item] := i;
97 result := True;
98end;
99
100function TestPut(Item, Value: integer): boolean;
101var
102 i: integer;
103begin
104 assert(Item<CurrentSize);
105 i := Ix[Item];
106 result := (i < 0) or (bh[i].Value > Value);
107end;
108
109//Left(i) = 2*i+1.
110//Right(i) = 2*i+2 => Left(i)+1
111function Get(var Item, Value: integer): boolean; //O(lg(n))
112var
113 i, j: integer;
114 last: TheapItem;
115begin
116 if n = 0 then
117 begin
118 result := False;
119 exit;
120 end;
121
122 Item := bh[0].Item;
123 Value := bh[0].Value;
124
125 Ix[Item] := -1;
126
127 dec(n);
128 if n > 0 then
129 begin
130 last := bh[n];
131 i := 0; j := 1;
132 while j < n do
133 begin
134 // Right(i) = Left(i)+1
135 if(j < n-1) and (bh[j].Value > bh[j + 1].Value)then
136 inc(j);
137 if last.Value <= bh[j].Value then break;
138
139 bh[i] := bh[j];
140 Ix[bh[i].Item] := i;
141 i := j;
142 j := j shl 1+1; //Left(j) = 2*j+1
143 end;
144
145 // Insert the root in the correct place in the heap.
146 bh[i] := last;
147 Ix[last.Item] := i;
148 end;
149 result := True
150end;
151
152initialization
153 n:=0;
154 CurrentSize:=0;
155 {$IFDEF DEBUG}InUse:=false;{$ENDIF}
156end.
157
Note: See TracBrowser for help on using the repository browser.