Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistySkewb.java @ 1d581993

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is free software: you can redistribute it and/or modify                            //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Magic Cube is distributed in the hope that it will be useful,                                 //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.objectlib.objects;
21

    
22
import static org.distorted.objectlib.touchcontrol.TouchControl.TC_HEXAHEDRON;
23
import static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_SPLIT_CORNER;
24

    
25
import java.io.InputStream;
26

    
27
import org.distorted.library.type.Static3D;
28
import org.distorted.library.type.Static4D;
29

    
30
import org.distorted.objectlib.helpers.ObjectFaceShape;
31
import org.distorted.objectlib.helpers.ObjectSignature;
32
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron;
33
import org.distorted.objectlib.main.ObjectType;
34
import org.distorted.objectlib.helpers.ObjectShape;
35
import org.distorted.objectlib.scrambling.ScrambleState;
36
import org.distorted.objectlib.main.ShapeHexahedron;
37

    
38
///////////////////////////////////////////////////////////////////////////////////////////////////
39

    
40
public class TwistySkewb extends ShapeHexahedron
41
{
42
  static final Static3D[] ROT_AXIS = new Static3D[]
43
         {
44
           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
45
           new Static3D(+SQ3/3,+SQ3/3,-SQ3/3),
46
           new Static3D(+SQ3/3,-SQ3/3,+SQ3/3),
47
           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
48
         };
49

    
50
  private ScrambleState[] mStates;
51
  private int[][] mBasicAngle;
52
  private float[][] mCuts;
53
  private float[][] mPositions;
54

    
55
///////////////////////////////////////////////////////////////////////////////////////////////////
56

    
57
  public TwistySkewb(int[] numL, int meshState, int iconMode, Static4D quat, Static3D move, float scale, InputStream stream)
58
    {
59
    super(numL, meshState, iconMode, 2*numL[0]-2, quat, move, scale, stream);
60
    }
61

    
62
///////////////////////////////////////////////////////////////////////////////////////////////////
63

    
64
  public ScrambleState[] getScrambleStates()
65
    {
66
    if( mStates==null )
67
      {
68
      int[] numLayers = getNumLayers();
69
      int numL = numLayers[0];
70

    
71
      int[] tmp = {0,-1,0, 0,1,0, numL-1,-1,0, numL-1,1,0 };
72

    
73
      mStates = new ScrambleState[]
74
        {
75
        new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
76
        };
77
      }
78

    
79
    return mStates;
80
    }
81

    
82
///////////////////////////////////////////////////////////////////////////////////////////////////
83

    
84
  private int getNumCorners()
85
    {
86
    return 8;
87
    }
88

    
89
///////////////////////////////////////////////////////////////////////////////////////////////////
90

    
91
  private int getNumEdges(int numLayers)
92
    {
93
    return (numLayers-2)*12;
94
    }
95

    
96
///////////////////////////////////////////////////////////////////////////////////////////////////
97

    
98
  private int getNumCentersPerFace(int numLayers)
99
    {
100
    return ((numLayers-2)*(numLayers-2) + (numLayers-1)*(numLayers-1));
101
    }
102

    
103
///////////////////////////////////////////////////////////////////////////////////////////////////
104

    
105
  public float[][] getCuts(int[] numLayers)
106
    {
107
    if( mCuts==null )
108
      {
109
      float[] c = numLayers[0]==2 ? (new float[] {0.0f}) : (new float[] {-SQ3/6,+SQ3/6});
110
      mCuts = new float[][] {c,c,c,c};
111
      }
112

    
113
    return mCuts;
114
    }
115

    
116
///////////////////////////////////////////////////////////////////////////////////////////////////
117

    
118
  public boolean[][] getLayerRotatable(int[] numLayers)
119
    {
120
    boolean[] tmp = numLayers[0]==2 ? (new boolean[] {true,true}) : (new boolean[] {true,false,true});
121
    return new boolean[][] { tmp,tmp,tmp,tmp };
122
    }
123

    
124
///////////////////////////////////////////////////////////////////////////////////////////////////
125

    
126
  public int getTouchControlType()
127
    {
128
    return TC_HEXAHEDRON;
129
    }
130

    
131
///////////////////////////////////////////////////////////////////////////////////////////////////
132

    
133
  public int getTouchControlSplit()
134
    {
135
    return TYPE_SPLIT_CORNER;
136
    }
137

    
138
///////////////////////////////////////////////////////////////////////////////////////////////////
139

    
140
  public int[][][] getEnabled()
141
    {
142
    return new int[][][]
143
      {
144
          {{0,1},{3,1},{2,3},{0,2}},
145
          {{2,3},{3,1},{0,1},{0,2}},
146
          {{1,2},{0,1},{0,3},{2,3}},
147
          {{1,2},{2,3},{0,3},{0,1}},
148
          {{0,3},{0,2},{1,2},{1,3}},
149
          {{1,2},{0,2},{0,3},{1,3}},
150
      };
151
    }
152

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

    
155
  public float[] getDist3D(int[] numLayers)
156
    {
157
    return TouchControlHexahedron.D3D;
158
    }
159

    
160
///////////////////////////////////////////////////////////////////////////////////////////////////
161

    
162
  public Static3D[] getFaceAxis()
163
    {
164
    return TouchControlHexahedron.FACE_AXIS;
165
    }
166

    
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168

    
169
  public float[][] getCubitPositions(int[] numLayers)
170
    {
171
    if( mPositions==null )
172
      {
173
      int numL = numLayers[0];
174
      final float DIST_CORNER = numL-1;
175
      final float DIST_EDGE   = numL-1;
176
      final float DIST_CENTER = numL-1;
177

    
178
      final int numCorners = getNumCorners();
179
      final int numEdges   = getNumEdges(numL);
180
      final int numCenters = 6*getNumCentersPerFace(numL);
181

    
182
      mPositions = new float[numCorners+numEdges+numCenters][];
183

    
184
      /// CORNERS //////////////////////////////////////////////
185

    
186
      mPositions[0] = new float[] { DIST_CORNER, DIST_CORNER, DIST_CORNER };
187
      mPositions[1] = new float[] { DIST_CORNER, DIST_CORNER,-DIST_CORNER };
188
      mPositions[2] = new float[] { DIST_CORNER,-DIST_CORNER, DIST_CORNER };
189
      mPositions[3] = new float[] { DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
190
      mPositions[4] = new float[] {-DIST_CORNER, DIST_CORNER, DIST_CORNER };
191
      mPositions[5] = new float[] {-DIST_CORNER, DIST_CORNER,-DIST_CORNER };
192
      mPositions[6] = new float[] {-DIST_CORNER,-DIST_CORNER, DIST_CORNER };
193
      mPositions[7] = new float[] {-DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
194

    
195
      /// CENTERS //////////////////////////////////////////////
196

    
197
      int index=8;
198
      final float X= -1000.0f;
199
      final float Y= -1001.0f;
200

    
201
      final float[][]  centerTable =
202
        {
203
            {X,Y,+DIST_CENTER},
204
            {X,Y,-DIST_CENTER},
205
            {X,+DIST_CENTER,Y},
206
            {X,-DIST_CENTER,Y},
207
            {+DIST_CENTER,X,Y},
208
            {-DIST_CENTER,X,Y},
209
        };
210

    
211
      float x,y, cen0, cen1, cen2;
212

    
213
      for( float[] centers : centerTable )
214
        {
215
        x = 2-numL;
216

    
217
        for(int i=0; i<numL-1; i++, x+=2)
218
          {
219
          y = 2-numL;
220

    
221
          for(int j=0; j<numL-1; j++, y+=2, index++)
222
            {
223
                 if( centers[0]==Y ) cen0 = y;
224
            else if( centers[0]==X ) cen0 = x;
225
            else                     cen0 = centers[0];
226

    
227
                 if( centers[1]==Y ) cen1 = y;
228
            else if( centers[1]==X ) cen1 = x;
229
            else                     cen1 = centers[1];
230

    
231
                 if( centers[2]==Y ) cen2 = y;
232
            else if( centers[2]==X ) cen2 = x;
233
            else                     cen2 = centers[2];
234

    
235
            mPositions[index] = new float[] {cen0,cen1,cen2};
236
            }
237
          }
238

    
239
        x = 3-numL;
240

    
241
        for(int i=0; i<numL-2; i++, x+=2)
242
          {
243
          y = 3-numL;
244

    
245
          for(int j=0; j<numL-2; j++, y+=2, index++)
246
            {
247
                 if( centers[0]==Y ) cen0 = y;
248
            else if( centers[0]==X ) cen0 = x;
249
            else                     cen0 = centers[0];
250

    
251
                 if( centers[1]==Y ) cen1 = y;
252
            else if( centers[1]==X ) cen1 = x;
253
            else                     cen1 = centers[1];
254

    
255
                 if( centers[2]==Y ) cen2 = y;
256
            else if( centers[2]==X ) cen2 = x;
257
            else                     cen2 = centers[2];
258

    
259
            mPositions[index] = new float[] {cen0,cen1,cen2};
260
            }
261
          }
262
        }
263

    
264
      /// EDGES ///////////////////////////////////////////////
265

    
266
      final float[][]  edgeTable =
267
        {
268
            {0,+DIST_EDGE,+DIST_EDGE},
269
            {+DIST_EDGE,0,+DIST_EDGE},
270
            {0,-DIST_EDGE,+DIST_EDGE},
271
            {-DIST_EDGE,0,+DIST_EDGE},
272
            {+DIST_EDGE,+DIST_EDGE,0},
273
            {+DIST_EDGE,-DIST_EDGE,0},
274
            {-DIST_EDGE,-DIST_EDGE,0},
275
            {-DIST_EDGE,+DIST_EDGE,0},
276
            {0,+DIST_EDGE,-DIST_EDGE},
277
            {+DIST_EDGE,0,-DIST_EDGE},
278
            {0,-DIST_EDGE,-DIST_EDGE},
279
            {-DIST_EDGE,0,-DIST_EDGE}
280
        };
281

    
282
      for (float[] edges : edgeTable)
283
        {
284
        float c = 3-numL;
285

    
286
        for (int j=0; j<numL-2; j++, c+=2, index++)
287
          {
288
          mPositions[index] = new float[] { edges[0]==0 ? c : edges[0] ,
289
                                            edges[1]==0 ? c : edges[1] ,
290
                                            edges[2]==0 ? c : edges[2] };
291
          }
292
        }
293
      }
294

    
295
    return mPositions;
296
    }
297

    
298
///////////////////////////////////////////////////////////////////////////////////////////////////
299

    
300
  public Static4D getCubitQuats(int cubit, int[] numLayers)
301
    {
302
    int numL = numLayers[0];
303
    int numCorners = getNumCorners();
304
    int numCentersPerFace = getNumCentersPerFace(numL);
305
    int numCenters = 6*numCentersPerFace;
306

    
307
    if( cubit<numCorners )
308
      {
309
      switch(cubit)
310
        {
311
        case  0: return mObjectQuats[0];                   //  unit quat
312
        case  1: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
313
        case  2: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
314
        case  3: return mObjectQuats[9];                   // 180 along X
315
        case  4: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
316
        case  5: return mObjectQuats[11];                  // 180 along Y
317
        case  6: return mObjectQuats[10];                  // 180 along Z
318
        case  7: return new Static4D(SQ2/2,0,-SQ2/2,0);    // 180 along (SQ2/2,0,-SQ2/2)
319
        }
320
      }
321
    else if( cubit<numCorners+numCenters )
322
      {
323
      int center = (cubit-numCorners)/numCentersPerFace;
324

    
325
      switch(center)
326
        {
327
        case 0: return mObjectQuats[0];
328
        case 1: return mObjectQuats[9];
329
        case 2: return mObjectQuats[1];
330
        case 3: return mObjectQuats[4];
331
        case 4: return mObjectQuats[2];
332
        case 5: return mObjectQuats[3];
333
        }
334
      }
335
    else
336
      {
337
      int edge = (cubit-numCorners-numCenters)/(numL-2);
338

    
339
      switch(edge)
340
        {
341
        case  0: return mObjectQuats[ 0];
342
        case  1: return mObjectQuats[ 2];
343
        case  2: return mObjectQuats[10];
344
        case  3: return mObjectQuats[ 8];
345
        case  4: return mObjectQuats[ 1];
346
        case  5: return mObjectQuats[ 4];
347
        case  6: return mObjectQuats[ 6];
348
        case  7: return mObjectQuats[ 7];
349
        case  8: return mObjectQuats[11];
350
        case  9: return mObjectQuats[ 5];
351
        case 10: return mObjectQuats[ 9];
352
        case 11: return mObjectQuats[ 3];
353
        }
354
      }
355

    
356
    return null;
357
    }
358

    
359
///////////////////////////////////////////////////////////////////////////////////////////////////
360

    
361
  public ObjectShape getObjectShape(int variant)
362
    {
363
    if( variant==0 )
364
      {
365
      float[][] vertices= { {-1,0,0},{0,-1,0},{0,0,-1},{-1,-1,-1},{0,0,0} };
366
      int[][] indices   = { {0,1,4},{2,0,4},{1,2,4},{3,1,0},{3,2,1},{3,0,2} };
367
      return new ObjectShape(vertices, indices);
368
      }
369
    else if( variant==1 )
370
      {
371
      float[][] vertices= { {-1,0,0},{0,-1,0},{1,0,0},{0,1,0},{0,0,-1} };
372
      int[][] indices   = { {0,1,2,3},{4,1,0},{4,2,1},{4,3,2},{4,0,3} };
373
      return new ObjectShape(vertices, indices);
374
      }
375
    else
376
      {
377
      float[][] vertices= { {-1,0,0},{1,0,0},{0,-1,0},{0,0,-1} };
378
      int[][] indices   = { {2,1,0},{3,0,1},{2,3,1},{3,2,0} };
379
      return new ObjectShape(vertices, indices);
380
      }
381
    }
382

    
383
///////////////////////////////////////////////////////////////////////////////////////////////////
384

    
385
  public ObjectFaceShape getObjectFaceShape(int variant)
386
    {
387
    int numL = getNumLayers()[0];
388

    
389
    if( variant==0 )
390
      {
391
      int N = numL==2 ? 7:5;
392
      int E1= numL==2 ? 3:2;
393
      int E2= numL==2 ? 5:3;
394
      float height = isInIconMode() ? 0.001f : 0.02f;
395
      float[][] bands     = { {height,35,0.16f,0.7f,N,E1,E1}, {0.001f, 35,1.00f,0.0f,3,1,E2} };
396
      int[] bandIndices   = { 0,0,0,1,1,1 };
397
      float[][] corners   = { {0.05f,0.25f}, {0.05f,0.20f} };
398
      int[] cornerIndices = { 1,1,1,0,0 };
399
      float[][] centers   = { {-0.5f, -0.5f, -0.5f} };
400
      int[] centerIndices = { 0,0,0,-1,0 };
401
      return new ObjectFaceShape(bands,bandIndices,corners,cornerIndices,centers,centerIndices,null);
402
      }
403
    else if( variant==1 )
404
      {
405
      int N = numL==2 ? 7:6;
406
      int E = numL==2 ? 3:1;
407
      float height = isInIconMode() ? 0.001f : 0.04f;
408
      float[][] bands     = { {height,35,SQ2/8,0.9f,N,E,E}, {0.001f,35,1,0.0f,3,0,0} };
409
      int[] bandIndices   = { 0,1,1,1,1 };
410
      float[][] corners   = { {0.06f,0.15f} };
411
      int[] cornerIndices = { 0,0,0,0,0 };
412
      float[][] centers   = { {0,0,-0.4f} };
413
      int[] centerIndices = { 0,0,0,0,-1 };
414
      return new ObjectFaceShape(bands,bandIndices,corners,cornerIndices,centers,centerIndices,null);
415
      }
416
    else
417
      {
418
      int N = numL==2 ? 7:5;
419
      int E = numL==2 ? 5:2;
420
      float h1 = isInIconMode() ? 0.001f : 0.035f;
421
      float h2 = isInIconMode() ? 0.001f : 0.020f;
422
      float[][] bands     = { {h1,30,0.16f,0.8f,N,2,E}, {h2,45,0.16f,0.2f,3,1,2} };
423
      int[] bandIndices   = { 0,0,1,1 };
424
      float[][] corners   = { {0.07f,0.20f}, {0.02f,0.30f} };
425
      int[] cornerIndices = { 0,0,1,1 };
426
      float[][] centers   = { {0.0f, -0.5f, -0.5f} };
427
      int[] centerIndices = { 0,0,0,0 };
428
      return new ObjectFaceShape(bands,bandIndices,corners,cornerIndices,centers,centerIndices,null);
429
      }
430
    }
431

    
432
///////////////////////////////////////////////////////////////////////////////////////////////////
433

    
434
  public int getNumCubitVariants(int[] numLayers)
435
    {
436
    return numLayers[0]==2 ? 2:3;
437
    }
438

    
439
///////////////////////////////////////////////////////////////////////////////////////////////////
440

    
441
  public int getCubitVariant(int cubit, int[] numLayers)
442
    {
443
    return cubit<8 ? 0 : (cubit<8+6*getNumCentersPerFace(numLayers[0]) ? 1:2);
444
    }
445

    
446
///////////////////////////////////////////////////////////////////////////////////////////////////
447

    
448
  public float getStickerRadius()
449
    {
450
    return 0.08f;
451
    }
452

    
453
///////////////////////////////////////////////////////////////////////////////////////////////////
454

    
455
  public float getStickerStroke()
456
    {
457
    float stroke = 0.08f;
458

    
459
    if( isInIconMode() )
460
      {
461
      int[] numLayers = getNumLayers();
462
      stroke *= (numLayers[0]==2 ? 2.0f : 2.7f);
463
      }
464

    
465
    return stroke;
466
    }
467

    
468
///////////////////////////////////////////////////////////////////////////////////////////////////
469

    
470
  public float[][] getStickerAngles()
471
    {
472
    return null;
473
    }
474

    
475
///////////////////////////////////////////////////////////////////////////////////////////////////
476
// PUBLIC API
477

    
478
  public Static3D[] getRotationAxis()
479
    {
480
    return ROT_AXIS;
481
    }
482

    
483
///////////////////////////////////////////////////////////////////////////////////////////////////
484

    
485
  public int[][] getBasicAngles()
486
    {
487
    if( mBasicAngle ==null )
488
      {
489
      int num = getNumLayers()[0];
490
      int[] tmp = new int[num];
491
      for(int i=0; i<num; i++) tmp[i] = 3;
492
      mBasicAngle = new int[][] { tmp,tmp,tmp,tmp };
493
      }
494

    
495
    return mBasicAngle;
496
    }
497

    
498
///////////////////////////////////////////////////////////////////////////////////////////////////
499

    
500
  public String getShortName()
501
    {
502
    switch(getNumLayers()[0])
503
      {
504
      case 2: return ObjectType.SKEW_2.name();
505
      case 3: return ObjectType.SKEW_3.name();
506
      }
507

    
508
    return ObjectType.SKEW_2.name();
509
    }
510

    
511
///////////////////////////////////////////////////////////////////////////////////////////////////
512

    
513
  public ObjectSignature getSignature()
514
    {
515
    switch(getNumLayers()[0])
516
      {
517
      case 2: return new ObjectSignature(ObjectType.SKEW_2);
518
      case 3: return new ObjectSignature(ObjectType.SKEW_3);
519
      }
520

    
521
    return null;
522
    }
523

    
524
///////////////////////////////////////////////////////////////////////////////////////////////////
525

    
526
  public String getObjectName()
527
    {
528
    switch(getNumLayers()[0])
529
      {
530
      case 2: return "Skewb";
531
      case 3: return "Master Skewb";
532
      }
533
    return null;
534
    }
535

    
536
///////////////////////////////////////////////////////////////////////////////////////////////////
537

    
538
  public String getInventor()
539
    {
540
    switch(getNumLayers()[0])
541
      {
542
      case 2: return "Tony Durham";
543
      case 3: return "Katsuhiko Okamoto";
544
      }
545
    return null;
546
    }
547

    
548
///////////////////////////////////////////////////////////////////////////////////////////////////
549

    
550
  public int getYearOfInvention()
551
    {
552
    switch(getNumLayers()[0])
553
      {
554
      case 2: return 1982;
555
      case 3: return 2003;
556
      }
557
    return 1982;
558
    }
559

    
560
///////////////////////////////////////////////////////////////////////////////////////////////////
561

    
562
  public int getComplexity()
563
    {
564
    switch(getNumLayers()[0])
565
      {
566
      case 2: return 1;
567
      case 3: return 3;
568
      }
569
    return 5;
570
    }
571

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

    
574
  public String[][] getTutorials()
575
    {
576
    int[] numLayers = getNumLayers();
577

    
578
    switch(numLayers[0])
579
      {
580
      case 2: return new String[][] {
581
                          {"gb","I6132yshkeU","How to Solve the Skewb","Z3"},
582
                          {"es","wxQX3HhPgds","Resolver Skewb (Principiantes)","Cuby"},
583
                          {"ru","EICw3aqn6Bc","Как собрать Скьюб?","Алексей Ярыгин"},
584
                          {"fr","lR-GuIroh4k","Comment réussir le skewb","Rachma Nikov"},
585
                          {"de","7RX6D5pznOk","Skewb lösen","Pezcraft"},
586
                          {"pl","ofRu1fByNpk","Jak ułożyć: Skewb","DżoDżo"},
587
                          {"br","mNycauwshWs","Como resolver o Skewb","Pedro Filho"},
588
                          {"kr","5R3sU-_bMAI","SKEWB 초보 공식","iamzoone"},
589
                          {"vn","Db5mXuqgQP8","Tutorial N.5 - Skewb","Duy Thích Rubik"},
590
                     //   {"tw","8srf9xhsS9k","Skewb斜轉方塊解法","1hrBLD"},
591
                         };
592
      case 3: return new String[][] {
593
                          {"gb","Jiuf7zQyPYI","Master Skewb Cube Tutorial","Bearded Cubing"},
594
                          {"es","8TP6p63KQCA","Master Skewb en Español","jorlozCubes"},
595
                          {"ru","7155QSp3T74","часть 1: Как собрать мастер Скьюб","Иван Циков"},
596
                          {"ru","14ey-RihjgY","часть 2: Как собрать мастер Скьюб","Иван Циков"},
597
                          {"ru","watq6TLa5_E","часть 2.5: Как собрать мастер Скьюб","Иван Циков"},
598
                          {"ru","UnsvseFBXmo","часть 3: Как собрать мастер Скьюб","Иван Циков"},
599
                          {"fr","tYMoY4EOHVA","Résolution du Master Skewb","Asthalis"},
600
                          {"de","LSErzqGNElI","Master Skewb lösen","JamesKnopf"},
601
                          {"pl","Y7l3AYFvDJI","Master Skewb TUTORIAL PL","MrUk"},
602
                          {"kr","ycR-WmXJCG0","마스터 스큐브 3번째 해법","듀나메스 큐브 해법연구소"},
603
                          {"vn","uG8H0ZQTZgw","Tutorial N.35 - Master Skewb","Duy Thích Rubik"},
604
                         };
605
      }
606
    return null;
607
    }
608
}
(28-28/36)