commit c02544211f1123131fad52cef892c1a0363320e4
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Wed Mar 24 22:00:43 2021 +0100

    Automatic scrambling of the Evil Cube works!

diff --git a/src/main/java/org/distorted/bandaged/BandagedState.java b/src/main/java/org/distorted/bandaged/BandagedState.java
new file mode 100644
index 00000000..64838182
--- /dev/null
+++ b/src/main/java/org/distorted/bandaged/BandagedState.java
@@ -0,0 +1,116 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// 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.bandaged;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public class BandagedState
+{
+  private final int mNumX, mNumY, mNumZ;
+  private final int[] mInfo;
+  private final int[] mTmp;
+  private final int LEN = 4;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public BandagedState(int[] x, int[] y, int[] z)
+    {
+    mTmp = new int[LEN];
+
+    mNumX = x==null ? 0 : x.length/(LEN-1);
+    mNumY = y==null ? 0 : y.length/(LEN-1);
+    mNumZ = z==null ? 0 : z.length/(LEN-1);
+
+    mInfo = new int[LEN*(mNumX+mNumY+mNumZ)];
+    int start = 0;
+
+    for(int i=0; i<mNumX; i++)
+      {
+      mInfo[LEN*i   + start] = 0;
+      mInfo[LEN*i+1 + start] = x[(LEN-1)*i  ];
+      mInfo[LEN*i+2 + start] = x[(LEN-1)*i+1];
+      mInfo[LEN*i+3 + start] = x[(LEN-1)*i+2];
+      }
+
+    start = LEN*mNumX;
+
+    for(int i=0; i<mNumY; i++)
+      {
+      mInfo[LEN*i   + start] = 1;
+      mInfo[LEN*i+1 + start] = y[(LEN-1)*i  ];
+      mInfo[LEN*i+2 + start] = y[(LEN-1)*i+1];
+      mInfo[LEN*i+3 + start] = y[(LEN-1)*i+2];
+      }
+
+    start = LEN*(mNumX+mNumY);
+
+    for(int i=0; i<mNumZ; i++)
+      {
+      mInfo[LEN*i   + start] = 2;
+      mInfo[LEN*i+1 + start] = z[(LEN-1)*i  ];
+      mInfo[LEN*i+2 + start] = z[(LEN-1)*i+1];
+      mInfo[LEN*i+3 + start] = z[(LEN-1)*i+2];
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private int getIndex(int num, boolean useX, boolean useY, boolean useZ)
+    {
+    int current= -1, total= mNumX + mNumY + mNumZ;
+
+    for(int i=0; i<total; i++)
+      {
+      if( (mInfo[LEN*i]==0 && useX) || (mInfo[LEN*i]==1 && useY) || (mInfo[LEN*i]==2 && useZ) )
+        {
+        if( ++current==num ) return i;
+        }
+      }
+
+    return -1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int getTotal(boolean useX, boolean useY, boolean useZ)
+    {
+    int total = 0;
+
+    if( useX ) total += mNumX;
+    if( useY ) total += mNumY;
+    if( useZ ) total += mNumZ;
+
+    return total;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int[] getInfo(int num, boolean useX, boolean useY, boolean useZ)
+    {
+    int index = getIndex(num,useX,useY,useZ);
+
+    mTmp[0] = mInfo[LEN*index  ];   // axis
+    mTmp[1] = mInfo[LEN*index+1];   // row
+    mTmp[2] = mInfo[LEN*index+2];   // angle
+    mTmp[3] = mInfo[LEN*index+3];   // next state
+
+    return mTmp;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/distorted/bandaged/BandagedStateGraph.java b/src/main/java/org/distorted/bandaged/BandagedStateGraph.java
new file mode 100644
index 00000000..8033acb9
--- /dev/null
+++ b/src/main/java/org/distorted/bandaged/BandagedStateGraph.java
@@ -0,0 +1,665 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// 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.bandaged;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+import java.util.ArrayList;
+
+public class BandagedStateGraph
+{
+  private static final int CORNER_S = 0;
+  private static final int CORNER_X = 1;
+  private static final int CORNER_Y = 2;
+  private static final int CORNER_Z = 3;
+
+  private static final int CENTER_0 = 0;
+  private static final int CENTER_1 = 1;
+  private static final int CENTER_2 = 2;
+  private static final int CENTER_3 = 3;
+
+  private int mID;
+  private final int[] mMoves;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public BandagedStateGraph(int id)
+    {
+    mID = id;
+    mMoves = createMoves(mID);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public static void computeGraph()
+    {
+    ArrayList<BandagedStateGraph> graph;
+
+    int id = 0;
+    int id1 = setCenter(id  , CENTER_2, 0);
+    int id2 = setCenter(id1 , CENTER_2, 1);
+    int id3 = setCenter(id2 , CENTER_3, 2);
+    int id4 = setCenter(id3 , CENTER_2, 3);
+
+    int id5 = setCorner(id4 , CORNER_X, 0);
+    int id6 = setCorner(id5 , CORNER_Y, 1);
+    int id7 = setCorner(id6 , CORNER_X, 2);
+    int id8 = setCorner(id7 , CORNER_Z, 3);
+    int id9 = setCorner(id8 , CORNER_Y, 4);
+    int id10= setCorner(id9 , CORNER_Y, 5);
+    int id11= setCorner(id10, CORNER_S, 6);
+    int id12= setCorner(id11, CORNER_Z, 7);
+
+    BandagedStateGraph bsg = new BandagedStateGraph(id12);
+    graph = new ArrayList<>();
+    graph.add(bsg);
+
+    insertChildren(graph,id12);
+    pruneGraph(graph);
+    remapGraph(graph);
+
+    int num = graph.size();
+    android.util.Log.e("D", "\n"+num+" states\n");
+
+    for(int i=0; i<num; i++)
+      {
+      bsg = graph.get(i);
+      android.util.Log.e("D", formatMoves(bsg));
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static void insertChildren(ArrayList<BandagedStateGraph> list, int id)
+    {
+    BandagedStateGraph bsg = findState(list,id);
+
+    if( bsg==null )
+      {
+      android.util.Log.e("D", "error: "+id+" doesn't exist");
+      return;
+      }
+
+    for(int i=0; i<12; i++)
+      {
+      int move = bsg.getMove(i);
+
+      if( move!=0 )
+        {
+        BandagedStateGraph tmp = findState(list,move);
+
+        if( tmp==null )
+          {
+          tmp = new BandagedStateGraph(move);
+          list.add(tmp);
+          insertChildren(list,move);
+          }
+        }
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static void pruneGraph(ArrayList<BandagedStateGraph> list)
+    {
+    int num = list.size(), numAxis;
+    boolean pruned = false;
+    BandagedStateGraph bsg;
+
+    for(int i=0; i<num; i++)
+      {
+      bsg = list.get(i);
+      numAxis = bsg.numAxis();
+
+      if( numAxis<2 )
+        {
+        list.remove(i);
+        int id = bsg.getID();
+        pruned = true;
+        remapID(list,id,0);
+        break;
+        }
+      }
+
+    if( pruned ) pruneGraph(list);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static void remapGraph(ArrayList<BandagedStateGraph> list)
+    {
+    int id, num = list.size();
+    BandagedStateGraph bsg;
+
+    for(int i=0; i<num; i++ )
+      {
+      bsg = list.get(i);
+      id = bsg.getID();
+      bsg.setID(i);
+      remapID(list,id,i);
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static void remapID(ArrayList<BandagedStateGraph> list, int id, int newId)
+    {
+    BandagedStateGraph bsg;
+    int size = list.size();
+
+    for(int i=0; i<size; i++)
+      {
+      bsg = list.get(i);
+
+      for(int j=0; j<12; j++)
+        {
+        if( bsg.getMove(j)==id ) bsg.setMove(j,newId);
+        }
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static BandagedStateGraph findState(ArrayList<BandagedStateGraph> list, int id)
+    {
+    BandagedStateGraph bsg;
+    int num = list.size();
+
+    for(int i=0; i<num; i++)
+      {
+      bsg= list.get(i);
+      if( bsg.getID() == id ) return bsg;
+      }
+
+    return null;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static String formatMoves(BandagedStateGraph bsg)
+    {
+    String x = getTable(bsg,0);
+    String y = getTable(bsg,3);
+    String z = getTable(bsg,6);
+
+    return "    new BandagedState( "+x+", "+y+", "+z+" ),";
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static String getTable(BandagedStateGraph sc, int index)
+    {
+    String ret = "";
+
+    if( index==0 || index==3 )
+      {
+      int m0 = sc.getMove(index  );
+      int m1 = sc.getMove(index+1);
+      int m2 = sc.getMove(index+2);
+
+      if( m0==0 && m1==0 && m2==0 ) return formatL("null");
+
+      if( m0!=0 ) ret += formatRet(ret,2, 1,m0);
+      if( m1!=0 ) ret += formatRet(ret,2, 2,m1);
+      if( m2!=0 ) ret += formatRet(ret,2,-1,m2);
+      }
+    else
+      {
+      int m0 = sc.getMove(index  );
+      int m1 = sc.getMove(index+1);
+      int m2 = sc.getMove(index+2);
+      int m3 = sc.getMove(index+3);
+      int m4 = sc.getMove(index+4);
+      int m5 = sc.getMove(index+5);
+
+      if( m0==0 && m1==0 && m2==0 && m3==0 && m4==0 && m5==0 )
+        {
+        return formatL("null");
+        }
+
+      if( m0!=0 ) ret += formatRet(ret,0, 1,m0);
+      if( m1!=0 ) ret += formatRet(ret,0, 2,m1);
+      if( m2!=0 ) ret += formatRet(ret,0,-1,m2);
+      if( m3!=0 ) ret += formatRet(ret,2, 1,m3);
+      if( m4!=0 ) ret += formatRet(ret,2, 2,m4);
+      if( m5!=0 ) ret += formatRet(ret,2,-1,m5);
+      }
+
+    return formatL("new int[] {" + ret + "}");
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static String formatRet(String str, int row, int angle, int id)
+    {
+    String ret = str.length()!=0 ? ",":"";
+
+    ret += row;
+    ret += angle<0 ? "," : ", ";
+    ret += angle;
+
+         if( id< 10 ) ret += (",  "+id);
+    else if( id<100 ) ret += (", " +id);
+    else              ret += (","  +id);
+
+    return ret;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static final int LENGTH = 38;
+
+  private static String formatL(String input)
+    {
+    int len = input.length();
+    String ret = input;
+    for(int i=0 ;i<LENGTH-len; i++) ret += " ";
+    return ret;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private int getID()
+    {
+    return mID;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void setID(int id)
+    {
+    mID = id;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private int getMove(int index)
+    {
+    return (index>=0 && index<12) ? mMoves[index] : -1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private int numAxis()
+    {
+    int num = 0;
+
+    if( mMoves[ 0]!=0 || mMoves[ 1]!=0 || mMoves[ 2]!=0 ) num++;
+    if( mMoves[ 3]!=0 || mMoves[ 4]!=0 || mMoves[ 5]!=0 ) num++;
+    if( mMoves[ 6]!=0 || mMoves[ 7]!=0 || mMoves[ 8]!=0 ) num++;
+    if( mMoves[ 9]!=0 || mMoves[10]!=0 || mMoves[11]!=0 ) num++;
+
+    return num;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void setMove(int index, int newMove)
+    {
+    if( index>=0 && index<12 ) mMoves[index] = newMove;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static String debug(int id)
+    {
+    int ce0 = getCenter(id,0);
+    int ce1 = getCenter(id,1);
+    int ce2 = getCenter(id,2);
+    int ce3 = getCenter(id,3);
+
+    int co0 = getCorner(id,0);
+    int co1 = getCorner(id,1);
+    int co2 = getCorner(id,2);
+    int co3 = getCorner(id,3);
+    int co4 = getCorner(id,4);
+    int co5 = getCorner(id,5);
+    int co6 = getCorner(id,6);
+    int co7 = getCorner(id,7);
+
+    String center = centerString(ce0) + centerString(ce1) + centerString(ce2) + centerString(ce3);
+    String corner = cornerString(co0) + cornerString(co1) + cornerString(co2) + cornerString(co3) +
+                    cornerString(co4) + cornerString(co5) + cornerString(co6) + cornerString(co7);
+
+    return center + " -" + corner;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static String centerString(int center)
+    {
+    return " "+center;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static String cornerString(int corner)
+    {
+    switch(corner)
+      {
+      case CORNER_S: return " S";
+      case CORNER_X: return " X";
+      case CORNER_Y: return " Y";
+      case CORNER_Z: return " Z";
+      }
+
+    return "?";
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static int[] createMoves(int id)
+    {
+    int[] ret = new int[12];
+
+    boolean moveX  = xPossible(id);
+    boolean moveY  = yPossible(id);
+    boolean moveZ0 = z0Possible(id);
+    boolean moveZ2 = z2Possible(id);
+
+    if( moveX ) createXmoves(id,ret);
+    else        { ret[ 0] = 0; ret[ 1] = 0; ret[ 2] = 0; }
+    if( moveY ) createYmoves(id,ret);
+    else        { ret[ 3] = 0; ret[ 4] = 0; ret[ 5] = 0; }
+    if( moveZ0) createZ0moves(id,ret);
+    else        { ret[ 6] = 0; ret[ 7] = 0; ret[ 8] = 0; }
+    if( moveZ2) createZ2moves(id,ret);
+    else        { ret[ 9] = 0; ret[10] = 0; ret[11] = 0; }
+
+    return ret;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static boolean xPossible(int id)
+    {
+    if( getCorner(id,4)==CORNER_X ) return false;
+    if( getCorner(id,5)==CORNER_X ) return false;
+    if( getCorner(id,6)==CORNER_X ) return false;
+    if( getCorner(id,7)==CORNER_X ) return false;
+
+    if( getCenter(id,1)==CENTER_1 ) return false;
+    if( getCenter(id,2)==CENTER_1 ) return false;
+    if( getCenter(id,3)==CENTER_1 ) return false;
+
+    return true;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static boolean yPossible(int id)
+    {
+    if( getCorner(id,2)==CORNER_Y ) return false;
+    if( getCorner(id,3)==CORNER_Y ) return false;
+    if( getCorner(id,6)==CORNER_Y ) return false;
+    if( getCorner(id,7)==CORNER_Y ) return false;
+
+    if( getCenter(id,0)==CENTER_0 ) return false;
+    if( getCenter(id,2)==CENTER_0 ) return false;
+    if( getCenter(id,3)==CENTER_0 ) return false;
+
+    return true;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static boolean z0Possible(int id)
+    {
+    if( getCorner(id,0)==CORNER_Z ) return false;
+    if( getCorner(id,2)==CORNER_Z ) return false;
+    if( getCorner(id,4)==CORNER_Z ) return false;
+    if( getCorner(id,6)==CORNER_Z ) return false;
+
+    if( getCenter(id,0)==CENTER_1 ) return false;
+    if( getCenter(id,1)==CENTER_0 ) return false;
+
+    return true;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static boolean z2Possible(int id)
+    {
+    if( getCorner(id,1)==CORNER_Z ) return false;
+    if( getCorner(id,3)==CORNER_Z ) return false;
+    if( getCorner(id,5)==CORNER_Z ) return false;
+    if( getCorner(id,7)==CORNER_Z ) return false;
+
+    if( getCenter(id,0)==CENTER_3 ) return false;
+    if( getCenter(id,1)==CENTER_2 ) return false;
+
+    return true;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static int getCorner(int id, int index)
+    {
+    return (id>>(14-2*index))&3;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static int getCenter(int id, int index)
+    {
+    return (id>>(22-2*index))&3;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static int setCorner(int id, int corner, int index)
+    {
+    return id + ((corner-getCorner(id,index))<<(14-2*index));
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static int setCenter(int id, int center, int index)
+    {
+    return id + ((center-getCenter(id,index))<<(22-2*index));
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static void createXmoves(int id, int[] moves)
+    {
+    int id1 = rotateX(id);
+    moves[0] = id1;
+    int id2 = rotateX(id1);
+    moves[1] = id2;
+    int id3 = rotateX(id2);
+    moves[2] = id3;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static void createYmoves(int id, int[] moves)
+    {
+    int id1 = rotateY(id);
+    moves[3] = id1;
+    int id2 = rotateY(id1);
+    moves[4] = id2;
+    int id3 = rotateY(id2);
+    moves[5] = id3;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static void createZ0moves(int id, int[] moves)
+    {
+    int id1 = rotateZ0(id);
+    moves[6] = id1;
+    int id2 = rotateZ0(id1);
+    moves[7] = id2;
+    int id3 = rotateZ0(id2);
+    moves[8] = id3;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static void createZ2moves(int id, int[] moves)
+    {
+    int id1 = rotateZ2(id);
+    moves[ 9] = id1;
+    int id2 = rotateZ2(id1);
+    moves[10] = id2;
+    int id3 = rotateZ2(id2);
+    moves[11] = id3;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static int rotateX(int id)
+    {
+    int newCorner4 = rotCornerX(getCorner(id,5));
+    int newCorner5 = rotCornerX(getCorner(id,7));
+    int newCorner6 = rotCornerX(getCorner(id,4));
+    int newCorner7 = rotCornerX(getCorner(id,6));
+    int newCenter  = rotCenter (getCenter(id,0));
+
+    int id1 = setCorner(id ,newCorner4,4);
+    int id2 = setCorner(id1,newCorner5,5);
+    int id3 = setCorner(id2,newCorner6,6);
+    int id4 = setCorner(id3,newCorner7,7);
+    int id5 = setCenter(id4,newCenter ,0);
+
+    return id5;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static int rotateY(int id)
+    {
+    int newCorner2 = rotCornerY(getCorner(id,6));
+    int newCorner3 = rotCornerY(getCorner(id,2));
+    int newCorner6 = rotCornerY(getCorner(id,7));
+    int newCorner7 = rotCornerY(getCorner(id,3));
+    int newCenter  = rotCenter (getCenter(id,1));
+
+    int id1 = setCorner(id ,newCorner2,2);
+    int id2 = setCorner(id1,newCorner3,3);
+    int id3 = setCorner(id2,newCorner6,6);
+    int id4 = setCorner(id3,newCorner7,7);
+    int id5 = setCenter(id4,newCenter ,1);
+
+    return id5;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static int rotateZ0(int id)
+    {
+    int newCorner0 = rotCornerZ(getCorner(id,2));
+    int newCorner2 = rotCornerZ(getCorner(id,6));
+    int newCorner4 = rotCornerZ(getCorner(id,0));
+    int newCorner6 = rotCornerZ(getCorner(id,4));
+    int newCenter  = rotCenter (getCenter(id,2));
+
+    int id1 = setCorner(id ,newCorner0,0);
+    int id2 = setCorner(id1,newCorner2,2);
+    int id3 = setCorner(id2,newCorner4,4);
+    int id4 = setCorner(id3,newCorner6,6);
+    int id5 = setCenter(id4,newCenter ,2);
+
+    return id5;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static int rotateZ2(int id)
+    {
+    int newCorner1 = rotCornerZ(getCorner(id,3));
+    int newCorner3 = rotCornerZ(getCorner(id,7));
+    int newCorner5 = rotCornerZ(getCorner(id,1));
+    int newCorner7 = rotCornerZ(getCorner(id,5));
+    int newCenter  = rotCenter (getCenter(id,3));
+
+    int id1 = setCorner(id ,newCorner1,1);
+    int id2 = setCorner(id1,newCorner3,3);
+    int id3 = setCorner(id2,newCorner5,5);
+    int id4 = setCorner(id3,newCorner7,7);
+    int id5 = setCenter(id4,newCenter ,3);
+
+    return id5;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static int rotCornerX(int corner)
+    {
+    switch(corner)
+      {
+      case CORNER_S: return CORNER_S;
+      case CORNER_X: android.util.Log.e("DIST", "rotateX: ERROR");
+                     return CORNER_S;
+      case CORNER_Y: return CORNER_Z;
+      case CORNER_Z: return CORNER_Y;
+      }
+
+    return CORNER_S;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static int rotCornerY(int corner)
+    {
+    switch(corner)
+      {
+      case CORNER_S: return CORNER_S;
+      case CORNER_X: return CORNER_Z;
+      case CORNER_Y: android.util.Log.e("DIST", "rotateY: ERROR");
+                     return CORNER_S;
+      case CORNER_Z: return CORNER_X;
+      }
+
+    return CORNER_S;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static int rotCornerZ(int corner)
+    {
+    switch(corner)
+      {
+      case CORNER_S: return CORNER_S;
+      case CORNER_X: return CORNER_Y;
+      case CORNER_Y: return CORNER_X;
+      case CORNER_Z: android.util.Log.e("DIST", "rotateZ: ERROR");
+                     return CORNER_S;
+      }
+
+    return CORNER_S;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static int rotCenter(int center)
+    {
+    switch(center)
+      {
+      case CENTER_0: return CENTER_3;
+      case CENTER_1: return CENTER_0;
+      case CENTER_2: return CENTER_1;
+      case CENTER_3: return CENTER_2;
+      }
+
+    return CENTER_0;
+    }
+}
diff --git a/src/main/java/org/distorted/objects/TwistyBandaged3Plate.java b/src/main/java/org/distorted/objects/TwistyBandaged3Plate.java
index cf337357..fde5f544 100644
--- a/src/main/java/org/distorted/objects/TwistyBandaged3Plate.java
+++ b/src/main/java/org/distorted/objects/TwistyBandaged3Plate.java
@@ -25,6 +25,7 @@ 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.bandaged.BandagedState;
 import org.distorted.main.R;
 
 import java.util.Random;
@@ -38,92 +39,6 @@ class TwistyBandaged3Plate extends TwistyBandagedAbstract
   private boolean mUseY;
   private boolean mUseZ;
 
-  private static class State
-    {
-    private final int mNumX, mNumY, mNumZ;
-    private final int[] mInfo;
-    private final int[] mTmp;
-    private final int LEN = 4;
-
-    State(int[] x, int[] y, int[] z)
-      {
-      mTmp = new int[LEN];
-
-      mNumX = x==null ? 0 : x.length/(LEN-1);
-      mNumY = y==null ? 0 : y.length/(LEN-1);
-      mNumZ = z==null ? 0 : z.length/(LEN-1);
-
-      mInfo = new int[LEN*(mNumX+mNumY+mNumZ)];
-      int start = 0;
-
-      for(int i=0; i<mNumX; i++)
-        {
-        mInfo[LEN*i   + start] = 0;
-        mInfo[LEN*i+1 + start] = x[(LEN-1)*i  ];
-        mInfo[LEN*i+2 + start] = x[(LEN-1)*i+1];
-        mInfo[LEN*i+3 + start] = x[(LEN-1)*i+2];
-        }
-
-      start = LEN*mNumX;
-
-      for(int i=0; i<mNumY; i++)
-        {
-        mInfo[LEN*i   + start] = 1;
-        mInfo[LEN*i+1 + start] = y[(LEN-1)*i  ];
-        mInfo[LEN*i+2 + start] = y[(LEN-1)*i+1];
-        mInfo[LEN*i+3 + start] = y[(LEN-1)*i+2];
-        }
-
-      start = LEN*(mNumX+mNumY);
-
-      for(int i=0; i<mNumZ; i++)
-        {
-        mInfo[LEN*i   + start] = 2;
-        mInfo[LEN*i+1 + start] = z[(LEN-1)*i  ];
-        mInfo[LEN*i+2 + start] = z[(LEN-1)*i+1];
-        mInfo[LEN*i+3 + start] = z[(LEN-1)*i+2];
-        }
-      }
-
-    private int getIndex(int num, boolean useX, boolean useY, boolean useZ)
-      {
-      int current= -1, total= mNumX + mNumY + mNumZ;
-
-      for(int i=0; i<total; i++)
-        {
-        if( (mInfo[LEN*i]==0 && useX) || (mInfo[LEN*i]==1 && useY) || (mInfo[LEN*i]==2 && useZ) )
-          {
-          if( ++current==num ) return i;
-          }
-        }
-
-      return -1;
-      }
-
-    int getTotal(boolean useX, boolean useY, boolean useZ)
-      {
-      int total = 0;
-
-      if( useX ) total += mNumX;
-      if( useY ) total += mNumY;
-      if( useZ ) total += mNumZ;
-
-      return total;
-      }
-
-    int[] getInfo(int num, boolean useX, boolean useY, boolean useZ)
-      {
-      int index = getIndex(num,useX,useY,useZ);
-
-      mTmp[0] = mInfo[LEN*index  ];   // axis
-      mTmp[1] = mInfo[LEN*index+1];   // row
-      mTmp[2] = mInfo[LEN*index+2];   // angle
-      mTmp[3] = mInfo[LEN*index+3];   // next state
-
-      return mTmp;
-      }
-    }
-
   // The 16 'significant' states of the 3Plate bandaged cube.
   // One State means one arrangement of the three 2x2 'plates'. Such State precisely defines which
   // rotations of the Cube are possible.
@@ -137,25 +52,25 @@ class TwistyBandaged3Plate extends TwistyBandagedAbstract
   // then we will land in state 10. If we make move (2,2), we will land in state 13. There are no other
   // 'x' moves that lead to a 'significant' state.
 
-  private final State[] mStates = new State[]
-      {
-         new State( new int[] { 2,-1, 1, 2, 1, 6                  }, new int[] { 0,-1, 5, 0, 1, 3                  }, new int[] { 2,-1, 2, 2, 1, 4                  } ),
-         new State( new int[] { 2, 1, 0                           }, null                                           , new int[] { 2, 1,10, 2, 2, 7                  } ),
-         new State( null                                           , new int[] { 0,-1,11, 0, 2, 8                  }, new int[] { 2, 1, 0                           } ),
-         new State( new int[] { 2, 1,12, 2, 2, 9                  }, new int[] { 0,-1, 0                           }, null                                            ),
-         new State( new int[] { 2,-1,10, 2, 2,13                  }, null                                           , new int[] { 2,-1, 0                           } ),
-         new State( null                                           , new int[] { 0, 1, 0                           }, new int[] { 2,-1,11, 2, 2,14                  } ),
-         new State( new int[] { 2,-1, 0                           }, new int[] { 0, 1,12, 0, 2,15                  }, null                                            ),
-         new State( null                                           , new int[] { 2,-2, 7, 2,-1, 7, 2, 1, 7, 2, 2, 7}, new int[] { 2,-1,10, 2, 2, 1                  } ),
-         new State( new int[] { 0,-2, 8, 0,-1, 8, 0, 1, 8, 0, 2, 8}, new int[] { 0, 1,11, 0, 2, 2                  }, null                                            ),
-         new State( new int[] { 2,-1,12, 2, 2, 3                  }, null                                           , new int[] { 0,-2, 9, 0,-1, 9, 0, 1, 9, 0, 2, 9} ),
-         new State( new int[] { 2,-1,13, 2, 1, 4                  }, new int[] { 2,-2,10, 2,-1,10, 2, 1,10, 2, 2,10}, new int[] { 2,-1, 1, 2, 1, 7                  } ),
-         new State( new int[] { 0,-2,11, 0,-1,11, 0, 1,11, 0, 2,11}, new int[] { 0,-1, 8, 0, 1, 2                  }, new int[] { 2,-1,14, 2, 1, 5                  } ),
-         new State( new int[] { 2,-1, 3, 2, 1, 9                  }, new int[] { 0,-1, 6, 0, 1,15                  }, new int[] { 0,-2,12, 0,-1,12, 0, 1,12, 0, 2,12} ),
-         new State( new int[] { 2, 1,10, 2, 2, 4                  }, new int[] { 2,-2,13, 2,-1,13, 2, 1,13, 2, 2,13}, null                                            ),
-         new State( new int[] { 0,-2,14, 0,-1,14, 0, 1,14, 0, 2,14}, null                                           , new int[] { 2, 1,11, 2, 2, 5                  } ),
-         new State( null                                           , new int[] { 0,-1,12, 0, 2, 6                  }, new int[] { 0,-2,15, 0,-1,15, 0, 1,15, 0, 2,15} )
-      };
+  private final BandagedState[] mStates = new BandagedState[]
+    {
+    new BandagedState( new int[] { 2,-1, 1, 2, 1, 6                  }, new int[] { 0,-1, 5, 0, 1, 3                  }, new int[] { 2,-1, 2, 2, 1, 4                  } ),
+    new BandagedState( new int[] { 2, 1, 0                           }, null                                           , new int[] { 2, 1,10, 2, 2, 7                  } ),
+    new BandagedState( null                                           , new int[] { 0,-1,11, 0, 2, 8                  }, new int[] { 2, 1, 0                           } ),
+    new BandagedState( new int[] { 2, 1,12, 2, 2, 9                  }, new int[] { 0,-1, 0                           }, null                                            ),
+    new BandagedState( new int[] { 2,-1,10, 2, 2,13                  }, null                                           , new int[] { 2,-1, 0                           } ),
+    new BandagedState( null                                           , new int[] { 0, 1, 0                           }, new int[] { 2,-1,11, 2, 2,14                  } ),
+    new BandagedState( new int[] { 2,-1, 0                           }, new int[] { 0, 1,12, 0, 2,15                  }, null                                            ),
+    new BandagedState( null                                           , new int[] { 2,-2, 7, 2,-1, 7, 2, 1, 7, 2, 2, 7}, new int[] { 2,-1,10, 2, 2, 1                  } ),
+    new BandagedState( new int[] { 0,-2, 8, 0,-1, 8, 0, 1, 8, 0, 2, 8}, new int[] { 0, 1,11, 0, 2, 2                  }, null                                            ),
+    new BandagedState( new int[] { 2,-1,12, 2, 2, 3                  }, null                                           , new int[] { 0,-2, 9, 0,-1, 9, 0, 1, 9, 0, 2, 9} ),
+    new BandagedState( new int[] { 2,-1,13, 2, 1, 4                  }, new int[] { 2,-2,10, 2,-1,10, 2, 1,10, 2, 2,10}, new int[] { 2,-1, 1, 2, 1, 7                  } ),
+    new BandagedState( new int[] { 0,-2,11, 0,-1,11, 0, 1,11, 0, 2,11}, new int[] { 0,-1, 8, 0, 1, 2                  }, new int[] { 2,-1,14, 2, 1, 5                  } ),
+    new BandagedState( new int[] { 2,-1, 3, 2, 1, 9                  }, new int[] { 0,-1, 6, 0, 1,15                  }, new int[] { 0,-2,12, 0,-1,12, 0, 1,12, 0, 2,12} ),
+    new BandagedState( new int[] { 2, 1,10, 2, 2, 4                  }, new int[] { 2,-2,13, 2,-1,13, 2, 1,13, 2, 2,13}, null                                            ),
+    new BandagedState( new int[] { 0,-2,14, 0,-1,14, 0, 1,14, 0, 2,14}, null                                           , new int[] { 2, 1,11, 2, 2, 5                  } ),
+    new BandagedState( null                                           , new int[] { 0,-1,12, 0, 2, 6                  }, new int[] { 0,-2,15, 0,-1,15, 0, 1,15, 0, 2,15} )
+    };
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/main/java/org/distorted/objects/TwistyBandagedEvil.java b/src/main/java/org/distorted/objects/TwistyBandagedEvil.java
index 5d8b2ca0..0db3bdda 100644
--- a/src/main/java/org/distorted/objects/TwistyBandagedEvil.java
+++ b/src/main/java/org/distorted/objects/TwistyBandagedEvil.java
@@ -21,6 +21,7 @@ package org.distorted.objects;
 
 import android.content.res.Resources;
 
+import org.distorted.bandaged.BandagedState;
 import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedTexture;
 import org.distorted.library.mesh.MeshSquare;
@@ -33,6 +34,164 @@ import java.util.Random;
 
 class TwistyBandagedEvil extends TwistyBandagedAbstract
 {
+   private int mCurrState;
+   private boolean mUseX;
+   private boolean mUseY;
+   private boolean mUseZ;
+
+   // The list of all 'significant' states of the Evil Cube, just like in the 3Plate Cube class.
+   // This time the list got computed automatically - by the BandagedStateGraph.computeGraph().
+
+   private final BandagedState[] mStates = new BandagedState[]
+     {
+     new BandagedState( new int[] {2, 1,  1,2,-1,  2}         , new int[] {2, 2,142,2,-1, 28}         , new int[] {0, 1,114}                   ),
+     new BandagedState( new int[] {2, 2,  2}                  , new int[] {2,-1,143}                  , null                                   ),
+     new BandagedState( new int[] {2, 2,  1}                  , null                                  , new int[] {0, 1,  3,0, 2, 47}          ),
+     new BandagedState( new int[] {2, 1,  4}                  , new int[] {2, 1,132,2,-1,131}         , new int[] {0, 1, 47,0,-1,  2}          ),
+     new BandagedState( new int[] {2,-1,  3}                  , new int[] {2, 1,  5,2,-1,  6}         , null                                   ),
+     new BandagedState( null                                  , new int[] {2, 2,  6,2,-1,  4}         , new int[] {0, 1, 51}                   ),
+     new BandagedState( null                                  , new int[] {2, 1,  4,2, 2,  5}         , new int[] {2, 2,  7,2,-1, 80}          ),
+     new BandagedState( new int[] {2, 2,  8}                  , null                                  , new int[] {2, 1, 80,2, 2,  6}          ),
+     new BandagedState( new int[] {2, 2,  7}                  , null                                  , new int[] {0,-1,  9}                   ),
+     new BandagedState( new int[] {2, 1, 10,2, 2, 11,2,-1, 12}, null                                  , new int[] {0, 1,  8}                   ),
+     new BandagedState( new int[] {2, 1, 11,2, 2, 12,2,-1,  9}, null                                  , new int[] {0,-1,118}                   ),
+     new BandagedState( new int[] {2, 1, 12,2, 2,  9,2,-1, 10}, null                                  , new int[] {2, 1, 77}                   ),
+     new BandagedState( new int[] {2, 1,  9,2, 2, 10,2,-1, 11}, null                                  , new int[] {2, 1, 13,2, 2,143}          ),
+     new BandagedState( new int[] {2, 1, 14,2, 2, 15,2,-1, 16}, new int[] {2, 1, 57,2,-1, 58}         , new int[] {2, 1,143,2,-1, 12}          ),
+     new BandagedState( new int[] {2, 1, 15,2, 2, 16,2,-1, 13}, null                                  , new int[] {2, 1, 41}                   ),
+     new BandagedState( new int[] {2, 1, 16,2, 2, 13,2,-1, 14}, null                                  , new int[] {0, 1, 82}                   ),
+     new BandagedState( new int[] {2, 1, 13,2, 2, 14,2,-1, 15}, new int[] {2, 1, 17,2,-1, 18}         , new int[] {0, 1,111,0,-1,115}          ),
+     new BandagedState( null                                  , new int[] {2, 2, 18,2,-1, 16}         , new int[] {0,-1,139}                   ),
+     new BandagedState( new int[] {2, 1, 19,2,-1, 20}         , new int[] {2, 1, 16,2, 2, 17}         , new int[] {2, 1,142}                   ),
+     new BandagedState( new int[] {2, 2, 20,2,-1, 18}         , null                                  , new int[] {2, 1, 39,2, 2,140}          ),
+     new BandagedState( new int[] {2, 1, 18,2, 2, 19}         , new int[] {2, 1, 21}                  , null                                   ),
+     new BandagedState( null                                  , new int[] {2,-1, 20}                  , new int[] {0,-1, 22}                   ),
+     new BandagedState( new int[] {2, 2, 23,2,-1, 24}         , null                                  , new int[] {0, 1, 21}                   ),
+     new BandagedState( new int[] {2, 1, 24,2, 2, 22}         , null                                  , new int[] {2, 1, 92}                   ),
+     new BandagedState( new int[] {2, 1, 22,2,-1, 23}         , null                                  , new int[] {0, 1, 25}                   ),
+     new BandagedState( new int[] {2, 1, 26,2, 2, 27}         , null                                  , new int[] {0,-1, 24}                   ),
+     new BandagedState( new int[] {2, 1, 27,2,-1, 25}         , new int[] {2, 1, 74}                  , null                                   ),
+     new BandagedState( new int[] {2, 2, 25,2,-1, 26}         , null                                  , new int[] {2, 1, 28,2, 2,124}          ),
+     new BandagedState( new int[] {2, 1, 29,2, 2, 30,2,-1, 31}, new int[] {2,-1,142}                  , new int[] {2, 1,124,2,-1, 27}          ),
+     new BandagedState( new int[] {2, 1, 30,2, 2, 31,2,-1, 28}, null                                  , new int[] {2, 1,141}                   ),
+     new BandagedState( new int[] {2, 1, 31,2, 2, 28,2,-1, 29}, null                                  , new int[] {0, 1,130}                   ),
+     new BandagedState( new int[] {2, 1, 28,2, 2, 29,2,-1, 30}, new int[] {2, 1, 32,2,-1, 33}         , new int[] {0, 1, 89,0,-1, 90}          ),
+     new BandagedState( null                                  , new int[] {2, 2, 33,2,-1, 31}         , new int[] {0,-1,137}                   ),
+     new BandagedState( new int[] {2, 1, 34}                  , new int[] {2, 1, 31,2, 2, 32}         , null                                   ),
+     new BandagedState( new int[] {2,-1, 33}                  , null                                  , new int[] {2, 1, 35}                   ),
+     new BandagedState( null                                  , new int[] {2,-1, 36}                  , new int[] {2,-1, 34}                   ),
+     new BandagedState( null                                  , new int[] {2, 1, 35}                  , new int[] {2,-1, 37}                   ),
+     new BandagedState( null                                  , new int[] {2, 1, 38,2, 2, 93}         , new int[] {2, 1, 36}                   ),
+     new BandagedState( new int[] {2, 1, 39}                  , new int[] {2, 1, 93,2,-1, 37}         , null                                   ),
+     new BandagedState( new int[] {2,-1, 38}                  , new int[] {2, 1, 40,2,-1, 64}         , new int[] {2, 1,140,2,-1, 19}          ),
+     new BandagedState( new int[] {2, 1, 41,2,-1, 42}         , new int[] {2, 2, 64,2,-1, 39}         , null                                   ),
+     new BandagedState( new int[] {2, 2, 42,2,-1, 40}         , null                                  , new int[] {2,-1, 14}                   ),
+     new BandagedState( new int[] {2, 1, 40,2, 2, 41}         , null                                  , new int[] {0, 1, 43,0, 2,128}          ),
+     new BandagedState( new int[] {2, 1, 44,2,-1, 45}         , new int[] {2, 1,114,2, 2,113,2,-1, 86}, new int[] {0, 1,128,0,-1, 42}          ),
+     new BandagedState( new int[] {2, 2, 45,2,-1, 43}         , new int[] {2, 1, 48,2,-1,108}         , new int[] {2,-1, 81}                   ),
+     new BandagedState( new int[] {2, 1, 43,2, 2, 44}         , null                                  , new int[] {0, 1, 46}                   ),
+     new BandagedState( null                                  , new int[] {2, 1, 47}                  , new int[] {0,-1, 45}                   ),
+     new BandagedState( null                                  , new int[] {2,-1, 46}                  , new int[] {0, 2,  2,0,-1,  3}          ),
+     new BandagedState( new int[] {2,-1, 49}                  , new int[] {2, 2,108,2,-1, 44}         , null                                   ),
+     new BandagedState( new int[] {2, 1, 48}                  , null                                  , new int[] {0, 1, 50}                   ),
+     new BandagedState( null                                  , new int[] {2, 1, 51,2, 2, 52}         , new int[] {0,-1, 49}                   ),
+     new BandagedState( null                                  , new int[] {2, 1, 52,2,-1, 50}         , new int[] {0,-1,  5}                   ),
+     new BandagedState( null                                  , new int[] {2, 2, 50,2,-1, 51}         , new int[] {2,-1, 53}                   ),
+     new BandagedState( null                                  , new int[] {2, 1, 54,2, 2, 55}         , new int[] {2, 1, 52}                   ),
+     new BandagedState( null                                  , new int[] {2, 1, 55,2,-1, 53}         , new int[] {0,-1,104}                   ),
+     new BandagedState( null                                  , new int[] {2, 2, 53,2,-1, 54}         , new int[] {0, 2, 56,0,-1, 65}          ),
+     new BandagedState( new int[] {2, 1, 57}                  , null                                  , new int[] {0, 1, 65,0, 2, 55}          ),
+     new BandagedState( new int[] {2,-1, 56}                  , new int[] {2, 2, 58,2,-1, 13}         , null                                   ),
+     new BandagedState( null                                  , new int[] {2, 1, 13,2, 2, 57}         , new int[] {2,-1, 59}                   ),
+     new BandagedState( new int[] {2, 1, 60}                  , null                                  , new int[] {2, 1, 58}                   ),
+     new BandagedState( new int[] {2,-1, 59}                  , null                                  , new int[] {2, 1, 61}                   ),
+     new BandagedState( new int[] {2,-1, 62}                  , null                                  , new int[] {2,-1, 60}                   ),
+     new BandagedState( new int[] {2, 1, 61}                  , new int[] {2,-1, 63}                  , null                                   ),
+     new BandagedState( null                                  , new int[] {2, 1, 62}                  , new int[] {2, 1, 64}                   ),
+     new BandagedState( null                                  , new int[] {2, 1, 39,2, 2, 40}         , new int[] {2,-1, 63}                   ),
+     new BandagedState( new int[] {2, 1, 66,2,-1, 67}         , new int[] {2, 1, 78,2, 2, 79,2,-1, 80}, new int[] {0, 1, 55,0,-1, 56}          ),
+     new BandagedState( new int[] {2, 2, 67,2,-1, 65}         , new int[] {2,-1,107}                  , null                                   ),
+     new BandagedState( new int[] {2, 1, 65,2, 2, 66}         , null                                  , new int[] {0, 1, 68}                   ),
+     new BandagedState( null                                  , new int[] {2, 1, 69}                  , new int[] {0,-1, 67}                   ),
+     new BandagedState( null                                  , new int[] {2,-1, 68}                  , new int[] {0,-1, 70}                   ),
+     new BandagedState( null                                  , new int[] {2,-1, 71}                  , new int[] {0, 1, 69}                   ),
+     new BandagedState( new int[] {2,-1, 72}                  , new int[] {2, 1, 70}                  , null                                   ),
+     new BandagedState( new int[] {2, 1, 71}                  , null                                  , new int[] {0,-1, 73}                   ),
+     new BandagedState( new int[] {2, 1, 74,2, 2, 75}         , null                                  , new int[] {0, 1, 72}                   ),
+     new BandagedState( new int[] {2, 1, 75,2,-1, 73}         , new int[] {2,-1, 26}                  , new int[] {0, 1, 83,0,-1,138}          ),
+     new BandagedState( new int[] {2, 2, 73,2,-1, 74}         , new int[] {2, 1, 76,2,-1, 77}         , null                                   ),
+     new BandagedState( null                                  , new int[] {2, 2, 77,2,-1, 75}         , new int[] {0, 1, 78}                   ),
+     new BandagedState( null                                  , new int[] {2, 1, 75,2, 2, 76}         , new int[] {2,-1, 11}                   ),
+     new BandagedState( null                                  , new int[] {2, 1, 79,2, 2, 80,2,-1, 65}, new int[] {0,-1, 76}                   ),
+     new BandagedState( null                                  , new int[] {2, 1, 80,2, 2, 65,2,-1, 78}, new int[] {2,-1,110}                   ),
+     new BandagedState( new int[] {2, 1, 81,2,-1, 82}         , new int[] {2, 1, 65,2, 2, 78,2,-1, 79}, new int[] {2, 1,  6,2,-1,  7}          ),
+     new BandagedState( new int[] {2, 2, 82,2,-1, 80}         , null                                  , new int[] {2, 1, 44}                   ),
+     new BandagedState( new int[] {2, 1, 80,2, 2, 81}         , new int[] {2, 1, 83,2,-1, 84}         , new int[] {0,-1, 15}                   ),
+     new BandagedState( null                                  , new int[] {2, 2, 84,2,-1, 82}         , new int[] {0, 2,138,0,-1, 74}          ),
+     new BandagedState( new int[] {2, 1, 85}                  , new int[] {2, 1, 82,2, 2, 83}         , null                                   ),
+     new BandagedState( new int[] {2,-1, 84}                  , null                                  , new int[] {2, 1, 86,2, 2,119}          ),
+     new BandagedState( new int[] {2, 1, 87,2,-1, 88}         , new int[] {2, 1, 43,2, 2,114,2,-1,113}, new int[] {2, 1,119,2,-1, 85}          ),
+     new BandagedState( new int[] {2, 2, 88,2,-1, 86}         , null                                  , new int[] {2, 1, 94}                   ),
+     new BandagedState( new int[] {2, 1, 86,2, 2, 87}         , new int[] {2, 1, 89}                  , null                                   ),
+     new BandagedState( null                                  , new int[] {2,-1, 88}                  , new int[] {0, 2, 90,0,-1, 31}          ),
+     new BandagedState( new int[] {2, 1, 91,2, 2, 92}         , null                                  , new int[] {0, 1, 31,0, 2, 89}          ),
+     new BandagedState( new int[] {2, 1, 92,2,-1, 90}         , null                                  , new int[] {0, 1, 93}                   ),
+     new BandagedState( new int[] {2, 2, 90,2,-1, 91}         , null                                  , new int[] {2,-1, 23}                   ),
+     new BandagedState( null                                  , new int[] {2, 2, 37,2,-1, 38}         , new int[] {0,-1, 91}                   ),
+     new BandagedState( null                                  , new int[] {2,-1, 95}                  , new int[] {2,-1, 87}                   ),
+     new BandagedState( null                                  , new int[] {2, 1, 94}                  , new int[] {2,-1, 96}                   ),
+     new BandagedState( null                                  , new int[] {2, 1, 97}                  , new int[] {2, 1, 95}                   ),
+     new BandagedState( new int[] {2, 1, 98}                  , new int[] {2,-1, 96}                  , null                                   ),
+     new BandagedState( new int[] {2,-1, 97}                  , null                                  , new int[] {2,-1, 99}                   ),
+     new BandagedState( new int[] {2, 2,100,2,-1,101}         , null                                  , new int[] {2, 1, 98}                   ),
+     new BandagedState( new int[] {2, 1,101,2, 2, 99}         , new int[] {2, 1,111,2,-1,112}         , null                                   ),
+     new BandagedState( new int[] {2, 1, 99,2,-1,100}         , new int[] {2, 1,102}                  , new int[] {2, 1,108,2,-1,109}          ),
+     new BandagedState( new int[] {2, 1,103,2,-1,104}         , new int[] {2,-1,101}                  , null                                   ),
+     new BandagedState( new int[] {2, 2,104,2,-1,102}         , null                                  , new int[] {2,-1,105}                   ),
+     new BandagedState( new int[] {2, 1,102,2, 2,103}         , null                                  , new int[] {0, 1, 54}                   ),
+     new BandagedState( new int[] {2,-1,106}                  , null                                  , new int[] {2, 1,103}                   ),
+     new BandagedState( new int[] {2, 1,105}                  , null                                  , new int[] {2, 1,107}                   ),
+     new BandagedState( null                                  , new int[] {2, 1, 66}                  , new int[] {2,-1,106}                   ),
+     new BandagedState( null                                  , new int[] {2, 1, 44,2, 2, 48}         , new int[] {2, 2,109,2,-1,101}          ),
+     new BandagedState( new int[] {2,-1,110}                  , null                                  , new int[] {2, 1,101,2, 2,108}          ),
+     new BandagedState( new int[] {2, 1,109}                  , null                                  , new int[] {2, 1, 79}                   ),
+     new BandagedState( null                                  , new int[] {2, 2,112,2,-1,100}         , new int[] {0, 2,115,0,-1, 16}          ),
+     new BandagedState( null                                  , new int[] {2, 1,100,2, 2,111}         , new int[] {2, 1,113}                   ),
+     new BandagedState( null                                  , new int[] {2, 1, 86,2, 2, 43,2,-1,114}, new int[] {2,-1,112}                   ),
+     new BandagedState( null                                  , new int[] {2, 1,113,2, 2, 86,2,-1, 43}, null                                   ),
+     new BandagedState( new int[] {2, 2,116}                  , null                                  , new int[] {0, 1, 16,0, 2,111}          ),
+     new BandagedState( new int[] {2, 2,115}                  , null                                  , new int[] {2,-1,117}                   ),
+     new BandagedState( new int[] {2, 1,118}                  , null                                  , new int[] {2, 1,116}                   ),
+     new BandagedState( new int[] {2,-1,117}                  , null                                  , new int[] {0, 1, 10}                   ),
+     new BandagedState( null                                  , new int[] {2, 1,120,2, 2,121,2,-1,122}, new int[] {2, 2, 85,2,-1, 86}          ),
+     new BandagedState( null                                  , new int[] {2, 1,121,2, 2,122,2,-1,119}, new int[] {2,-1,129}                   ),
+     new BandagedState( null                                  , new int[] {2, 1,122,2, 2,119,2,-1,120}, new int[] {0, 1,125}                   ),
+     new BandagedState( null                                  , new int[] {2, 1,119,2, 2,120,2,-1,121}, new int[] {0,-1,123}                   ),
+     new BandagedState( null                                  , new int[] {2, 2,124}                  , new int[] {0, 1,122}                   ),
+     new BandagedState( null                                  , new int[] {2, 2,123}                  , new int[] {2, 2, 27,2,-1, 28}          ),
+     new BandagedState( null                                  , new int[] {2, 1,126}                  , new int[] {0,-1,121}                   ),
+     new BandagedState( null                                  , new int[] {2,-1,125}                  , new int[] {2,-1,127}                   ),
+     new BandagedState( null                                  , new int[] {2, 2,128}                  , new int[] {2, 1,126}                   ),
+     new BandagedState( null                                  , new int[] {2, 2,127}                  , new int[] {0, 2, 42,0,-1, 43}          ),
+     new BandagedState( new int[] {2, 2,130,2,-1,131}         , null                                  , new int[] {2, 1,120}                   ),
+     new BandagedState( new int[] {2, 1,131,2, 2,129}         , null                                  , new int[] {0,-1, 30}                   ),
+     new BandagedState( new int[] {2, 1,129,2,-1,130}         , new int[] {2, 1,  3,2, 2,132}         , null                                   ),
+     new BandagedState( null                                  , new int[] {2, 2,131,2,-1,  3}         , new int[] {0,-1,133}                   ),
+     new BandagedState( null                                  , new int[] {2,-1,134}                  , new int[] {0, 1,132}                   ),
+     new BandagedState( new int[] {2,-1,135}                  , new int[] {2, 1,133}                  , null                                   ),
+     new BandagedState( new int[] {2, 1,134}                  , null                                  , new int[] {0,-1,136}                   ),
+     new BandagedState( new int[] {2, 1,137}                  , null                                  , new int[] {0, 1,135}                   ),
+     new BandagedState( new int[] {2,-1,136}                  , null                                  , new int[] {0, 1, 32}                   ),
+     new BandagedState( new int[] {2, 1,139}                  , null                                  , new int[] {0, 1, 74,0, 2, 83}          ),
+     new BandagedState( new int[] {2,-1,138}                  , null                                  , new int[] {0, 1, 17}                   ),
+     new BandagedState( null                                  , new int[] {2, 1,141}                  , new int[] {2, 2, 19,2,-1, 39}          ),
+     new BandagedState( null                                  , new int[] {2,-1,140}                  , new int[] {2,-1, 29}                   ),
+     new BandagedState( null                                  , new int[] {2, 1, 28}                  , new int[] {2,-1, 18}                   ),
+     new BandagedState( null                                  , new int[] {2, 1,  1}                  , new int[] {2, 2, 12,2,-1, 13}          )
+     };
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
   private static final float[][] POSITIONS = new float[][]
       {
         { 1.0f,  1.0f, -1.0f},
@@ -77,38 +236,35 @@ class TwistyBandagedEvil extends TwistyBandagedAbstract
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // PUBLIC API
-// TODO
 
   public void randomizeNewScramble(int[][] scramble, Random rnd, int num)
     {
     if( num==0 )
       {
-      scramble[num][0] = rnd.nextInt(ROTATION_AXIS.length);
-      }
-    else
-      {
-      int newVector = rnd.nextInt(ROTATION_AXIS.length-1);
-      scramble[num][0] = (newVector>=scramble[num-1][0] ? newVector+1 : newVector);
+      mCurrState = 0;
+      mUseX = true;
+      mUseY = true;
+      mUseZ = true;
       }
 
-    float rowFloat = rnd.nextFloat();
+    int total = mStates[mCurrState].getTotal(mUseX,mUseY,mUseZ);
+    int random= rnd.nextInt(total);
+    int[] info= mStates[mCurrState].getInfo(random,mUseX,mUseY,mUseZ);
 
-    for(int row=0; row<mRowChances.length; row++)
-      {
-      if( rowFloat<=mRowChances[row] )
-        {
-        scramble[num][1] = row;
-        break;
-        }
-      }
+    scramble[num][0] = info[0];
+    scramble[num][1] = info[1];
+    scramble[num][2] = info[2];
 
-    switch( rnd.nextInt(4) )
+    mCurrState = info[3];
+
+    switch(info[0])
       {
-      case 0: scramble[num][2] = -2; break;
-      case 1: scramble[num][2] = -1; break;
-      case 2: scramble[num][2] =  1; break;
-      case 3: scramble[num][2] =  2; break;
+      case 0: mUseX = false; mUseY = true ; mUseZ = true ; break;
+      case 1: mUseX = true ; mUseY = false; mUseZ = true ; break;
+      case 2: mUseX = true ; mUseY = true ; mUseZ = false; break;
       }
+
+    //android.util.Log.e("D", (info[0]==0 ? "X" : (info[0]==1 ? "Y" : "Z")) + info[2] +" --> "+info[3]);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
