forked from blunty666/CC-Pathfinding-and-Mapping
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpQueue.lua
108 lines (95 loc) · 2.41 KB
/
pQueue.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
local function sift_up(queue, index)
local current, parent = index, (index - (index % 2))/2
while current > 1 and queue.cmp(queue[current][2], queue[parent][2]) do
queue[current], queue[parent] = queue[parent], queue[current]
current, parent = parent, (parent - (parent % 2))/2
end
return current
end
local function sift_down(queue, index)
local current, child, size = index, 2*index, #queue
while child <= size do
if child < size and queue.cmp(queue[child + 1][2], queue[child][2]) then
child = child + 1
end
if queue.cmp(queue[child][2], queue[current][2]) then
queue[current], queue[child] = queue[child], queue[current]
current, child = child, 2*child
else
break
end
end
return current
end
local methods = {
insert = function(self, element, value)
table.insert(self, {element, value})
return sift_up(self, #self)
end,
remove = function(self, element, compFunc)
local index = self:contains(element, compFunc)
if index then
local size = #self
self[index], self[size] = self[size], self[index]
local ret = table.remove(self)
if size > 1 and index < size then
sift_down(self, index)
if index > 1 then
sift_up(self, index)
end
end
return unpack(ret)
end
end,
pop = function(self)
if self[1] then
local size = #self
self[1], self[size] = self[size], self[1]
local ret = table.remove(self)
if size > 1 then
sift_down(self, 1)
end
return unpack(ret)
end
end,
peek = function(self)
if self[1] then
return self[1][1], self[1][2]
end
end,
contains = function(self, element, compFunc)
for index, entry in ipairs(self) do
if (compFunc and compFunc(entry[1], element)) or entry[1] == element then
return index
end
end
return false
end,
isEmpty = function(self)
return #self == 0
end,
size = function(self)
return #self
end,
getValue = function(self, element, compFunc)
local index = self:contains(element, compFunc)
return (index and self[index][2]) or false
end,
setValue = function(self, element, value, compFunc)
local index = self:contains(element, compFunc)
if index then
self[index][2] = value
sift_up(self, index)
sift_down(self, index)
return true
else
return false
end
end,
}
function new(compareFunc)
local queue = {}
queue.cmp = type(compareFunc) == "function" and compareFunc or function(a, b) return a < b end
setmetatable(queue, {__index = methods})
return queue
end