# Sorting scenes

Hi all,

I am trying to iterate over all scenes in my game in an order based upon a numeric property (sc-chapter). Can Inform do this or should I create such a list myself (entry 1 with sc-chapter 1, etc)?
The following fails to compile because apparently I cannot sort a list of scenes based on a property (sorting a list of scenes works, even in reverse order, but that ignores the proerty I want to sort in).

``````Laboratory is a room.

A scene has a number called sc-chapter. [ Entire Game will be chapter 0 ]

scene-two is a recurring scene. The sc-chapter of scene-two is 2.
scene-one is a recurring scene. The sc-chapter of scene-one is 1.

Definition: a scene is active if its sc-chapter is greater than 0. [ Excludes Entire Game ]

When play begins:
let L be the list of active scenes;
sort L in sc-chapter order; [ this line fails ]
repeat with S running through L:
say "[sc-chapter of S]: [S].";
``````

In WI 21.8 the phrase definitions quietly shift from `list of values` to `list of objects` for the sort in property order phrases. So sorting non-objects is unimplemented. Youâ€™ll have to write your own sort. (You could create a kind of object that had a scene property and an sc-chapter property, but itâ€™s probably simpler to write your own sort.)

3 Likes

I think the sorting only works with numeric properties of things, not properties of scenes. (Edit: or what Zed said.)

One way would be to use a relation:

``````Lab is a room.

A scene has a number called sc-chapter. The sc-chapter of a scene is usually -1.

Occurrence relates a scene (called S) to a number (called N) when the sc-chapter of S is N. The verb to occur at means the occurrence relation.

ScA is a scene.
The sc-chapter of ScA is 1.

ScB is a scene.
The sc-chapter of ScB is 3.

ScC is a scene.
The sc-chapter of ScC is 2.

Sc-totalchapters is a number that varies. Sc-totalchapters is 3.

After jumping:
repeat with X running from 1 to sc-totalchapters:
let S be a random scene which occurs at X;
say "Chapter [X]: [S].";
``````

Output:

>jump
Chapter 1: ScA.
Chapter 2: ScC.
Chapter 3: ScB.

4 Likes

I wonder how useful a general-purpose sort that takes a list of K and a phrase K => number would be.

Probably not very useful without lambdas.

1 Like

I dunno. Letâ€™s find out.

``````use the serial comma.

lab is a room.

A scene has a number called sc-chapter.

scene-two is a recurring scene. The sc-chapter of scene-two is 2.
scene-four is a recurring scene. The sc-chapter of scene-four is 4.
scene-one is a recurring scene. The sc-chapter of scene-one is 1.
scene-three is a recurring scene. The sc-chapter of scene-three is 3.

to decide what number is (s1 - scene) vs (s2 - scene) (this is scene-cmp):
decide on the sc-chapter of s1 <=> the sc-chapter of s2;

when play begins:
let l be the list of scenes;
sort l by scene-cmp;
puts l;

Include (-
[ partition_fn arr p start end fn pivot l h tmp index;
l = start;
h = end - 2;
pivot = LIST_OF_TY_GetItem(arr, p+1);
ListSwapEntries(arr, end, p+1);
while (l < h) {
if ((fn)(LIST_OF_TY_GetItem(arr, l+1),pivot) < 0) {
l++;
} else if ((fn)(LIST_OF_TY_GetItem(arr, h+1),pivot) >= 0)  {
h--;
} else {
ListSwapEntries(arr,l+1,h+1);
}
}
index = h;
if ((fn)(LIST_OF_TY_GetItem(arr, h+1), pivot) < 0) index++;
ListSwapEntries(arr,end,index+1);
return index;
];

[ phrase_sort_fn arr start end fn p;
if ((end - start) < 2) return;
p = start + ((end-start)/2);
p = partition_fn(arr, p, start, end, fn);
phrase_sort_fn(arr, start, p, fn);
phrase_sort_fn(arr, p+1, end, fn);
];

[ spaceship v1 v2 k cmp_fn;
if KOVComparisonFunction(k) cmp_fn = (KOVComparisonFunction(k))(v1,v2);
if ((~~cmp_fn) || (cmp_fn == UnsignedCompare)) return v1 - v2;
return cmp_fn(v1,v2);
];
-)

To sort (L - a list of values of kind K) by (ph - phrase (K, K) -> number):
Edited: @drpeterbatesuk alerted me to a problem with my `spaceship` phrase: as written, it only worked with block kinds of value (e.g., texts) and the one non-block type Iâ€™d special-cased, number. It should now work in the general case, where â€śworkâ€ť means â€śmake the same comparison Inform would when sorting a list of this kindâ€ť. Plus I noticed thereâ€™s an existing ListSwapEntries function that was basically the same thing as my swap_list_entries so now my code uses it.