commit 20df890a3665b4a00f6b22cb6c834d4bb841f9c6
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Mon Mar 6 15:21:46 2023 +0100

    First version of 'clever' pyraminx tablebase scrambling (with layers 2 & 3 combined if possible)
    Still incorrect.

diff --git a/src/main/java/org/distorted/objectlib/tablebases/TablebasesPyraminx.java b/src/main/java/org/distorted/objectlib/tablebases/TablebasesPyraminx.java
index b4fb1215..64bc2339 100644
--- a/src/main/java/org/distorted/objectlib/tablebases/TablebasesPyraminx.java
+++ b/src/main/java/org/distorted/objectlib/tablebases/TablebasesPyraminx.java
@@ -110,33 +110,131 @@ public class TablebasesPyraminx extends TablebasesAbstract
   private void addMove(int[] move, int axis, int twist)
     {
     move[0] = axis;
-    move[1] = (1<<2);
+    move[1] = 4;
     move[2] = (twist==2 ? -1:twist);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private int[][] constructTipMoves(int[] twist)
+  private boolean failedInsertingTipMove(int[][] moves, int[] extra, int extraIndex, int axis)
     {
-    int total = 0;
+    int numAxis = 0;
+    boolean ret = true;
 
-    for(int i=0; i<4; i++)
-      if( twist[i]!=0 ) total++;
+    for( int[] move : moves )
+      {
+      if( move[0]==axis )
+        {
+        numAxis++;
+
+android.util.Log.e("D", "sameAxis, numAxis="+numAxis+" "+move[2]+" "+extra[extraIndex]);
+
+        if( (numAxis==1 && move[2]==extra[extraIndex]) || numAxis>=2 ) ret=false;
+        }
+      }
+
+android.util.Log.e("D", "failedInsertingTipMove "+axis+" : "+ret);
+
+    int currAx = 0;
+    int numMoves = moves.length;
+    int foreIndex=-1;
+    int lastIndex = -1;
 
-    if( total>0 )
+    for( int index=0; index<numMoves; index++ )
       {
-      int[][] moves = new int[total][3];
+      int[] move = moves[index];
 
-      int index=0;
-      if( twist[0]!=0 ) { addMove(moves[index],1,twist[0]); index++; }
-      if( twist[1]!=0 ) { addMove(moves[index],0,twist[1]); index++; }
-      if( twist[2]!=0 ) { addMove(moves[index],3,twist[2]); index++; }
-      if( twist[3]!=0 ) { addMove(moves[index],2,twist[3]);          }
+      if( move[0]==axis )
+        {
+        if (currAx < numAxis-2 )
+          {
+          move[1] = 6;
+          extra[extraIndex] += (move[2]==1 ? 1:2);
+          }
+        if( currAx == numAxis-2 ) foreIndex = index;
+        if( currAx == numAxis-1 ) lastIndex = index;
+
+        currAx++;
+        }
+      }
+
+    extra[extraIndex] = (extra[extraIndex]%3);
+
+    if( foreIndex>=0 )
+      {
+      int foreAngle = moves[foreIndex][2];
+      int lastAngle = moves[lastIndex][2];
 
-      return moves;
+      if( extra[extraIndex]==1 )
+        {
+        if( foreAngle==1 )
+          {
+          moves[foreIndex][1] = 6;
+          extra[extraIndex]++;
+          }
+        else
+          {
+          if( lastAngle==1 )
+            {
+            moves[lastIndex][1] = 6;
+            extra[extraIndex]++;
+            }
+          else
+            {
+            moves[foreIndex][1] = 6;
+            moves[lastIndex][1] = 6;
+            extra[extraIndex]+=2;
+            }
+          }
+        }
+      else if( extra[extraIndex]==2 )
+        {
+        if( foreAngle==-1 )
+          {
+          moves[foreIndex][1] = 6;
+          extra[extraIndex]+=2;
+          }
+        else
+          {
+          if( lastAngle==-1 )
+            {
+            moves[lastIndex][1] = 6;
+            extra[extraIndex]+=2;
+            }
+          else
+            {
+            moves[foreIndex][1] = 6;
+            moves[lastIndex][1] = 6;
+            extra[extraIndex]++;
+            }
+          }
+        }
       }
+    else if( lastIndex>=0 )
+      {
+      int lastAngle = moves[lastIndex][2];
 
-    return null;
+      if( extra[extraIndex]==1 )
+        {
+        if( lastAngle==1 )
+          {
+          moves[lastIndex][1] = 6;
+          extra[extraIndex]++;
+          }
+        }
+      else if( extra[extraIndex]==2 )
+        {
+        if( lastAngle==-1 )
+          {
+          moves[lastIndex][1] = 6;
+          extra[extraIndex]+=2;
+          }
+        }
+      }
+
+    extra[extraIndex] = (extra[extraIndex]%3);
+
+    return ret;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -145,17 +243,39 @@ public class TablebasesPyraminx extends TablebasesAbstract
   @Override
   int[][] extraInfo(int[][] moves, int[] extra)
     {
-    int[][] tipMoves = constructTipMoves(extra);
+    int lenExtra = 0;
 
-    int len1 = (   moves==null ? 0:   moves.length);
-    int len2 = (tipMoves==null ? 0:tipMoves.length);
+    if( failedInsertingTipMove(moves,extra,0,1) && extra[0]!=0 ) lenExtra++;
+    if( failedInsertingTipMove(moves,extra,1,0) && extra[1]!=0 ) lenExtra++;
+    if( failedInsertingTipMove(moves,extra,2,3) && extra[2]!=0 ) lenExtra++;
+    if( failedInsertingTipMove(moves,extra,3,2) && extra[3]!=0 ) lenExtra++;
 
-    int[][] ret = new int[len1+len2][3];
+android.util.Log.e("D", "lenExtra="+lenExtra);
 
-    if( len1>0 ) System.arraycopy(   moves, 0, ret,    0, len1);
-    if( len2>0 ) System.arraycopy(tipMoves, 0, ret, len1, len2);
+    if( lenExtra>0 )
+      {
+      int[][] extraMoves = new int[lenExtra][3];
 
-    return ret;
+      int index=0;
+      if( extra[0]!=0 ) { addMove(extraMoves[index],1,extra[0]); index++; }
+      if( extra[1]!=0 ) { addMove(extraMoves[index],0,extra[1]); index++; }
+      if( extra[2]!=0 ) { addMove(extraMoves[index],3,extra[2]); index++; }
+      if( extra[3]!=0 ) { addMove(extraMoves[index],2,extra[3]);          }
+
+      int len = moves.length;
+      int totalLen = len+lenExtra;
+      int[][] totalMoves = new int[totalLen][];
+
+      if( len>0 ) System.arraycopy(moves, 0, totalMoves, 0, len);
+      System.arraycopy(extraMoves, 0, totalMoves, len, lenExtra);
+
+for(int i=0; i<totalLen; i++)
+  android.util.Log.e("D", totalMoves[i][0]+" "+totalMoves[i][1]+" "+totalMoves[i][2]);
+
+      return totalMoves;
+      }
+
+    return moves;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
