@@ -11,7 +11,7 @@ extern "C"{
1111#endif
1212
1313const version_t VERSION = {
14- .major = 0 , .minor = 5 , .patch = 7 ,
14+ .major = 0 , .minor = 5 , .patch = 8 ,
1515};
1616
1717const size_t FILE_HEADER_SIZE = 25 ;
@@ -202,35 +202,40 @@ spiral_collides(spiral_t spiral) {
202202
203203// private function, given a spiral struct, the index of one of it's lines and
204204// a target length to set that line to, attempt to set the target line to that
205- // length, recursively calling self to resize the previous line if that is not
206- // possible.
205+ // length, back-tacking to resize the previous line if it collides.
207206static spiral_t
208207resize_spiral (spiral_t spiral , size_t index , uint32_t length ) {
209- // first, set the target line to the target length
210- spiral .lines [index ].length = length ;
211- // also, set cache validity to this index so we invalidate any invalid
212- // entries in the co-ord cache
213- spiral .co_ord_cache .validity = (
214- index < spiral .co_ord_cache .validity
215- ) ? index : spiral .co_ord_cache .validity ;
216- // update the spiral's co-ord cache
217- cache_spiral_points (& spiral , index + 1 );
218- // now, check for collisions
219- if (spiral_collides (spiral )) {
220- // there were collisions, so reset the target line to 1
221- spiral .lines [index ].length = 1 ;
222- do {
223- // recursively call resize_spiral(), increasing the size of the
224- // previous line until we get something that doesn't collide
225- spiral = resize_spiral (
226- spiral , index - 1 , spiral .lines [index - 1 ].length + 1
227- );
228- // update the spiral's co-ord cache
229- cache_spiral_points (& spiral , index + 1 );
230- // check if it still collides
231- } while (spiral_collides (spiral ));
208+ // setup state variables, these are used in place of recursion for managing
209+ // state of which line is being resized, and what size it should be.
210+ size_t current_index = index ;
211+ size_t current_length = length ;
212+ while (true) {
213+ // set the target line to the target length
214+ spiral .lines [current_index ].length = current_length ;
215+ // also, set cache validity to this index so we invalidate any invalid
216+ // entries in the co-ord cache
217+ spiral .co_ord_cache .validity = (
218+ current_index < spiral .co_ord_cache .validity
219+ ) ? current_index : spiral .co_ord_cache .validity ;
220+ // update the spiral's co-ord cache
221+ cache_spiral_points (& spiral , current_index + 1 );
222+ if (spiral_collides (spiral )) {
223+ // if we've caused a collision, we should back-track
224+ // and increase the size of the previous line segment
225+ current_index -- ;
226+ current_length = spiral .lines [current_index ].length + 1 ;
227+ } else if (current_index != index ) {
228+ // if we didn't cause a collision but we're not on the top-most
229+ // line, then we've just resolved a collision situation.
230+ // we now need to work on the next line and start by setting to 1.
231+ current_index ++ ;
232+ current_length = 1 ;
233+ } else {
234+ // if we're on the top-most line and there's no collision
235+ // this means we've finished! Return result.
236+ return spiral ;
237+ }
232238 }
233- return spiral ;
234239}
235240
236241// given a spiral for which the length of all its lines are not yet known,
0 commit comments