commit 4f2ad1670e0ef4a3dd495dd1273868a83a005191
Author: leszek <leszek@koltunski.pl>
Date:   Tue Oct 3 16:01:39 2023 +0200

    Fix SkewbSolver.

diff --git a/src/main/java/org/distorted/solvers/SolverSkewb.java b/src/main/java/org/distorted/solvers/SolverSkewb.java
index cf8f8e27..d1ca2da3 100644
--- a/src/main/java/org/distorted/solvers/SolverSkewb.java
+++ b/src/main/java/org/distorted/solvers/SolverSkewb.java
@@ -9,6 +9,7 @@
 
 package org.distorted.solvers;
 
+import static org.distorted.objectlib.tablebases.TBSkewb.FIXED;
 import static org.distorted.objectlib.tablebases.TBSkewb.FREE;
 
 import android.content.res.Resources;
@@ -47,6 +48,9 @@ public class SolverSkewb extends SolverTablebase
   private static final int ERROR_TWO_CENTERS        = -17;
   private static final int ERROR_TWO_CORNERS        = -18;
 
+  private static final int ERROR_FREE_CORNERS_NOT_EVEN    = -19;
+  private static final int ERROR_FREE_CORNERS_ROTATED     = -20;
+
   private TablebasesAbstract mSolver;
   private final int[] mFaceColors;
 
@@ -69,17 +73,35 @@ public class SolverSkewb extends SolverTablebase
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private int getCenters(TwistyObject object, int[] output)
+  private void createCenterPermutation(int[] output, int[] symbols, int[] perm)
+    {
+    for(int s=0; s<6; s++)
+      {
+      int symbol = symbols[s];
+
+      for(int p=0; p<6; p++)
+        if( perm[p]==symbol )
+          {
+          output[s] = p;
+          break;
+          }
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private int getCenters(TwistyObject object, int[] out)
     {
     final int[] map = {4,5,2,3,0,1};
-    int[] inverted_perm = new int[6];
+    int[] tmp = new int[6];
+    int[] mcl = new int[6];
     boolean[] present = new boolean[6];
 
     for(int i=0; i<6; i++)
       {
       int color = object.getCubitFaceStickerIndex(i+8,0) - 6;
       present[color] = true;
-      inverted_perm[i] = map[mFaceColors[color]];
+      tmp[i] = color;
       }
 
     if( !present[0] ) return ERROR_CENTER_0_MISSING;
@@ -89,7 +111,9 @@ public class SolverSkewb extends SolverTablebase
     if( !present[4] ) return ERROR_CENTER_4_MISSING;
     if( !present[5] ) return ERROR_CENTER_5_MISSING;
 
-    TablebaseHelpers.invertPermutation(inverted_perm,output);
+    for(int i=0; i<6; i++) mcl[i] = map[mFaceColors[i]];
+    createCenterPermutation(out,mcl,tmp);
+
     return 0;
     }
 
@@ -198,25 +222,6 @@ public class SolverSkewb extends SolverTablebase
     return 0;
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int retCornerPerm(int index, int[] perm)
-    {
-    switch(index)
-      {
-      case 0: return 0;
-      case 1: return FREE[perm[0]];
-      case 2: return FREE[perm[1]];
-      case 3: return 3;
-      case 4: return FREE[perm[2]];
-      case 5: return 5;
-      case 6: return 6;
-      case 7: return FREE[perm[3]];
-      }
-
-    return -1;
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   private void computeCornerQuats(int[] quats, int[][] corners, int[] perm)
@@ -224,16 +229,54 @@ public class SolverSkewb extends SolverTablebase
     final int[] zeroeth_face_map = { 4,2,3,5,1,5,4,1 };
     int[] twist = new int[8];
 
-    for(int i=0; i<8; i++)
+    for(int i=0; i<4; i++)
       {
-      int color = mFaceColors[zeroeth_face_map[i]];
-      int[] c = corners[retCornerPerm(i,perm)];
+      int fi = FIXED[i];
+      int colorFi = mFaceColors[zeroeth_face_map[fi]];
+      int[] cFi = corners[fi];
 
-           if( c[0]==color ) twist[i] = 0;
-      else if( c[1]==color ) twist[i] = 1;
-      else                   twist[i] = 2;
+           if( cFi[0]==colorFi ) twist[fi] = 0;
+      else if( cFi[1]==colorFi ) twist[fi] = 1;
+      else                       twist[fi] = 2;
       }
 
+    int[] inv_perm = new int[4];
+    TablebaseHelpers.invertPermutation(perm,inv_perm);
+
+    int common14 = commonCornerColor(corners[1], corners[4]);
+    int common27 = commonCornerColor(corners[2], corners[7]);
+    int common47 = commonCornerColor(corners[4], corners[7]);
+    int index;
+    int[] c;
+
+    index = FREE[inv_perm[0]];
+    c = corners[FREE[0]];
+
+         if(c[0]==common14) twist[index] = 0;
+    else if(c[1]==common14) twist[index] = 2;
+    else                    twist[index] = 1;
+
+    index = FREE[inv_perm[1]];
+    c = corners[FREE[1]];
+
+         if(c[0]==common27) twist[index] = 0;
+    else if(c[1]==common27) twist[index] = 2;
+    else                    twist[index] = 1;
+
+    index = FREE[inv_perm[2]];
+    c = corners[FREE[2]];
+
+         if(c[0]==common47) twist[index] = 0;
+    else if(c[1]==common47) twist[index] = 2;
+    else                    twist[index] = 1;
+
+    index = FREE[inv_perm[3]];
+    c = corners[FREE[3]];
+
+         if(c[0]==common47) twist[index] = 0;
+    else if(c[1]==common47) twist[index] = 2;
+    else                    twist[index] = 1;
+
     TBSkewb.fillInQuats(quats,perm,twist);
     }
 
@@ -265,16 +308,23 @@ public class SolverSkewb extends SolverTablebase
     if( result4<0 ) return result4;
 
     computeCornerQuats(quats,corners,freePerm);
+
+    int[] freeLoc = new int[4];
+    for(int f=0; f<4; f++) freeLoc[f] = TBSkewb.computeLocation(f,quats[FREE[f]]);
+    if( !TablebaseHelpers.permutationIsEven(freeLoc) ) return ERROR_FREE_CORNERS_NOT_EVEN;
+
     TBSkewb.computeCornerTwists(twist,quats);
 
     int total = 0;
-    for(int i=0; i<4; i++) total += twist[FREE[i]];
+    for(int i=0; i<8; i++) total += twist[i];
     if( (total%3)!=0 ) return ERROR_CORNER_TWISTED;
     int totalTwist = twist[0]+ 3*(twist[1]+ 3*(twist[2]+ 3*(twist[3]+ 3*(twist[4]+ 3*(twist[5]+ 3*twist[6])))));
 
-    int locationOfFree0 = TBSkewb.computeLocation(0,quats[1]);
+    int sumFixedTwists = twist[FIXED[0]]+twist[FIXED[1]]+twist[FIXED[2]]+twist[FIXED[3]];
+    int freeLoc1 = TBSkewb.permFree1(freeLoc[0],sumFixedTwists);
+    if( freeLoc[1] != freeLoc1 ) return ERROR_FREE_CORNERS_ROTATED;
 
-    return center_perm_num+ 360*(totalTwist + 2187*locationOfFree0);
+    return center_perm_num+ 360*(totalTwist + 2187*freeLoc[0]);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -358,26 +408,29 @@ public class SolverSkewb extends SolverTablebase
     {
     switch(index)
       {
-      case ERROR_CORNER_135_MISSING: return cornerError(res,1,3,5);
-      case ERROR_CORNER_134_MISSING: return cornerError(res,1,3,4);
-      case ERROR_CORNER_125_MISSING: return cornerError(res,1,2,5);
-      case ERROR_CORNER_124_MISSING: return cornerError(res,1,2,4);
-      case ERROR_CORNER_035_MISSING: return cornerError(res,0,3,5);
-      case ERROR_CORNER_034_MISSING: return cornerError(res,0,3,4);
-      case ERROR_CORNER_025_MISSING: return cornerError(res,0,2,5);
-      case ERROR_CORNER_024_MISSING: return cornerError(res,0,2,4);
-
-      case ERROR_CENTER_0_MISSING  : return centerError(res,0);
-      case ERROR_CENTER_1_MISSING  : return centerError(res,1);
-      case ERROR_CENTER_2_MISSING  : return centerError(res,2);
-      case ERROR_CENTER_3_MISSING  : return centerError(res,3);
-      case ERROR_CENTER_4_MISSING  : return centerError(res,4);
-      case ERROR_CENTER_5_MISSING  : return centerError(res,5);
-
-      case ERROR_CORNERS_CANNOT    : return res.getString(R.string.solver_generic_corners_cannot);
-      case ERROR_CORNER_TWISTED    : return res.getString(R.string.solver_generic_corner_twist);
-      case ERROR_TWO_CENTERS       : return res.getString(R.string.solver_generic_two_centers);
-      case ERROR_TWO_CORNERS       : return res.getString(R.string.solver_generic_two_corners);
+      case ERROR_CORNER_135_MISSING   : return cornerError(res,1,3,5);
+      case ERROR_CORNER_134_MISSING   : return cornerError(res,1,3,4);
+      case ERROR_CORNER_125_MISSING   : return cornerError(res,1,2,5);
+      case ERROR_CORNER_124_MISSING   : return cornerError(res,1,2,4);
+      case ERROR_CORNER_035_MISSING   : return cornerError(res,0,3,5);
+      case ERROR_CORNER_034_MISSING   : return cornerError(res,0,3,4);
+      case ERROR_CORNER_025_MISSING   : return cornerError(res,0,2,5);
+      case ERROR_CORNER_024_MISSING   : return cornerError(res,0,2,4);
+
+      case ERROR_CENTER_0_MISSING     : return centerError(res,0);
+      case ERROR_CENTER_1_MISSING     : return centerError(res,1);
+      case ERROR_CENTER_2_MISSING     : return centerError(res,2);
+      case ERROR_CENTER_3_MISSING     : return centerError(res,3);
+      case ERROR_CENTER_4_MISSING     : return centerError(res,4);
+      case ERROR_CENTER_5_MISSING     : return centerError(res,5);
+
+      case ERROR_CORNERS_CANNOT       : return res.getString(R.string.solver_generic_corners_cannot);
+      case ERROR_CORNER_TWISTED       : return res.getString(R.string.solver_generic_corner_twist);
+      case ERROR_TWO_CENTERS          : return res.getString(R.string.solver_generic_two_centers);
+      case ERROR_TWO_CORNERS          : return res.getString(R.string.solver_generic_two_corners);
+
+      case ERROR_FREE_CORNERS_NOT_EVEN: return res.getString(R.string.solver_generic_free_corners_odd);
+      case ERROR_FREE_CORNERS_ROTATED : return res.getString(R.string.solver_generic_free_corners_rotated);
       }
 
     return null;
diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml
index 6e81a15a..389f36ad 100755
--- a/src/main/res/values-de/strings.xml
+++ b/src/main/res/values-de/strings.xml
@@ -102,6 +102,8 @@
     <string name="solver_generic_edge_mono">%1$s-%2$s Kante?</string>
     <string name="solver_generic_edge_twice">Zwei %1$s-%2$s Kanten!</string>
     <string name="solver_generic_edge_three">Es sollten 3 %1$s Kanten sein!</string>
+    <string name="solver_generic_free_corners_odd">Freie Ecken bilden keine gerade Permutation!</string>
+    <string name="solver_generic_free_corners_rotated">Freie Ecken falsch gedreht!</string>
 
     <string name="solver_cube3_error1">Es gibt nur %1$d %2$s Facelets.</string>
     <string name="solver_cube3_error2">Nicht alle 12 Kanten gibt es genau einmal!</string>
diff --git a/src/main/res/values-es/strings.xml b/src/main/res/values-es/strings.xml
index 1850b695..5abaf4c5 100755
--- a/src/main/res/values-es/strings.xml
+++ b/src/main/res/values-es/strings.xml
@@ -102,6 +102,8 @@
     <string name="solver_generic_edge_mono">Borde %1$s-%2$s?</string>
     <string name="solver_generic_edge_twice">¡Dos bordes %1$s-%2$s!</string>
     <string name="solver_generic_edge_three">¡Debe haber 3 bordes %1$s!</string>
+    <string name="solver_generic_free_corners_odd">¡Las esquinas libres no forman una permutación uniforme!</string>
+    <string name="solver_generic_free_corners_rotated">¡Esquinas libres giradas incorrectamente!</string>
 
     <string name="solver_cube3_error1">Solo hay %1$d facetas %2$s.</string>
     <string name="solver_cube3_error2">¡No todos los 12 bordes existen exactamente una vez!</string>
diff --git a/src/main/res/values-fr/strings.xml b/src/main/res/values-fr/strings.xml
index 8694217c..676c59e9 100755
--- a/src/main/res/values-fr/strings.xml
+++ b/src/main/res/values-fr/strings.xml
@@ -102,6 +102,8 @@
     <string name="solver_generic_edge_mono">Bord %1$s-%2$s?</string>
     <string name="solver_generic_edge_twice">Deux bords %1$s-%2$s !</string>
     <string name="solver_generic_edge_three">Il devrait y avoir 3 bords %1$s !</string>
+    <string name="solver_generic_free_corners_odd">Les coins libres ne forment pas une permutation égale !</string>
+    <string name="solver_generic_free_corners_rotated">Coins libres mal tournés !</string>
 
     <string name="solver_cube3_error1">Il n\'y a que %1$d facettes %2$s.</string>
     <string name="solver_cube3_error2">Les 12 arêtes n\'existent pas exactement une fois !</string>
diff --git a/src/main/res/values-ja/strings.xml b/src/main/res/values-ja/strings.xml
index 9a8e10b9..cbbed2f8 100755
--- a/src/main/res/values-ja/strings.xml
+++ b/src/main/res/values-ja/strings.xml
@@ -102,6 +102,8 @@
     <string name="solver_generic_edge_mono">%1$s%2$s エッジ?</string>
     <string name="solver_generic_edge_twice">2 つの %1$s-%2$s エッジ!</string>
     <string name="solver_generic_edge_three">3 つの %1$s エッジがあるはずです!</string>
+    <string name="solver_generic_free_corners_odd">フリーコーナーは均等な順列を形成しません。</string>
+    <string name="solver_generic_free_corners_rotated">フリーコーナーが正しく回転していません!</string>
 
     <string name="solver_cube3_error1">%2$s小顔は%1$dつだけ</string>
     <string name="solver_cube3_error2">12 のエッジすべてが 存在するわけではありません。</string>
diff --git a/src/main/res/values-ko/strings.xml b/src/main/res/values-ko/strings.xml
index 7fb525de..bd9cf14a 100755
--- a/src/main/res/values-ko/strings.xml
+++ b/src/main/res/values-ko/strings.xml
@@ -102,6 +102,8 @@
     <string name="solver_generic_edge_mono">%1$s%2$s 에지?</string>
     <string name="solver_generic_edge_twice">두 개의 %1$s-%2$s 모서리!</string>
     <string name="solver_generic_edge_three">3개의 %1$s 모서리가 있어야 합니다!</string>
+    <string name="solver_generic_free_corners_odd">자유로운 모서리는 균등한 순열을 형성하지 않습니다!</string>
+    <string name="solver_generic_free_corners_rotated">자유 코너가 잘못 회전했습니다!</string>
 
     <string name="solver_cube3_error1">%2$s작은 얼굴은  %1$d개뿐입니다.</string>
     <string name="solver_cube3_error2">12개의 가장자리 모두가 정확하게 한 번 존재하지 않습니다!</string>
diff --git a/src/main/res/values-pl/strings.xml b/src/main/res/values-pl/strings.xml
index b70ea78a..6110eb56 100644
--- a/src/main/res/values-pl/strings.xml
+++ b/src/main/res/values-pl/strings.xml
@@ -102,6 +102,8 @@
     <string name="solver_generic_edge_mono">%1$s-%2$s krawędz?</string>
     <string name="solver_generic_edge_twice">Dwie krawędzie %1$s-%2$s!</string>
     <string name="solver_generic_edge_three">Powinny być 3 %1$s krawędzie!</string>
+    <string name="solver_generic_free_corners_odd">Wolne rogi powinny być parzysto spermutowane!</string>
+    <string name="solver_generic_free_corners_rotated">Wolne rogi są źle obrócone!</string>
 
     <string name="solver_cube3_error1">Jest tylko %1$d %2$s ścian.</string>
     <string name="solver_cube3_error2">Któraś z 12 krawędzi nie istnieje!</string>
diff --git a/src/main/res/values-ru/strings.xml b/src/main/res/values-ru/strings.xml
index a662d7d5..82171e6d 100755
--- a/src/main/res/values-ru/strings.xml
+++ b/src/main/res/values-ru/strings.xml
@@ -102,6 +102,8 @@
     <string name="solver_generic_edge_mono">%1$s-%2$s ребрo?</string>
     <string name="solver_generic_edge_twice">Два ребра %1$s-%2$s!</string>
     <string name="solver_generic_edge_three">Должно быть 3 %1$s ребра!</string>
+    <string name="solver_generic_free_corners_odd">Свободные углы не образуют четную перестановку!</string>
+    <string name="solver_generic_free_corners_rotated">Свободные углы неправильно повернуты!</string>
 
     <string name="solver_cube3_error1">Всего %1$d %2$s граней!</string>
     <string name="solver_cube3_error2">Не все 12 ребер существуют в единичном экземпляре!</string>
diff --git a/src/main/res/values-zh-rCN/strings.xml b/src/main/res/values-zh-rCN/strings.xml
index 03c774d3..34400594 100644
--- a/src/main/res/values-zh-rCN/strings.xml
+++ b/src/main/res/values-zh-rCN/strings.xml
@@ -108,6 +108,8 @@
     <string name="solver_generic_edge_mono">%1$s%2$s 边缘？</string>
     <string name="solver_generic_edge_twice">两个 %1$s-%2$s 边！</string>
     <string name="solver_generic_edge_three">应该有 3 %1$s 条边！</string>
+    <string name="solver_generic_free_corners_odd">自由角不形成均匀排列！</string>
+    <string name="solver_generic_free_corners_rotated">自由角旋转不正确！</string>
 
     <string name="solver_cube3_error1">只有%1$d个%2$s小面</string>
     <string name="solver_cube3_error2">并非所有12条边都只存在一次！</string>
diff --git a/src/main/res/values-zh-rTW/strings.xml b/src/main/res/values-zh-rTW/strings.xml
index b287d3d4..1e84450d 100644
--- a/src/main/res/values-zh-rTW/strings.xml
+++ b/src/main/res/values-zh-rTW/strings.xml
@@ -102,6 +102,8 @@
     <string name="solver_generic_edge_mono">%1$s%2$s 邊緣？</string>
     <string name="solver_generic_edge_twice">兩個 %1$s-%2$s 邊！</string>
     <string name="solver_generic_edge_three">應該有 3 %1$s 條邊！</string>
+    <string name="solver_generic_free_corners_odd">自由角不形成均勻排列！</string>
+    <string name="solver_generic_free_corners_rotated">自由角旋轉不正確！</string>
 
     <string name="solver_cube3_error1">只有%1$d個%2$s小臉</string>
     <string name="solver_cube3_error2">並非所有12條邊都只存在一次！</string>
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index 229296c1..c96da85f 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -122,6 +122,8 @@
     <string name="solver_generic_edge_mono">%1$s-%2$s edge?</string>
     <string name="solver_generic_edge_twice">Two %1$s-%2$s edges!</string>
     <string name="solver_generic_edge_three">There should be 3 %1$s edges!</string>
+    <string name="solver_generic_free_corners_odd">Free corners do not form an even permutation!</string>
+    <string name="solver_generic_free_corners_rotated">Free corners incorrectly rotated!</string>
 
     <string name="solver_cube3_error1">There are only %1$d %2$s facelets.</string>
     <string name="solver_cube3_error2">Not all 12 edges exist exactly once!</string>
@@ -131,7 +133,6 @@
     <string name="solver_cube3_error8">Timeout, no solution found in 20 seconds!</string>
     <string name="solver_cube3_error9">Solver interrupted!</string>
 
-
     <string name="color_yellow1">yellow</string>
     <string name="color_white1">white</string>
     <string name="color_blue1">blue</string>
