commit fa0f7a56fc4d16fef16c696434483e02aa597a22
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Wed Apr 8 00:18:35 2020 +0100

    Progress with the Solver - RubikCube.retObjectString() finished.
    
    What remains to be done here: ban changing colors of the centers of 3x3x3 faces, this shouldn't be allowed!

diff --git a/src/main/java/org/distorted/objects/RubikCube.java b/src/main/java/org/distorted/objects/RubikCube.java
index f41d21d6..3cdaf9ea 100644
--- a/src/main/java/org/distorted/objects/RubikCube.java
+++ b/src/main/java/org/distorted/objects/RubikCube.java
@@ -230,41 +230,115 @@ class RubikCube extends RubikObject
 // order: Up --> Right --> Front --> Down --> Left --> Back
 // (because the first implemented Solver - the two-phase Cube3 one - expects such order)
 //
-// s : size of the cube
+// Solved 3x3x3 Cube maps to "UUUUUUUUURRRRRRRRRFFFFFFFFFDDDDDDDDDLLLLLLLLLBBBBBBBBB"
 //
-// Left  :   index --> ((s-1) + index/s) * s + index%s
+// s : size of the cube; let index = a*s + b    (i.e. a,b = row,column)
+//
+// Up    :   index --> b<s-1 ? (s-1)*(s+4b)+a : 6*s*s -13*s +8 +a
 // Right :   index --> 6*s*s - 12*s + 7 - index
-// Bottom:   index --> s|index ? (s-1 - index/s) : (s*s + s-1 + 4*(index%s -1)*(s-1) - index/s)
-// Top   :   index -->
-// Front :   index -->
-// Back  :   index -->
+// Front :   index --> if b==0  : s*s - 1 - index
+//                     if b==s-1: 6*s*s -11*s +6 - index
+//                     else
+//                         a==0: s*s + s-1 + 4*(b-1)*(s-1) + 2*(s-2) + s
+//                         else: s*s + s-1 + 4*(b-1)*(s-1) + 2*(s-1-a)
+// Down  :   index --> b==0 ? (s-1-a) : s*s + s-1 + 4*(b-1)*(s-1) - a
+// Left  :   index --> (s-1-a)*s + b
+// Back  :   index --> if b==s-1: s*(s-1-a)
+//                     if b==0  : 5*s*s -12*s + 8 + (s-1-a)*s
+//                     else
+//                        if a==s-1: s*s + 4*(s-2-b)*(s-1)
+//                        else     : s*s + 4*(s-2-b)*(s-1) + s + (s-2-a)*2
 
   public String retObjectString()
     {
-    String ret="UUUUUUUUURRRRRRRRRFFFFFFFFFDDDDDDDDDLLLLLLLLLBBBBBBBBB";
-/*
-		int color;
-		int F=retColor(FRONT , 1,1);
-		int B=retColor(BACK  , 1,1);
-		int L=retColor(LEFT  , 1,1);
-		int R=retColor(RIGHT , 1,1);
-		int U=retColor(TOP   , 1,1);
-		int D=retColor(BOTTOM, 1,1);
-
-		for(int face in {TOP,RIGHT,FRONT,BOTTOM,LEFT,BACK} )
-		  for(int row=0; row<mSize; row++)
-			  for(int col=0; col<mSize; col++)
-			    {
-				  color = retColor(TOP,col,row);
-
-				  if(color==F) ret+="F";
-				  if(color==B) ret+="B";
-				  if(color==L) ret+="L";
-				  if(color==R) ret+="R";
-				  if(color==U) ret+="U";
-				  if(color==D) ret+="D";
-			    }
-*/
-    return ret;
+    StringBuilder objectString = new StringBuilder();
+    int size = getSize();
+    int len = size*size;
+    int cubitIndex, row, col;
+    int color;
+
+    final int RIGHT= 0;
+    final int LEFT = 1;
+    final int UP   = 2;
+    final int DOWN = 3;
+    final int FRONT= 4;
+    final int BACK = 5;
+
+    final char[] FACE_NAMES = { 'R', 'L', 'U', 'D', 'F', 'B'};
+
+    for(int i=0; i<len; i++)
+      {
+      row = i/size;
+      col = i%size;
+
+      cubitIndex = col<size-1 ? (size-1)*(size+4*col) + row : 6*size*size - 13*size + 8 + row;
+      color = getCubitFaceColorIndex(cubitIndex,UP);
+      objectString.append(FACE_NAMES[color]);
+      }
+
+    for(int i=0; i<len; i++)
+      {
+      cubitIndex = 6*size*size - 12*size +7 - i;
+      color = getCubitFaceColorIndex(cubitIndex,RIGHT);
+      objectString.append(FACE_NAMES[color]);
+      }
+
+    for(int i=0; i<len; i++)
+      {
+      row = i/size;
+      col = i%size;
+
+      if( col==size-1 ) cubitIndex = 6*size*size - 11*size + 6 -i;
+      else if( col==0 ) cubitIndex = size*size - 1 - i;
+      else
+        {
+        if( row==0 ) cubitIndex = size*size + size-1 + 4*(col-1)*(size-1) + 2*(size-2) + size;
+        else         cubitIndex = size*size + size-1 + 4*(col-1)*(size-1) + 2*(size-1-row);
+        }
+
+      color = getCubitFaceColorIndex(cubitIndex,FRONT);
+      objectString.append(FACE_NAMES[color]);
+      }
+
+    for(int i=0; i<len; i++)
+      {
+      row = i/size;
+      col = i%size;
+
+      cubitIndex = col==0 ? size-1-row : size*size + size-1 + 4*(col-1)*(size-1) - row;
+      color = getCubitFaceColorIndex(cubitIndex,DOWN);
+      objectString.append(FACE_NAMES[color]);
+      }
+
+    for(int i=0; i<len; i++)
+      {
+      row = i/size;
+      col = i%size;
+
+      cubitIndex = (size-1-row)*size + col;
+      color = getCubitFaceColorIndex(cubitIndex,LEFT);
+      objectString.append(FACE_NAMES[color]);
+      }
+
+    for(int i=0; i<len; i++)
+      {
+      row = i/size;
+      col = i%size;
+
+      if( col==size-1 ) cubitIndex = size*(size-1-row);
+      else if( col==0 ) cubitIndex = 5*size*size - 12*size + 8 + (size-1-row)*size;
+      else
+        {
+        if( row==size-1 ) cubitIndex = size*size + 4*(size-2-col)*(size-1);
+        else              cubitIndex = size*size + 4*(size-2-col)*(size-1) + size + 2*(size-2-row);
+        }
+
+      color = getCubitFaceColorIndex(cubitIndex,BACK);
+      objectString.append(FACE_NAMES[color]);
+      }
+
+    // android.util.Log.e("cube", "string: "+objectString.toString());
+
+    return objectString.toString();
     }
 }
diff --git a/src/main/java/org/distorted/objects/RubikObject.java b/src/main/java/org/distorted/objects/RubikObject.java
index 732bf16e..e9cf9f2a 100644
--- a/src/main/java/org/distorted/objects/RubikObject.java
+++ b/src/main/java/org/distorted/objects/RubikObject.java
@@ -260,6 +260,13 @@ public abstract class RubikObject extends DistortedNode
       }
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  int getCubitFaceColorIndex(int cubit, int face)
+    {
+    return mCubits[cubit].getColorIndex(face);
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Clamp all rotated positions to one of those original ones to avoid accumulating errors.
 
