commit d3c2aa29a5f58f6a0845cba2d32f0edbd403efc9
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Mon Feb 27 14:04:50 2023 +0100

    Pyraminx solver: progress

diff --git a/src/main/java/org/distorted/solvers/SolverPyraminx.java b/src/main/java/org/distorted/solvers/SolverPyraminx.java
index 2f66ee3b..11c5c940 100644
--- a/src/main/java/org/distorted/solvers/SolverPyraminx.java
+++ b/src/main/java/org/distorted/solvers/SolverPyraminx.java
@@ -47,6 +47,11 @@ public class SolverPyraminx extends SolverTablebase
   private static final int ERROR_C_V_DONT_MATCH   = -19;
   private static final int ERROR_TWO_EDGES        = -20;
 
+  private static final int[][] edgeColors = new int[][]
+      {
+          {3,2},{1,3},{0,3},{2,1},{2,0},{1,0}  // order of those pairs determines edge twist
+      };
+
   TablebasesAbstract mSolver;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -63,10 +68,10 @@ public class SolverPyraminx extends SolverTablebase
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private boolean pieceEqual2(int[] piece, int c1, int c2)
+  private boolean pieceEqual2(int[] piece, int[] colors)
     {
-    return ( (piece[0]==c1 && piece[1]==c2) ||
-             (piece[0]==c2 && piece[1]==c1)  );
+    return ( (piece[0]==colors[0] && piece[1]==colors[1]) ||
+             (piece[0]==colors[1] && piece[1]==colors[0])  );
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -123,29 +128,23 @@ public class SolverPyraminx extends SolverTablebase
 
   private int checkAllEdgesPresent(int[][] edges)
     {
-    boolean rb = false;
-    boolean ry = false;
-    boolean rg = false;
-    boolean yb = false;
-    boolean gb = false;
-    boolean gy = false;
+    boolean[] present = new boolean[6];
+    for(int i=0; i<6; i++) present[i] = false;
 
     for(int i=0; i<6; i++)
-      {
-      if( pieceEqual2(edges[i],3,2) ) rb = true;
-      if( pieceEqual2(edges[i],3,1) ) ry = true;
-      if( pieceEqual2(edges[i],3,0) ) rg = true;
-      if( pieceEqual2(edges[i],2,1) ) yb = true;
-      if( pieceEqual2(edges[i],2,0) ) gb = true;
-      if( pieceEqual2(edges[i],1,0) ) gy = true;
-      }
-
-    if( !rb ) return ERROR_EDGE_RB_MISSING;
-    if( !ry ) return ERROR_EDGE_RY_MISSING;
-    if( !rg ) return ERROR_EDGE_RG_MISSING;
-    if( !yb ) return ERROR_EDGE_YB_MISSING;
-    if( !gb ) return ERROR_EDGE_GB_MISSING;
-    if( !gy ) return ERROR_EDGE_GY_MISSING;
+      for(int j=0; j<6; j++)
+        if (pieceEqual2(edges[i], edgeColors[j]))
+          {
+          present[j] = true;
+          break;
+          }
+
+    if( !present[0] ) return ERROR_EDGE_RB_MISSING;
+    if( !present[1] ) return ERROR_EDGE_RY_MISSING;
+    if( !present[2] ) return ERROR_EDGE_RG_MISSING;
+    if( !present[3] ) return ERROR_EDGE_YB_MISSING;
+    if( !present[4] ) return ERROR_EDGE_GB_MISSING;
+    if( !present[5] ) return ERROR_EDGE_GY_MISSING;
 
     return 0;
     }
@@ -211,14 +210,47 @@ public class SolverPyraminx extends SolverTablebase
               break;
       }
 
-    return ( twist1!=twist2 || twist1!=twist3 ) ? -1 : twist1;
+    return ( twist1!=twist2 || twist1!=twist3 ) ? ERROR_CORNERS_CANNOT : twist1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private int locateEdge(int[][] edges, int[] colors)
+    {
+    for(int i=0; i<6; i++)
+      if( edges[i][0]==colors[0] && edges[i][1]==colors[1] ||
+          edges[i][0]==colors[1] && edges[i][1]==colors[0]  ) return i;
+
+    return -1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private int edgeTwist(int[] edge, int[] colors)
+    {
+    return edge[0]==colors[0] ? 0:1;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   private int[] computeEdgeQuats(int[][] edges)
     {
-    return null;
+    int[] quats = new int[6];
+
+    for(int i=0; i<6; i++)
+      {
+      int pos   = locateEdge(edges,edgeColors[i]);
+      int twist = edgeTwist(edges[pos],edgeColors[i]);
+
+//android.util.Log.e("D", "edge "+i+" pos: "+pos+" twist: "+twist);
+
+      quats[i]  = TablebasesPyraminx.EDGE_QUATS[pos][twist];
+      }
+/*
+for(int i=0; i<6; i++)
+  android.util.Log.e("D", "edge "+i+" : "+quats[i]);
+*/
+    return quats;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -232,42 +264,42 @@ public class SolverPyraminx extends SolverTablebase
 
   private void getCorners(TwistyObject object, int[][] corners)
     {
-    corners[0][0] = object.getCubitFaceStickerIndex(6,3);  // R
-    corners[0][1] = object.getCubitFaceStickerIndex(6,2);  // B
-    corners[0][2] = object.getCubitFaceStickerIndex(6,1);  // Y
+    corners[0][0] = object.getCubitFaceStickerIndex(4,0);  // G
+    corners[0][1] = object.getCubitFaceStickerIndex(4,3);  // R
+    corners[0][2] = object.getCubitFaceStickerIndex(4,2);  // B
 
-    corners[1][0] = object.getCubitFaceStickerIndex(4,3);  // R
-    corners[1][1] = object.getCubitFaceStickerIndex(4,0);  // G
-    corners[1][2] = object.getCubitFaceStickerIndex(4,2);  // B
+    corners[1][0] = object.getCubitFaceStickerIndex(6,1);  // Y
+    corners[1][1] = object.getCubitFaceStickerIndex(6,2);  // B
+    corners[1][2] = object.getCubitFaceStickerIndex(6,3);  // R
 
-    corners[2][0] = object.getCubitFaceStickerIndex(13,3);  // R
-    corners[2][1] = object.getCubitFaceStickerIndex(13,1);  // Y
-    corners[2][2] = object.getCubitFaceStickerIndex(13,0);  // G
+    corners[2][0] = object.getCubitFaceStickerIndex(11,1);  // Y
+    corners[2][1] = object.getCubitFaceStickerIndex(11,0);  // G
+    corners[2][2] = object.getCubitFaceStickerIndex(11,2);  // B
 
-    corners[3][0] = object.getCubitFaceStickerIndex(11,0);  // G
-    corners[3][1] = object.getCubitFaceStickerIndex(11,1);  // Y
-    corners[3][2] = object.getCubitFaceStickerIndex(11,2);  // B
+    corners[3][0] = object.getCubitFaceStickerIndex(13,1);  // Y
+    corners[3][1] = object.getCubitFaceStickerIndex(13,3);  // R
+    corners[3][2] = object.getCubitFaceStickerIndex(13,0);  // G
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   private void getVertices(TwistyObject object, int[][] vertex)
     {
-    vertex[0][0] = object.getCubitFaceStickerIndex(1,5);  // R
-    vertex[0][1] = object.getCubitFaceStickerIndex(1,7);  // B
-    vertex[0][2] = object.getCubitFaceStickerIndex(1,2);  // Y
+    vertex[0][0] = object.getCubitFaceStickerIndex(0,0);  // G
+    vertex[0][1] = object.getCubitFaceStickerIndex(0,5);  // R
+    vertex[0][2] = object.getCubitFaceStickerIndex(0,7);  // B
 
-    vertex[1][0] = object.getCubitFaceStickerIndex(0,5);  // R
-    vertex[1][1] = object.getCubitFaceStickerIndex(0,0);  // G
-    vertex[1][2] = object.getCubitFaceStickerIndex(0,7);  // B
+    vertex[1][0] = object.getCubitFaceStickerIndex(1,2);  // Y
+    vertex[1][1] = object.getCubitFaceStickerIndex(1,7);  // B
+    vertex[1][2] = object.getCubitFaceStickerIndex(1,5);  // R
 
-    vertex[2][0] = object.getCubitFaceStickerIndex(3,5);  // R
-    vertex[2][1] = object.getCubitFaceStickerIndex(3,2);  // Y
-    vertex[2][2] = object.getCubitFaceStickerIndex(3,0);  // G
+    vertex[2][0] = object.getCubitFaceStickerIndex(2,2);  // Y
+    vertex[2][1] = object.getCubitFaceStickerIndex(2,0);  // G
+    vertex[2][2] = object.getCubitFaceStickerIndex(2,7);  // B
 
-    vertex[3][0] = object.getCubitFaceStickerIndex(2,0);  // G
-    vertex[3][1] = object.getCubitFaceStickerIndex(2,2);  // Y
-    vertex[3][2] = object.getCubitFaceStickerIndex(2,7);  // B
+    vertex[3][0] = object.getCubitFaceStickerIndex(3,2);  // Y
+    vertex[3][1] = object.getCubitFaceStickerIndex(3,5);  // R
+    vertex[3][2] = object.getCubitFaceStickerIndex(3,0);  // G
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -277,20 +309,20 @@ public class SolverPyraminx extends SolverTablebase
     edges[0][0] = object.getCubitFaceStickerIndex(5,3);  // R
     edges[0][1] = object.getCubitFaceStickerIndex(5,2);  // B
 
-    edges[1][0] = object.getCubitFaceStickerIndex(10,3); // R
-    edges[1][1] = object.getCubitFaceStickerIndex(10,1); // Y
+    edges[1][0] = object.getCubitFaceStickerIndex(10,1); // Y
+    edges[1][1] = object.getCubitFaceStickerIndex(10,3); // R
 
-    edges[2][0] = object.getCubitFaceStickerIndex(9,3);  // R
-    edges[2][1] = object.getCubitFaceStickerIndex(9,0);  // G
+    edges[2][0] = object.getCubitFaceStickerIndex(9,0);  // G
+    edges[2][1] = object.getCubitFaceStickerIndex(9,3);  // R
 
-    edges[3][0] = object.getCubitFaceStickerIndex(8,1);  // Y
-    edges[3][1] = object.getCubitFaceStickerIndex(8,2);  // B
+    edges[3][0] = object.getCubitFaceStickerIndex(8,2);  // B
+    edges[3][1] = object.getCubitFaceStickerIndex(8,1);  // Y
 
-    edges[4][0] = object.getCubitFaceStickerIndex(7,0);  // G
-    edges[4][1] = object.getCubitFaceStickerIndex(7,2);  // B
+    edges[4][0] = object.getCubitFaceStickerIndex(7,2);  // B
+    edges[4][1] = object.getCubitFaceStickerIndex(7,0);  // G
 
-    edges[5][0] = object.getCubitFaceStickerIndex(12,0); // G
-    edges[5][1] = object.getCubitFaceStickerIndex(12,1); // Y
+    edges[5][0] = object.getCubitFaceStickerIndex(12,1); // Y
+    edges[5][1] = object.getCubitFaceStickerIndex(12,0); // G
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -321,10 +353,16 @@ public class SolverPyraminx extends SolverTablebase
 
     int result4 = checkAgreement(faces1,faces2);
     if( result4<0 ) return result4;
-
+/*
+for(int i=0; i<4; i++)
+  android.util.Log.e("D", "face "+i+" : "+faces1[i]);
+*/
     for(int i=0; i<4; i++)
       {
       corner_twist[i] = computePieceTwist(i,corners[i],faces1);
+
+      android.util.Log.e("D", "corner twist "+i+" : "+corner_twist[i]);
+
       if( corner_twist[i]<0 ) return ERROR_CORNERS_CANNOT;
       }
 
@@ -333,14 +371,33 @@ public class SolverPyraminx extends SolverTablebase
       vertex_twist[i] = computePieceTwist(i,vertices[i],faces1);
       if( vertex_twist[i]<0 ) return ERROR_VERTICES_CANNOT;
       }
+/*
+for(int i=0; i<6; i++)
+  android.util.Log.e("D", "edge "+i+" : "+edges[i][0]+" "+edges[i][1]);
+*/
 
     int[] quats = computeEdgeQuats(edges);
     int[] permutation = new int[6];
-    TablebasesPyraminx.getEdgePermutation(permutation,quats);
+    TablebasesPyraminx.getEdgePermutation(permutation,quats,0);
     boolean even = TablebaseHelpers.permutationIsEven(permutation);
     if( !even ) return ERROR_TWO_EDGES;
-
-    return 0;
+    int[] edge_twist = new int[6];
+    TablebasesPyraminx.getEdgeTwist(edge_twist,quats,0);
+/*
+for(int i=0; i<6; i++)
+  android.util.Log.e("D", "edge twist "+i+" : "+edge_twist[i]);
+*/
+    int totalEdgeTwist=0;
+    for(int i=0; i<6; i++) totalEdgeTwist += edge_twist[i];
+    if( (totalEdgeTwist%2)!=0 ) return ERROR_EDGE_TWISTED;
+
+    int vertexTwist = vertex_twist[0]+ 3*(vertex_twist[1]+ 3*(vertex_twist[2]+ 3*vertex_twist[3]));
+    int edgeTwist = edge_twist[0]+ 2*(edge_twist[1]+ 2*(edge_twist[2]+ 2*(edge_twist[3]+ 2*edge_twist[4])));
+    int perm_num = TablebaseHelpers.computeEvenPermutationNum(permutation);
+
+android.util.Log.e("D", "vertexTwist: : "+vertexTwist+" edgeTwist: "+edgeTwist+" perm_num: "+perm_num );
+
+    return vertexTwist + 81*(edgeTwist + 32*perm_num);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
