Project

General

Profile

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

magiccube / src / main / java / org / distorted / solvers / SolverCuboid323.java @ 8c8a9fb9

1
///////////////////////////////////////////////////////////////////////////////////////////////////
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
import org.distorted.objectlib.helpers.OperatingSystemInterface;
16
import org.distorted.objectlib.main.ObjectSignatures;
17
import org.distorted.objectlib.main.TwistyObject;
18
import org.distorted.objectlib.tablebases.ImplementedTablebasesList;
19
import org.distorted.objectlib.tablebases.TablebasesAbstract;
20

    
21
///////////////////////////////////////////////////////////////////////////////////////////////////
22

    
23
public class SolverCuboid323 extends SolverTablebase
24
{
25
  private static final int ERROR_CORNER_MISSING = -1;
26
  private static final int ERROR_EDGE_MISSING   = -2;
27
  private static final int ERROR_CORNERS_CANNOT = -3;
28
  private static final int ERROR_EDGE_TWISTED   = -4;
29
  private static final int ERROR_CORNER_TWISTED = -5;
30

    
31
  TablebasesAbstract mSolver;
32
  private final int[] mFaceColors;
33
  private int mErrorColor1, mErrorColor2, mErrorColor3;
34
  private boolean mUpper;
35

    
36
///////////////////////////////////////////////////////////////////////////////////////////////////
37

    
38
  private int edgeIs(int[] edge, int i0, int i1)
39
    {
40
    int c0 = mFaceColors[i0];
41
    int c1 = mFaceColors[i1];
42

    
43
    if( edge[0]==c0 && edge[1]==c1 ) return 0;
44
    if( edge[0]==c1 && edge[1]==c0 ) return 1;
45
    return 2;
46
    }
47

    
48
///////////////////////////////////////////////////////////////////////////////////////////////////
49

    
50
  private int retEdgePermutation(int[] output, int[][] edges)
51
    {
52
    for(int i=0; i<4; i++) output[i] = -1;
53

    
54
    for(int i=0; i<4; i++)
55
      {
56
      int edge0 = edgeIs(edges[i],1,5);
57
           if( edge0==0 ) output[0]=i;
58
      else if( edge0==1 ) return ERROR_EDGE_TWISTED;
59

    
60
      int edge1 = edgeIs(edges[i],1,4);
61
           if( edge1==0 ) output[1]=i;
62
      else if( edge1==1 ) return ERROR_EDGE_TWISTED;
63

    
64
      int edge2 = edgeIs(edges[i],0,5);
65
           if( edge2==0 ) output[2]=i;
66
      else if( edge2==1 ) return ERROR_EDGE_TWISTED;
67

    
68
      int edge3 = edgeIs(edges[i],0,4);
69
           if( edge3==0 ) output[3]=i;
70
      else if( edge3==1 ) return ERROR_EDGE_TWISTED;
71
      }
72
/*
73
    if( output[0]==-1 ) return ERROR_EDGE_15_MISSING;
74
    if( output[1]==-1 ) return ERROR_EDGE_14_MISSING;
75
    if( output[2]==-1 ) return ERROR_EDGE_05_MISSING;
76
    if( output[3]==-1 ) return ERROR_EDGE_04_MISSING;
77
*/
78
    return 0;
79
    }
80

    
81
///////////////////////////////////////////////////////////////////////////////////////////////////
82

    
83
  private int cornerIs(int[] corner, int i0, int i1, int i2)
84
    {
85
    int c0 = mFaceColors[i0];
86
    int c1 = mFaceColors[i1];
87
    int c2 = mFaceColors[i2];
88

    
89
    if( corner[0]==c0 && corner[1]==c1 && corner[2]==c2 ) return 0;
90

    
91
    if( corner[0]==c0 && corner[1]==c2 && corner[2]==c1 ||
92
        corner[0]==c1 && corner[1]==c0 && corner[2]==c2 ||
93
        corner[0]==c1 && corner[1]==c2 && corner[2]==c0 ||
94
        corner[0]==c2 && corner[1]==c0 && corner[2]==c1 ||
95
        corner[0]==c2 && corner[1]==c1 && corner[2]==c0  ) return 1;
96

    
97
    return 2;
98
    }
99

    
100
///////////////////////////////////////////////////////////////////////////////////////////////////
101

    
102
  private int retCornerPermutation(int[] output, int[][] corners)
103
    {
104
    for(int i=0; i<8; i++) output[i] = -1;
105

    
106
    for(int i=0; i<8; i++)
107
      {
108
      int corner7 = cornerIs(corners[i],2,4,0);
109
           if( corner7==0 ) output[7]=i;
110
      else if( corner7==1 ) return ERROR_CORNER_TWISTED;
111

    
112
      int corner6 = cornerIs(corners[i],2,0,5);
113
           if( corner6==0 ) output[6]=i;
114
      else if( corner6==1 ) return ERROR_CORNER_TWISTED;
115

    
116
      int corner5 = cornerIs(corners[i],3,0,4);
117
           if( corner5==0 ) output[5]=i;
118
      else if( corner5==1 ) return ERROR_CORNER_TWISTED;
119

    
120
      int corner4 = cornerIs(corners[i],3,5,0);
121
           if( corner4==0 ) output[4]=i;
122
      else if( corner4==1 ) return ERROR_CORNER_TWISTED;
123

    
124
      int corner3 = cornerIs(corners[i],2,1,4);
125
           if( corner3==0 ) output[3]=i;
126
      else if( corner3==1 ) return ERROR_CORNER_TWISTED;
127

    
128
      int corner2 = cornerIs(corners[i],2,5,1);
129
           if( corner2==0 ) output[2]=i;
130
      else if( corner2==1 ) return ERROR_CORNER_TWISTED;
131

    
132
      int corner1 = cornerIs(corners[i],3,4,1);
133
           if( corner1==0 ) output[1]=i;
134
      else if( corner1==1 ) return ERROR_CORNER_TWISTED;
135

    
136
      int corner0 = cornerIs(corners[i],3,1,5);
137
           if( corner0==0 ) output[0]=i;
138
      else if( corner0==1 ) return ERROR_CORNER_TWISTED;
139
      }
140
/*
141
    if( output[0]==-1 ) return ERROR_CORNER_135_MISSING;
142
    if( output[1]==-1 ) return ERROR_CORNER_134_MISSING;
143
    if( output[2]==-1 ) return ERROR_CORNER_125_MISSING;
144
    if( output[3]==-1 ) return ERROR_CORNER_124_MISSING;
145
    if( output[4]==-1 ) return ERROR_CORNER_035_MISSING;
146
    if( output[5]==-1 ) return ERROR_CORNER_034_MISSING;
147
    if( output[6]==-1 ) return ERROR_CORNER_025_MISSING;
148
    if( output[7]==-1 ) return ERROR_CORNER_024_MISSING;
149
*/
150
    return 0;
151
    }
152

    
153
///////////////////////////////////////////////////////////////////////////////////////////////////
154

    
155
  private int[] correctEdgePerm(int[] perm)
156
    {
157
    int[] ret = new int[3];
158

    
159
    ret[0] = perm[0];
160
    ret[1] = perm[2];
161
    ret[2] = perm[3];
162

    
163
    if( ret[0]>1 ) ret[0]--;
164
    if( ret[1]>1 ) ret[1]--;
165
    if( ret[2]>1 ) ret[2]--;
166

    
167
    return ret;
168
    }
169

    
170
///////////////////////////////////////////////////////////////////////////////////////////////////
171

    
172
  public SolverCuboid323(OperatingSystemInterface os, Resources res, TwistyObject object)
173
    {
174
    super(os,res,object);
175
    mFaceColors = new int[6];
176
    }
177

    
178
////////////////////////////////////////////////////////////////////////////////////////
179

    
180
  private int findCorner(int[][] corners, int c1, int c2)
181
    {
182
    for(int i=0; i<8; i++)
183
      {
184
      int[] c = corners[i];
185

    
186
      if( c[0]==c1 && c[1]==c2 ) return c[2];
187
      if( c[1]==c1 && c[2]==c2 ) return c[0];
188
      if( c[2]==c1 && c[0]==c2 ) return c[1];
189
      }
190

    
191
    return ERROR_CORNERS_CANNOT;
192
    }
193

    
194
////////////////////////////////////////////////////////////////////////////////////////
195

    
196
  private int missingColor()
197
    {
198
    boolean[] present = new boolean[6];
199
    for(int i=0; i<5; i++) present[mFaceColors[i]] = true;
200

    
201
    int indexFalse = -1;
202

    
203
    for(int i=0; i<6; i++)
204
      if( !present[i] )
205
        {
206
        if( indexFalse<0 ) indexFalse=i;
207
        else return ERROR_CORNERS_CANNOT;
208
        }
209

    
210
    return indexFalse;
211
    }
212

    
213
////////////////////////////////////////////////////////////////////////////////////////
214

    
215
  private int edgePresent(int[][] edges, int f0, int f1)
216
    {
217
    int c0 = mFaceColors[f0];
218
    int c1 = mFaceColors[f1];
219

    
220
    for(int[] edge : edges)
221
      {
222
      if( edge[0]==c0 && edge[1]==c1 )
223
        return 0;
224
      if( edge[0]==c1 && edge[1]==c0 )
225
        {
226
        mErrorColor1 = c0;
227
        mErrorColor2 = c1;
228
        return ERROR_EDGE_TWISTED;
229
        }
230
      }
231

    
232
    mErrorColor1 = c0;
233
    mErrorColor2 = c1;
234
    return ERROR_EDGE_MISSING;
235
    }
236

    
237
////////////////////////////////////////////////////////////////////////////////////////
238

    
239
  private int cornerPresent(int[][] corners, int f0, int f1, int f2)
240
    {
241
    int c0 = mFaceColors[f0];
242
    int c1 = mFaceColors[f1];
243
    int c2 = mFaceColors[f2];
244

    
245
    for(int[] corner : corners )
246
      {
247
      if(  corner[0]==c0 && corner[1]==c1 && corner[2]==c2 ) return 0;
248
      if( (corner[0]==c1 && corner[1]==c2 && corner[2]==c0 ) ||
249
          (corner[0]==c2 && corner[1]==c0 && corner[2]==c1 )  )
250
        {
251
        mErrorColor1 = c0;
252
        mErrorColor2 = c1;
253
        mErrorColor3 = c2;
254
        return ERROR_CORNER_TWISTED;
255
        }
256
      }
257

    
258
    mErrorColor1 = c0;
259
    mErrorColor2 = c1;
260
    mErrorColor3 = c2;
261
    return ERROR_CORNER_MISSING;
262
    }
263

    
264
////////////////////////////////////////////////////////////////////////////////////////
265

    
266
  private int checkAllEdgesPresent(int[][] edges)
267
    {
268
    int result;
269

    
270
    result = edgePresent(edges,0,2);
271
    if( result<0 ) return result;
272
    result = edgePresent(edges,1,2);
273
    if( result<0 ) return result;
274
    result = edgePresent(edges,4,2);
275
    if( result<0 ) return result;
276
    result = edgePresent(edges,5,2);
277
    if( result<0 ) return result;
278
    result = edgePresent(edges,0,3);
279
    if( result<0 ) return result;
280
    result = edgePresent(edges,1,3);
281
    if( result<0 ) return result;
282
    result = edgePresent(edges,4,3);
283
    if( result<0 ) return result;
284
    result = edgePresent(edges,5,3);
285
    if( result<0 ) return result;
286

    
287
    return 0;
288
    }
289

    
290
////////////////////////////////////////////////////////////////////////////////////////
291

    
292
  private int checkAllCornersPresent(int[][] corners)
293
    {
294
    int result;
295

    
296
    result = cornerPresent(corners,0,4,2);
297
    if( result<0 ) return result;
298
    result = cornerPresent(corners,5,0,2);
299
    if( result<0 ) return result;
300
    result = cornerPresent(corners,1,5,2);
301
    if( result<0 ) return result;
302
    result = cornerPresent(corners,4,1,2);
303
    if( result<0 ) return result;
304
    result = cornerPresent(corners,4,0,3);
305
    if( result<0 ) return result;
306
    result = cornerPresent(corners,0,5,3);
307
    if( result<0 ) return result;
308
    result = cornerPresent(corners,5,1,3);
309
    if( result<0 ) return result;
310
    result = cornerPresent(corners,1,4,3);
311
    if( result<0 ) return result;
312

    
313
    return 0;
314
    }
315

    
316
////////////////////////////////////////////////////////////////////////////////////////
317

    
318
  private int computeFaceColors(int[][] corners, int[][] edges, int[] centers)
319
    {
320
    mFaceColors[2] = centers[0];
321
    mFaceColors[3] = centers[1];
322

    
323
    if( edges[1][1]==mFaceColors[2] )
324
      {
325
      mUpper = true;
326
      mFaceColors[4] = edges[1][0];
327
      }
328
    else if( edges[3][1]==mFaceColors[2] )
329
      {
330
      mUpper = true;
331
      mFaceColors[4] = edges[3][0];
332
      }
333
    else
334
      {
335
      mUpper = false;
336
      mFaceColors[4] = edges[3][0];
337
      }
338

    
339
    mFaceColors[0] = findCorner(corners,mFaceColors[4],mFaceColors[2]);
340
    if( mFaceColors[0]<0 ) return mFaceColors[0];
341

    
342
    mFaceColors[1] = findCorner(corners,mFaceColors[2],mFaceColors[4]);
343
    if( mFaceColors[1]<0 ) return mFaceColors[1];
344

    
345
    mFaceColors[5] = missingColor();
346
    if( mFaceColors[5]<0 ) return mFaceColors[5];
347

    
348
    return 0;
349
    }
350

    
351
///////////////////////////////////////////////////////////////////////////////////////////////////
352

    
353
  private void getCorners(TwistyObject object, int[][] corners)
354
    {
355
    corners[0][0] = object.getCubitFaceStickerIndex(0,5);
356
    corners[0][1] = object.getCubitFaceStickerIndex(0,1);
357
    corners[0][2] = object.getCubitFaceStickerIndex(0,3);
358

    
359
    corners[1][0] = object.getCubitFaceStickerIndex(1,3);
360
    corners[1][1] = object.getCubitFaceStickerIndex(1,5);
361
    corners[1][2] = object.getCubitFaceStickerIndex(1,1);
362

    
363
    corners[2][0] = object.getCubitFaceStickerIndex(2,5);
364
    corners[2][1] = object.getCubitFaceStickerIndex(2,1);
365
    corners[2][2] = object.getCubitFaceStickerIndex(2,3);
366

    
367
    corners[3][0] = object.getCubitFaceStickerIndex(3,5);
368
    corners[3][1] = object.getCubitFaceStickerIndex(3,1);
369
    corners[3][2] = object.getCubitFaceStickerIndex(3,3);
370

    
371
    corners[4][0] = object.getCubitFaceStickerIndex(4,1);
372
    corners[4][1] = object.getCubitFaceStickerIndex(4,3);
373
    corners[4][2] = object.getCubitFaceStickerIndex(4,5);
374

    
375
    corners[5][0] = object.getCubitFaceStickerIndex(5,5);
376
    corners[5][1] = object.getCubitFaceStickerIndex(5,1);
377
    corners[5][2] = object.getCubitFaceStickerIndex(5,3);
378

    
379
    corners[6][0] = object.getCubitFaceStickerIndex(6,5);
380
    corners[6][1] = object.getCubitFaceStickerIndex(6,1);
381
    corners[6][2] = object.getCubitFaceStickerIndex(6,3);
382

    
383
    corners[7][0] = object.getCubitFaceStickerIndex(7,1);
384
    corners[7][1] = object.getCubitFaceStickerIndex(7,3);
385
    corners[7][2] = object.getCubitFaceStickerIndex(7,5);
386
    }
387

    
388
///////////////////////////////////////////////////////////////////////////////////////////////////
389

    
390
  private void getEdges(TwistyObject object, int[][] edges)
391
    {
392
    edges[0][0] = object.getCubitFaceStickerIndex(8,5);
393
    edges[0][1] = object.getCubitFaceStickerIndex(8,3);
394
    edges[1][0] = object.getCubitFaceStickerIndex(9,3);
395
    edges[1][1] = object.getCubitFaceStickerIndex(9,5);
396
    edges[2][0] = object.getCubitFaceStickerIndex(10,3);
397
    edges[2][1] = object.getCubitFaceStickerIndex(10,5);
398
    edges[3][0] = object.getCubitFaceStickerIndex(11,5);
399
    edges[3][1] = object.getCubitFaceStickerIndex(11,3);
400
    edges[4][0] = object.getCubitFaceStickerIndex(12,3);
401
    edges[4][1] = object.getCubitFaceStickerIndex(12,5);
402
    edges[5][0] = object.getCubitFaceStickerIndex(13,5);
403
    edges[5][1] = object.getCubitFaceStickerIndex(13,3);
404
    edges[6][0] = object.getCubitFaceStickerIndex(14,3);
405
    edges[6][1] = object.getCubitFaceStickerIndex(14,5);
406
    edges[7][0] = object.getCubitFaceStickerIndex(15,5);
407
    edges[7][1] = object.getCubitFaceStickerIndex(15,3);
408
    }
409

    
410
///////////////////////////////////////////////////////////////////////////////////////////////////
411

    
412
  private void getCenters(TwistyObject object, int[] centers)
413
    {
414
    centers[0] = object.getCubitFaceStickerIndex(16,4);
415
    centers[1] = object.getCubitFaceStickerIndex(17,4);
416
    }
417

    
418
///////////////////////////////////////////////////////////////////////////////////////////////////
419

    
420
  public int tablebaseIndex(TwistyObject object)
421
    {
422
    int[][] corners= new int[8][3];
423
    int[][] edges  = new int[8][2];
424
    int[] centers  = new int[2];
425

    
426
    getCorners(object,corners);
427
    getEdges(object,edges);
428
    getCenters(object,centers);
429

    
430
for(int i=0; i<8; i++) android.util.Log.e("D", "corner: "+i+" : "+corners[i][0]+" "+corners[i][1]+" "+corners[i][2]);
431

    
432
    int result0 = computeFaceColors(corners, edges, centers);
433
    if( result0<0 ) return result0;
434

    
435
    int result1 = checkAllEdgesPresent(edges);
436
    if( result1<0 ) return result1;
437

    
438
    int result2 = checkAllCornersPresent(corners);
439
    if( result2<0 ) return result2;
440

    
441
android.util.Log.e("D", "upper: "+mUpper);
442
for(int i=0; i<6; i++) android.util.Log.e("D", "face color: "+mFaceColors[i]);
443
/*
444
    int[] corner_perm = new int[8];
445
    int result1 = retCornerPermutation(corner_perm,corners);
446
    if( result1<0 ) return result1;
447

    
448
    int[] edge_perm = new int[8];
449
    int result2 = retEdgePermutation(edge_perm,edges);
450
    if( result2<0 ) return result2;
451

    
452
    int[] edge_perm2 = correctEdgePerm(edge_perm); // edge1 is fixed!
453

    
454
    int corner_perm_num = TablebaseHelpers.computePermutationNum(corner_perm);
455
    int edge_perm_num = TablebaseHelpers.computePermutationNum(edge_perm2);
456

    
457
    return edge_perm_num + 6*corner_perm_num;
458

    
459
 */
460
    return 0;
461
    }
462

    
463
///////////////////////////////////////////////////////////////////////////////////////////////////
464

    
465
  private int getColorIndex4(int color)
466
    {
467
    switch(color)
468
      {
469
      case 0: return R.string.color_yellow4;
470
      case 1: return R.string.color_white4;
471
      case 2: return R.string.color_blue4;
472
      case 3: return R.string.color_green4;
473
      case 4: return R.string.color_red4;
474
      case 5: return R.string.color_orange4;
475
      }
476

    
477
    return -1;
478
    }
479

    
480
///////////////////////////////////////////////////////////////////////////////////////////////////
481

    
482
  private int getColorIndex3(int color)
483
    {
484
    switch(color)
485
      {
486
      case 0: return R.string.color_yellow3;
487
      case 1: return R.string.color_white3;
488
      case 2: return R.string.color_blue3;
489
      case 3: return R.string.color_green3;
490
      case 4: return R.string.color_red3;
491
      case 5: return R.string.color_orange3;
492
      }
493

    
494
    return -1;
495
    }
496

    
497
///////////////////////////////////////////////////////////////////////////////////////////////////
498

    
499
  private int getColorIndex5(int color)
500
    {
501
    switch(color)
502
      {
503
      case 0: return R.string.color_yellow5;
504
      case 1: return R.string.color_white5;
505
      case 2: return R.string.color_blue5;
506
      case 3: return R.string.color_green5;
507
      case 4: return R.string.color_red5;
508
      case 5: return R.string.color_orange5;
509
      }
510

    
511
    return -1;
512
    }
513

    
514
///////////////////////////////////////////////////////////////////////////////////////////////////
515

    
516
  private int getColorIndex6(int color)
517
    {
518
    switch(color)
519
      {
520
      case 0: return R.string.color_yellow6;
521
      case 1: return R.string.color_white6;
522
      case 2: return R.string.color_blue6;
523
      case 3: return R.string.color_green6;
524
      case 4: return R.string.color_red6;
525
      case 5: return R.string.color_orange6;
526
      }
527

    
528
    return -1;
529
    }
530

    
531
///////////////////////////////////////////////////////////////////////////////////////////////////
532

    
533
  private String edgeTwistedError(Resources res, int color0, int color1)
534
    {
535
    int j0 = getColorIndex3(color0);
536
    int j1 = getColorIndex6(color1);
537

    
538
    String c0 = res.getString(j0);
539
    String c1 = res.getString(j1);
540

    
541
    return res.getString(R.string.solver_generic_twisted_edge,c0,c1);
542
    }
543

    
544
///////////////////////////////////////////////////////////////////////////////////////////////////
545

    
546
  private String cornerTwistedError(Resources res, int color0, int color1, int color2)
547
    {
548
    int j0 = getColorIndex3(color0);
549
    int j1 = getColorIndex3(color1);
550
    int j2 = getColorIndex5(color2);
551

    
552
    String c0 = res.getString(j0);
553
    String c1 = res.getString(j1);
554
    String c2 = res.getString(j2);
555

    
556
    return res.getString(R.string.solver_generic_twisted_corner,c0,c1,c2);
557
    }
558

    
559
///////////////////////////////////////////////////////////////////////////////////////////////////
560

    
561
  private String edgeMissingError(Resources res, int color0, int color1)
562
    {
563
    int j0 = getColorIndex3(color0);
564
    int j1 = getColorIndex6(color1);
565

    
566
    String c0 = res.getString(j0);
567
    String c1 = res.getString(j1);
568

    
569
    return res.getString(R.string.solver_generic_missing_edge,c0,c1);
570
    }
571

    
572
///////////////////////////////////////////////////////////////////////////////////////////////////
573

    
574
  private String cornerMissingError(Resources res, int color0, int color1, int color2)
575
    {
576
    int j0 = getColorIndex3(color0);
577
    int j1 = getColorIndex3(color1);
578
    int j2 = getColorIndex4(color2);
579

    
580
    String c0 = res.getString(j0);
581
    String c1 = res.getString(j1);
582
    String c2 = res.getString(j2);
583

    
584
    return res.getString(R.string.solver_generic_missing_corner,c0,c1,c2);
585
    }
586

    
587
///////////////////////////////////////////////////////////////////////////////////////////////////
588

    
589
  public String error(int index, Resources res)
590
    {
591
    switch(index)
592
      {
593
      case ERROR_CORNER_MISSING : return cornerMissingError(res,mErrorColor1,mErrorColor2,mErrorColor3);
594
      case ERROR_EDGE_MISSING   : return edgeMissingError(res,mErrorColor1,mErrorColor2);
595
      case ERROR_CORNERS_CANNOT : return res.getString(R.string.solver_generic_corners_cannot);
596
      case ERROR_EDGE_TWISTED   : return edgeTwistedError(res,mErrorColor1,mErrorColor2);
597
      case ERROR_CORNER_TWISTED : return cornerTwistedError(res,mErrorColor1,mErrorColor2,mErrorColor3);
598
      }
599

    
600
    return null;
601
    }
602

    
603
///////////////////////////////////////////////////////////////////////////////////////////////////
604

    
605
  public int[][] solution(int index, OperatingSystemInterface os)
606
    {
607
    if( mSolver==null )
608
      {
609
      mSolver = ImplementedTablebasesList.createUnpacked(ObjectSignatures.CU_323);
610
      if( mSolver!=null ) mSolver.createTablebase(2);
611
      }
612

    
613
    return mSolver!=null ? mSolver.solution(index,null,os) : null;
614
    }
615
}  
616

    
(5-5/16)