Project

General

Profile

Download (8.43 KB) Statistics
| Branch: | Revision:

distorted-objectlib / src / main / java / org / distorted / objectlib / tablebases / TBDino4.java @ 6777e712

1 dbdb71d0 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2023 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8
///////////////////////////////////////////////////////////////////////////////////////////////////
9
10
package org.distorted.objectlib.tablebases;
11
12 d6e2cf37 Leszek Koltunski
import org.distorted.objectlib.R;
13 3103c3c8 Leszek Koltunski
import org.distorted.objectlib.helpers.OperatingSystemInterface;
14 dbdb71d0 Leszek Koltunski
15
///////////////////////////////////////////////////////////////////////////////////////////////////
16
17 a76bb8f6 Leszek Koltunski
public class TBDino4 extends TBDino
18 dbdb71d0 Leszek Koltunski
{
19 d6e2cf37 Leszek Koltunski
  private static final int[][] SAME = {{0,3,7},{1,2,5},{4,8,9},{6,10,11}};
20 a76bb8f6 Leszek Koltunski
  private static final int SOLVED1 =  6237;  // partition 011021302233
21
  private static final int SOLVED2 = 10837;  // partition 001102133223
22 dbdb71d0 Leszek Koltunski
23
///////////////////////////////////////////////////////////////////////////////////////////////////
24
25
  public TBDino4()
26
    {
27
    super();
28
    }
29
30
///////////////////////////////////////////////////////////////////////////////////////////////////
31
32 3103c3c8 Leszek Koltunski
  public TBDino4(OperatingSystemInterface os)
33 dbdb71d0 Leszek Koltunski
    {
34 3103c3c8 Leszek Koltunski
    super(os, new int[] {R.raw.din4_3_pruning2,R.raw.din4_3_pruning3}, new int[] {R.raw.din4_3_pruning7});
35 dbdb71d0 Leszek Koltunski
    }
36
37
///////////////////////////////////////////////////////////////////////////////////////////////////
38
// specifically for the tablebase
39
///////////////////////////////////////////////////////////////////////////////////////////////////
40
// two solved positions: original and mirrored (left face swapped with right)
41
42
  @Override
43
  int[] getSolvedIndices()
44
    {
45 d6e2cf37 Leszek Koltunski
    return new int[] {SOLVED1,SOLVED2};
46 dbdb71d0 Leszek Koltunski
    }
47
48
///////////////////////////////////////////////////////////////////////////////////////////////////
49
// ditto
50
51
  @Override
52
  boolean isSolved(int index)
53
    {
54 d6e2cf37 Leszek Koltunski
    return index==SOLVED1 || index==SOLVED2;
55 dbdb71d0 Leszek Koltunski
    }
56
57 94a0a353 leszek
58
///////////////////////////////////////////////////////////////////////////////////////////////////
59
// Because there are two solved positions [where the second one is the first one rotated by 90 deg
60
// around (0,1,0)] scrambling does not work - because when we randomize an index and solve it,
61
// about half the time we actually solve it to the second solved position. And then the first move
62
// of the randomised scramble sequence does not scramble anything!
63
// If we detect that the first move does not scramble anything [i.e. its layer is 1] - reverse the
64
// whole sequence, i.e. do layer 1<-->4.
65
66
  @Override
67
  void postScramble(int[][] scramble, int num)
68
    {
69
    if( num>0 )
70
      {
71
      if( scramble[0][1]==1 )
72
        {
73
        for(int i=0; i<num; i++)
74
          {
75
          int[] s = scramble[i];
76
          s[1] = (s[1]==1 ? 4:1);
77
          }
78
        }
79
      }
80
    }
81
82 dbdb71d0 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
83 a76bb8f6 Leszek Koltunski
// 15408 really (see https://www.jaapsch.net/puzzles/dinocube.htm)
84
// Here 15400 because we equal positions where colors are simply swapped (those are the same with
85
// respect to distance to the 2 solved positions) so there are (11 choose 2)*(8 choose 2)*(5 choose 2)
86
// = 55*28*10 = 15400 possibilities.
87
// We do not pack those tightly, some positions in the same orbit (by Burnside lemma) have 3 different
88
// indices.
89 dbdb71d0 Leszek Koltunski
90 a76bb8f6 Leszek Koltunski
  int getSize()
91 dbdb71d0 Leszek Koltunski
    {
92 a76bb8f6 Leszek Koltunski
    return 15400;
93 dbdb71d0 Leszek Koltunski
    }
94
95
///////////////////////////////////////////////////////////////////////////////////////////////////
96
97 a76bb8f6 Leszek Koltunski
  int getMinScramble()
98 dbdb71d0 Leszek Koltunski
    {
99 94a0a353 leszek
    return 6;
100 a76bb8f6 Leszek Koltunski
    }
101 dbdb71d0 Leszek Koltunski
102 a76bb8f6 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
103
104
  int[] getMidPruningLevels()
105
    {
106
    return new int[] {2,3};
107 dbdb71d0 Leszek Koltunski
    }
108
109
///////////////////////////////////////////////////////////////////////////////////////////////////
110
111 a76bb8f6 Leszek Koltunski
  int[] getHighPruningLevels()
112 dbdb71d0 Leszek Koltunski
    {
113 a76bb8f6 Leszek Koltunski
    return new int[] {7};
114 dbdb71d0 Leszek Koltunski
    }
115
116
///////////////////////////////////////////////////////////////////////////////////////////////////
117
118 a76bb8f6 Leszek Koltunski
  int getGodsNumber()
119 dbdb71d0 Leszek Koltunski
    {
120 a76bb8f6 Leszek Koltunski
    return 7;
121 dbdb71d0 Leszek Koltunski
    }
122
123 d6e2cf37 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
124
125
  private static int computeIndex(int[] partition, int section, int size)
126
    {
127
    int index0=0;
128
129
    for(;index0<12; index0++)
130
      if(partition[index0]==section ) break;
131
132
    int index1=index0+1;
133
    int D1 = 0;
134
135
    for(;index1<12; index1++)
136
      {
137
      int val = partition[index1];
138
      if(val >section ) D1++;
139
      if(val==section ) break;
140
      }
141
142
    int index2=index1+1;
143
    int D2 = 0;
144
145
    for(;index2<12; index2++)
146
      {
147
      int val = partition[index2];
148
      if(val >section ) D2++;
149
      if(val==section ) break;
150
      }
151
152
    return D1*size - (D1+1)*D1/2 + D2;
153
    }
154
155 dbdb71d0 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
156
157
  public static int indexFromPartition(int[] partition)
158
    {
159 d6e2cf37 Leszek Koltunski
    int index0 = computeIndex(partition,0,11);
160
    int index1 = computeIndex(partition,1,8);
161
    int index2 = computeIndex(partition,2,5);
162
163
    return index0 + 55*(index1 + 28*index2);
164 dbdb71d0 Leszek Koltunski
    }
165
166
///////////////////////////////////////////////////////////////////////////////////////////////////
167
168 d6e2cf37 Leszek Koltunski
  private static void fillPart(int[] part, int index, int section, int size)
169 dbdb71d0 Leszek Koltunski
    {
170 d6e2cf37 Leszek Koltunski
    int index0=0;
171
172
    for(; index0<10; index0++)
173
      if( part[index0]<0 )
174
        {
175
        part[index0] = section;
176
        break;
177
        }
178
179
    int index1 = index0+1;
180
    int diff = size-1;
181
182
    for(; index1<11; index1++)
183
      if( part[index1]<0 )
184
        {
185
        if( index<diff )
186
          {
187
          part[index1] = section;
188
          break;
189
          }
190
        else { index-=diff; diff--; }
191
        }
192
193
    int index2 = index1+1;
194
195
    for(; index2<12; index2++)
196
      {
197
      if( part[index2]<0 ) index--;
198
      if( index<0 )
199
        {
200
        part[index2] = section;
201
        break;
202
        }
203
      }
204 dbdb71d0 Leszek Koltunski
    }
205
206
///////////////////////////////////////////////////////////////////////////////////////////////////
207
208 d6e2cf37 Leszek Koltunski
  private static int[] partitionFromIndex(int index)
209 dbdb71d0 Leszek Koltunski
    {
210 d6e2cf37 Leszek Koltunski
    int index0 = (index%55);
211
    index /= 55;
212
    int index1 = (index%28);
213
    int index2 = (index/28);
214
215
    int[] part = new int[12];
216
    for(int i=0; i<12; i++) part[i] = -1;
217 83dadb4a Leszek Koltunski
218 d6e2cf37 Leszek Koltunski
    fillPart(part,index0,0,11);
219
    fillPart(part,index1,1,8);
220
    fillPart(part,index2,2,5);
221
222
    for(int i=0; i<12; i++)
223
      if( part[i]<0 ) part[i] = 3;
224
225
    return part;
226 dbdb71d0 Leszek Koltunski
    }
227
228
///////////////////////////////////////////////////////////////////////////////////////////////////
229
230 d6e2cf37 Leszek Koltunski
  private static void fillPerm(int[] perm, int[] part, int section)
231 dbdb71d0 Leszek Koltunski
    {
232 d6e2cf37 Leszek Koltunski
    int num=0;
233
    int[] same = SAME[section];
234
235
    for(int i=0; i<12; i++)
236
      if( part[i]==section )
237
        perm[same[num++]] = i;
238
    }
239
240
///////////////////////////////////////////////////////////////////////////////////////////////////
241
242
  private static int[] quatsFromPartition(int[] partition)
243
    {
244
    int[] perm = new int[12];
245
    fillPerm(perm,partition,0);
246
    fillPerm(perm,partition,1);
247
    fillPerm(perm,partition,2);
248
    fillPerm(perm,partition,3);
249
250 a80e95e4 Leszek Koltunski
    return TBDino.getQuatsFromPerm(perm);
251 d6e2cf37 Leszek Koltunski
    }
252
253
///////////////////////////////////////////////////////////////////////////////////////////////////
254
255
  private static int[] partitionFromQuats(int[] quats)
256
    {
257 7b3d2515 Leszek Koltunski
    int[] perm = TBDino.getPermFromQuats(quats);
258 d6e2cf37 Leszek Koltunski
    int[] part = new int[12];
259
260
    for(int i=0; i<4; i++)
261
      {
262
      int[] index = SAME[i];
263
      part[perm[index[0]]] = part[perm[index[1]]] = part[perm[index[2]]] = (-i-1);
264
      }
265
266
    int newVal=0;
267
268
    for(int i=0; i<12; i++)
269
      {
270
      int val = part[i];
271
272
      if( val<0 )
273
        {
274
        for(int j=i; j<12; j++)
275
          if( part[j]==val ) part[j] = newVal;
276
277
        newVal++;
278
        }
279
      }
280
281
    return part;
282 dbdb71d0 Leszek Koltunski
    }
283
284
///////////////////////////////////////////////////////////////////////////////////////////////////
285
286
  int[] getQuats(int index)
287
    {
288
    int[] partition = partitionFromIndex(index);
289
    return quatsFromPartition(partition);
290
    }
291
292
///////////////////////////////////////////////////////////////////////////////////////////////////
293
294
  int getIndex(int[] quats)
295
    {
296 0ed8f43f Leszek Koltunski
    normalizeQuats(quats);
297 dbdb71d0 Leszek Koltunski
    int[] partition = partitionFromQuats(quats);
298
    return indexFromPartition(partition);
299
    }
300
}