6 * Angband sorting algorithm -- quick sort in place
8 * Note that the details of the data we are sorting is hidden,
9 * and we rely on the "ang_sort_comp()" and "ang_sort_swap()"
10 * function hooks to interact with the data, which is given as
11 * two pointers, and which may have any user-defined form.
13 void ang_sort_aux(vptr u, vptr v, int p, int q)
31 while (!(*ang_sort_comp)(u, v, b, z)) b--;
34 while (!(*ang_sort_comp)(u, v, z, a)) a++;
40 (*ang_sort_swap)(u, v, a, b);
46 /* Recurse left side */
47 ang_sort_aux(u, v, p, b);
49 /* Recurse right side */
50 ang_sort_aux(u, v, b + 1, q);
55 * Angband sorting algorithm -- quick sort in place
57 * Note that the details of the data we are sorting is hidden,
58 * and we rely on the "ang_sort_comp()" and "ang_sort_swap()"
59 * function hooks to interact with the data, which is given as
60 * two pointers, and which may have any user-defined form.
62 void ang_sort(vptr u, vptr v, int n)
65 ang_sort_aux(u, v, 0, n - 1);
71 * Sorting hook -- comp function -- by "distance to player"
73 * We use "u" and "v" to point to arrays of "x" and "y" positions,
74 * and sort the arrays by double-distance to the player.
76 bool ang_sort_comp_distance(vptr u, vptr v, int a, int b)
78 POSITION *x = (POSITION*)(u);
79 POSITION *y = (POSITION*)(v);
81 POSITION da, db, kx, ky;
83 /* Absolute distance components */
84 kx = x[a]; kx -= p_ptr->x; kx = ABS(kx);
85 ky = y[a]; ky -= p_ptr->y; ky = ABS(ky);
87 /* Approximate Double Distance to the first point */
88 da = ((kx > ky) ? (kx + kx + ky) : (ky + ky + kx));
90 /* Absolute distance components */
91 kx = x[b]; kx -= p_ptr->x; kx = ABS(kx);
92 ky = y[b]; ky -= p_ptr->y; ky = ABS(ky);
94 /* Approximate Double Distance to the first point */
95 db = ((kx > ky) ? (kx + kx + ky) : (ky + ky + kx));
97 /* Compare the distances */
103 * Sorting hook -- comp function -- by importance level of grids
105 * We use "u" and "v" to point to arrays of "x" and "y" positions,
106 * and sort the arrays by level of monster
108 bool ang_sort_comp_importance(vptr u, vptr v, int a, int b)
110 POSITION *x = (POSITION*)(u);
111 POSITION *y = (POSITION*)(v);
112 grid_type *ca_ptr = ¤t_floor_ptr->grid_array[y[a]][x[a]];
113 grid_type *cb_ptr = ¤t_floor_ptr->grid_array[y[b]][x[b]];
114 monster_type *ma_ptr = ¤t_floor_ptr->m_list[ca_ptr->m_idx];
115 monster_type *mb_ptr = ¤t_floor_ptr->m_list[cb_ptr->m_idx];
116 monster_race *ap_ra_ptr, *ap_rb_ptr;
118 /* The player grid */
119 if (y[a] == p_ptr->y && x[a] == p_ptr->x) return TRUE;
120 if (y[b] == p_ptr->y && x[b] == p_ptr->x) return FALSE;
122 /* Extract monster race */
123 if (ca_ptr->m_idx && ma_ptr->ml) ap_ra_ptr = &r_info[ma_ptr->ap_r_idx];
124 else ap_ra_ptr = NULL;
125 if (cb_ptr->m_idx && mb_ptr->ml) ap_rb_ptr = &r_info[mb_ptr->ap_r_idx];
126 else ap_rb_ptr = NULL;
128 if (ap_ra_ptr && !ap_rb_ptr) return TRUE;
129 if (!ap_ra_ptr && ap_rb_ptr) return FALSE;
131 /* Compare two monsters */
132 if (ap_ra_ptr && ap_rb_ptr)
134 /* Unique monsters first */
135 if ((ap_ra_ptr->flags1 & RF1_UNIQUE) && !(ap_rb_ptr->flags1 & RF1_UNIQUE)) return TRUE;
136 if (!(ap_ra_ptr->flags1 & RF1_UNIQUE) && (ap_rb_ptr->flags1 & RF1_UNIQUE)) return FALSE;
138 /* Shadowers first (あやしい影) */
139 if ((ma_ptr->mflag2 & MFLAG2_KAGE) && !(mb_ptr->mflag2 & MFLAG2_KAGE)) return TRUE;
140 if (!(ma_ptr->mflag2 & MFLAG2_KAGE) && (mb_ptr->mflag2 & MFLAG2_KAGE)) return FALSE;
142 /* Unknown monsters first */
143 if (!ap_ra_ptr->r_tkills && ap_rb_ptr->r_tkills) return TRUE;
144 if (ap_ra_ptr->r_tkills && !ap_rb_ptr->r_tkills) return FALSE;
146 /* Higher level monsters first (if known) */
147 if (ap_ra_ptr->r_tkills && ap_rb_ptr->r_tkills)
149 if (ap_ra_ptr->level > ap_rb_ptr->level) return TRUE;
150 if (ap_ra_ptr->level < ap_rb_ptr->level) return FALSE;
153 /* Sort by index if all conditions are same */
154 if (ma_ptr->ap_r_idx > mb_ptr->ap_r_idx) return TRUE;
155 if (ma_ptr->ap_r_idx < mb_ptr->ap_r_idx) return FALSE;
158 /* An object get higher priority */
159 if (current_floor_ptr->grid_array[y[a]][x[a]].o_idx && !current_floor_ptr->grid_array[y[b]][x[b]].o_idx) return TRUE;
160 if (!current_floor_ptr->grid_array[y[a]][x[a]].o_idx && current_floor_ptr->grid_array[y[b]][x[b]].o_idx) return FALSE;
162 /* Priority from the terrain */
163 if (f_info[ca_ptr->feat].priority > f_info[cb_ptr->feat].priority) return TRUE;
164 if (f_info[ca_ptr->feat].priority < f_info[cb_ptr->feat].priority) return FALSE;
166 /* If all conditions are same, compare distance */
167 return ang_sort_comp_distance(u, v, a, b);
172 * Sorting hook -- swap function -- by "distance to player"
174 * We use "u" and "v" to point to arrays of "x" and "y" positions,
175 * and sort the arrays by distance to the player.
177 void ang_sort_swap_distance(vptr u, vptr v, int a, int b)
179 POSITION *x = (POSITION*)(u);
180 POSITION *y = (POSITION*)(v);
198 * Sorting hook -- Comp function -- see below
200 * We use "u" to point to array of monster indexes,
201 * and "v" to select the type of sorting to perform on "u".
203 bool ang_sort_art_comp(vptr u, vptr v, int a, int b)
205 u16b *who = (u16b*)(u);
206 u16b *why = (u16b*)(v);
213 /* Sort by total kills */
216 /* Extract total kills */
217 z1 = a_info[w1].tval;
218 z2 = a_info[w2].tval;
220 /* Compare total kills */
221 if (z1 < z2) return (TRUE);
222 if (z1 > z2) return (FALSE);
226 /* Sort by monster level */
230 z1 = a_info[w1].sval;
231 z2 = a_info[w2].sval;
234 if (z1 < z2) return (TRUE);
235 if (z1 > z2) return (FALSE);
239 /* Sort by monster experience */
242 /* Extract experience */
243 z1 = a_info[w1].level;
244 z2 = a_info[w2].level;
246 /* Compare experience */
247 if (z1 < z2) return (TRUE);
248 if (z1 > z2) return (FALSE);
252 /* Compare indexes */
258 * Sorting hook -- Swap function -- see below
260 * We use "u" to point to array of monster indexes,
261 * and "v" to select the type of sorting to perform.
263 void ang_sort_art_swap(vptr u, vptr v, int a, int b)
265 u16b *who = (u16b*)(u);
278 bool ang_sort_comp_quest_num(vptr u, vptr v, int a, int b)
280 QUEST_IDX *q_num = (QUEST_IDX *)u;
281 quest_type *qa = &quest[q_num[a]];
282 quest_type *qb = &quest[q_num[b]];
287 return (qa->comptime != qb->comptime) ?
288 (qa->comptime < qb->comptime) :
289 (qa->level <= qb->level);
292 void ang_sort_swap_quest_num(vptr u, vptr v, int a, int b)
294 QUEST_IDX *q_num = (QUEST_IDX *)u;