ID:2636898
 
(See the best response by Magicsofa.)
a litte trouble
im attempting a tactics type RPG & am uneducated about how to
"sort a list by there movement variable"
any insight?

Best response
Well, you have to loop through elements in the list, testing the relevant value, and swapping positions. I assume you have a list of mobs, so you can easily pass the list to a proc and then have the proc modify it into a sorted version. Like so:

    proc/SortPlayers(list/L)
for(var/i = 1, i < L.len, ++i)
var/mob/M = L[i]
var/k = i
var/hi = M.moves //whatever your movement variable is
for(var/j = i + 1, j <= L.len, ++j)
M = L[j]
if(M.moves > hi)
k = j
hi = M.moves
if(i != k)
M = L[i]
L[i] = L[k]
L[k] = M


Bascially there are two 'cursors' (i and j) and a max value (hi). Each j loop looks through the remaining list for something that scores higher than i. If you're not sure what's going on I recommend using sleep() and some output on each iteration so that you can see it working.
thanks for the help i will go ahead & give this a shot
if no avail :/ then ill have to come back
In response to Magicsofa
This sort is a selection sort, which is an easy one to implement (I used to favor it myself way back in the day) but might be one of the worst for performance.

For small lists, your best choice is a binary insertion sort. For larger lists, you'd want to do a quicksort or a merge sort.

Here's just a binary insertion sort:

// Sort in ascending order by the "value" var
proc/SortPlayers(list/L)
var/i,j,b,e,v,vj
// The following uses the : operator, but this is only to avoid overhead of type casting.
// You should be careful with the : operator.
for(i in 2 to L.len)
v = L[i]:value
if(L[i-1]:value <= v) continue // in order so far
// do a binary search through sorted items
// b is beginning, e is 1 after the last item
b = 1; e = i-1
while(b < e)
j = (b+e) >> 1 // halfway point
vj = L[j]:vlaue
if(v < vj) e = j
else b = j+1
L.Insert(b, L[i])
L.Cut(i+1,i+2)

Since the number of players should seldom top 100, although 200 is not unheard of for some games, this should do fine. For larger lists, I would suggest a quicksort or merge sort approach, falling back on binary insertion sort when sorting a smaller section. Quicksort is unstable; merge sort and insertion sort are stable.

Here's an example of a dual-pivot quicksort falling back on binary insertion sort. I'm leaving out the var reads and just sorting by value in this example.

// Sort L in ascending order using a quicksort or binary insertion
proc/SortPlayers(list/L)
var/list/stack = new
var/x=1, y=L.len
var/i,j,k,b,e,v,vi,vj
while(1)
i = y-x // len-1 of this section
if(i >= 64) // len > 64, so use dual-pivot quicksort
// grab two pivots and move them to the ends
k = round((i+1)/3)
i = x + k; j = y - k
vi = L[i]; vj = L[j]
// ensure pivots are in order (vi <= vj)
if(vi > vj) {L[i]=vj; L[j]=vj=vi; vi=L[i]}
// move pivot values to ends
L.Swap(i,x); i=x
L.Swap(j,y); j=y
// move the pivot points inward
for(k=i+1, k<j, ++k)
v = L[k]
// if L[k] <= left pivot, move k to the left and push the pivot point inward
if(v <= vi) L.Swap(k,++i)
// if L[k] >= right pivot, move k to the right and push the pivot point inward
else if(v >= vj)
L.Swap(k,--j)
// L[k] now holds a new value, so see if it needs to be moved too
while(k < j)
v = L[k]
if(v >= vj) {L.Swap(k,--j); continue}
if(v <= vi) L.Swap(k,++i)
break
// the pivots now belong at i and j
L.Swap(x,i); L.Swap(y,j)
// handle the left, middle, and end sections in future iterations
stack += i+1; stack += j-1 // middle
stack += j+1; stack += y // right
y = i-1 // left (keep x the same)
else // len <= 64, so do binary insertion
for(i in x+1 to y) // should do nothing if x >= y
v = L[i]
if(L[i-1] <= v) continue
b = 1; e = i-1
while(b < e)
j = (b+e) >> 1
vj = L[j]
if(v < vj) e = j
else b = j+1
// this is probably safer in a big list than Insert and Cut
while(b<i) L.Swap(b,i--)
// pop off the stack
if(!(e=stack.len)) break
y = stack[e--]
x = stack[e--]
stack.len = e