I'm trying to do this over a significantly large area, and as such, need some advice on how to do this effectively.
The method I'm using is pretty brute-force. Can anyone point me to a better method, or point me to a paper or something on the subject?
This is what I've got so far:
proc
divide(var/turf/start)
var/list/edges = list(start)
var/list/contents = list()
var/list/walls = list()
while(edges.len>0)
var/turf/t = edges[1]
if(!t.density)
var/d = NORTH
for(var/count=0;count<=3;count++)
var/turf/a = get_step(t,d)
if(!edges.Find(a)&&!contents.Find(a))
if(a.density)
walls += a
else
edges += a
d = turn(d,90)
contents += t
else
walls += t
edges -= t
var/area/a = new/area()
a.contents.Add(contents)
a.walls = walls
This method freezes pretty badly when diving big areas, and isn't really meant to profile an entire map. on a 1000x1000 tile scene, it takes over 15 minutes to manage all of this.
However, on a smaller area (50x50), it performs miraculously well, dividing an area in somewhere under a tenth of a second.
Anybody know of a better way to do this? I've got tons of ideas, but I'm pretty well stumped when it comes to optimizing them.
I'm not sure what the backing data structure for a raw /list in DM is - associative lists are done with a binary tree of some sort, so the find(), add(), and remove() operations are probably all O(log n).
What you're looking for here is some sort of set data structure - a hashset, for example. find(), add(), remove() in O(1) if it's done properly. Not sure if there are any DM implementations.
Any particular reason you're using list.Find() instead of the in operator? Not sure what the relative speeds are, just asking.