commit 91792184fad21e2afa0e8342266340a40b709b43
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Fri Sep 10 01:29:55 2021 +0200

    Make object scrambling abstract (well, almost - with exception of Square-1 - this theoretically could also be done the generic way, but this would require almost 20000 'ScrambleStates')

diff --git a/src/main/java/org/distorted/objects/TwistyBandaged2Bar.java b/src/main/java/org/distorted/objects/TwistyBandaged2Bar.java
index ebdfefaf..b1189d75 100644
--- a/src/main/java/org/distorted/objects/TwistyBandaged2Bar.java
+++ b/src/main/java/org/distorted/objects/TwistyBandaged2Bar.java
@@ -36,13 +36,23 @@ class TwistyBandaged2Bar extends TwistyBandagedAbstract
                      DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
     {
     super(size, quat, texture, mesh, effects, moves, ObjectList.BAN2, res, scrWidth);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    mStates = new ScrambleState[]
+  ScrambleState[] getScrambleStates()
+    {
+    if( mStates==null )
       {
-      new ScrambleState( new int[][] { {}                                          , {0,1,1, 0,-1,1, 2,1,2, 2,-1,2}, {} }),
-      new ScrambleState( new int[][] { {0,-1,1, 0,1,1, 0,2,1, 2,-1,1, 2,1,1, 2,2,1}, {0,2,1, 2,2,1}                , {} }),
-      new ScrambleState( new int[][] { {}, {0,2,2, 2,2,2}                , {0,-1,2, 0,1,2, 0,2,2, 2,-1,2, 2,1,2, 2,2,2} })
-      };
+      mStates = new ScrambleState[]
+        {
+        new ScrambleState( new int[][] { {}                                          , {0,1,1, 0,-1,1, 2,1,2, 2,-1,2}, {} }),
+        new ScrambleState( new int[][] { {0,-1,1, 0,1,1, 0,2,1, 2,-1,1, 2,1,1, 2,2,1}, {0,2,1, 2,2,1}                , {} }),
+        new ScrambleState( new int[][] { {}, {0,2,2, 2,2,2}                , {0,-1,2, 0,1,2, 0,2,2, 2,-1,2, 2,1,2, 2,2,2} })
+        };
+      }
+
+    return mStates;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyBandaged3Plate.java b/src/main/java/org/distorted/objects/TwistyBandaged3Plate.java
index 8796fbcf..e7b6fb35 100644
--- a/src/main/java/org/distorted/objects/TwistyBandaged3Plate.java
+++ b/src/main/java/org/distorted/objects/TwistyBandaged3Plate.java
@@ -36,26 +36,36 @@ class TwistyBandaged3Plate extends TwistyBandagedAbstract
                        DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
     {
     super(size, quat, texture, mesh, effects, moves, ObjectList.BAN3, res, scrWidth);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    mStates = new ScrambleState[]
+  ScrambleState[] getScrambleStates()
     {
-    new ScrambleState( new int[][] {{ 2,-1, 1, 2, 1, 6                  }, { 0,-1, 5, 0, 1, 3                  }, { 2,-1, 2, 2, 1, 4                  }} ),
-    new ScrambleState( new int[][] {{ 2, 1, 0                           }, {                                   }, { 2, 1,10, 2, 2, 7                  }} ),
-    new ScrambleState( new int[][] {{                                   }, { 0,-1,11, 0, 2, 8                  }, { 2, 1, 0                           }} ),
-    new ScrambleState( new int[][] {{ 2, 1,12, 2, 2, 9                  }, { 0,-1, 0                           }, {                                   }} ),
-    new ScrambleState( new int[][] {{ 2,-1,10, 2, 2,13                  }, {                                   }, { 2,-1, 0                           }} ),
-    new ScrambleState( new int[][] {{                                   }, { 0, 1, 0                           }, { 2,-1,11, 2, 2,14                  }} ),
-    new ScrambleState( new int[][] {{ 2,-1, 0                           }, { 0, 1,12, 0, 2,15                  }, {                                   }} ),
-    new ScrambleState( new int[][] {{                                   }, { 2,-2, 7, 2,-1, 7, 2, 1, 7, 2, 2, 7}, { 2,-1,10, 2, 2, 1                  }} ),
-    new ScrambleState( new int[][] {{ 0,-2, 8, 0,-1, 8, 0, 1, 8, 0, 2, 8}, { 0, 1,11, 0, 2, 2                  }, {                                   }} ),
-    new ScrambleState( new int[][] {{ 2,-1,12, 2, 2, 3                  }, {                                   }, { 0,-2, 9, 0,-1, 9, 0, 1, 9, 0, 2, 9}} ),
-    new ScrambleState( new int[][] {{ 2,-1,13, 2, 1, 4                  }, { 2,-2,10, 2,-1,10, 2, 1,10, 2, 2,10}, { 2,-1, 1, 2, 1, 7                  }} ),
-    new ScrambleState( new int[][] {{ 0,-2,11, 0,-1,11, 0, 1,11, 0, 2,11}, { 0,-1, 8, 0, 1, 2                  }, { 2,-1,14, 2, 1, 5                  }} ),
-    new ScrambleState( new int[][] {{ 2,-1, 3, 2, 1, 9                  }, { 0,-1, 6, 0, 1,15                  }, { 0,-2,12, 0,-1,12, 0, 1,12, 0, 2,12}} ),
-    new ScrambleState( new int[][] {{ 2, 1,10, 2, 2, 4                  }, { 2,-2,13, 2,-1,13, 2, 1,13, 2, 2,13}, {                                   }} ),
-    new ScrambleState( new int[][] {{ 0,-2,14, 0,-1,14, 0, 1,14, 0, 2,14}, {                                   }, { 2, 1,11, 2, 2, 5                  }} ),
-    new ScrambleState( new int[][] {{                                   }, { 0,-1,12, 0, 2, 6                  }, { 0,-2,15, 0,-1,15, 0, 1,15, 0, 2,15}} )
-    };
+    if( mStates==null )
+      {
+      mStates = new ScrambleState[]
+        {
+        new ScrambleState( new int[][] {{ 2,-1, 1, 2, 1, 6                  }, { 0,-1, 5, 0, 1, 3                  }, { 2,-1, 2, 2, 1, 4                  }} ),
+        new ScrambleState( new int[][] {{ 2, 1, 0                           }, {                                   }, { 2, 1,10, 2, 2, 7                  }} ),
+        new ScrambleState( new int[][] {{                                   }, { 0,-1,11, 0, 2, 8                  }, { 2, 1, 0                           }} ),
+        new ScrambleState( new int[][] {{ 2, 1,12, 2, 2, 9                  }, { 0,-1, 0                           }, {                                   }} ),
+        new ScrambleState( new int[][] {{ 2,-1,10, 2, 2,13                  }, {                                   }, { 2,-1, 0                           }} ),
+        new ScrambleState( new int[][] {{                                   }, { 0, 1, 0                           }, { 2,-1,11, 2, 2,14                  }} ),
+        new ScrambleState( new int[][] {{ 2,-1, 0                           }, { 0, 1,12, 0, 2,15                  }, {                                   }} ),
+        new ScrambleState( new int[][] {{                                   }, { 2,-2, 7, 2,-1, 7, 2, 1, 7, 2, 2, 7}, { 2,-1,10, 2, 2, 1                  }} ),
+        new ScrambleState( new int[][] {{ 0,-2, 8, 0,-1, 8, 0, 1, 8, 0, 2, 8}, { 0, 1,11, 0, 2, 2                  }, {                                   }} ),
+        new ScrambleState( new int[][] {{ 2,-1,12, 2, 2, 3                  }, {                                   }, { 0,-2, 9, 0,-1, 9, 0, 1, 9, 0, 2, 9}} ),
+        new ScrambleState( new int[][] {{ 2,-1,13, 2, 1, 4                  }, { 2,-2,10, 2,-1,10, 2, 1,10, 2, 2,10}, { 2,-1, 1, 2, 1, 7                  }} ),
+        new ScrambleState( new int[][] {{ 0,-2,11, 0,-1,11, 0, 1,11, 0, 2,11}, { 0,-1, 8, 0, 1, 2                  }, { 2,-1,14, 2, 1, 5                  }} ),
+        new ScrambleState( new int[][] {{ 2,-1, 3, 2, 1, 9                  }, { 0,-1, 6, 0, 1,15                  }, { 0,-2,12, 0,-1,12, 0, 1,12, 0, 2,12}} ),
+        new ScrambleState( new int[][] {{ 2, 1,10, 2, 2, 4                  }, { 2,-2,13, 2,-1,13, 2, 1,13, 2, 2,13}, {                                   }} ),
+        new ScrambleState( new int[][] {{ 0,-2,14, 0,-1,14, 0, 1,14, 0, 2,14}, {                                   }, { 2, 1,11, 2, 2, 5                  }} ),
+        new ScrambleState( new int[][] {{                                   }, { 0,-1,12, 0, 2, 6                  }, { 0,-2,15, 0,-1,15, 0, 1,15, 0, 2,15}} )
+        };
+      }
+
+    return mStates;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyBandagedAbstract.java b/src/main/java/org/distorted/objects/TwistyBandagedAbstract.java
index a410be79..5551b2ce 100644
--- a/src/main/java/org/distorted/objects/TwistyBandagedAbstract.java
+++ b/src/main/java/org/distorted/objects/TwistyBandagedAbstract.java
@@ -30,8 +30,6 @@ import org.distorted.library.mesh.MeshSquare;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 
-import java.util.Random;
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 abstract class TwistyBandagedAbstract extends TwistyObject
@@ -63,10 +61,6 @@ abstract class TwistyBandagedAbstract extends TwistyObject
   private static final int NUM_STICKERS = 4;
 
   private int[] mBasicAngle;
-  private int mCurrState;
-  private int mIndexExcluded;
-  private int[][] mScrambleTable;
-  private int[] mNumOccurences;
   private Static4D[] mQuats;
   private ObjectSticker[] mStickers;
   private Static4D[] mInitQuats;
@@ -466,57 +460,9 @@ abstract class TwistyBandagedAbstract extends TwistyObject
     return getNumLayers();
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeScrambling()
-    {
-    int numLayers = getNumLayers();
-
-    if( mScrambleTable ==null )
-      {
-      mScrambleTable = new int[NUM_AXIS][numLayers];
-      }
-    if( mNumOccurences ==null )
-      {
-      int max=0;
-
-      for (ScrambleState mState : mStates)
-        {
-        int tmp = mState.getTotal(-1);
-        if (max < tmp) max = tmp;
-        }
-
-      mNumOccurences = new int[max];
-      }
-
-    for(int i=0; i<NUM_AXIS; i++)
-      for(int j=0; j<numLayers; j++) mScrambleTable[i][j] = 0;
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // PUBLIC API
 
-  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
-    {
-    if( curr==0 )
-      {
-      mCurrState     = 0;
-      mIndexExcluded =-1;
-      initializeScrambling();
-      }
-
-    int[] info= mStates[mCurrState].getRandom(rnd, mIndexExcluded, mScrambleTable, mNumOccurences);
-
-    scramble[curr][0] = info[0];
-    scramble[curr][1] = info[1];
-    scramble[curr][2] = info[2];
-
-    mCurrState     = info[3];
-    mIndexExcluded = info[0];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
   public Static3D[] getRotationAxis()
     {
     return ROT_AXIS;
diff --git a/src/main/java/org/distorted/objects/TwistyBandagedEvil.java b/src/main/java/org/distorted/objects/TwistyBandagedEvil.java
index 8775fed6..7365c1e7 100644
--- a/src/main/java/org/distorted/objects/TwistyBandagedEvil.java
+++ b/src/main/java/org/distorted/objects/TwistyBandagedEvil.java
@@ -36,155 +36,166 @@ class TwistyBandagedEvil extends TwistyBandagedAbstract
                      DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
     {
     super(size, quat, texture, mesh, effects, moves, ObjectList.BAN4, res, scrWidth);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  ScrambleState[] getScrambleStates()
+    {
+    if( mStates==null )
+      {
+      mStates = new ScrambleState[]
+        {
+        new ScrambleState( new int[][] {{2, 1,  1,2,-1,  2}         , {2, 2,142,2,-1, 28}         , {0, 1,114}          }),   //0
+        new ScrambleState( new int[][] {{2, 2,  2}                  , {2,-1,143}                  , {}                  }),
+        new ScrambleState( new int[][] {{2, 2,  1}                  , {}                          , {0, 1,  3,0, 2, 47} }),
+        new ScrambleState( new int[][] {{2, 1,  4}                  , {2, 1,132,2,-1,131}         , {0, 1, 47,0,-1,  2} }),
+        new ScrambleState( new int[][] {{2,-1,  3}                  , {2, 1,  5,2,-1,  6}         , {}                  }),
+        new ScrambleState( new int[][] {{}                          , {2, 2,  6,2,-1,  4}         , {0, 1, 51}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 1,  4,2, 2,  5}         , {2, 2,  7,2,-1, 80} }),
+        new ScrambleState( new int[][] {{2, 2,  8}                  , {}                          , {2, 1, 80,2, 2,  6} }),
+        new ScrambleState( new int[][] {{2, 2,  7}                  , {}                          , {0,-1,  9}          }),
+        new ScrambleState( new int[][] {{2, 1, 10,2, 2, 11,2,-1, 12}, {}                          , {0, 1,  8}          }),
+        new ScrambleState( new int[][] {{2, 1, 11,2, 2, 12,2,-1,  9}, {}                          , {0,-1,118}          }),   //10
+        new ScrambleState( new int[][] {{2, 1, 12,2, 2,  9,2,-1, 10}, {}                          , {2, 1, 77}          }),
+        new ScrambleState( new int[][] {{2, 1,  9,2, 2, 10,2,-1, 11}, {}                          , {2, 1, 13,2, 2,143} }),
+        new ScrambleState( new int[][] {{2, 1, 14,2, 2, 15,2,-1, 16}, {2, 1, 57,2,-1, 58}         , {2, 1,143,2,-1, 12} }),
+        new ScrambleState( new int[][] {{2, 1, 15,2, 2, 16,2,-1, 13}, {}                          , {2, 1, 41}          }),
+        new ScrambleState( new int[][] {{2, 1, 16,2, 2, 13,2,-1, 14}, {}                          , {0, 1, 82}          }),
+        new ScrambleState( new int[][] {{2, 1, 13,2, 2, 14,2,-1, 15}, {2, 1, 17,2,-1, 18}         , {0, 1,111,0,-1,115} }),
+        new ScrambleState( new int[][] {{}                          , {2, 2, 18,2,-1, 16}         , {0,-1,139}          }),
+        new ScrambleState( new int[][] {{2, 1, 19,2,-1, 20}         , {2, 1, 16,2, 2, 17}         , {2, 1,142}          }),
+        new ScrambleState( new int[][] {{2, 2, 20,2,-1, 18}         , {}                          , {2, 1, 39,2, 2,140} }),
+        new ScrambleState( new int[][] {{2, 1, 18,2, 2, 19}         , {2, 1, 21}                  , {}                  }),   //20
+        new ScrambleState( new int[][] {{}                          , {2,-1, 20}                  , {0,-1, 22}          }),
+        new ScrambleState( new int[][] {{2, 2, 23,2,-1, 24}         , {}                          , {0, 1, 21}          }),
+        new ScrambleState( new int[][] {{2, 1, 24,2, 2, 22}         , {}                          , {2, 1, 92}          }),
+        new ScrambleState( new int[][] {{2, 1, 22,2,-1, 23}         , {}                          , {0, 1, 25}          }),
+        new ScrambleState( new int[][] {{2, 1, 26,2, 2, 27}         , {}                          , {0,-1, 24}          }),
+        new ScrambleState( new int[][] {{2, 1, 27,2,-1, 25}         , {2, 1, 74}                  , {}                  }),
+        new ScrambleState( new int[][] {{2, 2, 25,2,-1, 26}         , {}                          , {2, 1, 28,2, 2,124} }),
+        new ScrambleState( new int[][] {{2, 1, 29,2, 2, 30,2,-1, 31}, {2,-1,142}                  , {2, 1,124,2,-1, 27} }),
+        new ScrambleState( new int[][] {{2, 1, 30,2, 2, 31,2,-1, 28}, {}                          , {2, 1,141}          }),
+        new ScrambleState( new int[][] {{2, 1, 31,2, 2, 28,2,-1, 29}, {}                          , {0, 1,130}          }),   //30
+        new ScrambleState( new int[][] {{2, 1, 28,2, 2, 29,2,-1, 30}, {2, 1, 32,2,-1, 33}         , {0, 1, 89,0,-1, 90} }),
+        new ScrambleState( new int[][] {{}                          , {2, 2, 33,2,-1, 31}         , {0,-1,137}          }),
+        new ScrambleState( new int[][] {{2, 1, 34}                  , {2, 1, 31,2, 2, 32}         , {}                  }),
+        new ScrambleState( new int[][] {{2,-1, 33}                  , {}                          , {2, 1, 35}          }),
+        new ScrambleState( new int[][] {{}                          , {2,-1, 36}                  , {2,-1, 34}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 1, 35}                  , {2,-1, 37}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 1, 38,2, 2, 93}         , {2, 1, 36}          }),
+        new ScrambleState( new int[][] {{2, 1, 39}                  , {2, 1, 93,2,-1, 37}         , {}                  }),
+        new ScrambleState( new int[][] {{2,-1, 38}                  , {2, 1, 40,2,-1, 64}         , {2, 1,140,2,-1, 19} }),
+        new ScrambleState( new int[][] {{2, 1, 41,2,-1, 42}         , {2, 2, 64,2,-1, 39}         , {}                  }),   //40
+        new ScrambleState( new int[][] {{2, 2, 42,2,-1, 40}         , {}                          , {2,-1, 14}          }),
+        new ScrambleState( new int[][] {{2, 1, 40,2, 2, 41}         , {}                          , {0, 1, 43,0, 2,128} }),
+        new ScrambleState( new int[][] {{2, 1, 44,2,-1, 45}         , {2, 1,114,2, 2,113,2,-1, 86}, {0, 1,128,0,-1, 42} }),
+        new ScrambleState( new int[][] {{2, 2, 45,2,-1, 43}         , {2, 1, 48,2,-1,108}         , {2,-1, 81}          }),
+        new ScrambleState( new int[][] {{2, 1, 43,2, 2, 44}         , {}                          , {0, 1, 46}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 1, 47}                  , {0,-1, 45}          }),
+        new ScrambleState( new int[][] {{}                          , {2,-1, 46}                  , {0, 2,  2,0,-1,  3} }),
+        new ScrambleState( new int[][] {{2,-1, 49}                  , {2, 2,108,2,-1, 44}         , {}                  }),
+        new ScrambleState( new int[][] {{2, 1, 48}                  , {}                          , {0, 1, 50}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 1, 51,2, 2, 52}         , {0,-1, 49}          }),   //50
+        new ScrambleState( new int[][] {{}                          , {2, 1, 52,2,-1, 50}         , {0,-1,  5}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 2, 50,2,-1, 51}         , {2,-1, 53}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 1, 54,2, 2, 55}         , {2, 1, 52}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 1, 55,2,-1, 53}         , {0,-1,104}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 2, 53,2,-1, 54}         , {0, 2, 56,0,-1, 65} }),
+        new ScrambleState( new int[][] {{2, 1, 57}                  , {}                          , {0, 1, 65,0, 2, 55} }),
+        new ScrambleState( new int[][] {{2,-1, 56}                  , {2, 2, 58,2,-1, 13}         , {}                  }),
+        new ScrambleState( new int[][] {{}                          , {2, 1, 13,2, 2, 57}         , {2,-1, 59}          }),
+        new ScrambleState( new int[][] {{2, 1, 60}                  , {}                          , {2, 1, 58}          }),
+        new ScrambleState( new int[][] {{2,-1, 59}                  , {}                          , {2, 1, 61}          }),   //60
+        new ScrambleState( new int[][] {{2,-1, 62}                  , {}                          , {2,-1, 60}          }),
+        new ScrambleState( new int[][] {{2, 1, 61}                  , {2,-1, 63}                  , {}                  }),
+        new ScrambleState( new int[][] {{}                          , {2, 1, 62}                  , {2, 1, 64}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 1, 39,2, 2, 40}         , {2,-1, 63}          }),
+        new ScrambleState( new int[][] {{2, 1, 66,2,-1, 67}         , {2, 1, 78,2, 2, 79,2,-1, 80}, {0, 1, 55,0,-1, 56} }),
+        new ScrambleState( new int[][] {{2, 2, 67,2,-1, 65}         , {2,-1,107}                  , {}                  }),
+        new ScrambleState( new int[][] {{2, 1, 65,2, 2, 66}         , {}                          , {0, 1, 68}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 1, 69}                  , {0,-1, 67}          }),
+        new ScrambleState( new int[][] {{}                          , {2,-1, 68}                  , {0,-1, 70}          }),
+        new ScrambleState( new int[][] {{}                          , {2,-1, 71}                  , {0, 1, 69}          }),   //70
+        new ScrambleState( new int[][] {{2,-1, 72}                  , {2, 1, 70}                  , {}                  }),
+        new ScrambleState( new int[][] {{2, 1, 71}                  , {}                          , {0,-1, 73}          }),
+        new ScrambleState( new int[][] {{2, 1, 74,2, 2, 75}         , {}                          , {0, 1, 72}          }),
+        new ScrambleState( new int[][] {{2, 1, 75,2,-1, 73}         , {2,-1, 26}                  , {0, 1, 83,0,-1,138} }),
+        new ScrambleState( new int[][] {{2, 2, 73,2,-1, 74}         , {2, 1, 76,2,-1, 77}         , {}                  }),
+        new ScrambleState( new int[][] {{}                          , {2, 2, 77,2,-1, 75}         , {0, 1, 78}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 1, 75,2, 2, 76}         , {2,-1, 11}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 1, 79,2, 2, 80,2,-1, 65}, {0,-1, 76}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 1, 80,2, 2, 65,2,-1, 78}, {2,-1,110}          }),
+        new ScrambleState( new int[][] {{2, 1, 81,2,-1, 82}         , {2, 1, 65,2, 2, 78,2,-1, 79}, {2, 1,  6,2,-1,  7} }),   //80
+        new ScrambleState( new int[][] {{2, 2, 82,2,-1, 80}         , {}                          , {2, 1, 44}          }),
+        new ScrambleState( new int[][] {{2, 1, 80,2, 2, 81}         , {2, 1, 83,2,-1, 84}         , {0,-1, 15}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 2, 84,2,-1, 82}         , {0, 2,138,0,-1, 74} }),
+        new ScrambleState( new int[][] {{2, 1, 85}                  , {2, 1, 82,2, 2, 83}         , {}                  }),
+        new ScrambleState( new int[][] {{2,-1, 84}                  , {}                          , {2, 1, 86,2, 2,119} }),
+        new ScrambleState( new int[][] {{2, 1, 87,2,-1, 88}         , {2, 1, 43,2, 2,114,2,-1,113}, {2, 1,119,2,-1, 85} }),
+        new ScrambleState( new int[][] {{2, 2, 88,2,-1, 86}         , {}                          , {2, 1, 94}          }),
+        new ScrambleState( new int[][] {{2, 1, 86,2, 2, 87}         , {2, 1, 89}                  , {}                  }),
+        new ScrambleState( new int[][] {{}                          , {2,-1, 88}                  , {0, 2, 90,0,-1, 31} }),
+        new ScrambleState( new int[][] {{2, 1, 91,2, 2, 92}         , {}                          , {0, 1, 31,0, 2, 89} }),   //90
+        new ScrambleState( new int[][] {{2, 1, 92,2,-1, 90}         , {}                          , {0, 1, 93}          }),
+        new ScrambleState( new int[][] {{2, 2, 90,2,-1, 91}         , {}                          , {2,-1, 23}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 2, 37,2,-1, 38}         , {0,-1, 91}          }),
+        new ScrambleState( new int[][] {{}                          , {2,-1, 95}                  , {2,-1, 87}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 1, 94}                  , {2,-1, 96}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 1, 97}                  , {2, 1, 95}          }),
+        new ScrambleState( new int[][] {{2, 1, 98}                  , {2,-1, 96}                  , {}                  }),
+        new ScrambleState( new int[][] {{2,-1, 97}                  , {}                          , {2,-1, 99}          }),
+        new ScrambleState( new int[][] {{2, 2,100,2,-1,101}         , {}                          , {2, 1, 98}          }),
+        new ScrambleState( new int[][] {{2, 1,101,2, 2, 99}         , {2, 1,111,2,-1,112}         , {}                  }),   //100
+        new ScrambleState( new int[][] {{2, 1, 99,2,-1,100}         , {2, 1,102}                  , {2, 1,108,2,-1,109} }),
+        new ScrambleState( new int[][] {{2, 1,103,2,-1,104}         , {2,-1,101}                  , {}                  }),
+        new ScrambleState( new int[][] {{2, 2,104,2,-1,102}         , {}                          , {2,-1,105}          }),
+        new ScrambleState( new int[][] {{2, 1,102,2, 2,103}         , {}                          , {0, 1, 54}          }),
+        new ScrambleState( new int[][] {{2,-1,106}                  , {}                          , {2, 1,103}          }),
+        new ScrambleState( new int[][] {{2, 1,105}                  , {}                          , {2, 1,107}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 1, 66}                  , {2,-1,106}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 1, 44,2, 2, 48}         , {2, 2,109,2,-1,101} }),
+        new ScrambleState( new int[][] {{2,-1,110}                  , {}                          , {2, 1,101,2, 2,108} }),
+        new ScrambleState( new int[][] {{2, 1,109}                  , {}                          , {2, 1, 79}          }),   //110
+        new ScrambleState( new int[][] {{}                          , {2, 2,112,2,-1,100}         , {0, 2,115,0,-1, 16} }),
+        new ScrambleState( new int[][] {{}                          , {2, 1,100,2, 2,111}         , {2, 1,113}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 1, 86,2, 2, 43,2,-1,114}, {2,-1,112}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 1,113,2, 2, 86,2,-1, 43}, {0,-1,  0}          }),
+        new ScrambleState( new int[][] {{2, 2,116}                  , {}                          , {0, 1, 16,0, 2,111} }),
+        new ScrambleState( new int[][] {{2, 2,115}                  , {}                          , {2,-1,117}          }),
+        new ScrambleState( new int[][] {{2, 1,118}                  , {}                          , {2, 1,116}          }),
+        new ScrambleState( new int[][] {{2,-1,117}                  , {}                          , {0, 1, 10}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 1,120,2, 2,121,2,-1,122}, {2, 2, 85,2,-1, 86} }),
+        new ScrambleState( new int[][] {{}                          , {2, 1,121,2, 2,122,2,-1,119}, {2,-1,129}          }),   //120
+        new ScrambleState( new int[][] {{}                          , {2, 1,122,2, 2,119,2,-1,120}, {0, 1,125}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 1,119,2, 2,120,2,-1,121}, {0,-1,123}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 2,124}                  , {0, 1,122}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 2,123}                  , {2, 2, 27,2,-1, 28} }),
+        new ScrambleState( new int[][] {{}                          , {2, 1,126}                  , {0,-1,121}          }),
+        new ScrambleState( new int[][] {{}                          , {2,-1,125}                  , {2,-1,127}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 2,128}                  , {2, 1,126}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 2,127}                  , {0, 2, 42,0,-1, 43} }),
+        new ScrambleState( new int[][] {{2, 2,130,2,-1,131}         , {}                          , {2, 1,120}          }),
+        new ScrambleState( new int[][] {{2, 1,131,2, 2,129}         , {}                          , {0,-1, 30}          }),   //130
+        new ScrambleState( new int[][] {{2, 1,129,2,-1,130}         , {2, 1,  3,2, 2,132}         , {}                  }),
+        new ScrambleState( new int[][] {{}                          , {2, 2,131,2,-1,  3}         , {0,-1,133}          }),
+        new ScrambleState( new int[][] {{}                          , {2,-1,134}                  , {0, 1,132}          }),
+        new ScrambleState( new int[][] {{2,-1,135}                  , {2, 1,133}                  , {}                  }),
+        new ScrambleState( new int[][] {{2, 1,134}                  , {}                          , {0,-1,136}          }),
+        new ScrambleState( new int[][] {{2, 1,137}                  , {}                          , {0, 1,135}          }),
+        new ScrambleState( new int[][] {{2,-1,136}                  , {}                          , {0, 1, 32}          }),
+        new ScrambleState( new int[][] {{2, 1,139}                  , {}                          , {0, 1, 74,0, 2, 83} }),
+        new ScrambleState( new int[][] {{2,-1,138}                  , {}                          , {0, 1, 17}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 1,141}                  , {2, 2, 19,2,-1, 39} }),   //140
+        new ScrambleState( new int[][] {{}                          , {2,-1,140}                  , {2,-1, 29}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 1, 28}                  , {2,-1, 18}          }),
+        new ScrambleState( new int[][] {{}                          , {2, 1,  1}                  , {2, 2, 12,2,-1, 13} })
+        };
+      }
 
-    mStates = new ScrambleState[]
-     {
-     new ScrambleState( new int[][] {{2, 1,  1,2,-1,  2}         , {2, 2,142,2,-1, 28}         , {0, 1,114}          }),   //0
-     new ScrambleState( new int[][] {{2, 2,  2}                  , {2,-1,143}                  , {}                  }),
-     new ScrambleState( new int[][] {{2, 2,  1}                  , {}                          , {0, 1,  3,0, 2, 47} }),
-     new ScrambleState( new int[][] {{2, 1,  4}                  , {2, 1,132,2,-1,131}         , {0, 1, 47,0,-1,  2} }),
-     new ScrambleState( new int[][] {{2,-1,  3}                  , {2, 1,  5,2,-1,  6}         , {}                  }),
-     new ScrambleState( new int[][] {{}                          , {2, 2,  6,2,-1,  4}         , {0, 1, 51}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 1,  4,2, 2,  5}         , {2, 2,  7,2,-1, 80} }),
-     new ScrambleState( new int[][] {{2, 2,  8}                  , {}                          , {2, 1, 80,2, 2,  6} }),
-     new ScrambleState( new int[][] {{2, 2,  7}                  , {}                          , {0,-1,  9}          }),
-     new ScrambleState( new int[][] {{2, 1, 10,2, 2, 11,2,-1, 12}, {}                          , {0, 1,  8}          }),
-     new ScrambleState( new int[][] {{2, 1, 11,2, 2, 12,2,-1,  9}, {}                          , {0,-1,118}          }),   //10
-     new ScrambleState( new int[][] {{2, 1, 12,2, 2,  9,2,-1, 10}, {}                          , {2, 1, 77}          }),
-     new ScrambleState( new int[][] {{2, 1,  9,2, 2, 10,2,-1, 11}, {}                          , {2, 1, 13,2, 2,143} }),
-     new ScrambleState( new int[][] {{2, 1, 14,2, 2, 15,2,-1, 16}, {2, 1, 57,2,-1, 58}         , {2, 1,143,2,-1, 12} }),
-     new ScrambleState( new int[][] {{2, 1, 15,2, 2, 16,2,-1, 13}, {}                          , {2, 1, 41}          }),
-     new ScrambleState( new int[][] {{2, 1, 16,2, 2, 13,2,-1, 14}, {}                          , {0, 1, 82}          }),
-     new ScrambleState( new int[][] {{2, 1, 13,2, 2, 14,2,-1, 15}, {2, 1, 17,2,-1, 18}         , {0, 1,111,0,-1,115} }),
-     new ScrambleState( new int[][] {{}                          , {2, 2, 18,2,-1, 16}         , {0,-1,139}          }),
-     new ScrambleState( new int[][] {{2, 1, 19,2,-1, 20}         , {2, 1, 16,2, 2, 17}         , {2, 1,142}          }),
-     new ScrambleState( new int[][] {{2, 2, 20,2,-1, 18}         , {}                          , {2, 1, 39,2, 2,140} }),
-     new ScrambleState( new int[][] {{2, 1, 18,2, 2, 19}         , {2, 1, 21}                  , {}                  }),   //20
-     new ScrambleState( new int[][] {{}                          , {2,-1, 20}                  , {0,-1, 22}          }),
-     new ScrambleState( new int[][] {{2, 2, 23,2,-1, 24}         , {}                          , {0, 1, 21}          }),
-     new ScrambleState( new int[][] {{2, 1, 24,2, 2, 22}         , {}                          , {2, 1, 92}          }),
-     new ScrambleState( new int[][] {{2, 1, 22,2,-1, 23}         , {}                          , {0, 1, 25}          }),
-     new ScrambleState( new int[][] {{2, 1, 26,2, 2, 27}         , {}                          , {0,-1, 24}          }),
-     new ScrambleState( new int[][] {{2, 1, 27,2,-1, 25}         , {2, 1, 74}                  , {}                  }),
-     new ScrambleState( new int[][] {{2, 2, 25,2,-1, 26}         , {}                          , {2, 1, 28,2, 2,124} }),
-     new ScrambleState( new int[][] {{2, 1, 29,2, 2, 30,2,-1, 31}, {2,-1,142}                  , {2, 1,124,2,-1, 27} }),
-     new ScrambleState( new int[][] {{2, 1, 30,2, 2, 31,2,-1, 28}, {}                          , {2, 1,141}          }),
-     new ScrambleState( new int[][] {{2, 1, 31,2, 2, 28,2,-1, 29}, {}                          , {0, 1,130}          }),   //30
-     new ScrambleState( new int[][] {{2, 1, 28,2, 2, 29,2,-1, 30}, {2, 1, 32,2,-1, 33}         , {0, 1, 89,0,-1, 90} }),
-     new ScrambleState( new int[][] {{}                          , {2, 2, 33,2,-1, 31}         , {0,-1,137}          }),
-     new ScrambleState( new int[][] {{2, 1, 34}                  , {2, 1, 31,2, 2, 32}         , {}                  }),
-     new ScrambleState( new int[][] {{2,-1, 33}                  , {}                          , {2, 1, 35}          }),
-     new ScrambleState( new int[][] {{}                          , {2,-1, 36}                  , {2,-1, 34}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 1, 35}                  , {2,-1, 37}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 1, 38,2, 2, 93}         , {2, 1, 36}          }),
-     new ScrambleState( new int[][] {{2, 1, 39}                  , {2, 1, 93,2,-1, 37}         , {}                  }),
-     new ScrambleState( new int[][] {{2,-1, 38}                  , {2, 1, 40,2,-1, 64}         , {2, 1,140,2,-1, 19} }),
-     new ScrambleState( new int[][] {{2, 1, 41,2,-1, 42}         , {2, 2, 64,2,-1, 39}         , {}                  }),   //40
-     new ScrambleState( new int[][] {{2, 2, 42,2,-1, 40}         , {}                          , {2,-1, 14}          }),
-     new ScrambleState( new int[][] {{2, 1, 40,2, 2, 41}         , {}                          , {0, 1, 43,0, 2,128} }),
-     new ScrambleState( new int[][] {{2, 1, 44,2,-1, 45}         , {2, 1,114,2, 2,113,2,-1, 86}, {0, 1,128,0,-1, 42} }),
-     new ScrambleState( new int[][] {{2, 2, 45,2,-1, 43}         , {2, 1, 48,2,-1,108}         , {2,-1, 81}          }),
-     new ScrambleState( new int[][] {{2, 1, 43,2, 2, 44}         , {}                          , {0, 1, 46}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 1, 47}                  , {0,-1, 45}          }),
-     new ScrambleState( new int[][] {{}                          , {2,-1, 46}                  , {0, 2,  2,0,-1,  3} }),
-     new ScrambleState( new int[][] {{2,-1, 49}                  , {2, 2,108,2,-1, 44}         , {}                  }),
-     new ScrambleState( new int[][] {{2, 1, 48}                  , {}                          , {0, 1, 50}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 1, 51,2, 2, 52}         , {0,-1, 49}          }),   //50
-     new ScrambleState( new int[][] {{}                          , {2, 1, 52,2,-1, 50}         , {0,-1,  5}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 2, 50,2,-1, 51}         , {2,-1, 53}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 1, 54,2, 2, 55}         , {2, 1, 52}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 1, 55,2,-1, 53}         , {0,-1,104}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 2, 53,2,-1, 54}         , {0, 2, 56,0,-1, 65} }),
-     new ScrambleState( new int[][] {{2, 1, 57}                  , {}                          , {0, 1, 65,0, 2, 55} }),
-     new ScrambleState( new int[][] {{2,-1, 56}                  , {2, 2, 58,2,-1, 13}         , {}                  }),
-     new ScrambleState( new int[][] {{}                          , {2, 1, 13,2, 2, 57}         , {2,-1, 59}          }),
-     new ScrambleState( new int[][] {{2, 1, 60}                  , {}                          , {2, 1, 58}          }),
-     new ScrambleState( new int[][] {{2,-1, 59}                  , {}                          , {2, 1, 61}          }),   //60
-     new ScrambleState( new int[][] {{2,-1, 62}                  , {}                          , {2,-1, 60}          }),
-     new ScrambleState( new int[][] {{2, 1, 61}                  , {2,-1, 63}                  , {}                  }),
-     new ScrambleState( new int[][] {{}                          , {2, 1, 62}                  , {2, 1, 64}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 1, 39,2, 2, 40}         , {2,-1, 63}          }),
-     new ScrambleState( new int[][] {{2, 1, 66,2,-1, 67}         , {2, 1, 78,2, 2, 79,2,-1, 80}, {0, 1, 55,0,-1, 56} }),
-     new ScrambleState( new int[][] {{2, 2, 67,2,-1, 65}         , {2,-1,107}                  , {}                  }),
-     new ScrambleState( new int[][] {{2, 1, 65,2, 2, 66}         , {}                          , {0, 1, 68}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 1, 69}                  , {0,-1, 67}          }),
-     new ScrambleState( new int[][] {{}                          , {2,-1, 68}                  , {0,-1, 70}          }),
-     new ScrambleState( new int[][] {{}                          , {2,-1, 71}                  , {0, 1, 69}          }),   //70
-     new ScrambleState( new int[][] {{2,-1, 72}                  , {2, 1, 70}                  , {}                  }),
-     new ScrambleState( new int[][] {{2, 1, 71}                  , {}                          , {0,-1, 73}          }),
-     new ScrambleState( new int[][] {{2, 1, 74,2, 2, 75}         , {}                          , {0, 1, 72}          }),
-     new ScrambleState( new int[][] {{2, 1, 75,2,-1, 73}         , {2,-1, 26}                  , {0, 1, 83,0,-1,138} }),
-     new ScrambleState( new int[][] {{2, 2, 73,2,-1, 74}         , {2, 1, 76,2,-1, 77}         , {}                  }),
-     new ScrambleState( new int[][] {{}                          , {2, 2, 77,2,-1, 75}         , {0, 1, 78}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 1, 75,2, 2, 76}         , {2,-1, 11}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 1, 79,2, 2, 80,2,-1, 65}, {0,-1, 76}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 1, 80,2, 2, 65,2,-1, 78}, {2,-1,110}          }),
-     new ScrambleState( new int[][] {{2, 1, 81,2,-1, 82}         , {2, 1, 65,2, 2, 78,2,-1, 79}, {2, 1,  6,2,-1,  7} }),   //80
-     new ScrambleState( new int[][] {{2, 2, 82,2,-1, 80}         , {}                          , {2, 1, 44}          }),
-     new ScrambleState( new int[][] {{2, 1, 80,2, 2, 81}         , {2, 1, 83,2,-1, 84}         , {0,-1, 15}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 2, 84,2,-1, 82}         , {0, 2,138,0,-1, 74} }),
-     new ScrambleState( new int[][] {{2, 1, 85}                  , {2, 1, 82,2, 2, 83}         , {}                  }),
-     new ScrambleState( new int[][] {{2,-1, 84}                  , {}                          , {2, 1, 86,2, 2,119} }),
-     new ScrambleState( new int[][] {{2, 1, 87,2,-1, 88}         , {2, 1, 43,2, 2,114,2,-1,113}, {2, 1,119,2,-1, 85} }),
-     new ScrambleState( new int[][] {{2, 2, 88,2,-1, 86}         , {}                          , {2, 1, 94}          }),
-     new ScrambleState( new int[][] {{2, 1, 86,2, 2, 87}         , {2, 1, 89}                  , {}                  }),
-     new ScrambleState( new int[][] {{}                          , {2,-1, 88}                  , {0, 2, 90,0,-1, 31} }),
-     new ScrambleState( new int[][] {{2, 1, 91,2, 2, 92}         , {}                          , {0, 1, 31,0, 2, 89} }),   //90
-     new ScrambleState( new int[][] {{2, 1, 92,2,-1, 90}         , {}                          , {0, 1, 93}          }),
-     new ScrambleState( new int[][] {{2, 2, 90,2,-1, 91}         , {}                          , {2,-1, 23}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 2, 37,2,-1, 38}         , {0,-1, 91}          }),
-     new ScrambleState( new int[][] {{}                          , {2,-1, 95}                  , {2,-1, 87}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 1, 94}                  , {2,-1, 96}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 1, 97}                  , {2, 1, 95}          }),
-     new ScrambleState( new int[][] {{2, 1, 98}                  , {2,-1, 96}                  , {}                  }),
-     new ScrambleState( new int[][] {{2,-1, 97}                  , {}                          , {2,-1, 99}          }),
-     new ScrambleState( new int[][] {{2, 2,100,2,-1,101}         , {}                          , {2, 1, 98}          }),
-     new ScrambleState( new int[][] {{2, 1,101,2, 2, 99}         , {2, 1,111,2,-1,112}         , {}                  }),   //100
-     new ScrambleState( new int[][] {{2, 1, 99,2,-1,100}         , {2, 1,102}                  , {2, 1,108,2,-1,109} }),
-     new ScrambleState( new int[][] {{2, 1,103,2,-1,104}         , {2,-1,101}                  , {}                  }),
-     new ScrambleState( new int[][] {{2, 2,104,2,-1,102}         , {}                          , {2,-1,105}          }),
-     new ScrambleState( new int[][] {{2, 1,102,2, 2,103}         , {}                          , {0, 1, 54}          }),
-     new ScrambleState( new int[][] {{2,-1,106}                  , {}                          , {2, 1,103}          }),
-     new ScrambleState( new int[][] {{2, 1,105}                  , {}                          , {2, 1,107}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 1, 66}                  , {2,-1,106}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 1, 44,2, 2, 48}         , {2, 2,109,2,-1,101} }),
-     new ScrambleState( new int[][] {{2,-1,110}                  , {}                          , {2, 1,101,2, 2,108} }),
-     new ScrambleState( new int[][] {{2, 1,109}                  , {}                          , {2, 1, 79}          }),   //110
-     new ScrambleState( new int[][] {{}                          , {2, 2,112,2,-1,100}         , {0, 2,115,0,-1, 16} }),
-     new ScrambleState( new int[][] {{}                          , {2, 1,100,2, 2,111}         , {2, 1,113}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 1, 86,2, 2, 43,2,-1,114}, {2,-1,112}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 1,113,2, 2, 86,2,-1, 43}, {0,-1,  0}          }),
-     new ScrambleState( new int[][] {{2, 2,116}                  , {}                          , {0, 1, 16,0, 2,111} }),
-     new ScrambleState( new int[][] {{2, 2,115}                  , {}                          , {2,-1,117}          }),
-     new ScrambleState( new int[][] {{2, 1,118}                  , {}                          , {2, 1,116}          }),
-     new ScrambleState( new int[][] {{2,-1,117}                  , {}                          , {0, 1, 10}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 1,120,2, 2,121,2,-1,122}, {2, 2, 85,2,-1, 86} }),
-     new ScrambleState( new int[][] {{}                          , {2, 1,121,2, 2,122,2,-1,119}, {2,-1,129}          }),   //120
-     new ScrambleState( new int[][] {{}                          , {2, 1,122,2, 2,119,2,-1,120}, {0, 1,125}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 1,119,2, 2,120,2,-1,121}, {0,-1,123}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 2,124}                  , {0, 1,122}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 2,123}                  , {2, 2, 27,2,-1, 28} }),
-     new ScrambleState( new int[][] {{}                          , {2, 1,126}                  , {0,-1,121}          }),
-     new ScrambleState( new int[][] {{}                          , {2,-1,125}                  , {2,-1,127}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 2,128}                  , {2, 1,126}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 2,127}                  , {0, 2, 42,0,-1, 43} }),
-     new ScrambleState( new int[][] {{2, 2,130,2,-1,131}         , {}                          , {2, 1,120}          }),
-     new ScrambleState( new int[][] {{2, 1,131,2, 2,129}         , {}                          , {0,-1, 30}          }),   //130
-     new ScrambleState( new int[][] {{2, 1,129,2,-1,130}         , {2, 1,  3,2, 2,132}         , {}                  }),
-     new ScrambleState( new int[][] {{}                          , {2, 2,131,2,-1,  3}         , {0,-1,133}          }),
-     new ScrambleState( new int[][] {{}                          , {2,-1,134}                  , {0, 1,132}          }),
-     new ScrambleState( new int[][] {{2,-1,135}                  , {2, 1,133}                  , {}                  }),
-     new ScrambleState( new int[][] {{2, 1,134}                  , {}                          , {0,-1,136}          }),
-     new ScrambleState( new int[][] {{2, 1,137}                  , {}                          , {0, 1,135}          }),
-     new ScrambleState( new int[][] {{2,-1,136}                  , {}                          , {0, 1, 32}          }),
-     new ScrambleState( new int[][] {{2, 1,139}                  , {}                          , {0, 1, 74,0, 2, 83} }),
-     new ScrambleState( new int[][] {{2,-1,138}                  , {}                          , {0, 1, 17}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 1,141}                  , {2, 2, 19,2,-1, 39} }),   //140
-     new ScrambleState( new int[][] {{}                          , {2,-1,140}                  , {2,-1, 29}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 1, 28}                  , {2,-1, 18}          }),
-     new ScrambleState( new int[][] {{}                          , {2, 1,  1}                  , {2, 2, 12,2,-1, 13} })
-     };
+    return mStates;
     }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   float[][] getPositions()
diff --git a/src/main/java/org/distorted/objects/TwistyBandagedFused.java b/src/main/java/org/distorted/objects/TwistyBandagedFused.java
index e00009f6..f8febc7d 100644
--- a/src/main/java/org/distorted/objects/TwistyBandagedFused.java
+++ b/src/main/java/org/distorted/objects/TwistyBandagedFused.java
@@ -36,13 +36,23 @@ class TwistyBandagedFused extends TwistyBandagedAbstract
                       DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
     {
     super(size, quat, texture, mesh, effects, moves, ObjectList.BAN1, res, scrWidth);
+    }
 
-    int[] tmp = {0,-1,0, 0,1,0, 0,2,0, 2,-1,0, 2,1,0, 2,2,0};
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    mStates = new ScrambleState[]
+  ScrambleState[] getScrambleStates()
+    {
+    if( mStates==null )
       {
-      new ScrambleState( new int[][] {tmp,tmp,tmp} )
-      };
+      int[] tmp = {0,-1,0, 0,1,0, 0,2,0, 2,-1,0, 2,1,0, 2,2,0};
+
+      mStates = new ScrambleState[]
+        {
+        new ScrambleState( new int[][] {tmp,tmp,tmp} )
+        };
+      }
+
+    return mStates;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyCube.java b/src/main/java/org/distorted/objects/TwistyCube.java
index 812dfb45..a8b38fa0 100644
--- a/src/main/java/org/distorted/objects/TwistyCube.java
+++ b/src/main/java/org/distorted/objects/TwistyCube.java
@@ -31,8 +31,6 @@ import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 import org.distorted.main.R;
 
-import java.util.Random;
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 class TwistyCube extends TwistyObject
@@ -51,11 +49,7 @@ class TwistyCube extends TwistyObject
            COLOR_RED   , COLOR_ORANGE
          };
 
-  private int mCurrState;
-  private int mIndexExcluded;
-  private final ScrambleState[] mStates;
-  private int[][] mScrambleTable;
-  private int[] mNumOccurences;
+  private ScrambleState[] mStates;
   private Static4D[] mQuats;
   private int[] mBasicAngle;
   private ObjectSticker[] mStickers;
@@ -66,29 +60,40 @@ class TwistyCube extends TwistyObject
              DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
     {
     super(size, size, quat, texture, mesh, effects, moves, ObjectList.CUBE, res, scrWidth);
+    }
 
-    int[][] m = new int[16][];
-    for(int i=1; i<16; i++) m[i] = createEdges(size,i);
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    mStates = new ScrambleState[]  // built so that all 3 axes must be present in every 4 consecutive moves
+  ScrambleState[] getScrambleStates()
+    {
+    if( mStates==null )
       {
-      new ScrambleState( new int[][] { m[ 1], m[ 2], m[ 3] } ),  // 0
-      new ScrambleState( new int[][] {  null, m[ 4], m[ 5] } ),  // x
-      new ScrambleState( new int[][] { m[ 6],  null, m[ 7] } ),  // y
-      new ScrambleState( new int[][] { m[ 8], m[ 8],  null } ),  // z
-      new ScrambleState( new int[][] { m[10],  null, m[ 7] } ),  // xy
-      new ScrambleState( new int[][] { m[11], m[ 9],  null } ),  // xz
-      new ScrambleState( new int[][] {  null, m[12], m[ 5] } ),  // yx
-      new ScrambleState( new int[][] { m[ 8], m[13],  null } ),  // yz
-      new ScrambleState( new int[][] {  null, m[ 4], m[14] } ),  // zx
-      new ScrambleState( new int[][] { m[ 6],  null, m[15] } ),  // zy
-      new ScrambleState( new int[][] {  null,  null, m[ 5] } ),  // xyx
-      new ScrambleState( new int[][] {  null, m[ 4],  null } ),  // xzx
-      new ScrambleState( new int[][] {  null,  null, m[ 7] } ),  // yxy
-      new ScrambleState( new int[][] { m[ 6],  null,  null } ),  // yzy
-      new ScrambleState( new int[][] {  null, m[ 9],  null } ),  // zxz
-      new ScrambleState( new int[][] { m[ 8],  null,  null } ),  // zyz
-      };
+      int size = getNumLayers();
+      int[][] m = new int[16][];
+      for(int i=1; i<16; i++) m[i] = createEdges(size,i);
+
+      mStates = new ScrambleState[]
+        {
+        new ScrambleState( new int[][] { m[ 1], m[ 2], m[ 3] } ),  // 0
+        new ScrambleState( new int[][] {  null, m[ 4], m[ 5] } ),  // x
+        new ScrambleState( new int[][] { m[ 6],  null, m[ 7] } ),  // y
+        new ScrambleState( new int[][] { m[ 8], m[ 8],  null } ),  // z
+        new ScrambleState( new int[][] { m[10],  null, m[ 7] } ),  // xy
+        new ScrambleState( new int[][] { m[11], m[ 9],  null } ),  // xz
+        new ScrambleState( new int[][] {  null, m[12], m[ 5] } ),  // yx
+        new ScrambleState( new int[][] { m[ 8], m[13],  null } ),  // yz
+        new ScrambleState( new int[][] {  null, m[ 4], m[14] } ),  // zx
+        new ScrambleState( new int[][] { m[ 6],  null, m[15] } ),  // zy
+        new ScrambleState( new int[][] {  null,  null, m[ 5] } ),  // xyx
+        new ScrambleState( new int[][] {  null, m[ 4],  null } ),  // xzx
+        new ScrambleState( new int[][] {  null,  null, m[ 7] } ),  // yxy
+        new ScrambleState( new int[][] { m[ 6],  null,  null } ),  // yzy
+        new ScrambleState( new int[][] {  null, m[ 9],  null } ),  // zxz
+        new ScrambleState( new int[][] { m[ 8],  null,  null } ),  // zyz
+        };
+      }
+
+    return mStates;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -368,54 +373,6 @@ class TwistyCube extends TwistyObject
     return mBasicAngle;
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeScrambling()
-    {
-    int numLayers = getNumLayers();
-
-    if( mScrambleTable ==null )
-      {
-      mScrambleTable = new int[NUM_AXIS][numLayers];
-      }
-    if( mNumOccurences ==null )
-      {
-      int max=0;
-
-      for (ScrambleState mState : mStates)
-        {
-        int tmp = mState.getTotal(-1);
-        if (max < tmp) max = tmp;
-        }
-
-      mNumOccurences = new int[max];
-      }
-
-    for(int i=0; i<NUM_AXIS; i++)
-      for(int j=0; j<numLayers; j++) mScrambleTable[i][j] = 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
-    {
-    if( curr==0 )
-      {
-      mCurrState     = 0;
-      mIndexExcluded =-1;
-      initializeScrambling();
-      }
-
-    int[] info= mStates[mCurrState].getRandom(rnd, mIndexExcluded, mScrambleTable, mNumOccurences);
-
-    scramble[curr][0] = info[0];
-    scramble[curr][1] = info[1];
-    scramble[curr][2] = info[2];
-
-    mCurrState     = info[3];
-    mIndexExcluded = info[0];
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public int getObjectName(int numLayers)
diff --git a/src/main/java/org/distorted/objects/TwistyDiamond.java b/src/main/java/org/distorted/objects/TwistyDiamond.java
index d7ea3871..eb1fb177 100644
--- a/src/main/java/org/distorted/objects/TwistyDiamond.java
+++ b/src/main/java/org/distorted/objects/TwistyDiamond.java
@@ -31,8 +31,6 @@ import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 import org.distorted.main.R;
 
-import java.util.Random;
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class TwistyDiamond extends TwistyObject
@@ -57,11 +55,7 @@ public class TwistyDiamond extends TwistyObject
   private static final float DIST = 0.50f;
   private static final int FACES_PER_CUBIT =8;
 
-  private int mCurrState;
-  private int mIndexExcluded;
-  private final ScrambleState[] mStates;
-  private int[][] mScrambleTable;
-  private int[] mNumOccurences;
+  private ScrambleState[] mStates;
   private int[] mBasicAngle;
   private int[] mFaceMap;
   private Static4D[] mQuats;
@@ -74,20 +68,31 @@ public class TwistyDiamond extends TwistyObject
                 MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
     {
     super(size, size, quat, texture, mesh, effects, moves, ObjectList.DIAM, res, scrWidth);
+    }
 
-    int[] tmp = new int[3*2*size];
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    for(int i=0; i<2*size; i++)
+  ScrambleState[] getScrambleStates()
+    {
+    if( mStates==null )
       {
-      tmp[3*i  ] = (i<size) ?  i:i-size;
-      tmp[3*i+1] = (i%2==0) ? -1:1;
-      tmp[3*i+2] = 0;
+      int size = getNumLayers();
+      int[] tmp = new int[3*2*size];
+
+      for(int i=0; i<2*size; i++)
+        {
+        tmp[3*i  ] = (i<size) ?  i:i-size;
+        tmp[3*i+1] = (i%2==0) ? -1:1;
+        tmp[3*i+2] = 0;
+        }
+
+      mStates = new ScrambleState[]
+        {
+        new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
+        };
       }
 
-    mStates = new ScrambleState[]
-      {
-      new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
-      };
+    return mStates;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -507,57 +512,9 @@ public class TwistyDiamond extends TwistyObject
     return 1.5f;
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeScrambling()
-    {
-    int numLayers = getNumLayers();
-
-    if( mScrambleTable ==null )
-      {
-      mScrambleTable = new int[NUM_AXIS][numLayers];
-      }
-    if( mNumOccurences ==null )
-      {
-      int max=0;
-
-      for (ScrambleState mState : mStates)
-        {
-        int tmp = mState.getTotal(-1);
-        if (max < tmp) max = tmp;
-        }
-
-      mNumOccurences = new int[max];
-      }
-
-    for(int i=0; i<NUM_AXIS; i++)
-      for(int j=0; j<numLayers; j++) mScrambleTable[i][j] = 0;
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // PUBLIC API
 
-  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
-    {
-    if( curr==0 )
-      {
-      mCurrState     = 0;
-      mIndexExcluded =-1;
-      initializeScrambling();
-      }
-
-    int[] info= mStates[mCurrState].getRandom(rnd, mIndexExcluded, mScrambleTable, mNumOccurences);
-
-    scramble[curr][0] = info[0];
-    scramble[curr][1] = info[1];
-    scramble[curr][2] = info[2];
-
-    mCurrState     = info[3];
-    mIndexExcluded = info[0];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
   public Static3D[] getRotationAxis()
     {
     return ROT_AXIS;
diff --git a/src/main/java/org/distorted/objects/TwistyDino.java b/src/main/java/org/distorted/objects/TwistyDino.java
index 25075b81..a54f7007 100644
--- a/src/main/java/org/distorted/objects/TwistyDino.java
+++ b/src/main/java/org/distorted/objects/TwistyDino.java
@@ -30,8 +30,6 @@ import org.distorted.library.mesh.MeshSquare;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 
-import java.util.Random;
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public abstract class TwistyDino extends TwistyObject
@@ -52,10 +50,6 @@ public abstract class TwistyDino extends TwistyObject
            COLOR_RED   , COLOR_ORANGE
          };
 
-  private int mCurrState;
-  private int mIndexExcluded;
-  private int[][] mScrambleTable;
-  private int[] mNumOccurences;
   private int[] mBasicAngle;
   private Static4D[] mQuats;
   private ObjectSticker[] mStickers;
@@ -229,57 +223,9 @@ public abstract class TwistyDino extends TwistyObject
     return 2.0f;
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeScrambling()
-    {
-    int numLayers = getNumLayers();
-
-    if( mScrambleTable ==null )
-      {
-      mScrambleTable = new int[NUM_AXIS][numLayers];
-      }
-    if( mNumOccurences ==null )
-      {
-      int max=0;
-
-      for (ScrambleState mState : mStates)
-        {
-        int tmp = mState.getTotal(-1);
-        if (max < tmp) max = tmp;
-        }
-
-      mNumOccurences = new int[max];
-      }
-
-    for(int i=0; i<NUM_AXIS; i++)
-      for(int j=0; j<numLayers; j++) mScrambleTable[i][j] = 0;
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // PUBLIC API
 
-  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
-    {
-    if( curr==0 )
-      {
-      mCurrState     = 0;
-      mIndexExcluded =-1;
-      initializeScrambling();
-      }
-
-    int[] info= mStates[mCurrState].getRandom(rnd, mIndexExcluded, mScrambleTable, mNumOccurences);
-
-    scramble[curr][0] = info[0];
-    scramble[curr][1] = info[1];
-    scramble[curr][2] = info[2];
-
-    mCurrState     = info[3];
-    mIndexExcluded = info[0];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
   public Static3D[] getRotationAxis()
     {
     return ROT_AXIS;
diff --git a/src/main/java/org/distorted/objects/TwistyDino4.java b/src/main/java/org/distorted/objects/TwistyDino4.java
index 76b62805..243b6889 100644
--- a/src/main/java/org/distorted/objects/TwistyDino4.java
+++ b/src/main/java/org/distorted/objects/TwistyDino4.java
@@ -40,19 +40,29 @@ public class TwistyDino4 extends TwistyDino
               DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
     {
     super(size, quat, texture, mesh, effects, moves, ObjectList.DIN4, res, scrWidth);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    mStates = new ScrambleState[]
+  ScrambleState[] getScrambleStates()
+    {
+    if( mStates==null )
       {
-      new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{0,1,3,0,-1,3              },{0,1,5,0,-1,5              },{              2,1,8,2,-1,8} } ),
-      new ScrambleState( new int[][] { {                          },{0,1,3,0,-1,3              },{0,1,5,0,-1,5,             },{              2,1,8,2,-1,8} } ),
-      new ScrambleState( new int[][] { {                          },{              2,1,4,2,-1,4},{              2,1,6,2,-1,6},{0,1,7,0,-1,7              } } ),
-      new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{                          },{              2,1,6,2,-1,6},{0,1,7,0,-1,7              } } ),
-      new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{                          },{0,1,5,0,-1,5,             },{              2,1,8,2,-1,8} } ),
-      new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{              2,1,4,2,-1,4},{                          },{0,1,7,0,-1,7              } } ),
-      new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{0,1,3,0,-1,3              },{                          },{              2,1,8,2,-1,8} } ),
-      new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{0,1,3,0,-1,3              },{0,1,5,0,-1,5,             },{                          } } ),
-      new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{              2,1,4,2,-1,4},{              2,1,6,2,-1,6},{                          } } ),
-      };
+      mStates = new ScrambleState[]
+        {
+        new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{0,1,3,0,-1,3              },{0,1,5,0,-1,5              },{              2,1,8,2,-1,8} } ),
+        new ScrambleState( new int[][] { {                          },{0,1,3,0,-1,3              },{0,1,5,0,-1,5,             },{              2,1,8,2,-1,8} } ),
+        new ScrambleState( new int[][] { {                          },{              2,1,4,2,-1,4},{              2,1,6,2,-1,6},{0,1,7,0,-1,7              } } ),
+        new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{                          },{              2,1,6,2,-1,6},{0,1,7,0,-1,7              } } ),
+        new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{                          },{0,1,5,0,-1,5,             },{              2,1,8,2,-1,8} } ),
+        new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{              2,1,4,2,-1,4},{                          },{0,1,7,0,-1,7              } } ),
+        new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{0,1,3,0,-1,3              },{                          },{              2,1,8,2,-1,8} } ),
+        new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{0,1,3,0,-1,3              },{0,1,5,0,-1,5,             },{                          } } ),
+        new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{              2,1,4,2,-1,4},{              2,1,6,2,-1,6},{                          } } ),
+        };
+      }
+
+    return mStates;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyDino6.java b/src/main/java/org/distorted/objects/TwistyDino6.java
index d848380a..3408e669 100644
--- a/src/main/java/org/distorted/objects/TwistyDino6.java
+++ b/src/main/java/org/distorted/objects/TwistyDino6.java
@@ -40,19 +40,29 @@ public class TwistyDino6 extends TwistyDino
               DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
     {
     super(size, quat, texture, mesh, effects, moves, ObjectList.DINO, res, scrWidth);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    mStates = new ScrambleState[]
+  ScrambleState[] getScrambleStates()
+    {
+    if( mStates==null )
       {
-      new ScrambleState( new int[][] { {0,1,1,0,-1,1, 2,1,2,2,-1,2},{0,1,3,0,-1,3, 2,1,4,2,-1,4},{0,1,5,0,-1,5, 2,1,6,2,-1,6},{0,1,7,0,-1,7, 2,1,8,2,-1,8} } ),
-      new ScrambleState( new int[][] { {                          },{0,1,3,0,-1,3              },{0,1,5,0,-1,5,             },{              2,1,8,2,-1,8} } ),
-      new ScrambleState( new int[][] { {                          },{              2,1,4,2,-1,4},{              2,1,6,2,-1,6},{0,1,7,0,-1,7              } } ),
-      new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{                          },{              2,1,6,2,-1,6},{0,1,7,0,-1,7              } } ),
-      new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{                          },{0,1,5,0,-1,5,             },{              2,1,8,2,-1,8} } ),
-      new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{              2,1,4,2,-1,4},{                          },{0,1,7,0,-1,7              } } ),
-      new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{0,1,3,0,-1,3              },{                          },{              2,1,8,2,-1,8} } ),
-      new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{0,1,3,0,-1,3              },{0,1,5,0,-1,5,             },{                          } } ),
-      new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{              2,1,4,2,-1,4},{              2,1,6,2,-1,6},{                          } } ),
-      };
+      mStates = new ScrambleState[]
+        {
+        new ScrambleState( new int[][] { {0,1,1,0,-1,1, 2,1,2,2,-1,2},{0,1,3,0,-1,3, 2,1,4,2,-1,4},{0,1,5,0,-1,5, 2,1,6,2,-1,6},{0,1,7,0,-1,7, 2,1,8,2,-1,8} } ),
+        new ScrambleState( new int[][] { {                          },{0,1,3,0,-1,3              },{0,1,5,0,-1,5,             },{              2,1,8,2,-1,8} } ),
+        new ScrambleState( new int[][] { {                          },{              2,1,4,2,-1,4},{              2,1,6,2,-1,6},{0,1,7,0,-1,7              } } ),
+        new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{                          },{              2,1,6,2,-1,6},{0,1,7,0,-1,7              } } ),
+        new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{                          },{0,1,5,0,-1,5,             },{              2,1,8,2,-1,8} } ),
+        new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{              2,1,4,2,-1,4},{                          },{0,1,7,0,-1,7              } } ),
+        new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{0,1,3,0,-1,3              },{                          },{              2,1,8,2,-1,8} } ),
+        new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{0,1,3,0,-1,3              },{0,1,5,0,-1,5,             },{                          } } ),
+        new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{              2,1,4,2,-1,4},{              2,1,6,2,-1,6},{                          } } ),
+        };
+      }
+
+    return mStates;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyHelicopter.java b/src/main/java/org/distorted/objects/TwistyHelicopter.java
index bac24768..9ab67662 100644
--- a/src/main/java/org/distorted/objects/TwistyHelicopter.java
+++ b/src/main/java/org/distorted/objects/TwistyHelicopter.java
@@ -31,8 +31,6 @@ import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 import org.distorted.main.R;
 
-import java.util.Random;
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class TwistyHelicopter extends TwistyObject
@@ -57,11 +55,7 @@ public class TwistyHelicopter extends TwistyObject
 
   private static final int FACES_PER_CUBIT =6;
 
-  private int mCurrState;
-  private int mIndexExcluded;
-  private final ScrambleState[] mStates;
-  private int[][] mScrambleTable;
-  private int[] mNumOccurences;
+  private ScrambleState[] mStates;
   private int[] mBasicAngle;
   private Static4D[] mQuats;
   private float[][] mCenters;
@@ -75,23 +69,33 @@ public class TwistyHelicopter extends TwistyObject
                    MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
     {
     super(size, size, quat, texture, mesh, effects, moves, ObjectList.HELI, res, scrWidth);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    mStates = new ScrambleState[]
+  ScrambleState[] getScrambleStates()
+    {
+    if( mStates==null )
       {
-      new ScrambleState( new int[][] { {0,1,1,2,1,2},{0,1,3,2,1,4},{0,1,5,2,1,6},{0,1,7,2,1,8},{0,1,9,2,1,10},{0,1,11,2,1,12} } ),
-      new ScrambleState( new int[][] { {           },{           },{0,1,5      },{0,1,7      },{      2,1,10},{       2,1,12} } ),
-      new ScrambleState( new int[][] { {           },{           },{      2,1,6},{      2,1,8},{0,1,9       },{0,1,11       } } ),
-      new ScrambleState( new int[][] { {           },{           },{0,1,5      },{0,1,7      },{0,1,9       },{0,1,11       } } ),
-      new ScrambleState( new int[][] { {           },{           },{      2,1,6},{      2,1,8},{      2,1,10},{       2,1,12} } ),
-      new ScrambleState( new int[][] { {0,1,1      },{0,1,3      },{           },{           },{0,1,9       },{       2,1,12} } ),
-      new ScrambleState( new int[][] { {      2,1,2},{      2,1,4},{           },{           },{      2,1,10},{0,1,11       } } ),
-      new ScrambleState( new int[][] { {0,1,1      },{0,1,3      },{           },{           },{      2,1,10},{0,1,11       } } ),
-      new ScrambleState( new int[][] { {      2,1,2},{      2,1,4},{           },{           },{0,1,9       },{       2,1,12} } ),
-      new ScrambleState( new int[][] { {      2,1,2},{0,1,3      },{0,1,5      },{      2,1,8},{            },{             } } ),
-      new ScrambleState( new int[][] { {0,1,1      },{      2,1,4},{      2,1,6},{0,1,7      },{            },{             } } ),
-      new ScrambleState( new int[][] { {      2,1,2},{0,1,3      },{      2,1,6},{0,1,7      },{            },{             } } ),
-      new ScrambleState( new int[][] { {0,1,1      },{      2,1,4},{0,1,5      },{      2,1,8},{            },{             } } ),
-      };
+      mStates = new ScrambleState[]
+        {
+        new ScrambleState( new int[][] { {0,1,1,2,1,2},{0,1,3,2,1,4},{0,1,5,2,1,6},{0,1,7,2,1,8},{0,1,9,2,1,10},{0,1,11,2,1,12} } ),
+        new ScrambleState( new int[][] { {           },{           },{0,1,5      },{0,1,7      },{      2,1,10},{       2,1,12} } ),
+        new ScrambleState( new int[][] { {           },{           },{      2,1,6},{      2,1,8},{0,1,9       },{0,1,11       } } ),
+        new ScrambleState( new int[][] { {           },{           },{0,1,5      },{0,1,7      },{0,1,9       },{0,1,11       } } ),
+        new ScrambleState( new int[][] { {           },{           },{      2,1,6},{      2,1,8},{      2,1,10},{       2,1,12} } ),
+        new ScrambleState( new int[][] { {0,1,1      },{0,1,3      },{           },{           },{0,1,9       },{       2,1,12} } ),
+        new ScrambleState( new int[][] { {      2,1,2},{      2,1,4},{           },{           },{      2,1,10},{0,1,11       } } ),
+        new ScrambleState( new int[][] { {0,1,1      },{0,1,3      },{           },{           },{      2,1,10},{0,1,11       } } ),
+        new ScrambleState( new int[][] { {      2,1,2},{      2,1,4},{           },{           },{0,1,9       },{       2,1,12} } ),
+        new ScrambleState( new int[][] { {      2,1,2},{0,1,3      },{0,1,5      },{      2,1,8},{            },{             } } ),
+        new ScrambleState( new int[][] { {0,1,1      },{      2,1,4},{      2,1,6},{0,1,7      },{            },{             } } ),
+        new ScrambleState( new int[][] { {      2,1,2},{0,1,3      },{      2,1,6},{0,1,7      },{            },{             } } ),
+        new ScrambleState( new int[][] { {0,1,1      },{      2,1,4},{0,1,5      },{      2,1,8},{            },{             } } ),
+        };
+      }
+
+    return mStates;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -423,57 +427,9 @@ public class TwistyHelicopter extends TwistyObject
     return 2.0f;
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeScrambling()
-    {
-    int numLayers = getNumLayers();
-
-    if( mScrambleTable ==null )
-      {
-      mScrambleTable = new int[NUM_AXIS][numLayers];
-      }
-    if( mNumOccurences ==null )
-      {
-      int max=0;
-
-      for (ScrambleState mState : mStates)
-        {
-        int tmp = mState.getTotal(-1);
-        if (max < tmp) max = tmp;
-        }
-
-      mNumOccurences = new int[max];
-      }
-
-    for(int i=0; i<NUM_AXIS; i++)
-      for(int j=0; j<numLayers; j++) mScrambleTable[i][j] = 0;
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // PUBLIC API
 
-  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
-    {
-    if( curr==0 )
-      {
-      mCurrState     = 0;
-      mIndexExcluded =-1;
-      initializeScrambling();
-      }
-
-    int[] info= mStates[mCurrState].getRandom(rnd, mIndexExcluded, mScrambleTable, mNumOccurences);
-
-    scramble[curr][0] = info[0];
-    scramble[curr][1] = info[1];
-    scramble[curr][2] = info[2];
-
-    mCurrState     = info[3];
-    mIndexExcluded = info[0];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
   public Static3D[] getRotationAxis()
     {
     return ROT_AXIS;
diff --git a/src/main/java/org/distorted/objects/TwistyIvy.java b/src/main/java/org/distorted/objects/TwistyIvy.java
index b06f2dac..6f8a1f07 100644
--- a/src/main/java/org/distorted/objects/TwistyIvy.java
+++ b/src/main/java/org/distorted/objects/TwistyIvy.java
@@ -31,8 +31,6 @@ import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 import org.distorted.main.R;
 
-import java.util.Random;
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class TwistyIvy extends TwistyObject
@@ -58,11 +56,7 @@ public class TwistyIvy extends TwistyObject
   private static final int  IVY_N = 8;
   private static final int FACES_PER_CUBIT =6;
 
-  private int mCurrState;
-  private int mIndexExcluded;
-  private final ScrambleState[] mStates;
-  private int[][] mScrambleTable;
-  private int[] mNumOccurences;
+  private ScrambleState[] mStates;
   private int[] mBasicAngle;
   private Static4D[] mQuats;
   private int[][] mFaceMap;
@@ -83,6 +77,23 @@ public class TwistyIvy extends TwistyObject
       };
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  ScrambleState[] getScrambleStates()
+    {
+    if( mStates==null )
+      {
+      int[] tmp = {0,-1,0, 0,1,0, 1,-1,0, 1,1,0 };
+
+      mStates = new ScrambleState[]
+        {
+        new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
+        };
+      }
+
+    return mStates;
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   private void initializeQuats()
@@ -447,57 +458,9 @@ public class TwistyIvy extends TwistyObject
     return 2.0f;
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeScrambling()
-    {
-    int numLayers = getNumLayers();
-
-    if( mScrambleTable ==null )
-      {
-      mScrambleTable = new int[NUM_AXIS][numLayers];
-      }
-    if( mNumOccurences ==null )
-      {
-      int max=0;
-
-      for (ScrambleState mState : mStates)
-        {
-        int tmp = mState.getTotal(-1);
-        if (max < tmp) max = tmp;
-        }
-
-      mNumOccurences = new int[max];
-      }
-
-    for(int i=0; i<NUM_AXIS; i++)
-      for(int j=0; j<numLayers; j++) mScrambleTable[i][j] = 0;
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // PUBLIC API
 
-  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
-    {
-    if( curr==0 )
-      {
-      mCurrState     = 0;
-      mIndexExcluded =-1;
-      initializeScrambling();
-      }
-
-    int[] info= mStates[mCurrState].getRandom(rnd, mIndexExcluded, mScrambleTable, mNumOccurences);
-
-    scramble[curr][0] = info[0];
-    scramble[curr][1] = info[1];
-    scramble[curr][2] = info[2];
-
-    mCurrState     = info[3];
-    mIndexExcluded = info[0];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
   public Static3D[] getRotationAxis()
     {
     return ROT_AXIS;
diff --git a/src/main/java/org/distorted/objects/TwistyJing.java b/src/main/java/org/distorted/objects/TwistyJing.java
index 70e90fb1..f1202c0a 100644
--- a/src/main/java/org/distorted/objects/TwistyJing.java
+++ b/src/main/java/org/distorted/objects/TwistyJing.java
@@ -31,8 +31,6 @@ import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 import org.distorted.main.R;
 
-import java.util.Random;
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class TwistyJing extends TwistyObject
@@ -55,11 +53,7 @@ public class TwistyJing extends TwistyObject
                                  // the length of the edge of the whole tetrahedron.
                                  // keep < 0.25.
 
-  private int mCurrState;
-  private int mIndexExcluded;
-  private final ScrambleState[] mStates;
-  private int[][] mScrambleTable;
-  private int[] mNumOccurences;
+  private ScrambleState[] mStates;
   private int[] mBasicAngle;
   private int[] mRotQuat;
   private Static4D[] mQuats;
@@ -73,13 +67,23 @@ public class TwistyJing extends TwistyObject
              DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
     {
     super(size, size, quat, texture, mesh, effects, moves, ObjectList.JING, res, scrWidth);
+    }
 
-    int[] tmp = {0,-1,0, 0,1,0, 1,-1,0, 1,1,0 };
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    mStates = new ScrambleState[]
+  ScrambleState[] getScrambleStates()
+    {
+    if( mStates==null )
       {
-      new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
-      };
+      int[] tmp = {0,-1,0, 0,1,0, 1,-1,0, 1,1,0 };
+
+      mStates = new ScrambleState[]
+        {
+        new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
+        };
+      }
+
+    return mStates;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -408,57 +412,9 @@ public class TwistyJing extends TwistyObject
     return getNumLayers()/(SQ6/3);
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeScrambling()
-    {
-    int numLayers = getNumLayers();
-
-    if( mScrambleTable ==null )
-      {
-      mScrambleTable = new int[NUM_AXIS][numLayers];
-      }
-    if( mNumOccurences ==null )
-      {
-      int max=0;
-
-      for (ScrambleState mState : mStates)
-        {
-        int tmp = mState.getTotal(-1);
-        if (max < tmp) max = tmp;
-        }
-
-      mNumOccurences = new int[max];
-      }
-
-    for(int i=0; i<NUM_AXIS; i++)
-      for(int j=0; j<numLayers; j++) mScrambleTable[i][j] = 0;
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // PUBLIC API
 
-  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
-    {
-    if( curr==0 )
-      {
-      mCurrState     = 0;
-      mIndexExcluded =-1;
-      initializeScrambling();
-      }
-
-    int[] info= mStates[mCurrState].getRandom(rnd, mIndexExcluded, mScrambleTable, mNumOccurences);
-
-    scramble[curr][0] = info[0];
-    scramble[curr][1] = info[1];
-    scramble[curr][2] = info[2];
-
-    mCurrState     = info[3];
-    mIndexExcluded = info[0];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
   public Static3D[] getRotationAxis()
     {
     return ROT_AXIS;
diff --git a/src/main/java/org/distorted/objects/TwistyMinx.java b/src/main/java/org/distorted/objects/TwistyMinx.java
index be9b403c..d904e1b8 100644
--- a/src/main/java/org/distorted/objects/TwistyMinx.java
+++ b/src/main/java/org/distorted/objects/TwistyMinx.java
@@ -29,8 +29,6 @@ import org.distorted.library.mesh.MeshSquare;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 
-import java.util.Random;
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 abstract class TwistyMinx extends TwistyObject
@@ -81,11 +79,7 @@ abstract class TwistyMinx extends TwistyObject
            MINX_DBLUE , MINX_DYELLOW, MINX_WHITE , MINX_GREY
          };
 
-  private int mCurrState;
-  private int mIndexExcluded;
   private ScrambleState[] mStates;
-  private int[][] mScrambleTable;
-  private int[] mNumOccurences;
   private int[] mBasicAngle;
   private int[] mFaceMap;
   Static4D[] mQuats;
@@ -105,10 +99,20 @@ abstract class TwistyMinx extends TwistyObject
              DistortedEffects effects, int[][] moves, ObjectList obj, Resources res, int scrWidth)
     {
     super(numLayers, realSize, quat, texture, mesh, effects, moves, obj, res, scrWidth);
-
-    initializeScrambleStates(numLayers);
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  ScrambleState[] getScrambleStates()
+    {
+    if( mStates==null )
+      {
+      int numLayers = getNumLayers();
+      initializeScrambleStates(numLayers);
+      }
+
+    return mStates;
+    }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -553,57 +557,9 @@ abstract class TwistyMinx extends TwistyObject
     return 2.0f;
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeScrambling()
-    {
-    int numLayers = getNumLayers();
-
-    if( mScrambleTable ==null )
-      {
-      mScrambleTable = new int[NUM_AXIS][numLayers];
-      }
-    if( mNumOccurences ==null )
-      {
-      int max=0;
-
-      for (ScrambleState mState : mStates)
-        {
-        int tmp = mState.getTotal(-1);
-        if (max < tmp) max = tmp;
-        }
-
-      mNumOccurences = new int[max];
-      }
-
-    for(int i=0; i<NUM_AXIS; i++)
-      for(int j=0; j<numLayers; j++) mScrambleTable[i][j] = 0;
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // PUBLIC API
 
-  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
-    {
-    if( curr==0 )
-      {
-      mCurrState     = 0;
-      mIndexExcluded =-1;
-      initializeScrambling();
-      }
-
-    int[] info= mStates[mCurrState].getRandom(rnd, mIndexExcluded, mScrambleTable, mNumOccurences);
-
-    scramble[curr][0] = info[0];
-    scramble[curr][1] = info[1];
-    scramble[curr][2] = info[2];
-
-    mCurrState     = info[3];
-    mIndexExcluded = info[0];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
   public Static3D[] getRotationAxis()
     {
     return ROT_AXIS;
diff --git a/src/main/java/org/distorted/objects/TwistyObject.java b/src/main/java/org/distorted/objects/TwistyObject.java
index 8aef89ac..f9d6c23e 100644
--- a/src/main/java/org/distorted/objects/TwistyObject.java
+++ b/src/main/java/org/distorted/objects/TwistyObject.java
@@ -32,6 +32,7 @@ import org.distorted.helpers.FactorySticker;
 import org.distorted.helpers.ObjectShape;
 import org.distorted.helpers.ObjectSticker;
 import org.distorted.helpers.QuatHelper;
+import org.distorted.helpers.ScrambleState;
 import org.distorted.library.effect.Effect;
 import org.distorted.library.effect.MatrixEffectMove;
 import org.distorted.library.effect.MatrixEffectQuaternion;
@@ -126,6 +127,7 @@ public abstract class TwistyObject extends DistortedNode
   private int mRotRowBitmap;
   private int mRotAxis;
   private MeshBase mMesh;
+  private final TwistyObjectScrambler mScrambler;
 
   //////////////////// SOLVED1 ////////////////////////
 
@@ -166,6 +168,10 @@ public abstract class TwistyObject extends DistortedNode
     NUM_AXIS = mAxis.length;
     NUM_QUATS = OBJECT_QUATS.length;
 
+    int scramblingType = getScrambleType();
+    ScrambleState[] states = getScrambleStates();
+    mScrambler = new TwistyObjectScrambler(scramblingType,NUM_AXIS,numLayers,states);
+
     boolean bandaged=false;
 
     for(int c=0; c<NUM_CUBITS; c++)
@@ -746,6 +752,13 @@ public abstract class TwistyObject extends DistortedNode
       }
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  int getScrambleType()
+    {
+    return 0;
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   int computeBitmapFromRow(int rowBitmap, int axis)
@@ -1260,6 +1273,13 @@ public abstract class TwistyObject extends DistortedNode
     return mList;
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int total)
+    {
+    mScrambler.randomizeNewScramble(scramble,rnd,curr,total);
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   abstract float getScreenRatio();
@@ -1280,10 +1300,10 @@ public abstract class TwistyObject extends DistortedNode
   abstract ObjectShape getObjectShape(int cubit, int numLayers);
   abstract int[] getSolvedQuats(int cubit, int numLayers);
   abstract int getSolvedFunctionIndex();
+  abstract ScrambleState[] getScrambleStates();
 
   public abstract Static3D[] getRotationAxis();
   public abstract int[] getBasicAngle();
-  public abstract void randomizeNewScramble(int[][] scramble, Random rnd, int curScramble, int totScrambles);
   public abstract int getObjectName(int numLayers);
   public abstract int getInventor(int numLayers);
   public abstract int getComplexity(int numLayers);
diff --git a/src/main/java/org/distorted/objects/TwistyObjectScrambler.java b/src/main/java/org/distorted/objects/TwistyObjectScrambler.java
new file mode 100644
index 00000000..844e3d2a
--- /dev/null
+++ b/src/main/java/org/distorted/objects/TwistyObjectScrambler.java
@@ -0,0 +1,394 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2021 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of Magic Cube.                                                              //
+//                                                                                               //
+// Magic Cube is free software: you can redistribute it and/or modify                            //
+// it under the terms of the GNU General Public License as published by                          //
+// the Free Software Foundation, either version 2 of the License, or                             //
+// (at your option) any later version.                                                           //
+//                                                                                               //
+// Magic Cube is distributed in the hope that it will be useful,                                 //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
+// GNU General Public License for more details.                                                  //
+//                                                                                               //
+// You should have received a copy of the GNU General Public License                             //
+// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.objects;
+
+import org.distorted.helpers.ScrambleState;
+
+import java.util.Random;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public class TwistyObjectScrambler
+  {
+  private final ScrambleState[] mStates;
+  private final int mType;
+  private final int mNumAxis;
+  private final int mNumLayers;
+
+  // type=0, i.e. main
+  private int mCurrState;
+  private int mIndexExcluded;
+  private int[][] mScrambleTable;
+  private int[] mNumOccurences;
+
+  // type=1, i.e. the exception: Square-1
+  private static final int BASIC_ANGLE = 12;
+  private static final int LAST_SL = 0; // automatic rotations: last rot was a 'slash' i.e. along ROT_AXIS[1]
+  private static final int LAST_UP = 1; // last rot was along ROT_AXIS[0], upper layer and forelast was a slash
+  private static final int LAST_LO = 2; // last rot was along ROT_AXIS[0], lower layer and forelast was a slash
+  private static final int LAST_UL = 3; // two last rots were along ROT_AXIS[0] (so the next must be a slash)
+
+  private int[][] mPermittedAngles;
+  private int[] mCornerQuat;
+  private int mPermittedUp, mPermittedDo;
+  private int[][] mBadCornerQuats;
+  private int mLastRot;
+  private int[][] mQuatMult;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  TwistyObjectScrambler(int type, int numAxis, int numLayers, ScrambleState[] states)
+    {
+    mType = type;
+    mNumAxis = numAxis;
+    mNumLayers = numLayers;
+    mStates = states;
+
+    if( mType==1 )
+      {
+      mPermittedAngles = new int[2][BASIC_ANGLE];
+      mCornerQuat = new int[8];
+      mLastRot = LAST_SL;
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// QUATS[i]*QUATS[j] = QUATS[QUAT_MULT[i][j]]
+
+  void initializeQuatMult()
+    {
+    mQuatMult = new int[][]
+      {
+        {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,},
+        {  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11,  0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 12,},
+        {  2,  3,  4,  5,  6,  7,  8,  9, 10, 11,  0,  1, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 12, 13,},
+        {  3,  4,  5,  6,  7,  8,  9, 10, 11,  0,  1,  2, 15, 16, 17, 18, 19, 20, 21, 22, 23, 12, 13, 14,},
+        {  4,  5,  6,  7,  8,  9, 10, 11,  0,  1,  2,  3, 16, 17, 18, 19, 20, 21, 22, 23, 12, 13, 14, 15,},
+        {  5,  6,  7,  8,  9, 10, 11,  0,  1,  2,  3,  4, 17, 18, 19, 20, 21, 22, 23, 12, 13, 14, 15, 16,},
+        {  6,  7,  8,  9, 10, 11,  0,  1,  2,  3,  4,  5, 18, 19, 20, 21, 22, 23, 12, 13, 14, 15, 16, 17,},
+        {  7,  8,  9, 10, 11,  0,  1,  2,  3,  4,  5,  6, 19, 20, 21, 22, 23, 12, 13, 14, 15, 16, 17, 18,},
+        {  8,  9, 10, 11,  0,  1,  2,  3,  4,  5,  6,  7, 20, 21, 22, 23, 12, 13, 14, 15, 16, 17, 18, 19,},
+        {  9, 10, 11,  0,  1,  2,  3,  4,  5,  6,  7,  8, 21, 22, 23, 12, 13, 14, 15, 16, 17, 18, 19, 20,},
+        { 10, 11,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 22, 23, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,},
+        { 11,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 23, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,},
+        { 12, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13,  0, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,},
+        { 13, 12, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14,  1,  0, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,},
+        { 14, 13, 12, 23, 22, 21, 20, 19, 18, 17, 16, 15,  2,  1,  0, 11, 10,  9,  8,  7,  6,  5,  4,  3,},
+        { 15, 14, 13, 12, 23, 22, 21, 20, 19, 18, 17, 16,  3,  2,  1,  0, 11, 10,  9,  8,  7,  6,  5,  4,},
+        { 16, 15, 14, 13, 12, 23, 22, 21, 20, 19, 18, 17,  4,  3,  2,  1,  0, 11, 10,  9,  8,  7,  6,  5,},
+        { 17, 16, 15, 14, 13, 12, 23, 22, 21, 20, 19, 18,  5,  4,  3,  2,  1,  0, 11, 10,  9,  8,  7,  6,},
+        { 18, 17, 16, 15, 14, 13, 12, 23, 22, 21, 20, 19,  6,  5,  4,  3,  2,  1,  0, 11, 10,  9,  8,  7,},
+        { 19, 18, 17, 16, 15, 14, 13, 12, 23, 22, 21, 20,  7,  6,  5,  4,  3,  2,  1,  0, 11, 10,  9,  8,},
+        { 20, 19, 18, 17, 16, 15, 14, 13, 12, 23, 22, 21,  8,  7,  6,  5,  4,  3,  2,  1,  0, 11, 10,  9,},
+        { 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 23, 22,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0, 11, 10,},
+        { 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 23, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0, 11,},
+        { 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0,}
+      };
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void initializeScrambling()
+    {
+    if( mScrambleTable ==null )
+      {
+      mScrambleTable = new int[mNumAxis][mNumLayers];
+      }
+    if( mNumOccurences ==null )
+      {
+      int max=0;
+
+      for (ScrambleState mState : mStates)
+        {
+        int tmp = mState.getTotal(-1);
+        if (max < tmp) max = tmp;
+        }
+
+      mNumOccurences = new int[max];
+      }
+
+    for(int i=0; i<mNumAxis; i++)
+      for(int j=0; j<mNumLayers; j++) mScrambleTable[i][j] = 0;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// PUBLIC API
+
+  private void randomizeNewScramble0(int[][] scramble, Random rnd, int curr, int total)
+    {
+    if( curr==0 )
+      {
+      mCurrState     = 0;
+      mIndexExcluded =-1;
+      initializeScrambling();
+      }
+
+    int[] info= mStates[mCurrState].getRandom(rnd, mIndexExcluded, mScrambleTable, mNumOccurences);
+
+    scramble[curr][0] = info[0];
+    scramble[curr][1] = info[1];
+    scramble[curr][2] = info[2];
+
+    mCurrState     = info[3];
+    mIndexExcluded = info[0];
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private boolean cornerIsUp(int index)
+    {
+    return ((index<4) ^ (mCornerQuat[index]>=12));
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private boolean cornerIsLeft(int index)
+    {
+    int q = mCornerQuat[index];
+
+    switch(index)
+      {
+      case 0:
+      case 4: return ((q>=3 && q<= 7) || (q>=18 && q<=22));
+      case 1:
+      case 5: return ((q>=6 && q<=10) || (q>=15 && q<=19));
+      case 2:
+      case 6: return ((q==0 || q==1 || (q>=9 && q<=11)) || (q>=12 && q<=16));
+      case 3:
+      case 7: return ((q>=0 && q<=4) || (q==12 || q==13 || (q>=21 && q<=23)));
+      }
+
+    return false;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private boolean quatIsBad(int quatIndex, int corner)
+    {
+    if( mBadCornerQuats ==null )
+      {
+      // quat indices that make corner cubits bandage the puzzle.
+      mBadCornerQuats = new int[][] { { 2, 8,17,23}, { 5,11,14,20} };
+      }
+
+    int index = (corner%2);
+
+    return ( quatIndex== mBadCornerQuats[index][0] ||
+             quatIndex== mBadCornerQuats[index][1] ||
+             quatIndex== mBadCornerQuats[index][2] ||
+             quatIndex== mBadCornerQuats[index][3]  );
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private boolean isPermittedDo(int angle)
+    {
+    if( mQuatMult==null ) initializeQuatMult();
+
+    for(int corner=0; corner<8; corner++)
+      {
+      if( !cornerIsUp(corner) )
+        {
+        int currQuat = mCornerQuat[corner];
+        int finalQuat= mQuatMult[angle][currQuat];
+        if( quatIsBad(finalQuat,corner) ) return false;
+        }
+      }
+
+    return true;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private boolean isPermittedUp(int angle)
+    {
+    if( mQuatMult==null ) initializeQuatMult();
+
+    for(int corner=0; corner<8; corner++)
+      {
+      if( cornerIsUp(corner) )
+        {
+        int currQuat = mCornerQuat[corner];
+        int finalQuat= mQuatMult[angle][currQuat];
+        if( quatIsBad(finalQuat,corner) ) return false;
+        }
+      }
+
+    return true;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void computePermittedAngles()
+    {
+    mPermittedDo = 0;
+
+    for(int angle=0; angle<BASIC_ANGLE; angle++)
+      {
+      if( isPermittedDo(angle ) ) mPermittedAngles[0][mPermittedDo++] = angle;
+      }
+
+    mPermittedUp = 0;
+
+    for(int angle=0; angle<BASIC_ANGLE; angle++)
+      {
+      if( isPermittedUp(angle ) ) mPermittedAngles[1][mPermittedUp++] = angle;
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private int getNextAngle(Random rnd, int layer)
+    {
+    int num = layer==0 ? mPermittedDo:mPermittedUp;
+    int index = rnd.nextInt(num);
+    int angle = mPermittedAngles[layer][index];
+    return angle<BASIC_ANGLE/2 ? -angle : BASIC_ANGLE-angle;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private int getNextAngleNotZero(Random rnd, int layer)
+    {
+    int num = layer==0 ? mPermittedDo:mPermittedUp;
+    int index = rnd.nextInt(num-1);
+    int angle = mPermittedAngles[layer][index+1];
+    return angle<BASIC_ANGLE/2 ? -angle : BASIC_ANGLE-angle;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private int makeQuat(int axis,int index)
+    {
+    if( axis==1 ) return 13;
+    if( index<0 ) index+=12;
+    return index;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private boolean cornerBelongs(int index, int axis, int layer)
+    {
+    if( axis==0 )
+      {
+      boolean up = cornerIsUp(index);
+      return ((up && layer==2) || (!up && layer==0));
+      }
+    else
+      {
+      boolean le = cornerIsLeft(index);
+      return ((le && layer==0) || (!le && layer==1));
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void updateCornerQuats(int[] rotInfo)
+    {
+    if( mQuatMult==null ) initializeQuatMult();
+
+    int axis = rotInfo[0];
+    int layer= rotInfo[1];
+    int index=-rotInfo[2];
+
+    int quat = makeQuat(axis,index);
+
+    for(int corner=0; corner<8; corner++)
+      {
+      if( cornerBelongs(corner,axis,layer) )
+        {
+        int curr = mCornerQuat[corner];
+        mCornerQuat[corner] = mQuatMult[quat][curr];
+        }
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void randomizeNewScramble1(int[][] scramble, Random rnd, int curr, int total)
+    {
+    int layer, nextAngle;
+
+    if( curr==0 )
+      {
+      for(int corner=0; corner<8; corner++) mCornerQuat[corner] = 0;
+      mLastRot = rnd.nextInt(4);
+      computePermittedAngles();
+      }
+
+    switch(mLastRot)
+      {
+      case LAST_SL: layer = rnd.nextInt(2);
+                    nextAngle = getNextAngle(rnd,layer);
+
+                    if( nextAngle==0 )
+                      {
+                      layer = 1-layer;
+                      nextAngle = getNextAngleNotZero(rnd,layer);
+                      }
+
+                    scramble[curr][0] = 0;
+                    scramble[curr][1] = 2*layer;
+                    scramble[curr][2] = nextAngle;
+                    mLastRot = layer==0 ? LAST_LO : LAST_UP;
+                    updateCornerQuats(scramble[curr]);
+                    break;
+      case LAST_LO:
+      case LAST_UP: layer = mLastRot==LAST_LO ? 1:0;
+                    nextAngle = getNextAngle(rnd,layer);
+
+                    if( nextAngle!=0 )
+                      {
+                      scramble[curr][0] = 0;
+                      scramble[curr][1] = 2*layer;
+                      scramble[curr][2] = nextAngle;
+                      updateCornerQuats(scramble[curr]);
+                      mLastRot = LAST_UL;
+                      }
+                    else
+                      {
+                      scramble[curr][0] = 1;
+                      scramble[curr][1] = rnd.nextInt(2);
+                      scramble[curr][2] = 1;
+                      mLastRot = LAST_SL;
+                      updateCornerQuats(scramble[curr]);
+                      computePermittedAngles();
+                      }
+
+                    break;
+      case LAST_UL: scramble[curr][0] = 1;
+                    scramble[curr][1] = rnd.nextInt(2);
+                    scramble[curr][2] = 1;
+                    mLastRot = LAST_SL;
+                    updateCornerQuats(scramble[curr]);
+                    computePermittedAngles();
+                    break;
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// PUBLIC API
+
+  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int total)
+    {
+    if( mType==0 ) randomizeNewScramble0(scramble, rnd, curr, total);
+    if( mType==1 ) randomizeNewScramble1(scramble, rnd, curr, total);
+    }
+  }
diff --git a/src/main/java/org/distorted/objects/TwistyPyraminx.java b/src/main/java/org/distorted/objects/TwistyPyraminx.java
index 3b74cdc1..883651ea 100644
--- a/src/main/java/org/distorted/objects/TwistyPyraminx.java
+++ b/src/main/java/org/distorted/objects/TwistyPyraminx.java
@@ -31,8 +31,6 @@ import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 import org.distorted.main.R;
 
-import java.util.Random;
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class TwistyPyraminx extends TwistyObject
@@ -51,11 +49,7 @@ public class TwistyPyraminx extends TwistyObject
            COLOR_BLUE  , COLOR_RED
          };
 
-  private int mCurrState;
-  private int mIndexExcluded;
   private ScrambleState[] mStates;
-  private int[][] mScrambleTable;
-  private int[] mNumOccurences;
   private int[] mBasicAngle;
   private Static4D[] mQuats;
   private ObjectSticker[] mStickers;
@@ -66,8 +60,19 @@ public class TwistyPyraminx extends TwistyObject
                  DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
     {
     super(size, size, quat, texture, mesh, effects, moves, ObjectList.PYRA, res, scrWidth);
+    }
 
-    initializeScrambleStates(size);
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  ScrambleState[] getScrambleStates()
+    {
+    if( mStates==null )
+      {
+      int numLayers = getNumLayers();
+      initializeScrambleStates(numLayers);
+      }
+
+    return mStates;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -382,55 +387,7 @@ public class TwistyPyraminx extends TwistyObject
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeScrambling()
-    {
-    int numLayers = getNumLayers();
-
-    if( mScrambleTable ==null )
-      {
-      mScrambleTable = new int[NUM_AXIS][numLayers];
-      }
-    if( mNumOccurences ==null )
-      {
-      int max=0;
-
-      for (ScrambleState mState : mStates)
-        {
-        int tmp = mState.getTotal(-1);
-        if (max < tmp) max = tmp;
-        }
-
-      mNumOccurences = new int[max];
-      }
-
-    for(int i=0; i<NUM_AXIS; i++)
-      for(int j=0; j<numLayers; j++) mScrambleTable[i][j] = 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-
-  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
-    {
-    if( curr==0 )
-      {
-      mCurrState     = 0;
-      mIndexExcluded =-1;
-      initializeScrambling();
-      }
-
-    int[] info= mStates[mCurrState].getRandom(rnd, mIndexExcluded, mScrambleTable, mNumOccurences);
-
-    scramble[curr][0] = info[0];
-    scramble[curr][1] = info[1];
-    scramble[curr][2] = info[2];
-
-    mCurrState     = info[3];
-    mIndexExcluded = info[0];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
+// public API
 
   public Static3D[] getRotationAxis()
     {
diff --git a/src/main/java/org/distorted/objects/TwistyRedi.java b/src/main/java/org/distorted/objects/TwistyRedi.java
index dd9ffce9..24031a6f 100644
--- a/src/main/java/org/distorted/objects/TwistyRedi.java
+++ b/src/main/java/org/distorted/objects/TwistyRedi.java
@@ -31,8 +31,6 @@ import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 import org.distorted.main.R;
 
-import java.util.Random;
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class TwistyRedi extends TwistyObject
@@ -55,11 +53,7 @@ public class TwistyRedi extends TwistyObject
 
   private static final int FACES_PER_CUBIT =9;
 
-  private int mCurrState;
-  private int mIndexExcluded;
-  private final ScrambleState[] mStates;
-  private int[][] mScrambleTable;
-  private int[] mNumOccurences;
+  private ScrambleState[] mStates;
   private int[] mBasicAngle;
   private Static4D[] mQuats;
   private float[][] mCenters;
@@ -72,19 +66,29 @@ public class TwistyRedi extends TwistyObject
              DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
     {
     super(size, size, quat, texture, mesh, effects, moves, ObjectList.REDI, res, scrWidth);
+    }
 
-    mStates = new ScrambleState[]
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  ScrambleState[] getScrambleStates()
+    {
+    if( mStates==null )
       {
-      new ScrambleState( new int[][] { {0,1,1,0,-1,1, 2,1,2,2,-1,2},{0,1,3,0,-1,3, 2,1,4,2,-1,4},{0,1,5,0,-1,5, 2,1,6,2,-1,6},{0,1,7,0,-1,7, 2,1,8,2,-1,8} } ),
-      new ScrambleState( new int[][] { {                          },{0,1,3,0,-1,3              },{0,1,5,0,-1,5,             },{              2,1,8,2,-1,8} } ),
-      new ScrambleState( new int[][] { {                          },{              2,1,4,2,-1,4},{              2,1,6,2,-1,6},{0,1,7,0,-1,7              } } ),
-      new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{                          },{              2,1,6,2,-1,6},{0,1,7,0,-1,7              } } ),
-      new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{                          },{0,1,5,0,-1,5,             },{              2,1,8,2,-1,8} } ),
-      new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{              2,1,4,2,-1,4},{                          },{0,1,7,0,-1,7              } } ),
-      new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{0,1,3,0,-1,3              },{                          },{              2,1,8,2,-1,8} } ),
-      new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{0,1,3,0,-1,3              },{0,1,5,0,-1,5,             },{                          } } ),
-      new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{              2,1,4,2,-1,4},{              2,1,6,2,-1,6},{                          } } ),
-      };
+      mStates = new ScrambleState[]
+        {
+        new ScrambleState( new int[][] { {0,1,1,0,-1,1, 2,1,2,2,-1,2},{0,1,3,0,-1,3, 2,1,4,2,-1,4},{0,1,5,0,-1,5, 2,1,6,2,-1,6},{0,1,7,0,-1,7, 2,1,8,2,-1,8} } ),
+        new ScrambleState( new int[][] { {                          },{0,1,3,0,-1,3              },{0,1,5,0,-1,5,             },{              2,1,8,2,-1,8} } ),
+        new ScrambleState( new int[][] { {                          },{              2,1,4,2,-1,4},{              2,1,6,2,-1,6},{0,1,7,0,-1,7              } } ),
+        new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{                          },{              2,1,6,2,-1,6},{0,1,7,0,-1,7              } } ),
+        new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{                          },{0,1,5,0,-1,5,             },{              2,1,8,2,-1,8} } ),
+        new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{              2,1,4,2,-1,4},{                          },{0,1,7,0,-1,7              } } ),
+        new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{0,1,3,0,-1,3              },{                          },{              2,1,8,2,-1,8} } ),
+        new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{0,1,3,0,-1,3              },{0,1,5,0,-1,5,             },{                          } } ),
+        new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{              2,1,4,2,-1,4},{              2,1,6,2,-1,6},{                          } } ),
+        };
+      }
+
+    return mStates;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -419,57 +423,9 @@ public class TwistyRedi extends TwistyObject
     return 2.0f;
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeScrambling()
-    {
-    int numLayers = getNumLayers();
-
-    if( mScrambleTable ==null )
-      {
-      mScrambleTable = new int[NUM_AXIS][numLayers];
-      }
-    if( mNumOccurences ==null )
-      {
-      int max=0;
-
-      for (ScrambleState mState : mStates)
-        {
-        int tmp = mState.getTotal(-1);
-        if (max < tmp) max = tmp;
-        }
-
-      mNumOccurences = new int[max];
-      }
-
-    for(int i=0; i<NUM_AXIS; i++)
-      for(int j=0; j<numLayers; j++) mScrambleTable[i][j] = 0;
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // PUBLIC API
 
-  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
-    {
-    if( curr==0 )
-      {
-      mCurrState     = 0;
-      mIndexExcluded =-1;
-      initializeScrambling();
-      }
-
-    int[] info= mStates[mCurrState].getRandom(rnd, mIndexExcluded, mScrambleTable, mNumOccurences);
-
-    scramble[curr][0] = info[0];
-    scramble[curr][1] = info[1];
-    scramble[curr][2] = info[2];
-
-    mCurrState     = info[3];
-    mIndexExcluded = info[0];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
   public Static3D[] getRotationAxis()
     {
     return ROT_AXIS;
diff --git a/src/main/java/org/distorted/objects/TwistyRex.java b/src/main/java/org/distorted/objects/TwistyRex.java
index 3cb2b18e..ccecde9f 100644
--- a/src/main/java/org/distorted/objects/TwistyRex.java
+++ b/src/main/java/org/distorted/objects/TwistyRex.java
@@ -31,8 +31,6 @@ import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 import org.distorted.main.R;
 
-import java.util.Random;
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class TwistyRex extends TwistyObject
@@ -55,11 +53,7 @@ public class TwistyRex extends TwistyObject
 
   public static final float REX_D = 0.2f;
 
-  private int mCurrState;
-  private int mIndexExcluded;
-  private final ScrambleState[] mStates;
-  private int[][] mScrambleTable;
-  private int[] mNumOccurences;
+  private ScrambleState[] mStates;
   private int[] mBasicAngle;
   private Static4D[] mQuats;
   private int[][] mFaceMap;
@@ -71,13 +65,23 @@ public class TwistyRex extends TwistyObject
             DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
     {
     super(size, size, quat, texture, mesh, effects, moves, ObjectList.REX, res, scrWidth);
+    }
 
-    int[] tmp = {0,-1,0, 0,1,0, 2,-1,0, 2,1,0 };
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    mStates = new ScrambleState[]
+  ScrambleState[] getScrambleStates()
+    {
+    if( mStates==null )
       {
-      new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
-      };
+      int[] tmp = {0,-1,0, 0,1,0, 2,-1,0, 2,1,0 };
+
+      mStates = new ScrambleState[]
+        {
+        new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
+        };
+      }
+
+    return mStates;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -486,57 +490,9 @@ public class TwistyRex extends TwistyObject
     return 2.0f;
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeScrambling()
-    {
-    int numLayers = getNumLayers();
-
-    if( mScrambleTable ==null )
-      {
-      mScrambleTable = new int[NUM_AXIS][numLayers];
-      }
-    if( mNumOccurences ==null )
-      {
-      int max=0;
-
-      for (ScrambleState mState : mStates)
-        {
-        int tmp = mState.getTotal(-1);
-        if (max < tmp) max = tmp;
-        }
-
-      mNumOccurences = new int[max];
-      }
-
-    for(int i=0; i<NUM_AXIS; i++)
-      for(int j=0; j<numLayers; j++) mScrambleTable[i][j] = 0;
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // PUBLIC API
 
-  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
-    {
-    if( curr==0 )
-      {
-      mCurrState     = 0;
-      mIndexExcluded =-1;
-      initializeScrambling();
-      }
-
-    int[] info= mStates[mCurrState].getRandom(rnd, mIndexExcluded, mScrambleTable, mNumOccurences);
-
-    scramble[curr][0] = info[0];
-    scramble[curr][1] = info[1];
-    scramble[curr][2] = info[2];
-
-    mCurrState     = info[3];
-    mIndexExcluded = info[0];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
   public Static3D[] getRotationAxis()
     {
     return ROT_AXIS;
diff --git a/src/main/java/org/distorted/objects/TwistySkewb.java b/src/main/java/org/distorted/objects/TwistySkewb.java
index 011f585f..3721087d 100644
--- a/src/main/java/org/distorted/objects/TwistySkewb.java
+++ b/src/main/java/org/distorted/objects/TwistySkewb.java
@@ -31,8 +31,6 @@ import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 import org.distorted.main.R;
 
-import java.util.Random;
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class TwistySkewb extends TwistyObject
@@ -53,11 +51,7 @@ public class TwistySkewb extends TwistyObject
            COLOR_RED   , COLOR_ORANGE
          };
 
-  private int mCurrState;
-  private int mIndexExcluded;
-  private final ScrambleState[] mStates;
-  private int[][] mScrambleTable;
-  private int[] mNumOccurences;
+  private ScrambleState[] mStates;
   private int[] mBasicAngle;
   private Static4D[] mQuats;
   private int[][] mCornerMap,mEdgeMap,mCenterMap;
@@ -69,13 +63,24 @@ public class TwistySkewb extends TwistyObject
               MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
     {
     super(size, 2*size-2, quat, texture, mesh, effects, moves, ObjectList.SKEW, res, scrWidth);
+    }
 
-    int[] tmp = {0,-1,0, 0,1,0, size-1,-1,0, size-1,1,0 };
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    mStates = new ScrambleState[]
+  ScrambleState[] getScrambleStates()
+    {
+    if( mStates==null )
       {
-      new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
-      };
+      int size = getNumLayers();
+      int[] tmp = {0,-1,0, 0,1,0, size-1,-1,0, size-1,1,0 };
+
+      mStates = new ScrambleState[]
+        {
+        new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
+        };
+      }
+
+    return mStates;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -558,57 +563,9 @@ public class TwistySkewb extends TwistyObject
     return 2.0f;
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeScrambling()
-    {
-    int numLayers = getNumLayers();
-
-    if( mScrambleTable ==null )
-      {
-      mScrambleTable = new int[NUM_AXIS][numLayers];
-      }
-    if( mNumOccurences ==null )
-      {
-      int max=0;
-
-      for (ScrambleState mState : mStates)
-        {
-        int tmp = mState.getTotal(-1);
-        if (max < tmp) max = tmp;
-        }
-
-      mNumOccurences = new int[max];
-      }
-
-    for(int i=0; i<NUM_AXIS; i++)
-      for(int j=0; j<numLayers; j++) mScrambleTable[i][j] = 0;
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // PUBLIC API
 
-  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
-    {
-    if( curr==0 )
-      {
-      mCurrState     = 0;
-      mIndexExcluded =-1;
-      initializeScrambling();
-      }
-
-    int[] info= mStates[mCurrState].getRandom(rnd, mIndexExcluded, mScrambleTable, mNumOccurences);
-
-    scramble[curr][0] = info[0];
-    scramble[curr][1] = info[1];
-    scramble[curr][2] = info[2];
-
-    mCurrState     = info[3];
-    mIndexExcluded = info[0];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
   public Static3D[] getRotationAxis()
     {
     return ROT_AXIS;
diff --git a/src/main/java/org/distorted/objects/TwistySquare.java b/src/main/java/org/distorted/objects/TwistySquare.java
index fccfb04b..5adbe5e7 100644
--- a/src/main/java/org/distorted/objects/TwistySquare.java
+++ b/src/main/java/org/distorted/objects/TwistySquare.java
@@ -31,11 +31,6 @@ import org.distorted.library.type.Static4D;
 
 abstract class TwistySquare extends TwistyObject
 {
-  static final int LAST_SL = 0; // automatic rotations: last rot was a 'slash' i.e. along ROT_AXIS[1]
-  static final int LAST_UP = 1; // last rot was along ROT_AXIS[0], upper layer and forelast was a slash
-  static final int LAST_LO = 2; // last rot was along ROT_AXIS[0], lower layer and forelast was a slash
-  static final int LAST_UL = 3; // two last rots were along ROT_AXIS[0] (so the next must be a slash)
-
   static final float COS15 = (SQ6+SQ2)/4;
   static final float SIN15 = (SQ6-SQ2)/4;
   static final float     X = 3*(2-SQ3)/2;
@@ -58,10 +53,8 @@ abstract class TwistySquare extends TwistyObject
       COLOR_RED   , COLOR_ORANGE
     };
 
-  int mLastRot;
-  int[] mBasicAngle;
+  private int[] mBasicAngle;
   Static4D[] mQuats;
-  int[][] mQuatMult;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -105,41 +98,6 @@ abstract class TwistySquare extends TwistyObject
       };
     }
 
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// QUATS[i]*QUATS[j] = QUATS[QUAT_MULT[i][j]]
-
-  void initializeQuatMult()
-    {
-    mQuatMult = new int[][]
-      {
-        {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,},
-        {  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11,  0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 12,},
-        {  2,  3,  4,  5,  6,  7,  8,  9, 10, 11,  0,  1, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 12, 13,},
-        {  3,  4,  5,  6,  7,  8,  9, 10, 11,  0,  1,  2, 15, 16, 17, 18, 19, 20, 21, 22, 23, 12, 13, 14,},
-        {  4,  5,  6,  7,  8,  9, 10, 11,  0,  1,  2,  3, 16, 17, 18, 19, 20, 21, 22, 23, 12, 13, 14, 15,},
-        {  5,  6,  7,  8,  9, 10, 11,  0,  1,  2,  3,  4, 17, 18, 19, 20, 21, 22, 23, 12, 13, 14, 15, 16,},
-        {  6,  7,  8,  9, 10, 11,  0,  1,  2,  3,  4,  5, 18, 19, 20, 21, 22, 23, 12, 13, 14, 15, 16, 17,},
-        {  7,  8,  9, 10, 11,  0,  1,  2,  3,  4,  5,  6, 19, 20, 21, 22, 23, 12, 13, 14, 15, 16, 17, 18,},
-        {  8,  9, 10, 11,  0,  1,  2,  3,  4,  5,  6,  7, 20, 21, 22, 23, 12, 13, 14, 15, 16, 17, 18, 19,},
-        {  9, 10, 11,  0,  1,  2,  3,  4,  5,  6,  7,  8, 21, 22, 23, 12, 13, 14, 15, 16, 17, 18, 19, 20,},
-        { 10, 11,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 22, 23, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,},
-        { 11,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 23, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,},
-        { 12, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13,  0, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,},
-        { 13, 12, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14,  1,  0, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,},
-        { 14, 13, 12, 23, 22, 21, 20, 19, 18, 17, 16, 15,  2,  1,  0, 11, 10,  9,  8,  7,  6,  5,  4,  3,},
-        { 15, 14, 13, 12, 23, 22, 21, 20, 19, 18, 17, 16,  3,  2,  1,  0, 11, 10,  9,  8,  7,  6,  5,  4,},
-        { 16, 15, 14, 13, 12, 23, 22, 21, 20, 19, 18, 17,  4,  3,  2,  1,  0, 11, 10,  9,  8,  7,  6,  5,},
-        { 17, 16, 15, 14, 13, 12, 23, 22, 21, 20, 19, 18,  5,  4,  3,  2,  1,  0, 11, 10,  9,  8,  7,  6,},
-        { 18, 17, 16, 15, 14, 13, 12, 23, 22, 21, 20, 19,  6,  5,  4,  3,  2,  1,  0, 11, 10,  9,  8,  7,},
-        { 19, 18, 17, 16, 15, 14, 13, 12, 23, 22, 21, 20,  7,  6,  5,  4,  3,  2,  1,  0, 11, 10,  9,  8,},
-        { 20, 19, 18, 17, 16, 15, 14, 13, 12, 23, 22, 21,  8,  7,  6,  5,  4,  3,  2,  1,  0, 11, 10,  9,},
-        { 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 23, 22,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0, 11, 10,},
-        { 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 23, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0, 11,},
-        { 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0,}
-      };
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   void initializeBasicAngle()
diff --git a/src/main/java/org/distorted/objects/TwistySquare1.java b/src/main/java/org/distorted/objects/TwistySquare1.java
index 56aabc2f..d0026b9a 100644
--- a/src/main/java/org/distorted/objects/TwistySquare1.java
+++ b/src/main/java/org/distorted/objects/TwistySquare1.java
@@ -23,27 +23,22 @@ import android.content.res.Resources;
 
 import org.distorted.helpers.ObjectShape;
 import org.distorted.helpers.ObjectSticker;
+import org.distorted.helpers.ScrambleState;
 import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedTexture;
 import org.distorted.library.mesh.MeshSquare;
 import org.distorted.library.type.Static4D;
 import org.distorted.main.R;
 
-import java.util.Random;
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 class TwistySquare1 extends TwistySquare
 {
   private static final int NUM_STICKERS = 6;
 
-  private final int[][] mPermittedAngles;
-  private final int[] mCornerQuat;
-  private int mPermittedUp, mPermittedDo;
   private ObjectSticker[] mStickers;
   private int[] mQuatNumber;
   private float[][] mCenters;
-  private int[][] mBadCornerQuats;
   private int[][] mStickerColor;
   private int[][] mStickerType;
 
@@ -53,11 +48,20 @@ class TwistySquare1 extends TwistySquare
                 DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
     {
     super(size, quat, texture, mesh, effects, moves, ObjectList.SQU1, res, scrWidth);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    if( mBasicAngle==null ) initializeBasicAngle();
-    mLastRot = LAST_SL;
-    mPermittedAngles = new int[2][mBasicAngle[0]];
-    mCornerQuat = new int[8];
+  ScrambleState[] getScrambleStates()
+    {
+    return null;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  int getScrambleType()
+    {
+    return 1;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -333,248 +337,9 @@ class TwistySquare1 extends TwistySquare
     return mStickerType[variant][cubitface]*FACE_COLORS.length + mStickerColor[cubit][cubitface];
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private boolean cornerIsUp(int index)
-    {
-    return ((index<4) ^ (mCornerQuat[index]>=12));
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private boolean cornerIsLeft(int index)
-    {
-    int q = mCornerQuat[index];
-
-    switch(index)
-      {
-      case 0:
-      case 4: return ((q>=3 && q<= 7) || (q>=18 && q<=22));
-      case 1:
-      case 5: return ((q>=6 && q<=10) || (q>=15 && q<=19));
-      case 2:
-      case 6: return ((q==0 || q==1 || (q>=9 && q<=11)) || (q>=12 && q<=16));
-      case 3:
-      case 7: return ((q>=0 && q<=4) || (q==12 || q==13 || (q>=21 && q<=23)));
-      }
-
-    return false;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private boolean quatIsBad(int quatIndex, int corner)
-    {
-    if( mBadCornerQuats ==null )
-      {
-      // quat indices that make corner cubits bandage the puzzle.
-      mBadCornerQuats = new int[][] { { 2, 8,17,23}, { 5,11,14,20} };
-      }
-
-    int index = (corner%2);
-
-    return ( quatIndex== mBadCornerQuats[index][0] ||
-             quatIndex== mBadCornerQuats[index][1] ||
-             quatIndex== mBadCornerQuats[index][2] ||
-             quatIndex== mBadCornerQuats[index][3]  );
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private boolean isPermittedDo(int angle)
-    {
-    if( mQuatMult==null ) initializeQuatMult();
-
-    for(int corner=0; corner<8; corner++)
-      {
-      if( !cornerIsUp(corner) )
-        {
-        int currQuat = mCornerQuat[corner];
-        int finalQuat= mQuatMult[angle][currQuat];
-        if( quatIsBad(finalQuat,corner) ) return false;
-        }
-      }
-
-    return true;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private boolean isPermittedUp(int angle)
-    {
-    if( mQuatMult==null ) initializeQuatMult();
-
-    for(int corner=0; corner<8; corner++)
-      {
-      if( cornerIsUp(corner) )
-        {
-        int currQuat = mCornerQuat[corner];
-        int finalQuat= mQuatMult[angle][currQuat];
-        if( quatIsBad(finalQuat,corner) ) return false;
-        }
-      }
-
-    return true;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void computePermittedAngles()
-    {
-    if( mBasicAngle==null ) initializeBasicAngle();
-
-    mPermittedDo = 0;
-
-    for(int angle=0; angle<mBasicAngle[0]; angle++)
-      {
-      if( isPermittedDo(angle ) ) mPermittedAngles[0][mPermittedDo++] = angle;
-      }
-
-    mPermittedUp = 0;
-
-    for(int angle=0; angle<mBasicAngle[0]; angle++)
-      {
-      if( isPermittedUp(angle ) ) mPermittedAngles[1][mPermittedUp++] = angle;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int getNextAngle(Random rnd, int layer)
-    {
-    if( mBasicAngle==null ) initializeBasicAngle();
-    int basic = mBasicAngle[0];
-    int num = layer==0 ? mPermittedDo:mPermittedUp;
-    int index = rnd.nextInt(num);
-    int angle = mPermittedAngles[layer][index];
-    return angle<basic/2 ? -angle : basic-angle;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int getNextAngleNotZero(Random rnd, int layer)
-    {
-    if( mBasicAngle==null ) initializeBasicAngle();
-    int basic = mBasicAngle[0];
-    int num = layer==0 ? mPermittedDo:mPermittedUp;
-    int index = rnd.nextInt(num-1);
-    int angle = mPermittedAngles[layer][index+1];
-    return angle<basic/2 ? -angle : basic-angle;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int makeQuat(int axis,int index)
-    {
-    if( axis==1 ) return 13;
-    if( index<0 ) index+=12;
-    return index;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private boolean cornerBelongs(int index, int axis, int layer)
-    {
-    if( axis==0 )
-      {
-      boolean up = cornerIsUp(index);
-      return ((up && layer==2) || (!up && layer==0));
-      }
-    else
-      {
-      boolean le = cornerIsLeft(index);
-      return ((le && layer==0) || (!le && layer==1));
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void updateCornerQuats(int[] rotInfo)
-    {
-    if( mQuatMult==null ) initializeQuatMult();
-
-    int axis = rotInfo[0];
-    int layer= rotInfo[1];
-    int index=-rotInfo[2];
-
-    int quat = makeQuat(axis,index);
-
-    for(int corner=0; corner<8; corner++)
-      {
-      if( cornerBelongs(corner,axis,layer) )
-        {
-        int curr = mCornerQuat[corner];
-        mCornerQuat[corner] = mQuatMult[quat][curr];
-        }
-      }
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // PUBLIC API
 
-  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int total)
-    {
-    int layer, nextAngle;
-
-    if( curr==0 )
-      {
-      for(int corner=0; corner<8; corner++) mCornerQuat[corner] = 0;
-      mLastRot = rnd.nextInt(4);
-      computePermittedAngles();
-      }
-
-    switch(mLastRot)
-      {
-      case LAST_SL: layer = rnd.nextInt(2);
-                    nextAngle = getNextAngle(rnd,layer);
-
-                    if( nextAngle==0 )
-                      {
-                      layer = 1-layer;
-                      nextAngle = getNextAngleNotZero(rnd,layer);
-                      }
-
-                    scramble[curr][0] = 0;
-                    scramble[curr][1] = 2*layer;
-                    scramble[curr][2] = nextAngle;
-                    mLastRot = layer==0 ? LAST_LO : LAST_UP;
-                    updateCornerQuats(scramble[curr]);
-                    break;
-      case LAST_LO:
-      case LAST_UP: layer = mLastRot==LAST_LO ? 1:0;
-                    nextAngle = getNextAngle(rnd,layer);
-
-                    if( nextAngle!=0 )
-                      {
-                      scramble[curr][0] = 0;
-                      scramble[curr][1] = 2*layer;
-                      scramble[curr][2] = nextAngle;
-                      updateCornerQuats(scramble[curr]);
-                      mLastRot = LAST_UL;
-                      }
-                    else
-                      {
-                      scramble[curr][0] = 1;
-                      scramble[curr][1] = rnd.nextInt(2);
-                      scramble[curr][2] = 1;
-                      mLastRot = LAST_SL;
-                      updateCornerQuats(scramble[curr]);
-                      computePermittedAngles();
-                      }
-
-                    break;
-      case LAST_UL: scramble[curr][0] = 1;
-                    scramble[curr][1] = rnd.nextInt(2);
-                    scramble[curr][2] = 1;
-                    mLastRot = LAST_SL;
-                    updateCornerQuats(scramble[curr]);
-                    computePermittedAngles();
-                    break;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
   public int getObjectName(int numLayers)
     {
     return R.string.squa1;
diff --git a/src/main/java/org/distorted/objects/TwistySquare2.java b/src/main/java/org/distorted/objects/TwistySquare2.java
index 3a489c32..ea2cd46d 100644
--- a/src/main/java/org/distorted/objects/TwistySquare2.java
+++ b/src/main/java/org/distorted/objects/TwistySquare2.java
@@ -30,19 +30,13 @@ import org.distorted.library.mesh.MeshSquare;
 import org.distorted.library.type.Static4D;
 import org.distorted.main.R;
 
-import java.util.Random;
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 class TwistySquare2 extends TwistySquare
 {
   private static final int NUM_STICKERS = 6;
 
-  private int mCurrState;
-  private int mIndexExcluded;
-  private final ScrambleState[] mStates;
-  private int[][] mScrambleTable;
-  private int[] mNumOccurences;
+  private ScrambleState[] mStates;
   private int[] mQuatNumber;
   private float[][] mCenters;
   private int[][] mStickerColor;
@@ -55,21 +49,31 @@ class TwistySquare2 extends TwistySquare
                 DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
     {
     super(size, quat, texture, mesh, effects, moves, ObjectList.SQU2, res, scrWidth);
+    }
 
-    int[] SL_6 = new int[] { 0,1,1, 1,1,1, 0,1,1, 1,1,1, 0,1,1, 1,1,1, 0,1,1, 1,1,1, 0,1,1, 1,1,1, 0,1,1, 1,1,1};
-    int[] SL_1 = new int[] { 0,1,1, 1,1,1 };
-    int[] LO_2 = new int[] { 0,-5,2, 0,-4,2, 0,-3,2, 0,-2,2, 0,-1,2, 0,1,2, 0,2,2, 0,3,2, 0,4,2, 0,5,2, 0,5,2 };
-    int[] LO_3 = new int[] { 0,-5,3, 0,-4,3, 0,-3,3, 0,-2,3, 0,-1,3, 0,1,3, 0,2,3, 0,3,3, 0,4,3, 0,5,3, 0,5,3 };
-    int[] LO_4 = new int[] { 0,-5,4, 0,-4,4, 0,-3,4, 0,-2,4, 0,-1,4, 0,1,4, 0,2,4, 0,3,4, 0,4,4, 0,5,4, 0,5,4 };
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    mStates = new ScrambleState[]
+  ScrambleState[] getScrambleStates()
+    {
+    if( mStates==null )
       {
-      new ScrambleState( new int[][] { LO_2, SL_6, LO_3 } ),  // 0
-      new ScrambleState( new int[][] { LO_2, null, LO_3 } ),  // SL
-      new ScrambleState( new int[][] { null, SL_1, LO_4 } ),  // LO
-      new ScrambleState( new int[][] { LO_4, SL_1, null } ),  // UP
-      new ScrambleState( new int[][] { null, SL_1, null } ),  // UL
-      };
+      int[] SL_6 = new int[] { 0,1,1, 1,1,1, 0,1,1, 1,1,1, 0,1,1, 1,1,1, 0,1,1, 1,1,1, 0,1,1, 1,1,1, 0,1,1, 1,1,1};
+      int[] SL_1 = new int[] { 0,1,1, 1,1,1 };
+      int[] LO_2 = new int[] { 0,-5,2, 0,-4,2, 0,-3,2, 0,-2,2, 0,-1,2, 0,1,2, 0,2,2, 0,3,2, 0,4,2, 0,5,2, 0,5,2 };
+      int[] LO_3 = new int[] { 0,-5,3, 0,-4,3, 0,-3,3, 0,-2,3, 0,-1,3, 0,1,3, 0,2,3, 0,3,3, 0,4,3, 0,5,3, 0,5,3 };
+      int[] LO_4 = new int[] { 0,-5,4, 0,-4,4, 0,-3,4, 0,-2,4, 0,-1,4, 0,1,4, 0,2,4, 0,3,4, 0,4,4, 0,5,4, 0,5,4 };
+
+      mStates = new ScrambleState[]
+        {
+        new ScrambleState( new int[][] { LO_2, SL_6, LO_3 } ),  // 0
+        new ScrambleState( new int[][] { LO_2, null, LO_3 } ),  // SL
+        new ScrambleState( new int[][] { null, SL_1, LO_4 } ),  // LO
+        new ScrambleState( new int[][] { LO_4, SL_1, null } ),  // UP
+        new ScrambleState( new int[][] { null, SL_1, null } ),  // UL
+        };
+      }
+
+    return mStates;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -367,57 +371,9 @@ class TwistySquare2 extends TwistySquare
     return mStickerType[type][cubitface]*FACE_COLORS.length + mStickerColor[cubit][cubitface];
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeScrambling()
-    {
-    int numLayers = getNumLayers();
-
-    if( mScrambleTable ==null )
-      {
-      mScrambleTable = new int[NUM_AXIS][numLayers];
-      }
-    if( mNumOccurences ==null )
-      {
-      int max=0;
-
-      for (ScrambleState mState : mStates)
-        {
-        int tmp = mState.getTotal(-1);
-        if (max < tmp) max = tmp;
-        }
-
-      mNumOccurences = new int[max];
-      }
-
-    for(int i=0; i<NUM_AXIS; i++)
-      for(int j=0; j<numLayers; j++) mScrambleTable[i][j] = 0;
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // PUBLIC API
 
-  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
-    {
-    if( curr==0 )
-      {
-      mCurrState     = 0;
-      mIndexExcluded =-1;
-      initializeScrambling();
-      }
-
-    int[] info= mStates[mCurrState].getRandom(rnd, mIndexExcluded, mScrambleTable, mNumOccurences);
-
-    scramble[curr][0] = info[0];
-    scramble[curr][1] = info[1];
-    scramble[curr][2] = info[2];
-
-    mCurrState     = info[3];
-    mIndexExcluded = info[0];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
   public int getObjectName(int numLayers)
     {
     return R.string.squa2;
diff --git a/src/main/java/org/distorted/objects/TwistyUltimate.java b/src/main/java/org/distorted/objects/TwistyUltimate.java
index 1c073ac6..44cd2b73 100644
--- a/src/main/java/org/distorted/objects/TwistyUltimate.java
+++ b/src/main/java/org/distorted/objects/TwistyUltimate.java
@@ -31,8 +31,6 @@ import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 import org.distorted.main.R;
 
-import java.util.Random;
-
 import static org.distorted.objects.TwistyMinx.MINX_DBLUE;
 import static org.distorted.objects.TwistyMinx.MINX_DGREEN;
 import static org.distorted.objects.TwistyMinx.MINX_DRED;
@@ -73,11 +71,7 @@ class TwistyUltimate extends TwistyObject
            MINX_DBLUE , MINX_DYELLOW, MINX_WHITE , MINX_GREY
          };
 
-  private int mCurrState;
-  private int mIndexExcluded;
-  private final ScrambleState[] mStates;
-  private int[][] mScrambleTable;
-  private int[] mNumOccurences;
+  private ScrambleState[] mStates;
   private int[] mBasicAngle;
   private Static4D[] mQuats;
   private int[][] mFaceMap;
@@ -91,13 +85,23 @@ class TwistyUltimate extends TwistyObject
                  MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
     {
     super(size, size, quat, texture, mesh, effects, moves, ObjectList.ULTI, res, scrWidth);
+    }
 
-    int[] tmp = {0,-1,0, 0,1,0, 1,-1,0, 1,1,0 };
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    mStates = new ScrambleState[]
+  ScrambleState[] getScrambleStates()
+    {
+    if( mStates==null )
       {
-      new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
-      };
+      int[] tmp = {0,-1,0, 0,1,0, 1,-1,0, 1,1,0 };
+
+      mStates = new ScrambleState[]
+        {
+        new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
+        };
+      }
+
+    return mStates;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -421,57 +425,9 @@ class TwistyUltimate extends TwistyObject
     return 0.67f;
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeScrambling()
-    {
-    int numLayers = getNumLayers();
-
-    if( mScrambleTable ==null )
-      {
-      mScrambleTable = new int[NUM_AXIS][numLayers];
-      }
-    if( mNumOccurences ==null )
-      {
-      int max=0;
-
-      for (ScrambleState mState : mStates)
-        {
-        int tmp = mState.getTotal(-1);
-        if (max < tmp) max = tmp;
-        }
-
-      mNumOccurences = new int[max];
-      }
-
-    for(int i=0; i<NUM_AXIS; i++)
-      for(int j=0; j<numLayers; j++) mScrambleTable[i][j] = 0;
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // PUBLIC API
 
-  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
-    {
-    if( curr==0 )
-      {
-      mCurrState     = 0;
-      mIndexExcluded =-1;
-      initializeScrambling();
-      }
-
-    int[] info= mStates[mCurrState].getRandom(rnd, mIndexExcluded, mScrambleTable, mNumOccurences);
-
-    scramble[curr][0] = info[0];
-    scramble[curr][1] = info[1];
-    scramble[curr][2] = info[2];
-
-    mCurrState     = info[3];
-    mIndexExcluded = info[0];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
   public Static3D[] getRotationAxis()
     {
     return ROT_AXIS;
