Project

General

Profile

Download (20.1 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / solvers / SolverPyraminx.java @ 2876aeb6

1 7dbbda72 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.solvers;
11
12
import android.content.res.Resources;
13
14
import org.distorted.main.R;
15 2876aeb6 Leszek Koltunski
import org.distorted.objectlib.main.ObjectSignatures;
16 7dbbda72 Leszek Koltunski
import org.distorted.objectlib.main.TwistyObject;
17
import org.distorted.objectlib.tablebases.ImplementedTablebasesList;
18 55b2d967 Leszek Koltunski
import org.distorted.objectlib.tablebases.TablebaseHelpers;
19 7dbbda72 Leszek Koltunski
import org.distorted.objectlib.tablebases.TablebasesAbstract;
20 55b2d967 Leszek Koltunski
import org.distorted.objectlib.tablebases.TablebasesPyraminx;
21 7dbbda72 Leszek Koltunski
22
///////////////////////////////////////////////////////////////////////////////////////////////////
23
24
public class SolverPyraminx extends SolverTablebase
25
{
26
  private static final int ERROR_CORNER_GYB_MISSING = -1;
27
  private static final int ERROR_CORNER_GYR_MISSING = -2;
28
  private static final int ERROR_CORNER_GBR_MISSING = -3;
29
  private static final int ERROR_CORNER_YBR_MISSING = -4;
30
31
  private static final int ERROR_VERTEX_GYB_MISSING = -5;
32
  private static final int ERROR_VERTEX_GYR_MISSING = -6;
33
  private static final int ERROR_VERTEX_GBR_MISSING = -7;
34
  private static final int ERROR_VERTEX_YBR_MISSING = -8;
35
36
  private static final int ERROR_EDGE_RB_MISSING = -9;
37
  private static final int ERROR_EDGE_RY_MISSING = -10;
38
  private static final int ERROR_EDGE_RG_MISSING = -11;
39
  private static final int ERROR_EDGE_YB_MISSING = -12;
40
  private static final int ERROR_EDGE_GB_MISSING = -13;
41
  private static final int ERROR_EDGE_GY_MISSING = -14;
42
43
  private static final int ERROR_CORNERS_CANNOT   = -15;
44
  private static final int ERROR_VERTICES_CANNOT  = -16;
45 202b167e Leszek Koltunski
  private static final int ERROR_EDGE_TWISTED     = -17;
46
  private static final int ERROR_C_V_DONT_MATCH   = -18;
47
  private static final int ERROR_TWO_EDGES        = -19;
48 d3c2aa29 Leszek Koltunski
49 b8dab9fd Leszek Koltunski
  private TablebasesAbstract mSolver;
50
  private int[] mCornerTwist;
51 7dbbda72 Leszek Koltunski
52
///////////////////////////////////////////////////////////////////////////////////////////////////
53
54
  private boolean pieceEqual3(int[] piece, int c1, int c2, int c3)
55
    {
56
    return ( (piece[0]==c1 && piece[1]==c2 && piece[2]==c3) ||
57
             (piece[0]==c1 && piece[2]==c2 && piece[1]==c3) ||
58
             (piece[1]==c1 && piece[0]==c2 && piece[2]==c3) ||
59
             (piece[1]==c1 && piece[2]==c2 && piece[0]==c3) ||
60
             (piece[2]==c1 && piece[1]==c2 && piece[0]==c3) ||
61
             (piece[2]==c1 && piece[0]==c2 && piece[1]==c3)  );
62
    }
63
64
///////////////////////////////////////////////////////////////////////////////////////////////////
65
66 d3c2aa29 Leszek Koltunski
  private boolean pieceEqual2(int[] piece, int[] colors)
67 7dbbda72 Leszek Koltunski
    {
68 d3c2aa29 Leszek Koltunski
    return ( (piece[0]==colors[0] && piece[1]==colors[1]) ||
69
             (piece[0]==colors[1] && piece[1]==colors[0])  );
70 7dbbda72 Leszek Koltunski
    }
71
72
///////////////////////////////////////////////////////////////////////////////////////////////////
73
74
  private int checkAllCornersPresent(int[][] corners)
75
    {
76
    boolean ybr = false;
77
    boolean gbr = false;
78
    boolean gyr = false;
79
    boolean gyb = false;
80
81
    for(int i=0; i<4; i++)
82
      {
83
      if( pieceEqual3(corners[i],0,1,2) ) gyb = true;
84
      if( pieceEqual3(corners[i],0,1,3) ) gyr = true;
85
      if( pieceEqual3(corners[i],0,2,3) ) gbr = true;
86
      if( pieceEqual3(corners[i],1,2,3) ) ybr = true;
87
      }
88
89
    if( !ybr ) return ERROR_CORNER_YBR_MISSING;
90
    if( !gbr ) return ERROR_CORNER_GBR_MISSING;
91
    if( !gyr ) return ERROR_CORNER_GYR_MISSING;
92
    if( !gyb ) return ERROR_CORNER_GYB_MISSING;
93
94
    return 0;
95
    }
96
97
///////////////////////////////////////////////////////////////////////////////////////////////////
98
99
  private int checkAllVerticesPresent(int[][] vertex)
100
    {
101
    boolean ybr = false;
102
    boolean gbr = false;
103
    boolean gyr = false;
104
    boolean gyb = false;
105
106
    for(int i=0; i<4; i++)
107
      {
108
      if( pieceEqual3(vertex[i],0,1,2) ) gyb = true;
109
      if( pieceEqual3(vertex[i],0,1,3) ) gyr = true;
110
      if( pieceEqual3(vertex[i],0,2,3) ) gbr = true;
111
      if( pieceEqual3(vertex[i],1,2,3) ) ybr = true;
112
      }
113
114
    if( !ybr ) return ERROR_VERTEX_YBR_MISSING;
115
    if( !gbr ) return ERROR_VERTEX_GBR_MISSING;
116
    if( !gyr ) return ERROR_VERTEX_GYR_MISSING;
117
    if( !gyb ) return ERROR_VERTEX_GYB_MISSING;
118
119
    return 0;
120
    }
121
122
///////////////////////////////////////////////////////////////////////////////////////////////////
123
124 202b167e Leszek Koltunski
  private int checkAllEdgesPresent(int[][] edges, int[][] edgeColors)
125 7dbbda72 Leszek Koltunski
    {
126 d3c2aa29 Leszek Koltunski
    boolean[] present = new boolean[6];
127
    for(int i=0; i<6; i++) present[i] = false;
128 7dbbda72 Leszek Koltunski
129
    for(int i=0; i<6; i++)
130 d3c2aa29 Leszek Koltunski
      for(int j=0; j<6; j++)
131
        if (pieceEqual2(edges[i], edgeColors[j]))
132
          {
133
          present[j] = true;
134
          break;
135
          }
136
137
    if( !present[0] ) return ERROR_EDGE_RB_MISSING;
138
    if( !present[1] ) return ERROR_EDGE_RY_MISSING;
139
    if( !present[2] ) return ERROR_EDGE_RG_MISSING;
140
    if( !present[3] ) return ERROR_EDGE_YB_MISSING;
141
    if( !present[4] ) return ERROR_EDGE_GB_MISSING;
142
    if( !present[5] ) return ERROR_EDGE_GY_MISSING;
143 7dbbda72 Leszek Koltunski
144
    return 0;
145
    }
146
147
///////////////////////////////////////////////////////////////////////////////////////////////////
148
149
  private int[] computeFaceColors(int[][] corners)
150
    {
151
    int[] ret = new int[4];
152
153
    for(int i=0; i<4; i++)
154
      for(int j=0; j<4; j++)
155
        if( corners[i][0]!=j && corners[i][1]!=j && corners[i][2]!=j ) ret[i]=j;
156
157
    return ret;
158
    }
159
160
///////////////////////////////////////////////////////////////////////////////////////////////////
161
162
  private int checkAgreement(int[] faces1, int[] faces2)
163
    {
164
    for(int i=0; i<4; i++)
165
      if( faces1[i]!=faces2[i] ) return ERROR_C_V_DONT_MATCH;
166
167
    return 0;
168
    }
169
170
///////////////////////////////////////////////////////////////////////////////////////////////////
171
172
  private int computePieceTwist(int index, int[] corner, int[] faceColor)
173
    {
174
    int twist1=0, twist2=0, twist3=0;
175
176
    switch(index)
177
      {
178
      case 0: if( corner[1]==faceColor[1] ) twist1=1;
179
              if( corner[2]==faceColor[1] ) twist1=2;
180
              if( corner[0]==faceColor[2] ) twist2=2;
181
              if( corner[2]==faceColor[2] ) twist2=1;
182
              if( corner[0]==faceColor[3] ) twist3=1;
183
              if( corner[1]==faceColor[3] ) twist3=2;
184
              break;
185
      case 1: if( corner[1]==faceColor[0] ) twist1=1;
186
              if( corner[2]==faceColor[0] ) twist1=2;
187
              if( corner[0]==faceColor[2] ) twist2=1;
188
              if( corner[1]==faceColor[2] ) twist2=2;
189
              if( corner[0]==faceColor[3] ) twist3=2;
190
              if( corner[2]==faceColor[3] ) twist3=1;
191
              break;
192
      case 2: if( corner[1]==faceColor[0] ) twist1=1;
193
              if( corner[2]==faceColor[0] ) twist1=2;
194
              if( corner[0]==faceColor[1] ) twist2=2;
195
              if( corner[2]==faceColor[1] ) twist2=1;
196
              if( corner[0]==faceColor[3] ) twist3=1;
197
              if( corner[1]==faceColor[3] ) twist3=2;
198
              break;
199
      case 3: if( corner[1]==faceColor[0] ) twist1=1;
200
              if( corner[2]==faceColor[0] ) twist1=2;
201
              if( corner[0]==faceColor[1] ) twist2=1;
202
              if( corner[1]==faceColor[1] ) twist2=2;
203
              if( corner[0]==faceColor[2] ) twist3=2;
204
              if( corner[2]==faceColor[2] ) twist3=1;
205
              break;
206
      }
207
208 d3c2aa29 Leszek Koltunski
    return ( twist1!=twist2 || twist1!=twist3 ) ? ERROR_CORNERS_CANNOT : twist1;
209
    }
210
211
///////////////////////////////////////////////////////////////////////////////////////////////////
212
213
  private int locateEdge(int[][] edges, int[] colors)
214
    {
215
    for(int i=0; i<6; i++)
216
      if( edges[i][0]==colors[0] && edges[i][1]==colors[1] ||
217
          edges[i][0]==colors[1] && edges[i][1]==colors[0]  ) return i;
218
219
    return -1;
220
    }
221
222
///////////////////////////////////////////////////////////////////////////////////////////////////
223
224
  private int edgeTwist(int[] edge, int[] colors)
225
    {
226
    return edge[0]==colors[0] ? 0:1;
227 7dbbda72 Leszek Koltunski
    }
228
229 f41d2652 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
230
231 202b167e Leszek Koltunski
  private int[] computeEdgeQuats(int[][] edges, int[][] edgeColors)
232 f41d2652 Leszek Koltunski
    {
233 d3c2aa29 Leszek Koltunski
    int[] quats = new int[6];
234
235
    for(int i=0; i<6; i++)
236
      {
237
      int pos   = locateEdge(edges,edgeColors[i]);
238
      int twist = edgeTwist(edges[pos],edgeColors[i]);
239
      quats[i]  = TablebasesPyraminx.EDGE_QUATS[pos][twist];
240
      }
241 a2dd09be Leszek Koltunski
242 d3c2aa29 Leszek Koltunski
    return quats;
243 f41d2652 Leszek Koltunski
    }
244
245 7dbbda72 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
246
247
  public SolverPyraminx(Resources res, TwistyObject object)
248
    {
249
    super(res,object);
250
    }
251
252
///////////////////////////////////////////////////////////////////////////////////////////////////
253
254
  private void getCorners(TwistyObject object, int[][] corners)
255
    {
256 d3c2aa29 Leszek Koltunski
    corners[0][0] = object.getCubitFaceStickerIndex(4,0);  // G
257
    corners[0][1] = object.getCubitFaceStickerIndex(4,3);  // R
258
    corners[0][2] = object.getCubitFaceStickerIndex(4,2);  // B
259 7dbbda72 Leszek Koltunski
260 d3c2aa29 Leszek Koltunski
    corners[1][0] = object.getCubitFaceStickerIndex(6,1);  // Y
261
    corners[1][1] = object.getCubitFaceStickerIndex(6,2);  // B
262
    corners[1][2] = object.getCubitFaceStickerIndex(6,3);  // R
263 7dbbda72 Leszek Koltunski
264 d3c2aa29 Leszek Koltunski
    corners[2][0] = object.getCubitFaceStickerIndex(11,1);  // Y
265
    corners[2][1] = object.getCubitFaceStickerIndex(11,0);  // G
266
    corners[2][2] = object.getCubitFaceStickerIndex(11,2);  // B
267 7dbbda72 Leszek Koltunski
268 d3c2aa29 Leszek Koltunski
    corners[3][0] = object.getCubitFaceStickerIndex(13,1);  // Y
269
    corners[3][1] = object.getCubitFaceStickerIndex(13,3);  // R
270
    corners[3][2] = object.getCubitFaceStickerIndex(13,0);  // G
271 7dbbda72 Leszek Koltunski
    }
272
273
///////////////////////////////////////////////////////////////////////////////////////////////////
274
275
  private void getVertices(TwistyObject object, int[][] vertex)
276
    {
277 d3c2aa29 Leszek Koltunski
    vertex[0][0] = object.getCubitFaceStickerIndex(0,0);  // G
278
    vertex[0][1] = object.getCubitFaceStickerIndex(0,5);  // R
279
    vertex[0][2] = object.getCubitFaceStickerIndex(0,7);  // B
280 7dbbda72 Leszek Koltunski
281 d3c2aa29 Leszek Koltunski
    vertex[1][0] = object.getCubitFaceStickerIndex(1,2);  // Y
282
    vertex[1][1] = object.getCubitFaceStickerIndex(1,7);  // B
283
    vertex[1][2] = object.getCubitFaceStickerIndex(1,5);  // R
284 7dbbda72 Leszek Koltunski
285 d3c2aa29 Leszek Koltunski
    vertex[2][0] = object.getCubitFaceStickerIndex(2,2);  // Y
286
    vertex[2][1] = object.getCubitFaceStickerIndex(2,0);  // G
287
    vertex[2][2] = object.getCubitFaceStickerIndex(2,7);  // B
288 7dbbda72 Leszek Koltunski
289 d3c2aa29 Leszek Koltunski
    vertex[3][0] = object.getCubitFaceStickerIndex(3,2);  // Y
290
    vertex[3][1] = object.getCubitFaceStickerIndex(3,5);  // R
291
    vertex[3][2] = object.getCubitFaceStickerIndex(3,0);  // G
292 7dbbda72 Leszek Koltunski
    }
293
294
///////////////////////////////////////////////////////////////////////////////////////////////////
295
296
  private void getEdges(TwistyObject object, int[][] edges)
297
    {
298
    edges[0][0] = object.getCubitFaceStickerIndex(5,3);  // R
299
    edges[0][1] = object.getCubitFaceStickerIndex(5,2);  // B
300
301 d3c2aa29 Leszek Koltunski
    edges[1][0] = object.getCubitFaceStickerIndex(10,1); // Y
302
    edges[1][1] = object.getCubitFaceStickerIndex(10,3); // R
303 7dbbda72 Leszek Koltunski
304 d3c2aa29 Leszek Koltunski
    edges[2][0] = object.getCubitFaceStickerIndex(9,0);  // G
305
    edges[2][1] = object.getCubitFaceStickerIndex(9,3);  // R
306 7dbbda72 Leszek Koltunski
307 d3c2aa29 Leszek Koltunski
    edges[3][0] = object.getCubitFaceStickerIndex(8,2);  // B
308
    edges[3][1] = object.getCubitFaceStickerIndex(8,1);  // Y
309 7dbbda72 Leszek Koltunski
310 d3c2aa29 Leszek Koltunski
    edges[4][0] = object.getCubitFaceStickerIndex(7,2);  // B
311
    edges[4][1] = object.getCubitFaceStickerIndex(7,0);  // G
312 7dbbda72 Leszek Koltunski
313 d3c2aa29 Leszek Koltunski
    edges[5][0] = object.getCubitFaceStickerIndex(12,1); // Y
314
    edges[5][1] = object.getCubitFaceStickerIndex(12,0); // G
315 7dbbda72 Leszek Koltunski
    }
316
317 202b167e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
318
319
  private int[][] computeEdgeColors(int[] faceColor)
320
    {
321
    // The first pair being (2,3) means 'the first edge's first face is on the tetrahedron
322
    // face which oppeses corner number 2, and its second face on tetra face which opposes
323
    // corner number 3'
324
    // Order of those pairs determines edge twist.
325
326
    final int[][] edgeColorIndices = new int[][] { {2,3},{0,2},{1,2},{3,0},{3,1},{0,1}  };
327
    int[][] ret = new int[6][2];
328
329
    for(int i=0; i<6; i++)
330
      {
331
      ret[i][0] = faceColor[edgeColorIndices[i][0]];
332
      ret[i][1] = faceColor[edgeColorIndices[i][1]];
333
      }
334
335
    return ret;
336
    }
337
338 7dbbda72 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
339
340
  public int tablebaseIndex(TwistyObject object)
341
    {
342
    int[][] corners = new int[4][3];
343
    int[][] edges   = new int[6][2];
344
    int[][] vertices= new int[4][3];
345
    int[] vertex_twist = new int[4];
346 b8dab9fd Leszek Koltunski
    mCornerTwist = new int[4];
347 7dbbda72 Leszek Koltunski
348
    getCorners(object,corners);
349
    getVertices(object,vertices);
350
351
    int result1 = checkAllCornersPresent(corners);
352
    if( result1<0 ) return result1;
353
354
    int result2 = checkAllVerticesPresent(vertices);
355
    if( result2<0 ) return result2;
356
357
    int[] faces1 = computeFaceColors(corners);
358
    int[] faces2 = computeFaceColors(vertices);
359
360 202b167e Leszek Koltunski
    int result3 = checkAgreement(faces1,faces2);
361
    if( result3<0 ) return result3;
362
363
    int[][] edgeColors = computeEdgeColors(faces1);
364
365
    getEdges(object,edges);
366
    int result4 = checkAllEdgesPresent(edges,edgeColors);
367 7dbbda72 Leszek Koltunski
    if( result4<0 ) return result4;
368 e43fd306 Leszek Koltunski
369 7dbbda72 Leszek Koltunski
    for(int i=0; i<4; i++)
370
      {
371 b8dab9fd Leszek Koltunski
      mCornerTwist[i] = computePieceTwist(i,corners[i],faces1);
372
      if( mCornerTwist[i]<0 ) return ERROR_CORNERS_CANNOT;
373 7dbbda72 Leszek Koltunski
      }
374
375
    for(int i=0; i<4; i++)
376
      {
377
      vertex_twist[i] = computePieceTwist(i,vertices[i],faces1);
378
      if( vertex_twist[i]<0 ) return ERROR_VERTICES_CANNOT;
379
      }
380
381 202b167e Leszek Koltunski
    int[] quats = computeEdgeQuats(edges,edgeColors);
382 55b2d967 Leszek Koltunski
    int[] permutation = new int[6];
383 d3c2aa29 Leszek Koltunski
    TablebasesPyraminx.getEdgePermutation(permutation,quats,0);
384 55b2d967 Leszek Koltunski
    boolean even = TablebaseHelpers.permutationIsEven(permutation);
385
    if( !even ) return ERROR_TWO_EDGES;
386 d3c2aa29 Leszek Koltunski
    int[] edge_twist = new int[6];
387
    TablebasesPyraminx.getEdgeTwist(edge_twist,quats,0);
388 e43fd306 Leszek Koltunski
389 d3c2aa29 Leszek Koltunski
    int totalEdgeTwist=0;
390
    for(int i=0; i<6; i++) totalEdgeTwist += edge_twist[i];
391
    if( (totalEdgeTwist%2)!=0 ) return ERROR_EDGE_TWISTED;
392
393
    int vertexTwist = vertex_twist[0]+ 3*(vertex_twist[1]+ 3*(vertex_twist[2]+ 3*vertex_twist[3]));
394
    int edgeTwist = edge_twist[0]+ 2*(edge_twist[1]+ 2*(edge_twist[2]+ 2*(edge_twist[3]+ 2*edge_twist[4])));
395
    int perm_num = TablebaseHelpers.computeEvenPermutationNum(permutation);
396
397
    return vertexTwist + 81*(edgeTwist + 32*perm_num);
398 7dbbda72 Leszek Koltunski
    }
399
400
///////////////////////////////////////////////////////////////////////////////////////////////////
401
402
  private int getColorIndex3(int color)
403
    {
404
    switch(color)
405
      {
406
      case 0: return R.string.color_green3;
407
      case 1: return R.string.color_yellow3;
408
      case 2: return R.string.color_blue3;
409
      case 3: return R.string.color_red3;
410
      }
411
412
    return -1;
413
    }
414
415
///////////////////////////////////////////////////////////////////////////////////////////////////
416
417
  private int getColorIndex4(int color)
418
    {
419
    switch(color)
420
      {
421
      case 0: return R.string.color_green4;
422
      case 1: return R.string.color_yellow4;
423
      case 2: return R.string.color_blue4;
424
      case 3: return R.string.color_red4;
425
      }
426
427
    return -1;
428
    }
429
430
///////////////////////////////////////////////////////////////////////////////////////////////////
431
432
  private int getColorIndex6(int color)
433
    {
434
    switch(color)
435
      {
436
      case 0: return R.string.color_green6;
437
      case 1: return R.string.color_yellow6;
438
      case 2: return R.string.color_blue6;
439
      case 3: return R.string.color_red6;
440
      }
441
442
    return -1;
443
    }
444
445
///////////////////////////////////////////////////////////////////////////////////////////////////
446
447
  private String cornerError(Resources res, int color0, int color1, int color2)
448
    {
449
    int j0 = getColorIndex3(color0);
450
    int j1 = getColorIndex3(color1);
451
    int j2 = getColorIndex4(color2);
452
453
    String c0 = res.getString(j0);
454
    String c1 = res.getString(j1);
455
    String c2 = res.getString(j2);
456
457
    return res.getString(R.string.solver_generic_missing_corner,c0,c1,c2);
458
    }
459
460
///////////////////////////////////////////////////////////////////////////////////////////////////
461
462
  private String vertexError(Resources res, int color0, int color1, int color2)
463
    {
464
    int j0 = getColorIndex3(color0);
465
    int j1 = getColorIndex3(color1);
466
    int j2 = getColorIndex4(color2);
467
468
    String c0 = res.getString(j0);
469
    String c1 = res.getString(j1);
470
    String c2 = res.getString(j2);
471
472
    return res.getString(R.string.solver_generic_missing_vertex,c0,c1,c2);
473
    }
474
475
///////////////////////////////////////////////////////////////////////////////////////////////////
476
477
  private String edgeError(Resources res, int color0, int color1)
478
    {
479
    int j0 = getColorIndex3(color0);
480
    int j1 = getColorIndex6(color1);
481
482
    String c0 = res.getString(j0);
483
    String c1 = res.getString(j1);
484
485
    return res.getString(R.string.solver_generic_missing_edge,c0,c1);
486
    }
487
488
///////////////////////////////////////////////////////////////////////////////////////////////////
489
490
  public String error(int index, Resources res)
491
    {
492
    switch(index)
493
      {
494
      case ERROR_CORNER_YBR_MISSING: return cornerError(res,3,2,1);
495
      case ERROR_CORNER_GBR_MISSING: return cornerError(res,3,2,0);
496
      case ERROR_CORNER_GYR_MISSING: return cornerError(res,3,1,0);
497
      case ERROR_CORNER_GYB_MISSING: return cornerError(res,2,1,0);
498
      case ERROR_VERTEX_YBR_MISSING: return vertexError(res,3,2,1);
499
      case ERROR_VERTEX_GBR_MISSING: return vertexError(res,3,2,0);
500
      case ERROR_VERTEX_GYR_MISSING: return vertexError(res,3,1,0);
501
      case ERROR_VERTEX_GYB_MISSING: return vertexError(res,2,1,0);
502
      case ERROR_EDGE_RB_MISSING   : return edgeError(res,3,2);
503
      case ERROR_EDGE_RY_MISSING   : return edgeError(res,3,1);
504
      case ERROR_EDGE_RG_MISSING   : return edgeError(res,3,0);
505
      case ERROR_EDGE_YB_MISSING   : return edgeError(res,2,1);
506
      case ERROR_EDGE_GB_MISSING   : return edgeError(res,2,0);
507
      case ERROR_EDGE_GY_MISSING   : return edgeError(res,1,0);
508
      case ERROR_EDGE_TWISTED      : return res.getString(R.string.solver_generic_edge_twist);
509
      case ERROR_CORNERS_CANNOT    : return res.getString(R.string.solver_generic_corners_cannot);
510
      case ERROR_VERTICES_CANNOT   : return res.getString(R.string.solver_generic_vertices_cannot);
511
      case ERROR_C_V_DONT_MATCH    : return res.getString(R.string.solver_generic_c_v_dont_match);
512 55b2d967 Leszek Koltunski
      case ERROR_TWO_EDGES         : return res.getString(R.string.solver_generic_two_edges);
513 7dbbda72 Leszek Koltunski
      }
514
515
    return null;
516
    }
517
518 b8dab9fd Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
519
520
  private void addMove(int[] move, int axis, int twist)
521
    {
522
    move[0] = axis;
523
    move[1] = (1<<2);
524
    move[2] = (twist==2 ? -1:twist);
525
    }
526
527
///////////////////////////////////////////////////////////////////////////////////////////////////
528
529
  private int[][] constructTipMoves(int[] twist)
530
    {
531
    int total = 0;
532
533
    for(int i=0; i<4; i++)
534
      if( twist[i]!=0 ) total++;
535
536
    if( total>0 )
537
      {
538
      int[][] moves = new int[total][3];
539
540
      int index=0;
541
      if( twist[0]!=0 ) { addMove(moves[index],1,twist[0]); index++; }
542
      if( twist[1]!=0 ) { addMove(moves[index],0,twist[1]); index++; }
543
      if( twist[2]!=0 ) { addMove(moves[index],3,twist[2]); index++; }
544
      if( twist[3]!=0 ) { addMove(moves[index],2,twist[3]);          }
545
546
      return moves;
547
      }
548
549
    return null;
550
    }
551
552 7dbbda72 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
553
554
  public int[][] solution(int index, Resources res)
555
    {
556
    if( mSolver==null )
557
      {
558 2876aeb6 Leszek Koltunski
      mSolver = ImplementedTablebasesList.createPacked(res, ObjectSignatures.PYRA_3);
559 7dbbda72 Leszek Koltunski
      }
560
561 b8dab9fd Leszek Koltunski
    int[][] moves1 = mSolver!=null ? mSolver.solution(index) : null;
562
    int[][] moves2 = constructTipMoves(mCornerTwist);
563
564
    int len1 = (moves1==null ? 0:moves1.length);
565
    int len2 = (moves2==null ? 0:moves2.length);
566
567 202b167e Leszek Koltunski
    int[][] moves = new int[len1+len2][3];
568 b8dab9fd Leszek Koltunski
569
    if( len1>0 ) System.arraycopy(moves1, 0, moves,    0, len1);
570
    if( len2>0 ) System.arraycopy(moves2, 0, moves, len1, len2);
571
572
    return moves;
573 7dbbda72 Leszek Koltunski
    }
574
}