mirror of
https://github.com/fulpstation/fulpstation.git
synced 2025-12-10 01:57:01 +00:00
* Added a generic (array based) heap data structure * Changed A* to use a heap open set instead of a priority queue * Fixed A* not checking for already processed turfs * Fixed A* number of traversed nodes not being updated on new route * Changed the heuristic proc for every A* calls to /turf/proc/Distance_cardinal, since A* now only progress in cardinal directions
83 lines
1.7 KiB
Plaintext
83 lines
1.7 KiB
Plaintext
|
|
//////////////////////
|
|
//PriorityQueue object
|
|
//////////////////////
|
|
|
|
//an ordered list, using the cmp proc to weight the list elements
|
|
/PriorityQueue
|
|
var/list/L //the actual queue
|
|
var/cmp //the weight function used to order the queue
|
|
|
|
/PriorityQueue/New(compare)
|
|
L = new()
|
|
cmp = compare
|
|
|
|
/PriorityQueue/proc/IsEmpty()
|
|
return !L.len
|
|
|
|
//return the index the element should be in the priority queue using dichotomic search
|
|
/PriorityQueue/proc/FindElementIndex(atom/A)
|
|
var/i = 1
|
|
var/j = L.len
|
|
var/mid
|
|
|
|
while(i < j)
|
|
mid = round((i+j)/2)
|
|
|
|
if(call(cmp)(L[mid],A) < 0)
|
|
i = mid + 1
|
|
else
|
|
j = mid
|
|
|
|
if(i == 1 || i == L.len) //edge cases
|
|
return (call(cmp)(L[i],A) > 0) ? i : i+1
|
|
else
|
|
return i
|
|
|
|
|
|
//add an element in the list,
|
|
//immediatly ordering it to its position using dichotomic search
|
|
/PriorityQueue/proc/Enqueue(atom/A)
|
|
if(!L.len)
|
|
L.Add(A)
|
|
return
|
|
|
|
L.Insert(FindElementIndex(A),A)
|
|
|
|
//removes and returns the first element in the queue
|
|
/PriorityQueue/proc/Dequeue()
|
|
if(!L.len)
|
|
return 0
|
|
. = L[1]
|
|
|
|
Remove(.)
|
|
|
|
//removes an element
|
|
/PriorityQueue/proc/Remove(atom/A)
|
|
return L.Remove(A)
|
|
|
|
//returns a copy of the elements list
|
|
/PriorityQueue/proc/List()
|
|
. = L.Copy()
|
|
|
|
//return the position of an element or 0 if not found
|
|
/PriorityQueue/proc/Seek(atom/A)
|
|
. = L.Find(A)
|
|
|
|
//return the element at the i_th position
|
|
/PriorityQueue/proc/Get(i)
|
|
if(i > L.len || i < 1)
|
|
return 0
|
|
return L[i]
|
|
|
|
//replace the passed element at it's right position using the cmp proc
|
|
/PriorityQueue/proc/ReSort(atom/A)
|
|
var/i = Seek(A)
|
|
if(i == 0)
|
|
return
|
|
while(i < L.len && call(cmp)(L[i],L[i+1]) > 0)
|
|
L.Swap(i,i+1)
|
|
i++
|
|
while(i > 1 && call(cmp)(L[i],L[i-1]) <= 0) //last inserted element being first in case of ties (optimization)
|
|
L.Swap(i,i-1)
|
|
i-- |