Project

General

Profile

« Previous | Next » 

Revision 3a2dfb4a

Added by Leszek Koltunski 8 months ago

New verifier mechanism finished and being used by both KILO3 and CUBE3 algorithmic solvers.

View differences:

src/main/java/org/distorted/objectlib/main/TwistyObjectWithStickers.java
53 53
  // needed for verifiers
54 54
  private float[][][] mFaceCenters;     // fc[cubit][face] = point in the face, its center.
55 55
  private int[][] mCurrStickers;        // cs[cubit][face] = index of the sticker the face is stickered with at the moment
56
  private int[][] mOrigStickers;        // os[cubit][face] = original sticker index, before the user changed it by touching
56
  private int[][] mOrigColors;          // oc[cubit][face] = original color of the sticker, before the user changed it by touching
57
                                        // This is not the same as the 'sticker index' in mCurrStickers - only the same if there
58
                                        // is only a single type of sticker!
57 59
  private int[][][] mCubitFaceQuatMap;  // cfq[cubit][face][quat] = if we take the face and rotate it with quat, which cubit
58 60
                                        // face does it become? Format: (targetCubit<<8) + targetFace.
59 61
  private int[] mOrbits;                // o[cubit] - the number of orbit the cubit belongs to (starting from 0)
......
621 623

  
622 624
  private int getCubitAndFace(float[] point)
623 625
    {
626
    int minCubit=0, minFace=0;
627
    float minError = Float.MAX_VALUE;
628

  
624 629
    for(int c=0; c<mNumCubits; c++)
625 630
      {
626 631
      int numFaces = mFaceCenters[c].length;
......
631 636
        float dx = point[0] - cent[0];
632 637
        float dy = point[1] - cent[1];
633 638
        float dz = point[2] - cent[2];
639
        float error = dx*dx + dy*dy + dz*dz;
634 640

  
635
        if( dx*dx + dy*dy + dz*dz < 0.01f ) return (c<<8)+f;
641
        if( error<minError )
642
          {
643
          minCubit = c;
644
          minFace = f;
645
          minError = error;
646
          }
636 647
        }
637 648
      }
638 649

  
639
    return -1;
650
    return (minCubit<<8) + minFace;
640 651
    }
641 652

  
642 653
///////////////////////////////////////////////////////////////////////////////////////////////////
......
647 658

  
648 659
    for(int f=0; f<numFaces; f++)
649 660
      {
650
      int orig = mOrigStickers[cubit][f];
661
      int color = mOrigColors[cubit][f];
651 662

  
652
      if( orig>=0 )
663
      if( color>=0 )
653 664
        {
654 665
        int cubitFace = mCubitFaceQuatMap[cubit][f][quaternion];
655 666

  
......
657 668
          {
658 669
          targetCubit = cubitFace>>8;
659 670
          int targetFace = cubitFace&0xff;
660
          if( mCurrStickers[targetCubit][targetFace] != orig ) return -1;
671
          int stickerColor = mCurrStickers[targetCubit][targetFace]%mNumFaceColors;
672
          if( stickerColor != color ) return -1;
661 673
          }
662 674
        else return -1;
663 675
        }
......
693 705
    int numFaces = shape.getNumFaces();
694 706
    Static4D cubitQuat = getCubitOrigQuat(cubit);
695 707

  
696
    mFaceCenters[cubit] = new float[numFaces][];
697
    mOrigStickers[cubit] = new int[numFaces];
708
    mFaceCenters[cubit]  = new float[numFaces][];
709
    mOrigColors[cubit]   = new int[numFaces];
698 710
    mCurrStickers[cubit] = new int[numFaces];
699 711

  
700 712
    float[] po = mCubitPos[cubit];
......
713 725

  
714 726
    for(int f=0; f<numFaces; f++)
715 727
      {
716
      mOrigStickers[cubit][f] = getOriginalCubitFaceColor(cubit,f);
728
      mOrigColors[cubit][f] = getOriginalCubitFaceColor(cubit,f);
717 729

  
718 730
      mFaceCenters[cubit][f] = new float[3];
719 731
      shape.getFacePoint(f,tmp);
......
756 768
      int numFaces = mCurrStickers[c].length;
757 769
      for(int f=0; f<numFaces; f++) mCurrStickers[c][f] = getCubitFaceStickerIndex(c,f);
758 770
      }
771
/*
772
    String cur="";
773
    for(int c=0; c<mNumCubits; c++)
774
      {
775
      int[] fc = mCurrStickers[c];
776
      for( int ff : fc ) cur += (ff+" ");
777
      cur += "\n";
778
      }
779

  
780
    android.util.Log.e("D", "curr stickers: \n"+cur);
781
*/
759 782
    }
760 783

  
761 784
///////////////////////////////////////////////////////////////////////////////////////////////////
762 785

  
763 786
  private void prepareVerifierStuff()
764 787
    {
765
    mFaceCenters = new float[mNumCubits][][];
766
    mOrigStickers = new int[mNumCubits][];
788
    mFaceCenters  = new float[mNumCubits][][];
789
    mOrigColors   = new int[mNumCubits][];
767 790
    mCurrStickers = new int[mNumCubits][];
768 791
    mCubitFaceQuatMap = new int[mNumCubits][][];
769 792
    float[] tmp = new float[4];
770 793

  
771 794
    for(int c=0; c<mNumCubits; c++) computeCubitFaceCenterAndColor(c,tmp);
772 795
    for(int c=0; c<mNumCubits; c++) computeCubitFaceQuatMap(c,tmp);
796
/*
797
    String cen="";
798
    for(int c=0; c<mNumCubits; c++)
799
      {
800
      float[][] fc = mFaceCenters[c];
801
      for( float[] ff : fc ) cen += ("("+ff[0]+" "+ff[1]+" "+ff[2]+")");
802
      cen += "\n";
803
      }
804

  
805
    android.util.Log.e("D", "centers: \n"+cen);
806

  
807
    String ori="";
808
    for(int c=0; c<mNumCubits; c++)
809
      {
810
      int[] fc = mOrigColors[c];
811
      for( int ff : fc ) ori += (ff+" ");
812
      ori += "\n";
813
      }
814

  
815
    android.util.Log.e("D", "orig colors: \n"+ori);
816
*/
773 817
    }
774 818

  
775 819
///////////////////////////////////////////////////////////////////////////////////////////////////
......
781 825
    for( int c=0; c<mNumCubits; c++)
782 826
      if( mOrbits[c]==-1 )
783 827
        {
784
        android.util.Log.e("D", "generating cubit of orbit "+neworb+" : "+c);
828
        //android.util.Log.e("D", "generating cubit of orbit "+neworb+" : "+c);
785 829
        mOrbits[c] = neworb;
786 830
        ret++;
787 831
        genCubit = c;
......
793 837
    for(int q=0; q<mNumQuats; q++)
794 838
      {
795 839
      int cubit = mCubitFaceQuatMap[genCubit][face][q]>>8;
796

  
797
      if( cubit<0 )
798
        {
799
        android.util.Log.e("D", "error: genCubit="+genCubit+" face: "+face+" quat: "+q);
800
        }
801

  
802 840
      if( mOrbits[cubit]==-1 ) ret++;
803 841
      else if( mOrbits[cubit]<neworb ) System.out.println("newOrbit: impossible!! cubit="+cubit+" neworb="+neworb);
804 842
      mOrbits[cubit] = neworb;
805 843

  
806
      android.util.Log.e("D", "new cubit of orbit "+neworb+" : "+cubit);
844
      //android.util.Log.e("D", "new cubit of orbit "+neworb+" : "+cubit);
807 845
      }
808 846

  
809
    android.util.Log.e("D", "returning "+ret);
847
    //android.util.Log.e("D", "returning "+ret);
810 848
    return ret;
811 849
    }
812 850

  
......
844 882

  
845 883
    for(int c=0; c<mNumCubits; c++)
846 884
      {
847
      int numFaces = mOrigStickers[c].length;
885
      int numFaces = mOrigColors[c].length;
848 886
      mTwistInfo[c] = new int[numFaces];
849 887
      int index=0;
850 888

  
851 889
      for(int f=0; f<numFaces; f++)
852 890
        {
853
        int s = mOrigStickers[c][f];
854
        if( s>=0 ) mTwistInfo[c][index++] = f;
891
        int clr = mOrigColors[c][f];
892
        if( clr>=0 ) mTwistInfo[c][index++] = f;
855 893
        }
856 894
      for(int f=index; f<numFaces; f++) mTwistInfo[c][f] = -1;
857 895
      }
......
864 902
  public int[] getStickersOfMissingCubit(int cubit)
865 903
    {
866 904
    if( mFaceCenters==null ) prepareVerifierStuff();
867
    int[] stickers = mOrigStickers[cubit];
905
    int[] colors = mOrigColors[cubit];
868 906
    int numOuter = 0;
869 907

  
870
    for( int s : stickers )
871
      if( s>=0 ) numOuter++;
908
    for( int clr : colors )
909
      if( clr>=0 ) numOuter++;
872 910

  
873 911
    if( numOuter>0 )
874 912
      {
875 913
      int[] ret = new int[numOuter];
876 914
      int index = 0;
877 915

  
878
      for( int s : stickers )
879
        if( s>=0 ) ret[index++] = s;
916
      for( int clr : colors )
917
        if( clr>=0 ) ret[index++] = clr;
880 918

  
881 919
      return ret;
882 920
      }
src/main/java/org/distorted/objectlib/solvers/verifiers/SolverAlgorithmicCUBE3.java
18 18

  
19 19
public class SolverAlgorithmicCUBE3 extends SolverAlgorithmic
20 20
{
21
  protected int mErrColor1, mErrColor2, mErrColor3;
22

  
23
///////////////////////////////////////////////////////////////////////////////////////////////////
24

  
25 21
  public SolverAlgorithmicCUBE3(OperatingSystemInterface os, TwistyObject object)
26 22
    {
27 23
    mSolver = new PhasedSolver3x3Beginner();
28 24
    mSolvedObject = mSolver.getObject();
29
    mFaceColors = new int[6];
30
    }
31

  
32
///////////////////////////////////////////////////////////////////////////////////////////////////
33

  
34
  private void fillCornerTwists(int[] output, int[][] corners, int[] perm)
35
    {
36
    for(int i=0; i<8; i++)
37
      {
38
      int[] c = corners[perm[i]];
39

  
40
           if( c[0]==mFaceColors[0] || c[0]==mFaceColors[1] ) output[i] = 0;
41
      else if( c[1]==mFaceColors[0] || c[1]==mFaceColors[1] ) output[i] = 1;
42
      else                                                    output[i] = 2;
43
      }
44
    }
45

  
46
///////////////////////////////////////////////////////////////////////////////////////////////////
47

  
48
  private int cornerIndex(int[][] corners, int[] ind)
49
    {
50
    int c1 = mFaceColors[ind[0]];
51
    int c2 = mFaceColors[ind[1]];
52
    int c3 = mFaceColors[ind[2]];
53

  
54
    for(int i=0; i<8; i++)
55
      {
56
      int[] cor = corners[i];
57

  
58
      if( (cor[0]==c1 && cor[1]==c2 && cor[2]==c3) ||
59
          (cor[0]==c2 && cor[1]==c3 && cor[2]==c1) ||
60
          (cor[0]==c3 && cor[1]==c1 && cor[2]==c2)  ) return i;
61
      }
62

  
63
    return -1;
64 25
    }
65 26

  
66 27
///////////////////////////////////////////////////////////////////////////////////////////////////
67 28

  
68
  private int retCornerPermutation(int[] output, int[][] corners)
69
    {
70
    int[][] ind = new int[][] { {1,3,5},{1,4,3},{1,5,2},{1,2,4},{0,5,3},{0,3,4},{0,2,5},{0,4,2} };
71

  
72
    for(int i=0; i<8; i++) output[i] = cornerIndex(corners,ind[i]);
73

  
74
    for(int i=0; i<8; i++)
75
      if( output[i]==-1 )
76
        {
77
        mErrColor1 = ind[i][0];
78
        mErrColor2 = ind[i][1];
79
        mErrColor3 = ind[i][2];
80
        return ERROR_HEX_CORNER_MISSING;
81
        }
82

  
83
    return 0;
84
    }
85

  
86
///////////////////////////////////////////////////////////////////////////////////////////////////
87

  
88
  private void getCorners(TwistyObject object, int[][] corners)
89
    {
90
    corners[0][0] = object.getCubitFaceStickerIndex(0,1);
91
    corners[0][1] = object.getCubitFaceStickerIndex(0,3);
92
    corners[0][2] = object.getCubitFaceStickerIndex(0,5);
93

  
94
    corners[1][0] = object.getCubitFaceStickerIndex(1,3);
95
    corners[1][1] = object.getCubitFaceStickerIndex(1,5);
96
    corners[1][2] = object.getCubitFaceStickerIndex(1,1);
97

  
98
    corners[2][0] = object.getCubitFaceStickerIndex(2,5);
99
    corners[2][1] = object.getCubitFaceStickerIndex(2,1);
100
    corners[2][2] = object.getCubitFaceStickerIndex(2,3);
101

  
102
    corners[3][0] = object.getCubitFaceStickerIndex(3,1);
103
    corners[3][1] = object.getCubitFaceStickerIndex(3,3);
104
    corners[3][2] = object.getCubitFaceStickerIndex(3,5);
105

  
106
    corners[4][0] = object.getCubitFaceStickerIndex(4,1);
107
    corners[4][1] = object.getCubitFaceStickerIndex(4,3);
108
    corners[4][2] = object.getCubitFaceStickerIndex(4,5);
109

  
110
    corners[5][0] = object.getCubitFaceStickerIndex(5,1);
111
    corners[5][1] = object.getCubitFaceStickerIndex(5,3);
112
    corners[5][2] = object.getCubitFaceStickerIndex(5,5);
113

  
114
    corners[6][0] = object.getCubitFaceStickerIndex(6,1);
115
    corners[6][1] = object.getCubitFaceStickerIndex(6,3);
116
    corners[6][2] = object.getCubitFaceStickerIndex(6,5);
117

  
118
    corners[7][0] = object.getCubitFaceStickerIndex(7,1);
119
    corners[7][1] = object.getCubitFaceStickerIndex(7,3);
120
    corners[7][2] = object.getCubitFaceStickerIndex(7,5);
121
    }
122

  
123
///////////////////////////////////////////////////////////////////////////////////////////////////
124

  
125
  private void getEdges(TwistyObject object, int[][] edges)
126
    {
127
    edges[ 0][0] = object.getCubitFaceStickerIndex( 8,5);
128
    edges[ 0][1] = object.getCubitFaceStickerIndex( 8,3);
129

  
130
    edges[ 1][0] = object.getCubitFaceStickerIndex( 9,3);
131
    edges[ 1][1] = object.getCubitFaceStickerIndex( 9,5);
132

  
133
    edges[ 2][0] = object.getCubitFaceStickerIndex(10,3);
134
    edges[ 2][1] = object.getCubitFaceStickerIndex(10,5);
135

  
136
    edges[ 3][0] = object.getCubitFaceStickerIndex(11,5);
137
    edges[ 3][1] = object.getCubitFaceStickerIndex(11,3);
138

  
139
    edges[ 4][0] = object.getCubitFaceStickerIndex(12,3);
140
    edges[ 4][1] = object.getCubitFaceStickerIndex(12,5);
141

  
142
    edges[ 5][0] = object.getCubitFaceStickerIndex(13,5);
143
    edges[ 5][1] = object.getCubitFaceStickerIndex(13,3);
144

  
145
    edges[ 6][0] = object.getCubitFaceStickerIndex(14,3);
146
    edges[ 6][1] = object.getCubitFaceStickerIndex(14,5);
147

  
148
    edges[ 7][0] = object.getCubitFaceStickerIndex(15,5);
149
    edges[ 7][1] = object.getCubitFaceStickerIndex(15,3);
150

  
151
    edges[ 8][0] = object.getCubitFaceStickerIndex(16,5);
152
    edges[ 8][1] = object.getCubitFaceStickerIndex(16,3);
153

  
154
    edges[ 9][0] = object.getCubitFaceStickerIndex(17,3);
155
    edges[ 9][1] = object.getCubitFaceStickerIndex(17,5);
156

  
157
    edges[10][0] = object.getCubitFaceStickerIndex(18,5);
158
    edges[10][1] = object.getCubitFaceStickerIndex(18,3);
159

  
160
    edges[11][0] = object.getCubitFaceStickerIndex(19,3);
161
    edges[11][1] = object.getCubitFaceStickerIndex(19,5);
162
    }
163

  
164
///////////////////////////////////////////////////////////////////////////////////////////////////
165

  
166
  private int edgeIndex(int[][] edges, int[] ind)
29
  public int[] validatePosition(TwistyObject object)
167 30
    {
168
    int c1 = mFaceColors[ind[0]];
169
    int c2 = mFaceColors[ind[1]];
31
    int[] quats = object.computeCubitQuats();
32
    int numQ = quats.length;
170 33

  
171
    for(int i=0; i<12; i++)
34
    for(int q=0; q<numQ; q++)
172 35
      {
173
      int[] e = edges[i];
174
      if( (e[0]==c1 && e[1]==c2) || (e[0]==c2 && e[1]==c1) ) return i;
175
      }
176

  
177
    return -1;
178
    }
179

  
180
///////////////////////////////////////////////////////////////////////////////////////////////////
181

  
182
  private int retEdgePermutation(int[] output, int[][] edges)
183
    {
184
    int[][] ind = new int[][] { {5,3},{4,3},{5,2},{4,2},{5,1},{4,1},{5,0},{4,0},{3,1},{2,1},{3,0},{2,0} };
185

  
186
    for(int i=0; i<12; i++) output[i] = edgeIndex(edges,ind[i]);
187

  
188
    for(int i=0; i<12; i++)
189
      if( output[i]==-1 )
36
      if( quats[q]<0 )
190 37
        {
191
        mErrColor1 = ind[i][0];
192
        mErrColor2 = ind[i][1];
193
        return ERROR_HEX_EDGE_MISSING;
38
        int[] st = object.getStickersOfMissingCubit(q);
39

  
40
        switch(st.length)
41
          {
42
          case 1: return new int[] {ERROR_HEX_CENTER_MISSING, st[0]};
43
          case 2: return new int[] {ERROR_HEX_EDGE_MISSING  , st[0],st[1]};
44
          case 3: return new int[] {ERROR_HEX_CORNER_MISSING, st[0],st[1],st[2]};
45
          default:System.out.println("Error in validatePosition: st length = "+st.length);
46
          }
47
        break;
194 48
        }
195

  
196
    return 0;
197
    }
198

  
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200

  
201
  private void fillEdgeTwists(int[] output, int[][] edges, int[] perm)
202
    {
203
    for(int i=0; i<12; i++)
204
      {
205
      int[] e = edges[perm[i]];
206
      output[i] = e[0]>e[1] ? 0 : 1;
207 49
      }
208
    }
209 50

  
210
///////////////////////////////////////////////////////////////////////////////////////////////////
51
    int[][] perms = object.getPermutations(quats);
52
    boolean evenC = TablebaseHelpers.permutationIsEven(perms[0]);
53
    boolean evenE = TablebaseHelpers.permutationIsEven(perms[1]);
211 54

  
212
  private void computeFaceColors(TwistyObject object)
213
    {
214
    for(int i=0; i<6; i++) mFaceColors[i] = object.getCubitFaceStickerIndex(20+i,4);
215
    }
55
    if( evenC!=evenE ) return new int[] {ERROR_TWO_CORNERS_TWO_EDGES};
216 56

  
217
///////////////////////////////////////////////////////////////////////////////////////////////////
218

  
219
  public int[] validatePosition(TwistyObject object)
220
    {
221
    computeFaceColors(object);
222

  
223
    int[][] corners= new int[8][3];
224
    getCorners(object,corners);
225

  
226
    //for(int i=0; i<8; i++) android.util.Log.e("D", "corner: "+i+" : "+corners[i][0]+" "+corners[i][1]+" "+corners[i][2]);
227
    //for(int i=0; i<6; i++) android.util.Log.e("D", "face color: "+i+" : "+mFaceColors[i]);
228

  
229
    int[] permC = new int[8];
230
    int result0 = retCornerPermutation(permC,corners);
231
    if( result0<0 ) return new int[] {result0,mErrColor1,mErrColor2,mErrColor3};
232

  
233
    int[] twistC = new int[8];
234
    fillCornerTwists(twistC,corners,permC);
57
    int[][] twists = object.getTwists(quats);
235 58

  
236 59
    int totalTwistC = 0;
237
    for(int i=0; i<8; i++) totalTwistC += twistC[i];
238
    if( ((totalTwistC)%3) != 0 ) return new int[] {ERROR_CORNER_TWISTED};
239

  
240
    int[][] edges = new int[12][2];
241
    getEdges(object,edges);
242

  
243
    //for(int i=0; i<12; i++) android.util.Log.e("D", "edge: "+i+" : "+edges[i][0]+" "+edges[i][1]);
244

  
245
    int[] permE = new int[12];
246
    int result1 = retEdgePermutation(permE,edges);
247
    if( result1<0 ) return new int[] {result1,mErrColor1,mErrColor2,mErrColor3};
248

  
249
    int[] twistE = new int[12];
250
    fillEdgeTwists(twistE,edges,permE);
60
    int[] twistC = twists[0];
61
    for( int t : twistC ) totalTwistC += t;
251 62

  
252 63
    int totalTwistE = 0;
253
    for(int i=0; i<12; i++) totalTwistE += twistE[i];
254
    if( ((totalTwistE)%2) != 0 ) return new int[] {ERROR_EDGE_TWISTED};
255

  
256
    boolean evenC = TablebaseHelpers.permutationIsEven(permC);
257
    boolean evenE = TablebaseHelpers.permutationIsEven(permE);
64
    int[] twistE = twists[1];
65
    for( int t : twistE ) totalTwistE += t;
258 66

  
259
    if( evenC^evenE ) return new int[] {ERROR_TWO_CORNERS_TWO_EDGES};
67
    if( (totalTwistC%3) !=0 ) return new int[] {ERROR_CORNER_TWISTED};
68
    if( (totalTwistE%2) !=0 ) return new int[] {ERROR_EDGE_TWISTED};
260 69

  
261
    return object.computeCubitQuats();
70
    return quats;
262 71
    }
263 72
}  
264 73

  
src/main/java/org/distorted/objectlib/solvers/verifiers/SolverAlgorithmicKILO3.java
40 40
        }
41 41

  
42 42
    int[][] perms = object.getPermutations(quats);
43
/*
44
    for(int o=0; o<perms.length; o++)
45
      {
46
      String s="";
47
      int len = perms[o].length;
48

  
49
      for(int e=0; e<len; e++)
50
        {
51
        s += " ";
52
        s += perms[o][e];
53
        }
54

  
55
      android.util.Log.e("D", "permutation "+o+" : "+s);
56
      }
57
*/
58
    if( !TablebaseHelpers.permutationIsEven(perms[0]) )
59
      {
60
      return new int[] {ERROR_TWO_CORNERS};
61
      }
43
    if( !TablebaseHelpers.permutationIsEven(perms[0]) ) return new int[] {ERROR_TWO_CORNERS};
62 44

  
63 45
    int[][] twists = object.getTwists(quats);
64
/*
65
    for(int o=0; o<twists.length; o++)
66
      {
67
      String s="";
68
      int len = twists[o].length;
69

  
70
      for(int e=0; e<len; e++)
71
        {
72
        s += " ";
73
        s += twists[o][e];
74
        }
75

  
76
      android.util.Log.e("D", "twists of orbit "+o+" : "+s);
77
      }
78
*/
79 46
    int totalTwist = 0;
80
    int[] twist = twists[0];
81
    for( int t : twist ) totalTwist += t;
82

  
47
    for( int t : twists[0] ) totalTwist += t;
83 48
    if( (totalTwist%3)!=0 ) return new int[] {ERROR_CORNER_TWISTED};
84 49

  
85 50
    return quats;

Also available in: Unified diff