mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 02:34:00 +00:00
Ai update (#8023)
Co-authored-by: silicons <2003111+silicons@users.noreply.github.com> Co-authored-by: silicons <no@you.cat>
This commit is contained in:
89
code/_helpers/priority_queue_ch.dm
Normal file
89
code/_helpers/priority_queue_ch.dm
Normal file
@@ -0,0 +1,89 @@
|
||||
//* 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)
|
||||
Reference in New Issue
Block a user