- r = 1 + 2 * random_upto(rs, 2);
- } while (x == oldx && y == oldy && (oldr == 0 || r == oldr));
-
- do_rotate(grid, w, h, n, params->orientable,
- x, y, r);
+ r = 2 * random_upto(rs, 2) - 1;
+
+ /*
+ * See if any previous rotations has happened at
+ * this point which nothing has overlapped since.
+ * If so, ensure we haven't either undone a
+ * previous move or repeated one so many times that
+ * it turns into fewer moves in the inverse
+ * direction (i.e. three identical rotations).
+ */
+ oldtotal = prevmoves[y*rw+x];
+ newtotal = oldtotal + r;
+
+ /*
+ * Special case here for w==h==n, in which case
+ * there is actually no way to _avoid_ all moves
+ * repeating or undoing previous ones.
+ */
+ } while ((w != n || h != n) &&
+ (abs(newtotal) < abs(oldtotal) || abs(newtotal) > 2));
+
+ do_rotate(grid, w, h, n, params->orientable, x, y, r);