commit ad6f6f035c40b1ea87bff1cf69c434ac1c85145a
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Sun Sep 27 02:02:30 2020 +0100

    Fix Diamond's isSolved()

diff --git a/src/main/java/org/distorted/objects/TwistyDiamond.java b/src/main/java/org/distorted/objects/TwistyDiamond.java
index 282ac8dd..a4601ee8 100644
--- a/src/main/java/org/distorted/objects/TwistyDiamond.java
+++ b/src/main/java/org/distorted/objects/TwistyDiamond.java
@@ -38,6 +38,7 @@ import org.distorted.library.mesh.MeshTriangle;
 import org.distorted.library.type.Static1D;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
+import org.distorted.main.RubikSurfaceView;
 
 import java.util.Random;
 
@@ -589,28 +590,97 @@ public class TwistyDiamond extends TwistyObject
     return 0;
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  int mulQuat(int q1, int q2)
+    {
+    Static4D result = RubikSurfaceView.quatMultiply(QUATS[q1],QUATS[q2]);
+
+    float rX = result.get0();
+    float rY = result.get1();
+    float rZ = result.get2();
+    float rW = result.get3();
+
+    final float MAX_ERROR = 0.1f;
+    float dX,dY,dZ,dW;
+
+    for(int i=0; i<QUATS.length; i++)
+      {
+      dX = QUATS[i].get0() - rX;
+      dY = QUATS[i].get1() - rY;
+      dZ = QUATS[i].get2() - rZ;
+      dW = QUATS[i].get3() - rW;
+
+      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
+          dY<MAX_ERROR && dY>-MAX_ERROR &&
+          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
+          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
+
+      dX = QUATS[i].get0() + rX;
+      dY = QUATS[i].get1() + rY;
+      dZ = QUATS[i].get2() + rZ;
+      dW = QUATS[i].get3() + rW;
+
+      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
+          dY<MAX_ERROR && dY>-MAX_ERROR &&
+          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
+          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
+      }
+
+    return -1;
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // The Diamond is solved if and only if:
 //
-// ??
+// 1) all 5 octahedrons are rotated with the same quat
+// 2) the 8 tetrahedrons are rotated with the quat and, optionally, the can also be rotated
+//    by multitudes of 120 degrees along the face they are the center of.
+//
+// so:
+// 1) cubits 6,12: can also be QUAT 6,10
+// 2) cubits 7,13: can also be QUAT 4,8
+// 3) cubits 8,10: can also be QUAT 7,11
+// 4) cubits 9,11: can also be QUAT 5,9
 
   public boolean isSolved()
     {
     int q = CUBITS[0].mQuatIndex;
 
-    return ( CUBITS[ 1].mQuatIndex == q &&
-             CUBITS[ 2].mQuatIndex == q &&
-             CUBITS[ 3].mQuatIndex == q &&
-             CUBITS[ 4].mQuatIndex == q &&
-             CUBITS[ 5].mQuatIndex == q &&
-             CUBITS[ 6].mQuatIndex == q &&
-             CUBITS[ 7].mQuatIndex == q &&
-             CUBITS[ 8].mQuatIndex == q &&
-             CUBITS[ 9].mQuatIndex == q &&
-             CUBITS[10].mQuatIndex == q &&
-             CUBITS[11].mQuatIndex == q &&
-             CUBITS[12].mQuatIndex == q &&
-             CUBITS[13].mQuatIndex == q  );
+    if ( CUBITS[ 1].mQuatIndex == q &&
+         CUBITS[ 2].mQuatIndex == q &&
+         CUBITS[ 3].mQuatIndex == q &&
+         CUBITS[ 4].mQuatIndex == q &&
+         CUBITS[ 5].mQuatIndex == q  )
+      {
+      int q1 = mulQuat(q,5);
+      int q2 = mulQuat(q,9);
+
+      if( CUBITS[ 9].mQuatIndex != q && CUBITS[ 9].mQuatIndex != q1 && CUBITS[ 9].mQuatIndex != q2 ) return false;
+      if( CUBITS[11].mQuatIndex != q && CUBITS[11].mQuatIndex != q1 && CUBITS[11].mQuatIndex != q2 ) return false;
+
+      q1 = mulQuat(q,4);
+      q2 = mulQuat(q,8);
+
+      if( CUBITS[ 7].mQuatIndex != q && CUBITS[ 7].mQuatIndex != q1 && CUBITS[ 7].mQuatIndex != q2 ) return false;
+      if( CUBITS[13].mQuatIndex != q && CUBITS[13].mQuatIndex != q1 && CUBITS[13].mQuatIndex != q2 ) return false;
+
+      q1 = mulQuat(q,6);
+      q2 = mulQuat(q,10);
+
+      if( CUBITS[ 6].mQuatIndex != q && CUBITS[ 6].mQuatIndex != q1 && CUBITS[ 6].mQuatIndex != q2 ) return false;
+      if( CUBITS[12].mQuatIndex != q && CUBITS[12].mQuatIndex != q1 && CUBITS[12].mQuatIndex != q2 ) return false;
+
+      q1 = mulQuat(q,7);
+      q2 = mulQuat(q,11);
+
+      if( CUBITS[ 8].mQuatIndex != q && CUBITS[ 8].mQuatIndex != q1 && CUBITS[ 8].mQuatIndex != q2 ) return false;
+      if( CUBITS[10].mQuatIndex != q && CUBITS[10].mQuatIndex != q1 && CUBITS[10].mQuatIndex != q2 ) return false;
+
+      return true;
+      }
+
+    return false;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
