Project

General

Profile

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

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

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 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.objects;
11

    
12
import static org.distorted.objectlib.touchcontrol.TouchControl.TC_HEXAHEDRON;
13
import static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_SPLIT_CORNER;
14

    
15
import org.distorted.library.type.Static3D;
16
import org.distorted.library.type.Static4D;
17

    
18
import org.distorted.objectlib.helpers.FactoryCubit;
19
import org.distorted.objectlib.helpers.ObjectFaceShape;
20
import org.distorted.objectlib.helpers.ObjectSignature;
21
import org.distorted.objectlib.helpers.ObjectVertexEffects;
22
import org.distorted.objectlib.main.InitAssets;
23
import org.distorted.objectlib.main.ObjectSignatures;
24
import org.distorted.objectlib.scrambling.ScrambleEdgeGenerator;
25
import org.distorted.objectlib.main.InitData;
26
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron;
27
import org.distorted.objectlib.main.ObjectType;
28
import org.distorted.objectlib.helpers.ObjectShape;
29
import org.distorted.objectlib.shape.ShapeHexahedron;
30

    
31
///////////////////////////////////////////////////////////////////////////////////////////////////
32

    
33
public class TwistySkewb extends ShapeHexahedron
34
{
35
  static final Static3D[] ROT_AXIS = new Static3D[]
36
         {
37
           new Static3D( SQ3/3, SQ3/3, SQ3/3),
38
           new Static3D( SQ3/3, SQ3/3,-SQ3/3),
39
           new Static3D( SQ3/3,-SQ3/3, SQ3/3),
40
           new Static3D( SQ3/3,-SQ3/3,-SQ3/3)
41
         };
42

    
43
  private int[][] mEdges;
44
  private int[][] mBasicAngle;
45
  private float[][] mCuts;
46
  private float[][] mPositions;
47

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

    
50
  public TwistySkewb(int meshState, int iconMode, Static4D quat, Static3D move, float scale, InitData data, InitAssets asset)
51
    {
52
    super(meshState, iconMode, 2*data.getNumLayers()[0]-2, quat, move, scale, data, asset);
53
    }
54

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

    
57
  @Override
58
  public float[][] returnRotationFactor()
59
    {
60
    int numL = getNumLayers()[0];
61
    float[] f = new float[numL];
62
    for(int i=0; i<numL; i++) f[i] = 1.7f;
63
    return new float[][] { f,f,f,f };
64
    }
65

    
66
///////////////////////////////////////////////////////////////////////////////////////////////////
67

    
68
  public int[][] getScrambleEdges()
69
    {
70
    if( mEdges==null ) mEdges = ScrambleEdgeGenerator.getScrambleEdgesSingle(mBasicAngle);
71
    return mEdges;
72
    }
73

    
74
///////////////////////////////////////////////////////////////////////////////////////////////////
75

    
76
  private int getNumCorners()
77
    {
78
    return 8;
79
    }
80

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

    
83
  private int getNumEdges(int numLayers)
84
    {
85
    return (numLayers-2)*12;
86
    }
87

    
88
///////////////////////////////////////////////////////////////////////////////////////////////////
89

    
90
  private int getNumCentersPerFace(int numLayers)
91
    {
92
    return ((numLayers-2)*(numLayers-2) + (numLayers-1)*(numLayers-1));
93
    }
94

    
95
///////////////////////////////////////////////////////////////////////////////////////////////////
96

    
97
  public float[][] getCuts(int[] numLayers)
98
    {
99
    if( mCuts==null )
100
      {
101
      float[] c = numLayers[0]==2 ? (new float[] {0.0f}) : (new float[] {-SQ3/6, SQ3/6});
102
      mCuts = new float[][] {c,c,c,c};
103
      }
104

    
105
    return mCuts;
106
    }
107

    
108
///////////////////////////////////////////////////////////////////////////////////////////////////
109

    
110
  public boolean[][] getLayerRotatable(int[] numLayers)
111
    {
112
    boolean[] tmp = numLayers[0]==2 ? (new boolean[] {true,true}) : (new boolean[] {true,false,true});
113
    return new boolean[][] { tmp,tmp,tmp,tmp };
114
    }
115

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

    
118
  public int getTouchControlType()
119
    {
120
    return TC_HEXAHEDRON;
121
    }
122

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

    
125
  public int getTouchControlSplit()
126
    {
127
    return TYPE_SPLIT_CORNER;
128
    }
129

    
130
///////////////////////////////////////////////////////////////////////////////////////////////////
131

    
132
  public int[][][] getEnabled()
133
    {
134
    return new int[][][]
135
      {
136
          {{0,1},{3,1},{2,3},{0,2}},
137
          {{2,3},{3,1},{0,1},{0,2}},
138
          {{1,2},{0,1},{0,3},{2,3}},
139
          {{1,2},{2,3},{0,3},{0,1}},
140
          {{0,3},{0,2},{1,2},{1,3}},
141
          {{1,2},{0,2},{0,3},{1,3}},
142
      };
143
    }
144

    
145
///////////////////////////////////////////////////////////////////////////////////////////////////
146

    
147
  public float[] getDist3D(int[] numLayers)
148
    {
149
    return TouchControlHexahedron.D3D;
150
    }
151

    
152
///////////////////////////////////////////////////////////////////////////////////////////////////
153

    
154
  public Static3D[] getFaceAxis()
155
    {
156
    return TouchControlHexahedron.FACE_AXIS;
157
    }
158

    
159
///////////////////////////////////////////////////////////////////////////////////////////////////
160

    
161
  public float[][] getCubitPositions(int[] numLayers)
162
    {
163
    if( mPositions==null )
164
      {
165
      int numL = numLayers[0];
166
      final float DIST_CORNER = numL-1;
167
      final float DIST_EDGE   = numL-1;
168
      final float DIST_CENTER = numL-1;
169

    
170
      final int numCorners = getNumCorners();
171
      final int numEdges   = getNumEdges(numL);
172
      final int numCenters = 6*getNumCentersPerFace(numL);
173

    
174
      mPositions = new float[numCorners+numEdges+numCenters][];
175

    
176
      /// CORNERS //////////////////////////////////////////////
177

    
178
      mPositions[0] = new float[] { DIST_CORNER, DIST_CORNER, DIST_CORNER };
179
      mPositions[1] = new float[] { DIST_CORNER, DIST_CORNER,-DIST_CORNER };
180
      mPositions[2] = new float[] { DIST_CORNER,-DIST_CORNER, DIST_CORNER };
181
      mPositions[3] = new float[] { DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
182
      mPositions[4] = new float[] {-DIST_CORNER, DIST_CORNER, DIST_CORNER };
183
      mPositions[5] = new float[] {-DIST_CORNER, DIST_CORNER,-DIST_CORNER };
184
      mPositions[6] = new float[] {-DIST_CORNER,-DIST_CORNER, DIST_CORNER };
185
      mPositions[7] = new float[] {-DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
186

    
187
      /// CENTERS //////////////////////////////////////////////
188

    
189
      int index=8;
190
      final float X= -1000.0f;
191
      final float Y= -1001.0f;
192

    
193
      final float[][]  centerTable =
194
        {
195
            {X,Y,+DIST_CENTER},
196
            {X,Y,-DIST_CENTER},
197
            {X,+DIST_CENTER,Y},
198
            {X,-DIST_CENTER,Y},
199
            {+DIST_CENTER,X,Y},
200
            {-DIST_CENTER,X,Y},
201
        };
202

    
203
      float x,y, cen0, cen1, cen2;
204

    
205
      for( float[] centers : centerTable )
206
        {
207
        x = 2-numL;
208

    
209
        for(int i=0; i<numL-1; i++, x+=2)
210
          {
211
          y = 2-numL;
212

    
213
          for(int j=0; j<numL-1; j++, y+=2, index++)
214
            {
215
                 if( centers[0]==Y ) cen0 = y;
216
            else if( centers[0]==X ) cen0 = x;
217
            else                     cen0 = centers[0];
218

    
219
                 if( centers[1]==Y ) cen1 = y;
220
            else if( centers[1]==X ) cen1 = x;
221
            else                     cen1 = centers[1];
222

    
223
                 if( centers[2]==Y ) cen2 = y;
224
            else if( centers[2]==X ) cen2 = x;
225
            else                     cen2 = centers[2];
226

    
227
            mPositions[index] = new float[] {cen0,cen1,cen2};
228
            }
229
          }
230

    
231
        x = 3-numL;
232

    
233
        for(int i=0; i<numL-2; i++, x+=2)
234
          {
235
          y = 3-numL;
236

    
237
          for(int j=0; j<numL-2; j++, y+=2, index++)
238
            {
239
                 if( centers[0]==Y ) cen0 = y;
240
            else if( centers[0]==X ) cen0 = x;
241
            else                     cen0 = centers[0];
242

    
243
                 if( centers[1]==Y ) cen1 = y;
244
            else if( centers[1]==X ) cen1 = x;
245
            else                     cen1 = centers[1];
246

    
247
                 if( centers[2]==Y ) cen2 = y;
248
            else if( centers[2]==X ) cen2 = x;
249
            else                     cen2 = centers[2];
250

    
251
            mPositions[index] = new float[] {cen0,cen1,cen2};
252
            }
253
          }
254
        }
255

    
256
      /// EDGES ///////////////////////////////////////////////
257

    
258
      final float[][]  edgeTable =
259
        {
260
            {0,+DIST_EDGE,+DIST_EDGE},
261
            {+DIST_EDGE,0,+DIST_EDGE},
262
            {0,-DIST_EDGE,+DIST_EDGE},
263
            {-DIST_EDGE,0,+DIST_EDGE},
264
            {+DIST_EDGE,+DIST_EDGE,0},
265
            {+DIST_EDGE,-DIST_EDGE,0},
266
            {-DIST_EDGE,-DIST_EDGE,0},
267
            {-DIST_EDGE,+DIST_EDGE,0},
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
        };
273

    
274
      for (float[] edges : edgeTable)
275
        {
276
        float c = 3-numL;
277

    
278
        for (int j=0; j<numL-2; j++, c+=2, index++)
279
          {
280
          mPositions[index] = new float[] { edges[0]==0 ? c : edges[0] ,
281
                                            edges[1]==0 ? c : edges[1] ,
282
                                            edges[2]==0 ? c : edges[2] };
283
          }
284
        }
285
      }
286

    
287
    return mPositions;
288
    }
289

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

    
292
  public Static4D getCubitQuats(int cubit, int[] numLayers)
293
    {
294
    int numL = numLayers[0];
295
    int numCorners = getNumCorners();
296
    int numCentersPerFace = getNumCentersPerFace(numL);
297
    int numCenters = 6*numCentersPerFace;
298

    
299
    if( cubit<numCorners )
300
      {
301
      switch(cubit)
302
        {
303
        case  0: return mObjectQuats[0];                   //  unit quat
304
        case  1: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
305
        case  2: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
306
        case  3: return mObjectQuats[9];                   // 180 along X
307
        case  4: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
308
        case  5: return mObjectQuats[11];                  // 180 along Y
309
        case  6: return mObjectQuats[10];                  // 180 along Z
310
        case  7: return new Static4D(SQ2/2,0,-SQ2/2,0);    // 180 along (SQ2/2,0,-SQ2/2)
311
        }
312
      }
313
    else if( cubit<numCorners+numCenters )
314
      {
315
      int center = (cubit-numCorners)/numCentersPerFace;
316

    
317
      switch(center)
318
        {
319
        case 0: return mObjectQuats[0];
320
        case 1: return mObjectQuats[9];
321
        case 2: return mObjectQuats[1];
322
        case 3: return mObjectQuats[4];
323
        case 4: return mObjectQuats[2];
324
        case 5: return mObjectQuats[3];
325
        }
326
      }
327
    else
328
      {
329
      int edge = (cubit-numCorners-numCenters)/(numL-2);
330

    
331
      switch(edge)
332
        {
333
        case  0: return mObjectQuats[ 0];
334
        case  1: return mObjectQuats[ 2];
335
        case  2: return mObjectQuats[10];
336
        case  3: return mObjectQuats[ 8];
337
        case  4: return mObjectQuats[ 1];
338
        case  5: return mObjectQuats[ 4];
339
        case  6: return mObjectQuats[ 6];
340
        case  7: return mObjectQuats[ 7];
341
        case  8: return mObjectQuats[11];
342
        case  9: return mObjectQuats[ 5];
343
        case 10: return mObjectQuats[ 9];
344
        case 11: return mObjectQuats[ 3];
345
        }
346
      }
347

    
348
    return null;
349
    }
350

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

    
353
  private float[][] getVertices(int variant)
354
    {
355
    if( variant==0 )
356
      {
357
      return new float[][] { {-1,0,0},{0,-1,0},{0,0,-1},{-1,-1,-1},{0,0,0} };
358
      }
359
    else if( variant==1 )
360
      {
361
      return new float[][] { {-1,0,0},{0,-1,0},{1,0,0},{0,1,0},{0,0,-1} };
362
      }
363
    else
364
      {
365
      return new float[][] { {-1,0,0},{1,0,0},{0,-1,0},{0,0,-1} };
366
      }
367
    }
368

    
369
///////////////////////////////////////////////////////////////////////////////////////////////////
370

    
371
  public ObjectShape getObjectShape(int variant)
372
    {
373
    if( variant==0 )
374
      {
375
      int[][] indices = { {0,1,4},{2,0,4},{1,2,4},{3,1,0},{3,2,1},{3,0,2} };
376
      return new ObjectShape(getVertices(variant), indices);
377
      }
378
    else if( variant==1 )
379
      {
380
      int[][] indices = { {0,1,2,3},{4,1,0},{4,2,1},{4,3,2},{4,0,3} };
381
      return new ObjectShape(getVertices(variant), indices);
382
      }
383
    else
384
      {
385
      int[][] indices = { {2,1,0},{3,0,1},{2,3,1},{3,2,0} };
386
      return new ObjectShape(getVertices(variant), indices);
387
      }
388
    }
389

    
390
///////////////////////////////////////////////////////////////////////////////////////////////////
391

    
392
  public ObjectFaceShape getObjectFaceShape(int variant)
393
    {
394
    int numL = getNumLayers()[0];
395

    
396
    if( variant==0 )
397
      {
398
      int N = numL==2 ? 7:5;
399
      int E1= numL==2 ? 3:2;
400
      int E2= numL==2 ? 5:3;
401
      float height = isInIconMode() ? 0.001f : 0.02f;
402
      float[][] bands = { {height,35,0.16f,0.7f,N,E1,E1}, {0.001f, 35,1.00f,0.0f,3,1,E2} };
403
      int[] indices   = { 0,0,0,1,1,1 };
404
      return new ObjectFaceShape(bands,indices,null);
405
      }
406
    else if( variant==1 )
407
      {
408
      int N = numL==2 ? 7:6;
409
      int E = numL==2 ? 3:1;
410
      float height = isInIconMode() ? 0.001f : 0.04f;
411
      float[][] bands = { {height,35,SQ2/8,0.9f,N,E,E}, {0.001f,35,1,0.0f,3,0,0} };
412
      int[] indices   = { 0,1,1,1,1 };
413
      return new ObjectFaceShape(bands,indices,null);
414
      }
415
    else
416
      {
417
      int N = numL==2 ? 7:5;
418
      int E = numL==2 ? 5:2;
419
      float h1 = isInIconMode() ? 0.001f : 0.035f;
420
      float h2 = isInIconMode() ? 0.001f : 0.020f;
421
      float[][] bands = { {h1,30,0.16f,0.8f,N,2,E}, {h2,45,0.16f,0.2f,3,1,2} };
422
      int[] indices   = { 0,0,1,1 };
423
      return new ObjectFaceShape(bands,indices,null);
424
      }
425
    }
426

    
427
///////////////////////////////////////////////////////////////////////////////////////////////////
428

    
429
  public ObjectVertexEffects getVertexEffects(int variant)
430
    {
431
    if( variant==0 )
432
      {
433
      float[][] corners   = { {0.05f,0.25f}, {0.05f,0.20f} };
434
      int[] cornerIndices = { 1,1,1,0,0 };
435
      float[][] centers   = { {-0.5f, -0.5f, -0.5f} };
436
      int[] centerIndices = { 0,0,0,-1,0 };
437
       return FactoryCubit.generateVertexEffect(getVertices(variant),corners,cornerIndices,centers,centerIndices);
438
      }
439
    else if( variant==1 )
440
      {
441
      float[][] corners   = { {0.06f,0.15f} };
442
      int[] cornerIndices = { 0,0,0,0,0 };
443
      float[][] centers   = { {0,0,-0.4f} };
444
      int[] centerIndices = { 0,0,0,0,-1 };
445
       return FactoryCubit.generateVertexEffect(getVertices(variant),corners,cornerIndices,centers,centerIndices);
446
      }
447
    else
448
      {
449
      float[][] corners   = { {0.07f,0.20f}, {0.02f,0.30f} };
450
      int[] cornerIndices = { 0,0,1,1 };
451
      float[][] centers   = { {0.0f, -0.5f, -0.5f} };
452
      int[] centerIndices = { 0,0,0,0 };
453
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,cornerIndices,centers,centerIndices);
454
      }
455
    }
456

    
457
///////////////////////////////////////////////////////////////////////////////////////////////////
458

    
459
  public int getNumCubitVariants(int[] numLayers)
460
    {
461
    return numLayers[0]==2 ? 2:3;
462
    }
463

    
464
///////////////////////////////////////////////////////////////////////////////////////////////////
465

    
466
  public int getCubitVariant(int cubit, int[] numLayers)
467
    {
468
    return cubit<8 ? 0 : (cubit<8+6*getNumCentersPerFace(numLayers[0]) ? 1:2);
469
    }
470

    
471
///////////////////////////////////////////////////////////////////////////////////////////////////
472

    
473
  public float getStickerRadius()
474
    {
475
    return 0.08f;
476
    }
477

    
478
///////////////////////////////////////////////////////////////////////////////////////////////////
479

    
480
  public float getStickerStroke()
481
    {
482
    float stroke = 0.08f;
483

    
484
    if( isInIconMode() )
485
      {
486
      int[] numLayers = getNumLayers();
487
      stroke *= (numLayers[0]==2 ? 2.0f : 2.7f);
488
      }
489

    
490
    return stroke;
491
    }
492

    
493
///////////////////////////////////////////////////////////////////////////////////////////////////
494

    
495
  public float[][] getStickerAngles()
496
    {
497
    return null;
498
    }
499

    
500
///////////////////////////////////////////////////////////////////////////////////////////////////
501
// PUBLIC API
502

    
503
  public Static3D[] getRotationAxis()
504
    {
505
    return ROT_AXIS;
506
    }
507

    
508
///////////////////////////////////////////////////////////////////////////////////////////////////
509

    
510
  public int[][] getBasicAngles()
511
    {
512
    if( mBasicAngle ==null )
513
      {
514
      int num = getNumLayers()[0];
515
      int[] tmp = new int[num];
516
      for(int i=0; i<num; i++) tmp[i] = 3;
517
      mBasicAngle = new int[][] { tmp,tmp,tmp,tmp };
518
      }
519

    
520
    return mBasicAngle;
521
    }
522

    
523
///////////////////////////////////////////////////////////////////////////////////////////////////
524

    
525
  public String getShortName()
526
    {
527
    switch(getNumLayers()[0])
528
      {
529
      case 2: return ObjectType.SKEW_2.name();
530
      case 3: return ObjectType.SKEW_3.name();
531
      }
532

    
533
    return ObjectType.SKEW_2.name();
534
    }
535

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

    
538
  public ObjectSignature getSignature()
539
    {
540
    switch(getNumLayers()[0])
541
      {
542
      case 2: return new ObjectSignature(ObjectSignatures.SKEW_2);
543
      case 3: return new ObjectSignature(ObjectSignatures.SKEW_3);
544
      }
545

    
546
    return null;
547
    }
548

    
549
///////////////////////////////////////////////////////////////////////////////////////////////////
550

    
551
  public String getObjectName()
552
    {
553
    switch(getNumLayers()[0])
554
      {
555
      case 2: return "Skewb";
556
      case 3: return "Master Skewb";
557
      }
558
    return null;
559
    }
560

    
561
///////////////////////////////////////////////////////////////////////////////////////////////////
562

    
563
  public String getInventor()
564
    {
565
    switch(getNumLayers()[0])
566
      {
567
      case 2: return "Tony Durham";
568
      case 3: return "Katsuhiko Okamoto";
569
      }
570
    return null;
571
    }
572

    
573
///////////////////////////////////////////////////////////////////////////////////////////////////
574

    
575
  public int getYearOfInvention()
576
    {
577
    switch(getNumLayers()[0])
578
      {
579
      case 2: return 1982;
580
      case 3: return 2003;
581
      }
582
    return 1982;
583
    }
584

    
585
///////////////////////////////////////////////////////////////////////////////////////////////////
586

    
587
  public int getComplexity()
588
    {
589
    switch(getNumLayers()[0])
590
      {
591
      case 2: return 1;
592
      case 3: return 3;
593
      }
594
    return 5;
595
    }
596

    
597
///////////////////////////////////////////////////////////////////////////////////////////////////
598

    
599
  public String[][] getTutorials()
600
    {
601
    int[] numLayers = getNumLayers();
602

    
603
    switch(numLayers[0])
604
      {
605
      case 2: return new String[][] {
606
                          {"gb","I6132yshkeU","How to Solve the Skewb","Z3"},
607
                          {"es","wxQX3HhPgds","Resolver Skewb (Principiantes)","Cuby"},
608
                          {"ru","EICw3aqn6Bc","Как собрать Скьюб?","Алексей Ярыгин"},
609
                          {"fr","lR-GuIroh4k","Comment réussir le skewb","Rachma Nikov"},
610
                          {"de","7RX6D5pznOk","Skewb lösen","Pezcraft"},
611
                          {"pl","ofRu1fByNpk","Jak ułożyć: Skewb","DżoDżo"},
612
                          {"br","mNycauwshWs","Como resolver o Skewb","Pedro Filho"},
613
                          {"kr","5R3sU-_bMAI","SKEWB 초보 공식","iamzoone"},
614
                          {"vn","Db5mXuqgQP8","Tutorial N.5 - Skewb","Duy Thích Rubik"},
615
                     //   {"tw","8srf9xhsS9k","Skewb斜轉方塊解法","1hrBLD"},
616
                         };
617
      case 3: return new String[][] {
618
                          {"gb","Jiuf7zQyPYI","Master Skewb Cube Tutorial","Bearded Cubing"},
619
                          {"es","8TP6p63KQCA","Master Skewb en Español","jorlozCubes"},
620
                          {"ru","7155QSp3T74","часть 1: Как собрать мастер Скьюб","Иван Циков"},
621
                          {"ru","14ey-RihjgY","часть 2: Как собрать мастер Скьюб","Иван Циков"},
622
                          {"ru","watq6TLa5_E","часть 2.5: Как собрать мастер Скьюб","Иван Циков"},
623
                          {"ru","UnsvseFBXmo","часть 3: Как собрать мастер Скьюб","Иван Циков"},
624
                          {"fr","tYMoY4EOHVA","Résolution du Master Skewb","Asthalis"},
625
                          {"de","LSErzqGNElI","Master Skewb lösen","JamesKnopf"},
626
                          {"pl","Y7l3AYFvDJI","Master Skewb TUTORIAL PL","MrUk"},
627
                          {"kr","ycR-WmXJCG0","마스터 스큐브 3번째 해법","듀나메스 큐브 해법연구소"},
628
                          {"vn","uG8H0ZQTZgw","Tutorial N.35 - Master Skewb","Duy Thích Rubik"},
629
                         };
630
      }
631
    return null;
632
    }
633
}
(37-37/47)