Files
CHOMPStation2/code/_helpers/priority_queue_ch.dm
Cadyn ecd8125771 Ai update (#8023)
Co-authored-by: silicons <2003111+silicons@users.noreply.github.com>
Co-authored-by: silicons <no@you.cat>
2024-03-31 13:38:23 +02:00

90 lines
2.2 KiB
Plaintext

//* This file is explicitly licensed under the MIT license. *//
//* Copyright (c) 2023 Citadel Station developers. *//
/**
* An array-backed priority queue.
*
* The "front" of the queue is popped first; check comparators.dm for what this means.
*/
/datum/priority_queue
/// comparaison function
var/procpath/comparison
/// internal array
var/list/array = list()
/datum/priority_queue/New(cmp)
src.comparison = cmp
array = list()
/datum/priority_queue/proc/is_empty()
return length(array) == 0
/datum/priority_queue/proc/enqueue(entry)
array += entry
bubble_up(length(array))
/datum/priority_queue/proc/dequeue()
if(length(array) == 0)
return null
. = array[1]
array.Swap(1, length(array))
--array.len
bubble_down(1)
/datum/priority_queue/proc/peek()
return length(array)? array[1] : null
// todo: define this
/datum/priority_queue/proc/bubble_up(index)
while(index >= 2 && call(comparison)(array[index], array[index / 2]) < 0)
array.Swap(index, index / 2)
index /= 2
// todo: define this
/datum/priority_queue/proc/bubble_down(index)
var/length = length(array)
var/next = index * 2
while(next <= length)
// left always exists, right doesn't necessarily exist
if(call(comparison)(array[next], array[index]) < 0)
if(next < length && call(comparison)(array[next], array[next + 1]) > 0)
array.Swap(index, next + 1)
index = next + 1
else
array.Swap(index, next)
index = next
else if(next < length && call(comparison)(array[next + 1], array[index]) < 0)
array.Swap(index, next + 1)
index = next + 1
else
break
next = index * 2
/**
* returns copy of list of entries in no particular order
*/
/datum/priority_queue/proc/flattened()
return array.Copy()
/datum/priority_queue/proc/remove_index(index)
var/length = length(array)
if(!index || index > length)
return
if(index == length)
. = array[index]
--array.len
return
. = array[index]
array.Swap(index, length)
--array.len
bubble_down(index)
/datum/priority_queue/proc/find(entry)
return array.Find(entry)
/datum/priority_queue/proc/remove_entry(entry)
return remove_index(array.Find(entry))
/datum/priority_queue/proc/size()
return length(array)