MFEM v4.8.0
Finite element discretization library
Loading...
Searching...
No Matches
rubik.cpp
Go to the documentation of this file.
1// Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11//
12// ---------------------------------------------------
13// Rubik Miniapp: Model of the Rubik's Cube_TM Puzzle
14// ---------------------------------------------------
15//
16// This miniapp provides a light-hearted example of mesh manipulation and
17// GLVis integration.
18//
19// Compile with: make rubik
20//
21// Sample runs: rubik
22// echo "x21 y21 x23 y23 q\n" | ./rubik
23// echo "x22 z21 x22 z23 q\n" | ./rubik
24// echo "x22 y22 z22 q\n" | ./rubik
25//
26// Other interesting patterns:
27// "x13 x31 y13 y31 x13 x31 y13 y31 x13 x31 y13 y31"
28// "y13 z11 y11 x31 z13 y11 x33 z13 x31 z13 x11 y13 x13 z13 x33 y13 z11"
29// "y13 y33 z31 y13 z31 y13 z31 x13 y31 x12 y33 z31 y11 x13 z31 x11 y31"
30// "y13 x11 z13 y11 z33 y31 z31 y13 z33 y13 x33 y12 x13 z33 x33 z12"
31//
32// Interactive commands:
33// [xyz][1,2,3][0-3]
34// Rotate the specified tier (first integer) of the cube
35// about the given axis (initial character) in the clockwise
36// direction (looking from the tip of the axis vector towards
37// the origin) by so many increments (final integer).
38// r[0-9]+
39// Initiate a random sequence of moves. The integer
40// following 'r' is the number of desired moves.
41// p
42// Print the current state of the cube.
43// c
44// Swap the corners in the 0th and 1st positions.
45// t[0,1]
46// Twist the corners of the bottom tier in the clockwise '1'
47// or counter-clockwise '0' direction leaving the 3rd corner
48// unchanged.
49// e[0,1]
50// Permute the edges of the bottom tier in the clockwise '1'
51// or counter-clockwise '0' direction leaving the 3rd edge
52// unchanged.
53// f[2,4]
54// Flip the edges of the bottom tier while keeping them in
55// place. The integer '2' indicates flipping the 0th and 2nd
56// edges while '4' indicates flipping all four edges.
57// R
58// Resets (or Repaints) the cube to its original configuration.
59// T
60// Solve the top tier only.
61// M
62// Solve the middle tier only (assumes the top tier has already
63// been solved.)
64// B
65// Solve the bottom tier only (assumes the top two tiers have already
66// been solved.)
67// s or S
68// Solve the cube starting from the top tier and working down.
69// q or Q
70// Quit
71//
72#include "mfem.hpp"
74#include <cstdlib>
75#include <fstream>
76#include <iostream>
77#include <set>
78
79using namespace std;
80using namespace mfem;
81using namespace mfem::common;
82
83static int step_ = 0;
84static int nstep_ = 6;
85static int count_ = 0;
86static int logging_ = 0;
87
88static real_t cosa_ = cos(0.5 * M_PI / nstep_);
89static real_t sina_ = sin(0.5 * M_PI / nstep_);
90
91struct RubikState
92{
93 // Centers are indexed by the local face indices of Geometry::Type CUBE
94 // {Bottom, Front, Right, Back, Left, Top}
95 int cent_[6];
96
97 // Corners are sorted according to the local vertex index of
98 // Geometry::Type CUBE. Each corner piece is identified by the
99 // three colors it contains. The orientation is determined by the
100 // sequence of colors which corresponds to the x-directed, y-directed,
101 // and then z-directed face.
102 int corn_[24];
103
104 // Edges are sorted according to the local edge indices of
105 // Geometry::Type CUBE. Each edge piece is identified by the two face
106 // colors it contains. The edge piece orientations are determined by a
107 // right-hand-rule with the thumb directed along the edge and the fingers
108 // curling from the first face color to the second.
109 int edge_[24];
110};
111
112static RubikState rubik;
113
114static int edge_colors_[24] =
115{
116 0,1, 0,2, 3,0, 4,0,
117 1,5, 2,5, 5,3, 5,4,
118 1,4, 2,1, 3,2, 4,3
119};
120
121static int corn_colors_[24] =
122{
123 4,1,0, 2,1,0, 2,3,0, 4,3,0,
124 4,1,5, 2,1,5, 2,3,5, 4,3,5
125};
126
127struct Move
128{
129 char axis;
130 int tier;
131 int incr;
132};
133
134void interactive_help();
135
136void init_hex_mesh(Mesh & mesh);
137
138void init_state();
139
140void print_state(ostream & out);
141
142void repaint_cube(Mesh & mesh, GridFunction & color, socketstream & sock);
143
144bool validate_centers(const int max_ind = 6);
145
146bool validate_edges(const int max_ind = 12);
147
148bool validate_corners(const int max_ind = 8);
149
150void anim_move(char axis, int tier, int increment,
151 Mesh & mesh, GridFunction & color,
152 socketstream & sock);
153
154void anim_move(const Move & move,
155 Mesh & mesh, GridFunction & color,
156 socketstream & sock)
157{
158 anim_move(move.axis, move.tier, move.incr, mesh, color, sock);
159}
160
162
163void swap_corners(Mesh & mesh, GridFunction & color, socketstream & sock,
164 int * c0 = NULL, int * c1 = NULL);
165
166void twist_corners(Mesh & mesh, GridFunction & color, socketstream & sock,
167 bool cw, int * c0 = NULL, int * c1 = NULL, int * c2 = NULL);
168
169void permute_edges(Mesh & mesh, GridFunction & color, socketstream & sock,
170 int * e0, int * e1, int * e2);
171
172void permute_edges(Mesh & mesh, GridFunction & color, socketstream & sock,
173 bool cw);
174
175void flip_edges(Mesh & mesh, GridFunction & color, socketstream & sock,
176 int n, int * e0 = NULL, int * e1 = NULL,
177 int * e2 = NULL, int * e3 = NULL);
178
179void solve_top(Mesh & mesh, GridFunction & color, socketstream & sock);
180
181void solve_mid(Mesh & mesh, GridFunction & color, socketstream & sock);
182
183void solve_bot(Mesh & mesh, GridFunction & color, socketstream & sock);
184
185void solve(Mesh & mesh, GridFunction & color, socketstream & sock);
186
187int main(int argc, char *argv[])
188{
189 bool anim = true;
190 int visport = 19916;
191 bool visualization = true;
192
193 OptionsParser args(argc, argv);
194 args.AddOption(&anim, "-anim", "--animation", "-no-anim",
195 "--no-animation",
196 "Enable or disable GLVis animation.");
197 args.AddOption(&logging_, "-l", "--log-level",
198 "Control the amount of logging information.");
199 args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
200 "--no-visualization",
201 "Enable or disable GLVis visualization.");
202 args.AddOption(&visport, "-p", "--send-port", "Socket for GLVis.");
203 args.Parse();
204 if (!args.Good())
205 {
206 args.PrintUsage(cout);
207 return 1;
208 }
209 args.PrintOptions(cout);
210
212
213 if (!visualization) { anim = false; }
214
215 init_state();
216
217 // Define an empty mesh
218 Mesh mesh(3, 16 * 27, 27 * 6); // Hexagonal mesh
219
220 init_hex_mesh(mesh);
221
222 L2_FECollection fec(0, 3, 1);
223 FiniteElementSpace fespace(&mesh, &fec);
224 GridFunction color(&fespace);
225 color = 0.0;
226
227 PWConstCoefficient pwCoef(7);
228 for (int i=1; i<=7; i++) { pwCoef(i) = (real_t)(i-1)/6.0; }
229 color.ProjectCoefficient(pwCoef);
230
231 // Output the initial mesh to a file
232 {
233 ostringstream oss;
234 oss << "rubik-init.mesh";
235 ofstream ofs(oss.str().c_str());
236 ofs.precision(8);
237 mesh.Print(ofs);
238 ofs.close();
239 }
240
241 // Output the resulting mesh to GLVis
242 if (visualization)
243 {
244 char vishost[] = "localhost";
245 socketstream sock(vishost, visport);
246 sock.precision(8);
247 sock << "solution\n" << mesh << color << "keys Amaa\n"
248 << "palette 25\n" << "autoscale off\n" << flush;
249
250 while (true)
251 {
252 char axis;
253 int tier, incr;
254 cout << "Enter axis (x, y, z), tier index (1, 2, 3), "
255 << "and rotation (0, 1, 2, 3) with no spaces: ";
256 cin >> axis;
257 if ( axis == 'x' || axis == 'y' || axis == 'z' )
258 {
259 cin >> tier;
260 incr = tier % 10;
261 tier = tier / 10;
262 if (tier >= 1 && tier <= 3)
263 {
264 anim_move(axis, tier, incr, mesh, color, sock);
265 }
266 else
267 {
268 cout << "tier index must be 1, 2, or 3." << endl;
269 }
270 }
271 else if ( axis == 'r' )
272 {
273 // Execute a sequence of random moves
274 // Input the number of moves
275 int num;
276 cin >> num;
277 Array<Move> moves(num);
279 for (int i=0; i<num; i++)
280 {
281 anim_move(moves[i], mesh, color, sock);
282 }
283 }
284 else if ( axis == 'p' )
285 {
286 print_state(std::cout);
287 }
288 else if ( axis == 'c' )
289 {
290 swap_corners(mesh, color, sock);
291 }
292 else if ( axis == 't' )
293 {
294 bool cw;
295 cin >> cw;
296 twist_corners(mesh, color, sock, cw);
297 }
298 else if ( axis == 'e' )
299 {
300 bool cw;
301 cin >> cw;
302 permute_edges(mesh, color, sock, cw);
303 }
304 else if ( axis == 'f' )
305 {
306 int n = -1;
307 cin >> n;
308 if (n == 2 || n == 4)
309 {
310 flip_edges(mesh, color, sock, n);
311 }
312 else
313 {
314 cout << "Can only flip 2 or 4 edges at a time." << endl;
315 }
316 }
317 else if ( axis == 'R' )
318 {
319 repaint_cube(mesh, color, sock);
320 }
321 else if ( axis == 'T' )
322 {
323 solve_top(mesh, color, sock);
324 }
325 else if ( axis == 'M' )
326 {
327 solve_mid(mesh, color, sock);
328 }
329 else if ( axis == 'B' )
330 {
331 solve_bot(mesh, color, sock);
332 }
333 else if ( axis == 's' || axis == 'S')
334 {
335 solve(mesh, color, sock);
336 }
337 else if ( axis == 'h' || axis == 'H')
338 {
340 }
341 else if ( axis == 'q' || axis == 'Q')
342 {
343 break;
344 }
345 else
346 {
347 cout << endl << "Unrecognized command. "
348 "Enter 'x', 'y', 'z' followed by '1', '2', or '3' to proceed "
349 "or enter 'q' to quit: ";
350 }
351 }
352 }
353
354 print_state(std::cout);
355
356 // Clean up and exit
357 return 0;
358}
359
360void
362{
363 cout << "\nInteractive Commands\n"
364 << " [xyz][1,2,3][0-3]\n"
365 << "\tRotate the specified tier (first integer) of the cube\n"
366 << "\tabout the given axis (initial character) in the clockwise\n"
367 << "\tdirection (looking from the tip of the axis vector towards\n"
368 << "\tthe origin) by so many increments (final integer).\n"
369 << " r[0-9]+\n"
370 << "\tInitiate a random sequence of moves. The integer\n"
371 << "\tfollowing 'r' is the number of desired moves.\n"
372 << " p\n"
373 << "\tPrint the current state of the cube.\n"
374 << " c\n"
375 << "\tSwap the corners in the 0th and 1st positions.\n"
376 << " t[0,1]\n"
377 << "\tTwist the corners of the bottom tier in the clockwise '1'\n"
378 << "\tor counter-clockwise '0' direction leaving the 3rd corner\n"
379 << "\tunchanged.\n"
380 << " e[0,1]\n"
381 << "\tPermute the edges of the bottom tier in the clockwise '1'\n"
382 << "\tor counter-clockwise '0' direction leaving the 3rd edge\n"
383 << "\tunchanged.\n"
384 << " f[2,4]\n"
385 << "\tFlip the edges of the bottom tier while keeping them in\n"
386 << "\tplace. The integer '2' indicates flipping the 0th and 2nd\n"
387 << "\tedges while '4' indicates flipping all four edges.\n"
388 << " R\n"
389 << "\tResets (or Repaints) the cube to its original configuration.\n"
390 << " T\n"
391 << "\tSolve the top tier only.\n"
392 << " M\n"
393 << "\tSolve the middle tier only (assumes the top tier has already\n"
394 << "\tbeen solved.)\n"
395 << " B\n"
396 << "\tSolve the bottom tier only (assumes the top two tiers have\n"
397 << "\talready been solved.)\n"
398 << " s or S\n"
399 << "\tSolve the cube starting from the top tier and working down.\n"
400 << " h or H\n"
401 << "\tPrint this message.\n"
402 << " q or Q\n"
403 << "\tQuit\n\n";
404}
405
406void
408{
409 // Add vertices and hexahedra for 27 cubes
410 real_t c[3];
411 int v[16];
412 int vh[8];
413 int l = 0;
414 for (int k=0; k<3; k++)
415 {
416 for (int j=0; j<3; j++)
417 {
418 for (int i=0; i<3; i++)
419 {
420 c[0] = -1.5 + i;
421 c[1] = -1.5 + j;
422 c[2] = -1.5 + k;
423 mesh.AddVertex(c);
424 v[0] = l; l++;
425
426 c[0] = -1.5 + i + 1;
427 c[1] = -1.5 + j;
428 c[2] = -1.5 + k;
429 mesh.AddVertex(c);
430 v[1] = l; l++;
431
432 c[0] = -1.5 + i + 1;
433 c[1] = -1.5 + j + 1;
434 c[2] = -1.5 + k;
435 mesh.AddVertex(c);
436 v[2] = l; l++;
437
438 c[0] = -1.5 + i;
439 c[1] = -1.5 + j + 1;
440 c[2] = -1.5 + k;
441 mesh.AddVertex(c);
442 v[3] = l; l++;
443
444 c[0] = -1.5 + i;
445 c[1] = -1.5 + j;
446 c[2] = -1.5 + k + 1;
447 mesh.AddVertex(c);
448 v[4] = l; l++;
449
450 c[0] = -1.5 + i + 1;
451 c[1] = -1.5 + j;
452 c[2] = -1.5 + k + 1;
453 mesh.AddVertex(c);
454 v[5] = l; l++;
455
456 c[0] = -1.5 + i + 1;
457 c[1] = -1.5 + j + 1;
458 c[2] = -1.5 + k + 1;
459 mesh.AddVertex(c);
460 v[6] = l; l++;
461
462 c[0] = -1.5 + i;
463 c[1] = -1.5 + j + 1;
464 c[2] = -1.5 + k + 1;
465 mesh.AddVertex(c);
466 v[7] = l; l++;
467
468 c[0] = -1.5 + i + 0.25;
469 c[1] = -1.5 + j + 0.25;
470 c[2] = -1.5 + k + 0.25;
471 mesh.AddVertex(c);
472 v[8] = l; l++;
473
474 c[0] = -1.5 + i + 0.75;
475 c[1] = -1.5 + j + 0.25;
476 c[2] = -1.5 + k + 0.25;
477 mesh.AddVertex(c);
478 v[9] = l; l++;
479
480 c[0] = -1.5 + i + 0.75;
481 c[1] = -1.5 + j + 0.75;
482 c[2] = -1.5 + k + 0.25;
483 mesh.AddVertex(c);
484 v[10] = l; l++;
485
486 c[0] = -1.5 + i + 0.25;
487 c[1] = -1.5 + j + 0.75;
488 c[2] = -1.5 + k + 0.25;
489 mesh.AddVertex(c);
490 v[11] = l; l++;
491
492 c[0] = -1.5 + i + 0.25;
493 c[1] = -1.5 + j + 0.25;
494 c[2] = -1.5 + k + 0.75;
495 mesh.AddVertex(c);
496 v[12] = l; l++;
497
498 c[0] = -1.5 + i + 0.75;
499 c[1] = -1.5 + j + 0.25;
500 c[2] = -1.5 + k + 0.75;
501 mesh.AddVertex(c);
502 v[13] = l; l++;
503
504 c[0] = -1.5 + i + 0.75;
505 c[1] = -1.5 + j + 0.75;
506 c[2] = -1.5 + k + 0.75;
507 mesh.AddVertex(c);
508 v[14] = l; l++;
509
510 c[0] = -1.5 + i + 0.25;
511 c[1] = -1.5 + j + 0.75;
512 c[2] = -1.5 + k + 0.75;
513 mesh.AddVertex(c);
514 v[15] = l; l++;
515
516 // Bottom
517 vh[0] = v[ 0]; vh[1] = v[ 1]; vh[2] = v[ 2]; vh[3] = v[ 3];
518 vh[4] = v[ 8]; vh[5] = v[ 9]; vh[6] = v[10]; vh[7] = v[11];
519 mesh.AddHex(vh, k==0 ? 6 : 1);
520
521 // Top
522 vh[0] = v[12]; vh[1] = v[13]; vh[2] = v[14]; vh[3] = v[15];
523 vh[4] = v[ 4]; vh[5] = v[ 5]; vh[6] = v[ 6]; vh[7] = v[ 7];
524 mesh.AddHex(vh, k==2 ? 7 : 1);
525
526 // Front
527 vh[0] = v[ 0]; vh[1] = v[ 4]; vh[2] = v[ 5]; vh[3] = v[ 1];
528 vh[4] = v[ 8]; vh[5] = v[12]; vh[6] = v[13]; vh[7] = v[ 9];
529 mesh.AddHex(vh, j==0 ? 4 : 1);
530
531 // Back
532 vh[0] = v[11]; vh[1] = v[15]; vh[2] = v[14]; vh[3] = v[10];
533 vh[4] = v[ 3]; vh[5] = v[ 7]; vh[6] = v[ 6]; vh[7] = v[ 2];
534 mesh.AddHex(vh, j==2 ? 5 : 1);
535
536 // Left
537 vh[0] = v[ 0]; vh[1] = v[ 3]; vh[2] = v[ 7]; vh[3] = v[ 4];
538 vh[4] = v[ 8]; vh[5] = v[11]; vh[6] = v[15]; vh[7] = v[12];
539 mesh.AddHex(vh, i==0 ? 3 : 1);
540
541 // Right
542 vh[0] = v[ 9]; vh[1] = v[10]; vh[2] = v[14]; vh[3] = v[13];
543 vh[4] = v[ 1]; vh[5] = v[ 2]; vh[6] = v[ 6]; vh[7] = v[ 5];
544 mesh.AddHex(vh, i==2 ? 2 : 1);
545 }
546 }
547 }
548
549 mesh.FinalizeTopology();
550}
551
552void
554{
555 for (int i=0; i<6; i++) { rubik.cent_[i] = i; }
556 for (int i=0; i<24; i++) { rubik.edge_[i] = edge_colors_[i]; }
557 for (int i=0; i<24; i++) { rubik.corn_[i] = corn_colors_[i]; }
558}
559
560void
561update_centers(char axis, int incr)
562{
563 int i = (axis == 'x') ? 0 : ((axis == 'y') ? 1 : 2);
564 int i0 = 0 + i * (i - 1) / 2;
565 int i1 = 1 + i * (i + 1) / 2;
566 int i3 = 3 - i * (3 * i - 5) / 2;
567 int i5 = 5 - i * (i - 1);
568
569 switch (incr)
570 {
571 case 1:
572 std::swap(rubik.cent_[i3], rubik.cent_[i0]);
573 std::swap(rubik.cent_[i5], rubik.cent_[i3]);
574 std::swap(rubik.cent_[i1], rubik.cent_[i5]);
575 break;
576 case 2:
577 std::swap(rubik.cent_[i0], rubik.cent_[i5]);
578 std::swap(rubik.cent_[i1], rubik.cent_[i3]);
579 break;
580 case 3:
581 std::swap(rubik.cent_[i1], rubik.cent_[i0]);
582 std::swap(rubik.cent_[i5], rubik.cent_[i1]);
583 std::swap(rubik.cent_[i3], rubik.cent_[i5]);
584 break;
585 }
586}
587
588void
589update_corners(char axis, int tier, int incr)
590{
591 if (tier == 2) { return; }
592
593 int i = (axis == 'x') ? 0 : ((axis == 'y') ? 1 : 2);
594
595 if (tier == 1)
596 {
597 // 00:01:02 09:10:11 21:22:23 12:13:14
598 // 01:02:00 13:14:12 16:17:15 04:05:03
599 // 02:00:01 05:03:04 08:06:07 11:09:10
600
601 int i00 = i;
602 int i09 = 9 - i * ( 6 * i - 10);
603 int i21 = 21 - i * ( 3 * i + 7) / 2;
604 int i12 = 12 + i * (15 * i - 31) / 2;
605
606 int i01 = 1 - i * ( 3 * i - 5) / 2;
607 int i10 = 10 - i * (15 * i - 23) / 2;
608 int i22 = 22 - i * ( 3 * i + 2);
609 int i13 = 13 + i * ( 6 * i - 14);
610
611 int i02 = 2 + i * ( 3 * i - 7) / 2;
612 int i11 = 11 - i * ( 9 * i - 11) / 2;
613 int i23 = 23 - 8 * i;
614 int i14 = 14 + i * ( 9 * i - 20);
615
616 switch (incr)
617 {
618 case 1:
619 // 0->12->21->9->0
620 std::swap(rubik.corn_[i09], rubik.corn_[i00]);
621 std::swap(rubik.corn_[i21], rubik.corn_[i09]);
622 std::swap(rubik.corn_[i12], rubik.corn_[i21]);
623
624 // 1->14->22->11->1
625 std::swap(rubik.corn_[i11], rubik.corn_[i01]);
626 std::swap(rubik.corn_[i22], rubik.corn_[i11]);
627 std::swap(rubik.corn_[i14], rubik.corn_[i22]);
628
629 // 2->13->23->10->2
630 std::swap(rubik.corn_[i10], rubik.corn_[i02]);
631 std::swap(rubik.corn_[i23], rubik.corn_[i10]);
632 std::swap(rubik.corn_[i13], rubik.corn_[i23]);
633 break;
634 case 2:
635 // 0->21, 9->12, 1->22, 11->14, 2->23, 10->13
636 std::swap(rubik.corn_[i00], rubik.corn_[i21]);
637 std::swap(rubik.corn_[i09], rubik.corn_[i12]);
638 std::swap(rubik.corn_[i01], rubik.corn_[i22]);
639 std::swap(rubik.corn_[i11], rubik.corn_[i14]);
640 std::swap(rubik.corn_[i02], rubik.corn_[i23]);
641 std::swap(rubik.corn_[i10], rubik.corn_[i13]);
642 break;
643 case 3:
644 // 0->9->21->12->0
645 std::swap(rubik.corn_[i12], rubik.corn_[i00]);
646 std::swap(rubik.corn_[i21], rubik.corn_[i12]);
647 std::swap(rubik.corn_[i09], rubik.corn_[i21]);
648
649 // 1->11->22->14->1
650 std::swap(rubik.corn_[i14], rubik.corn_[i01]);
651 std::swap(rubik.corn_[i22], rubik.corn_[i14]);
652 std::swap(rubik.corn_[i11], rubik.corn_[i22]);
653
654 // 2->10->23->13->2
655 std::swap(rubik.corn_[i13], rubik.corn_[i02]);
656 std::swap(rubik.corn_[i23], rubik.corn_[i13]);
657 std::swap(rubik.corn_[i10], rubik.corn_[i23]);
658 break;
659 }
660 }
661 else
662 {
663 // 03:04:05 06:07:08 18:19:20 15:16:17
664 // 10:11:09 22:23:21 19:20:18 07:08:06
665 // 14:12:13 17:15:16 20:18:19 23:21:22
666
667 int i03 = 3 - i * ( 3 * i - 17) / 2;
668 int i06 = 6 - i * (21 * i - 53) / 2;
669 int i18 = 18 + i;
670 int i15 = 15 + i * (12 * i - 20);
671
672 int i04 = 4 - i * ( 3 * i - 10);
673 int i07 = 7 - i * (12 * i - 28);
674 int i19 = 19 - i * ( 3 * i - 5) / 2;
675 int i16 = 16 + i * (21 * i - 37) / 2;
676
677 int i05 = 5 + 4 * i;
678 int i08 = 8 - i * ( 9 * i - 22);
679 int i20 = 20 + i * ( 3 * i - 7) / 2;
680 int i17 = 17 + i * (27 * i - 49) / 2;
681
682 switch (incr)
683 {
684 case 1:
685 // 3->15->18->6->3
686 std::swap(rubik.corn_[i06], rubik.corn_[i03]);
687 std::swap(rubik.corn_[i18], rubik.corn_[i06]);
688 std::swap(rubik.corn_[i15], rubik.corn_[i18]);
689
690 // 4->17->19->8->4
691 std::swap(rubik.corn_[i08], rubik.corn_[i04]);
692 std::swap(rubik.corn_[i19], rubik.corn_[i08]);
693 std::swap(rubik.corn_[i17], rubik.corn_[i19]);
694
695 // 5->16->20->7->5
696 std::swap(rubik.corn_[i07], rubik.corn_[i05]);
697 std::swap(rubik.corn_[i20], rubik.corn_[i07]);
698 std::swap(rubik.corn_[i16], rubik.corn_[i20]);
699 break;
700 case 2:
701 // 3->18, 15->6, 4->19, 17->8, 5->20, 16->7
702 std::swap(rubik.corn_[i03], rubik.corn_[i18]);
703 std::swap(rubik.corn_[i15], rubik.corn_[i06]);
704 std::swap(rubik.corn_[i04], rubik.corn_[i19]);
705 std::swap(rubik.corn_[i17], rubik.corn_[i08]);
706 std::swap(rubik.corn_[i05], rubik.corn_[i20]);
707 std::swap(rubik.corn_[i16], rubik.corn_[i07]);
708 break;
709 case 3:
710 // 3->6->18->15->3
711 std::swap(rubik.corn_[i15], rubik.corn_[i03]);
712 std::swap(rubik.corn_[i18], rubik.corn_[i15]);
713 std::swap(rubik.corn_[i06], rubik.corn_[i18]);
714
715 // 4->8->19->17->4
716 std::swap(rubik.corn_[i17], rubik.corn_[i04]);
717 std::swap(rubik.corn_[i19], rubik.corn_[i17]);
718 std::swap(rubik.corn_[i08], rubik.corn_[i19]);
719
720 // 5->7->20->16->5
721 std::swap(rubik.corn_[i16], rubik.corn_[i05]);
722 std::swap(rubik.corn_[i20], rubik.corn_[i16]);
723 std::swap(rubik.corn_[i07], rubik.corn_[i20]);
724 break;
725 }
726 }
727}
728
729void
730update_edges(char axis, int tier, int incr)
731{
732 int i = (axis == 'x') ? 0 : ((axis == 'y') ? 1 : 2);
733
734 if (tier == 1)
735 {
736 int i06 = 6 - i * (13 * i - 23);
737 int i14 = 14 - i * ( 9 * i - 13);
738 int i16 = 16 + i * (11 * i - 27);
739 int i22 = 22 + i * ( 4 * i - 18);
740
741 switch (incr)
742 {
743 case 1:
744 // 6->17->15->22->6, 7->16->14->23->7
745 std::swap(rubik.edge_[i22], rubik.edge_[i06]);
746 std::swap(rubik.edge_[i14+1], rubik.edge_[i22]);
747 std::swap(rubik.edge_[i16+1], rubik.edge_[i14+1]);
748
749 std::swap(rubik.edge_[i22+1], rubik.edge_[i06+1]);
750 std::swap(rubik.edge_[i14], rubik.edge_[i22+1]);
751 std::swap(rubik.edge_[i16], rubik.edge_[i14]);
752 break;
753 case 2:
754 // 6->15, 7->14, 16->23, 17->22
755 std::swap(rubik.edge_[i06], rubik.edge_[i14+1]);
756 std::swap(rubik.edge_[i06+1], rubik.edge_[i14]);
757 std::swap(rubik.edge_[i16], rubik.edge_[i22+1]);
758 std::swap(rubik.edge_[i16+1], rubik.edge_[i22]);
759 break;
760 case 3:
761 // 6->22->15->17->6, 7->23->14->16->7
762 std::swap(rubik.edge_[i16+1], rubik.edge_[i06]);
763 std::swap(rubik.edge_[i14+1], rubik.edge_[i16+1]);
764 std::swap(rubik.edge_[i22], rubik.edge_[i14+1]);
765
766 std::swap(rubik.edge_[i16], rubik.edge_[i06+1]);
767 std::swap(rubik.edge_[i14], rubik.edge_[i16]);
768 std::swap(rubik.edge_[i22+1], rubik.edge_[i14]);
769 break;
770 }
771 }
772 else if (tier == 2)
773 {
774 // 00:01 04:05 12:13 08:09
775 // 06:07 14:15 10:11 02:03
776 // 16:17 18:19 20:21 22:23
777 int i00 = 0 + i * ( 2 * i + 4);
778 int i04 = 4 - i * ( 3 * i - 13);
779 int i08 = 8 + i * (13 * i - 19);
780 int i12 = 12 + i * ( 6 * i - 8);
781
782 switch (incr)
783 {
784 case 1:
785 // 0->8->12->4->0, 1->9->13->5->1
786 std::swap(rubik.edge_[i04], rubik.edge_[i00]);
787 std::swap(rubik.edge_[i12], rubik.edge_[i04]);
788 std::swap(rubik.edge_[i08], rubik.edge_[i12]);
789
790 std::swap(rubik.edge_[i04+1], rubik.edge_[i00+1]);
791 std::swap(rubik.edge_[i12+1], rubik.edge_[i04+1]);
792 std::swap(rubik.edge_[i08+1], rubik.edge_[i12+1]);
793 break;
794 case 2:
795 // 0->12, 1->13, 4->8, 5->9
796 std::swap(rubik.edge_[i00], rubik.edge_[i12]);
797 std::swap(rubik.edge_[i00+1], rubik.edge_[i12+1]);
798 std::swap(rubik.edge_[i04], rubik.edge_[i08]);
799 std::swap(rubik.edge_[i04+1], rubik.edge_[i08+1]);
800 break;
801 case 3:
802 // 0->4->12->8->0, 1->5->13->9->1
803 std::swap(rubik.edge_[i08], rubik.edge_[i00]);
804 std::swap(rubik.edge_[i12], rubik.edge_[i08]);
805 std::swap(rubik.edge_[i04], rubik.edge_[i12]);
806
807 std::swap(rubik.edge_[i08+1], rubik.edge_[i00+1]);
808 std::swap(rubik.edge_[i12+1], rubik.edge_[i08+1]);
809 std::swap(rubik.edge_[i04+1], rubik.edge_[i12+1]);
810 break;
811 }
812 }
813 else
814 {
815 // 02:03 20:21 10:11 18:19
816 // 22:23 12:13 20:21 04:05
817 // 08:09 10:11 12:13 14:15
818 int i02 = 2 - i * (17 * i - 37);
819 int i10 = 10 - i * ( 9 * i - 19);
820 int i18 = 18 + i * (12 * i - 26);
821 int i20 = 20 + i * ( 3 * i - 11);
822
823 switch (incr)
824 {
825 case 1:
826 // 2->19->11->20->2, 3->18->10->21->3
827 std::swap(rubik.edge_[i20], rubik.edge_[i02]);
828 std::swap(rubik.edge_[i10+1], rubik.edge_[i20]);
829 std::swap(rubik.edge_[i18+1], rubik.edge_[i10+1]);
830
831 std::swap(rubik.edge_[i20+1], rubik.edge_[i02+1]);
832 std::swap(rubik.edge_[i10], rubik.edge_[i20+1]);
833 std::swap(rubik.edge_[i18], rubik.edge_[i10]);
834 break;
835 case 2:
836 // 2->11, 19->20, 3->10, 18->21
837 std::swap(rubik.edge_[i02], rubik.edge_[i10+1]);
838 std::swap(rubik.edge_[i02+1], rubik.edge_[i10]);
839 std::swap(rubik.edge_[i18], rubik.edge_[i20+1]);
840 std::swap(rubik.edge_[i18+1], rubik.edge_[i20]);
841 break;
842 case 3:
843 // 2->20->11->19->2, 3->21->10->18->3
844 std::swap(rubik.edge_[i18+1], rubik.edge_[i02]);
845 std::swap(rubik.edge_[i10+1], rubik.edge_[i18+1]);
846 std::swap(rubik.edge_[i20], rubik.edge_[i10+1]);
847
848 std::swap(rubik.edge_[i18], rubik.edge_[i02+1]);
849 std::swap(rubik.edge_[i10], rubik.edge_[i18]);
850 std::swap(rubik.edge_[i20+1], rubik.edge_[i10]);
851 break;
852 }
853 }
854}
855
856void
857update_state(char axis, int tier, int incr)
858{
859 if (incr == 0) { return; }
860
861 // Centers only change if tier == 2
862 if (tier == 2)
863 {
864 update_centers(axis, incr);
865 }
866 else
867 {
868 // Corners only change if tier != 2
869 update_corners(axis, tier, incr);
870 }
871
872 // Edges always change
873 update_edges(axis, tier, incr);
874}
875
876void
877print_state(ostream & out_stream)
878{
879 out_stream << "Rubik's Cube State:\n";
880 out_stream << " Centers: ";
881 for (int i=0; i<6; i++)
882 {
883 out_stream << " " << rubik.cent_[i];
884 }
885 out_stream << "\n";
886 out_stream << " Edges: ";
887 for (int i=0; i<12; i++)
888 {
889 out_stream << " " << rubik.edge_[2 * i + 0]
890 << ":" << rubik.edge_[2 * i + 1];
891 }
892 out_stream << "\n";
893 out_stream << " Corners: ";
894 for (int i=0; i<8; i++)
895 {
896 out_stream << " " << rubik.corn_[3 * i + 0]
897 << ":" << rubik.corn_[3 * i + 1]
898 << ":" << rubik.corn_[3 * i + 2];
899 }
900 out_stream << "\n";
901}
902
903void repaint_cube(Mesh & mesh, GridFunction & color, socketstream & sock)
904{
905 real_t xData[3];
906 Vector x(xData,3);
907
908 real_t eps = 0.1;
909
910 Array<int> v;
911 for (int i=0; i<mesh.GetNBE(); i++)
912 {
913 mesh.GetBdrElementVertices(i, v);
914
915 x = 0.0;
916 for (int j=0; j<v.Size(); j++)
917 {
918 Vector vx(mesh.GetVertex(v[j]), 3);
919 x += vx;
920 }
921 x /= v.Size();
922
923 int elem = -1;
924 int info = -1;
925
926 mesh.GetBdrElementAdjacentElement(i, elem, info);
927
928 if (x[0] > 1.5 - eps)
929 {
930 color[elem] = 1.0 / 6.0;
931 }
932 else if (x[0] < -1.5 + eps)
933 {
934 color[elem] = 2.0 / 6.0;
935 }
936 else if (x[1] < -1.5 + eps)
937 {
938 color[elem] = 3.0 / 6.0;
939 }
940 else if (x[1] > 1.5 - eps)
941 {
942 color[elem] = 4.0 / 6.0;
943 }
944 else if (x[2] < -1.5 + eps)
945 {
946 color[elem] = 5.0 / 6.0;
947 }
948 else if (x[2] > 1.5 - eps)
949 {
950 color[elem] = 1.0;
951 }
952 }
953 sock << "solution\n" << mesh << color << flush;
954
955 init_state();
956}
957
958bool validate_centers(const int min_ind, const int max_ind)
959{
960 MFEM_ASSERT(0 <= min_ind && max_ind <= 6, "Maximum center index of "
961 << max_ind << " is out of range.");
962
963 for (int i=min_ind; i<max_ind; i++)
964 {
965 if (rubik.cent_[i] != i) { return false; }
966 }
967 return true;
968}
969
970bool validate_edges(const int min_ind, const int max_ind)
971{
972 MFEM_ASSERT(0 <= min_ind && max_ind <= 12, "Maximum edge index of "
973 << max_ind << " is out of range.");
974
975 for (int i=min_ind; i<max_ind; i++)
976 {
977 if (rubik.edge_[2 * i + 0] != edge_colors_[2 * i + 0] ||
978 rubik.edge_[2 * i + 1] != edge_colors_[2 * i + 1])
979 {
980 return false;
981 }
982 }
983 return true;
984}
985
986bool validate_corners(const int min_ind, const int max_ind)
987{
988 MFEM_ASSERT(0 <= min_ind && max_ind <= 8, "Maximum corner index of "
989 << max_ind << " is out of range.");
990
991 for (int i=min_ind; i<max_ind; i++)
992 {
993 if (rubik.corn_[3 * i + 0] != corn_colors_[3 * i + 0] ||
994 rubik.corn_[3 * i + 1] != corn_colors_[3 * i + 1] ||
995 rubik.corn_[3 * i + 2] != corn_colors_[3 * i + 2])
996 {
997 return false;
998 }
999 }
1000 return true;
1001}
1002
1003void
1004rotate_step(char axis, int incr, real_t * x)
1005{
1006 if (incr == 0) { return; }
1007
1008 real_t y[3];
1009 Vector xVec(x,3);
1010 Vector yVec(y,3);
1011
1012 yVec = xVec;
1013
1014 switch (axis)
1015 {
1016 case 'x':
1017 {
1018 switch (incr)
1019 {
1020 case 1:
1021 xVec[1] = cosa_ * yVec[1] + sina_ * yVec[2];
1022 xVec[2] = -sina_ * yVec[1] + cosa_ * yVec[2];
1023 break;
1024 case 2:
1025 xVec[1] = cosa_ * yVec[1] + sina_ * yVec[2];
1026 xVec[2] = -sina_ * yVec[1] + cosa_ * yVec[2];
1027 break;
1028 case 3:
1029 xVec[1] = cosa_ * yVec[1] - sina_ * yVec[2];
1030 xVec[2] = sina_ * yVec[1] + cosa_ * yVec[2];
1031 break;
1032 }
1033 }
1034 break;
1035 case 'y':
1036 {
1037 switch (incr)
1038 {
1039 case 1:
1040 xVec[2] = cosa_ * yVec[2] + sina_ * yVec[0];
1041 xVec[0] = -sina_ * yVec[2] + cosa_ * yVec[0];
1042 break;
1043 case 2:
1044 xVec[2] = cosa_ * yVec[2] + sina_ * yVec[0];
1045 xVec[0] = -sina_ * yVec[2] + cosa_ * yVec[0];
1046 break;
1047 case 3:
1048 xVec[2] = cosa_ * yVec[2] - sina_ * yVec[0];
1049 xVec[0] = sina_ * yVec[2] + cosa_ * yVec[0];
1050 break;
1051 }
1052 }
1053 break;
1054 case 'z':
1055 {
1056 switch (incr)
1057 {
1058 case 1:
1059 xVec[0] = cosa_ * yVec[0] + sina_ * yVec[1];
1060 xVec[1] = -sina_ * yVec[0] + cosa_ * yVec[1];
1061 break;
1062 case 2:
1063 xVec[0] = cosa_ * yVec[0] + sina_ * yVec[1];
1064 xVec[1] = -sina_ * yVec[0] + cosa_ * yVec[1];
1065 break;
1066 case 3:
1067 xVec[0] = cosa_ * yVec[0] - sina_ * yVec[1];
1068 xVec[1] = sina_ * yVec[0] + cosa_ * yVec[1];
1069 break;
1070 }
1071 }
1072 break;
1073 }
1074}
1075
1076bool
1077anim_step(char axis, int incr, Mesh & mesh)
1078{
1079 if (incr == 0) { step_ = 0; return false; }
1080 if (incr != 2 && step_ == nstep_) { step_ = 0; return false; }
1081 if (incr == 2 && step_ == 2 * nstep_) { step_ = 0; return false; }
1082
1083 std::set<int> verts;
1084 Array<int> v;
1085 for (int i=0; i<mesh.GetNE(); i++)
1086 {
1087 if (mesh.GetAttribute(i) == 1) { continue; }
1088
1089 mesh.GetElementVertices(i, v);
1090
1091 for (int j=0; j<v.Size(); j++)
1092 {
1093 verts.insert(v[j]);
1094 }
1095 }
1096 for (std::set<int>::iterator sit = verts.begin(); sit!=verts.end(); sit++)
1097 {
1098 rotate_step(axis, incr, mesh.GetVertex(*sit));
1099 }
1100
1101 step_++;
1102 return true;
1103}
1104
1105void mark_elements(Mesh & mesh, char axis, int tier)
1106{
1107 real_t xData[3];
1108 Vector x(xData,3);
1109
1110 Array<int> v;
1111 for (int i=0; i<mesh.GetNE(); i++)
1112 {
1113 mesh.GetElementVertices(i, v);
1114
1115 x = 0.0;
1116 for (int j=0; j<v.Size(); j++)
1117 {
1118 Vector vx(mesh.GetVertex(v[j]), 3);
1119 x += vx;
1120 }
1121 x /= v.Size();
1122
1123 switch (axis)
1124 {
1125 case 'x':
1126 if ( x[0] > -2.5 + tier && x[0] < -1.5 + tier )
1127 {
1128 mesh.SetAttribute(i, 2);
1129 }
1130 else
1131 {
1132 mesh.SetAttribute(i, 1);
1133 }
1134 break;
1135 case 'y':
1136 if ( x[1] > -2.5 + tier && x[1] < -1.5 + tier )
1137 {
1138 mesh.SetAttribute(i, 2);
1139 }
1140 else
1141 {
1142 mesh.SetAttribute(i, 1);
1143 }
1144 break;
1145 case 'z':
1146 if ( x[2] > -2.5 + tier && x[2] < -1.5 + tier )
1147 {
1148 mesh.SetAttribute(i, 2);
1149 }
1150 else
1151 {
1152 mesh.SetAttribute(i, 1);
1153 }
1154 break;
1155 }
1156 }
1157}
1158
1159void
1160anim_move(char axis, int tier, int incr,
1161 Mesh & mesh, GridFunction & color, socketstream & sock)
1162{
1163 update_state(axis, tier, incr);
1164 mark_elements(mesh, axis, tier);
1165 while (anim_step(axis, incr, mesh))
1166 {
1167 sock << "solution\n" << mesh << color << flush;
1168 }
1169 count_++;
1170}
1171
1173{
1174 for (int i=0; i<moves.Size(); i++)
1175 {
1176 real_t ran = real_t(rand()) / real_t(RAND_MAX);
1177 int ir = (int)(26 * ran);
1178 int incr = (ir % 3) + 1; ir /= 3;
1179 int tier = (ir % 3) + 1; ir /= 3;
1180 char axis = (ir == 0)? 'x' : ((ir == 1) ? 'y' : 'z');
1181
1182 if (i == 0)
1183 {
1184 moves[i].axis = axis;
1185 moves[i].tier = tier;
1186 moves[i].incr = incr;
1187 }
1188 else if (axis == moves[i-1].axis)
1189 {
1190 if (tier == moves[i-1].tier)
1191 {
1192 int new_incr = (moves[i-1].incr + incr) % 4;
1193 if (new_incr != 0)
1194 {
1195 moves[i-1].incr = new_incr;
1196 }
1197 i--;
1198 }
1199 else if (incr == moves[i-1].incr)
1200 {
1201 moves[i-1].tier = 6 - moves[i-1].tier - tier;
1202 moves[i-1].incr = 4 - incr;
1203 i--;
1204 }
1205 }
1206 else
1207 {
1208 moves[i].axis = axis;
1209 moves[i].tier = tier;
1210 moves[i].incr = incr;
1211 }
1212 }
1213}
1214
1215void
1217{
1218 int i5 = -1;
1219 for (int i=0; i<6; i++)
1220 {
1221 if (rubik.cent_[i] == 5)
1222 {
1223 i5 = i;
1224 break;
1225 }
1226 }
1227 switch (i5)
1228 {
1229 case 0:
1230 anim_move('x', 2, 2, mesh, color, sock);
1231 break;
1232 case 1:
1233 anim_move('x', 2, 1, mesh, color, sock);
1234 break;
1235 case 2:
1236 anim_move('y', 2, 1, mesh, color, sock);
1237 break;
1238 case 3:
1239 anim_move('x', 2, 3, mesh, color, sock);
1240 break;
1241 case 4:
1242 anim_move('y', 2, 3, mesh, color, sock);
1243 break;
1244 case 5:
1245 // Do nothing
1246 break;
1247 }
1248}
1249
1250void
1252{
1253 // Centers are either all correct, all wrong, or two are correct.
1254 // Check for two being correct
1255 bool allWrong = true;
1256 bool allRight = true;
1257 for (int i=0; i<6; i++)
1258 {
1259 if (rubik.cent_[i] == i)
1260 {
1261 allWrong = false;
1262 }
1263 else
1264 {
1265 allRight = false;
1266 }
1267 }
1268
1269 // If the centers are already correct then return.
1270 if (allRight) { return; }
1271
1272 if (!allWrong)
1273 {
1274 // Two are correct. Determine which axis should be spun and by how much.
1275 char axis = ' ';
1276 int incr = 0;
1277
1278 if (rubik.cent_[2] == 2)
1279 {
1280 axis = 'x';
1281
1282 switch (rubik.cent_[0])
1283 {
1284 case 1:
1285 incr = 1;
1286 break;
1287 case 5:
1288 incr = 2;
1289 break;
1290 case 3:
1291 incr = 3;
1292 break;
1293 }
1294 }
1295 else if (rubik.cent_[1] == 1)
1296 {
1297 axis = 'y';
1298
1299 switch (rubik.cent_[0])
1300 {
1301 case 2:
1302 incr = 1;
1303 break;
1304 case 5:
1305 incr = 2;
1306 break;
1307 case 4:
1308 incr = 3;
1309 break;
1310 }
1311 }
1312 else
1313 {
1314 axis = 'z';
1315
1316 switch (rubik.cent_[1])
1317 {
1318 case 4:
1319 incr = 1;
1320 break;
1321 case 3:
1322 incr = 2;
1323 break;
1324 case 2:
1325 incr = 3;
1326 break;
1327 }
1328 }
1329 anim_move(axis, 2, incr, mesh, color, sock);
1330 }
1331 else
1332 {
1333 // They are all incorrect. Find the bottom center and move it into place.
1334 int i0 = -1;
1335 for (int i=1; i<6; i++)
1336 {
1337 if (rubik.cent_[i] == 0)
1338 {
1339 i0 = i;
1340 break;
1341 }
1342 }
1343
1344 char axis = ' ';
1345 int incr = 0;
1346 switch (i0)
1347 {
1348 case 1:
1349 axis = 'x'; incr = 3;
1350 break;
1351 case 2:
1352 axis = 'y'; incr = 3;
1353 break;
1354 case 3:
1355 axis = 'x'; incr = 1;
1356 break;
1357 case 4:
1358 axis = 'y'; incr = 1;
1359 break;
1360 case 5:
1361 axis = 'x'; incr = 2;
1362 break;
1363 }
1364 anim_move(axis, 2, incr, mesh, color, sock);
1365
1366 // Two centers should be correct now so recall this function.
1367 solve_centers(mesh, color, sock);
1368 }
1369}
1370
1371int
1373{
1374 for (int i=0; i<8; i++)
1375 {
1376 if (rubik.corn_[3 * i + 0] == corn_colors_[3 * ind + 0] &&
1377 rubik.corn_[3 * i + 1] == corn_colors_[3 * ind + 1] &&
1378 rubik.corn_[3 * i + 2] == corn_colors_[3 * ind + 2])
1379 {
1380 return i;
1381 }
1382 else if (rubik.corn_[3 * i + 0] == corn_colors_[3 * ind + 1] &&
1383 rubik.corn_[3 * i + 1] == corn_colors_[3 * ind + 2] &&
1384 rubik.corn_[3 * i + 2] == corn_colors_[3 * ind + 0])
1385 {
1386 return i + 8;
1387 }
1388 else if (rubik.corn_[3 * i + 0] == corn_colors_[3 * ind + 2] &&
1389 rubik.corn_[3 * i + 1] == corn_colors_[3 * ind + 0] &&
1390 rubik.corn_[3 * i + 2] == corn_colors_[3 * ind + 1])
1391 {
1392 return i + 16;
1393 }
1394 else if (rubik.corn_[3 * i + 0] == corn_colors_[3 * ind + 2] &&
1395 rubik.corn_[3 * i + 1] == corn_colors_[3 * ind + 1] &&
1396 rubik.corn_[3 * i + 2] == corn_colors_[3 * ind + 0])
1397 {
1398 return i + 24;
1399 }
1400 else if (rubik.corn_[3 * i + 0] == corn_colors_[3 * ind + 1] &&
1401 rubik.corn_[3 * i + 1] == corn_colors_[3 * ind + 0] &&
1402 rubik.corn_[3 * i + 2] == corn_colors_[3 * ind + 2])
1403 {
1404 return i + 32;
1405 }
1406 else if (rubik.corn_[3 * i + 0] == corn_colors_[3 * ind + 0] &&
1407 rubik.corn_[3 * i + 1] == corn_colors_[3 * ind + 2] &&
1408 rubik.corn_[3 * i + 2] == corn_colors_[3 * ind + 1])
1409 {
1410 return i + 40;
1411 }
1412 }
1413 return -1;
1414}
1415
1416void
1417move_to_c4(int i4, int o4,
1418 Mesh & mesh, GridFunction & color, socketstream & sock)
1419{
1420 switch (i4)
1421 {
1422 case 0:
1423 switch (o4)
1424 {
1425 case 3:
1426 anim_move('x', 1, 3, mesh, color, sock);
1427 anim_move('z', 1, 3, mesh, color, sock);
1428 anim_move('x', 1, 1, mesh, color, sock);
1429 break;
1430 case 4:
1431 anim_move('y', 1, 1, mesh, color, sock);
1432 anim_move('z', 1, 3, mesh, color, sock);
1433 anim_move('y', 1, 3, mesh, color, sock);
1434 anim_move('x', 1, 3, mesh, color, sock);
1435 anim_move('z', 1, 2, mesh, color, sock);
1436 anim_move('x', 1, 1, mesh, color, sock);
1437 break;
1438 case 5:
1439 anim_move('y', 1, 1, mesh, color, sock);
1440 anim_move('z', 1, 1, mesh, color, sock);
1441 anim_move('y', 1, 3, mesh, color, sock);
1442 break;
1443 }
1444 break;
1445 case 1:
1446 switch (o4)
1447 {
1448 case 0:
1449 anim_move('x', 2, 1, mesh, color, sock);
1450 anim_move('y', 1, 2, mesh, color, sock);
1451 anim_move('x', 2, 3, mesh, color, sock);
1452 break;
1453 case 1:
1454 anim_move('z', 1, 1, mesh, color, sock);
1455 anim_move('x', 2, 1, mesh, color, sock);
1456 anim_move('y', 1, 3, mesh, color, sock);
1457 anim_move('x', 2, 3, mesh, color, sock);
1458 break;
1459 case 2:
1460 anim_move('x', 1, 3, mesh, color, sock);
1461 anim_move('z', 1, 1, mesh, color, sock);
1462 anim_move('x', 1, 1, mesh, color, sock);
1463 break;
1464 }
1465 break;
1466 case 2:
1467 switch (o4)
1468 {
1469 case 3:
1470 anim_move('y', 1, 1, mesh, color, sock);
1471 anim_move('z', 1, 2, mesh, color, sock);
1472 anim_move('y', 1, 3, mesh, color, sock);
1473 break;
1474 case 4:
1475 anim_move('x', 3, 1, mesh, color, sock);
1476 anim_move('z', 1, 1, mesh, color, sock);
1477 anim_move('x', 3, 3, mesh, color, sock);
1478 anim_move('x', 2, 1, mesh, color, sock);
1479 anim_move('y', 1, 3, mesh, color, sock);
1480 anim_move('x', 2, 3, mesh, color, sock);
1481 break;
1482 case 5:
1483 anim_move('x', 1, 3, mesh, color, sock);
1484 anim_move('z', 1, 2, mesh, color, sock);
1485 anim_move('x', 1, 1, mesh, color, sock);
1486 break;
1487 }
1488 break;
1489 case 3:
1490 switch (o4)
1491 {
1492 case 0:
1493 anim_move('y', 2, 3, mesh, color, sock);
1494 anim_move('x', 1, 2, mesh, color, sock);
1495 anim_move('y', 2, 1, mesh, color, sock);
1496 break;
1497 case 1:
1498 anim_move('y', 1, 1, mesh, color, sock);
1499 anim_move('z', 1, 3, mesh, color, sock);
1500 anim_move('y', 1, 3, mesh, color, sock);
1501 break;
1502 case 2:
1503 anim_move('z', 1, 3, mesh, color, sock);
1504 anim_move('y', 1, 1, mesh, color, sock);
1505 anim_move('z', 1, 1, mesh, color, sock);
1506 anim_move('y', 1, 3, mesh, color, sock);
1507 break;
1508 }
1509 break;
1510 case 4:
1511 switch (o4)
1512 {
1513 case 1:
1514 anim_move('y', 1, 1, mesh, color, sock);
1515 anim_move('z', 1, 1, mesh, color, sock);
1516 anim_move('y', 1, 3, mesh, color, sock);
1517 anim_move('z', 1, 3, mesh, color, sock);
1518 anim_move('y', 1, 1, mesh, color, sock);
1519 anim_move('z', 1, 1, mesh, color, sock);
1520 anim_move('y', 1, 3, mesh, color, sock);
1521 break;
1522 case 2:
1523 anim_move('x', 1, 3, mesh, color, sock);
1524 anim_move('z', 1, 3, mesh, color, sock);
1525 anim_move('x', 1, 1, mesh, color, sock);
1526 anim_move('z', 1, 1, mesh, color, sock);
1527 anim_move('x', 1, 3, mesh, color, sock);
1528 anim_move('z', 1, 3, mesh, color, sock);
1529 anim_move('x', 1, 1, mesh, color, sock);
1530 break;
1531 }
1532 break;
1533 case 5:
1534 switch (o4)
1535 {
1536 case 3:
1537 anim_move('x', 2, 1, mesh, color, sock);
1538 anim_move('y', 1, 1, mesh, color, sock);
1539 anim_move('x', 2, 3, mesh, color, sock);
1540 break;
1541 case 4:
1542 anim_move('x', 3, 3, mesh, color, sock);
1543 anim_move('z', 1, 1, mesh, color, sock);
1544 anim_move('x', 3, 1, mesh, color, sock);
1545 anim_move('x', 1, 3, mesh, color, sock);
1546 anim_move('z', 1, 3, mesh, color, sock);
1547 anim_move('x', 1, 1, mesh, color, sock);
1548 break;
1549 case 5:
1550 anim_move('y', 1, 3, mesh, color, sock);
1551 anim_move('z', 1, 3, mesh, color, sock);
1552 anim_move('y', 1, 2, mesh, color, sock);
1553 anim_move('z', 1, 2, mesh, color, sock);
1554 anim_move('y', 1, 3, mesh, color, sock);
1555 break;
1556 }
1557 break;
1558 case 6:
1559 switch (o4)
1560 {
1561 case 0:
1562 anim_move('y', 1, 1, mesh, color, sock);
1563 anim_move('y', 3, 3, mesh, color, sock);
1564 anim_move('z', 1, 2, mesh, color, sock);
1565 anim_move('y', 3, 1, mesh, color, sock);
1566 anim_move('y', 1, 3, mesh, color, sock);
1567 break;
1568 case 1:
1569 anim_move('x', 3, 1, mesh, color, sock);
1570 anim_move('z', 1, 1, mesh, color, sock);
1571 anim_move('x', 3, 3, mesh, color, sock);
1572 anim_move('x', 1, 3, mesh, color, sock);
1573 anim_move('z', 1, 2, mesh, color, sock);
1574 anim_move('x', 1, 1, mesh, color, sock);
1575 break;
1576 case 2:
1577 anim_move('y', 3, 3, mesh, color, sock);
1578 anim_move('z', 1, 3, mesh, color, sock);
1579 anim_move('y', 3, 1, mesh, color, sock);
1580 anim_move('y', 1, 1, mesh, color, sock);
1581 anim_move('z', 1, 2, mesh, color, sock);
1582 anim_move('y', 1, 3, mesh, color, sock);
1583 break;
1584 }
1585 break;
1586 case 7:
1587 switch (o4)
1588 {
1589 case 3:
1590 anim_move('x', 1, 1, mesh, color, sock);
1591 anim_move('z', 1, 1, mesh, color, sock);
1592 anim_move('x', 1, 2, mesh, color, sock);
1593 anim_move('z', 1, 2, mesh, color, sock);
1594 anim_move('x', 1, 1, mesh, color, sock);
1595 break;
1596 case 4:
1597 anim_move('y', 3, 1, mesh, color, sock);
1598 anim_move('z', 1, 3, mesh, color, sock);
1599 anim_move('y', 3, 3, mesh, color, sock);
1600 anim_move('y', 1, 1, mesh, color, sock);
1601 anim_move('z', 1, 1, mesh, color, sock);
1602 anim_move('y', 1, 3, mesh, color, sock);
1603 break;
1604 case 5:
1605 anim_move('y', 2, 3, mesh, color, sock);
1606 anim_move('x', 1, 3, mesh, color, sock);
1607 anim_move('y', 2, 1, mesh, color, sock);
1608 break;
1609 }
1610 break;
1611 }
1612}
1613
1614void
1615move_to_c5(int i5, int o5,
1616 Mesh & mesh, GridFunction & color, socketstream & sock)
1617{
1618 switch (i5)
1619 {
1620 case 0:
1621 switch (o5)
1622 {
1623 case 0:
1624 anim_move('z', 1, 2, mesh, color, sock);
1625 anim_move('y', 2, 1, mesh, color, sock);
1626 anim_move('x', 3, 2, mesh, color, sock);
1627 anim_move('y', 2, 3, mesh, color, sock);
1628 break;
1629 case 1:
1630 anim_move('z', 1, 3, mesh, color, sock);
1631 anim_move('x', 3, 3, mesh, color, sock);
1632 anim_move('z', 1, 1, mesh, color, sock);
1633 anim_move('x', 3, 1, mesh, color, sock);
1634 break;
1635 case 2:
1636 anim_move('x', 3, 3, mesh, color, sock);
1637 anim_move('z', 1, 3, mesh, color, sock);
1638 anim_move('x', 3, 1, mesh, color, sock);
1639 break;
1640 }
1641 break;
1642 case 1:
1643 switch (o5)
1644 {
1645 case 3:
1646 anim_move('x', 3, 3, mesh, color, sock);
1647 anim_move('z', 1, 1, mesh, color, sock);
1648 anim_move('x', 3, 1, mesh, color, sock);
1649 break;
1650 case 4:
1651 anim_move('y', 1, 3, mesh, color, sock);
1652 anim_move('z', 1, 1, mesh, color, sock);
1653 anim_move('y', 1, 1, mesh, color, sock);
1654 anim_move('x', 3, 3, mesh, color, sock);
1655 anim_move('z', 1, 2, mesh, color, sock);
1656 anim_move('x', 3, 1, mesh, color, sock);
1657 break;
1658 case 5:
1659 anim_move('y', 1, 3, mesh, color, sock);
1660 anim_move('z', 1, 3, mesh, color, sock);
1661 anim_move('y', 1, 1, mesh, color, sock);
1662 break;
1663 }
1664 break;
1665 case 2:
1666 switch (o5)
1667 {
1668 case 0:
1669 anim_move('y', 2, 1, mesh, color, sock);
1670 anim_move('x', 3, 2, mesh, color, sock);
1671 anim_move('y', 2, 3, mesh, color, sock);
1672 break;
1673 case 1:
1674 anim_move('y', 1, 3, mesh, color, sock);
1675 anim_move('z', 1, 1, mesh, color, sock);
1676 anim_move('y', 1, 1, mesh, color, sock);
1677 break;
1678 case 2:
1679 anim_move('z', 1, 1, mesh, color, sock);
1680 anim_move('y', 2, 1, mesh, color, sock);
1681 anim_move('x', 3, 1, mesh, color, sock);
1682 anim_move('y', 2, 3, mesh, color, sock);
1683 break;
1684 }
1685 break;
1686 case 3:
1687 switch (o5)
1688 {
1689 case 3:
1690 anim_move('y', 1, 3, mesh, color, sock);
1691 anim_move('z', 1, 2, mesh, color, sock);
1692 anim_move('y', 1, 1, mesh, color, sock);
1693 break;
1694 case 4:
1695 anim_move('z', 1, 1, mesh, color, sock);
1696 anim_move('y', 2, 1, mesh, color, sock);
1697 anim_move('x', 3, 2, mesh, color, sock);
1698 anim_move('y', 2, 3, mesh, color, sock);
1699 break;
1700 case 5:
1701 anim_move('x', 3, 3, mesh, color, sock);
1702 anim_move('z', 1, 2, mesh, color, sock);
1703 anim_move('x', 3, 1, mesh, color, sock);
1704 break;
1705 }
1706 break;
1707 case 5:
1708 switch (o5)
1709 {
1710 case 1:
1711 anim_move('y', 1, 3, mesh, color, sock);
1712 anim_move('z', 1, 3, mesh, color, sock);
1713 anim_move('y', 1, 1, mesh, color, sock);
1714 anim_move('z', 1, 1, mesh, color, sock);
1715 anim_move('y', 1, 3, mesh, color, sock);
1716 anim_move('z', 1, 3, mesh, color, sock);
1717 anim_move('y', 1, 1, mesh, color, sock);
1718 break;
1719 case 2:
1720 anim_move('x', 3, 3, mesh, color, sock);
1721 anim_move('z', 1, 1, mesh, color, sock);
1722 anim_move('x', 3, 1, mesh, color, sock);
1723 anim_move('z', 1, 3, mesh, color, sock);
1724 anim_move('x', 3, 3, mesh, color, sock);
1725 anim_move('z', 1, 1, mesh, color, sock);
1726 anim_move('x', 3, 1, mesh, color, sock);
1727 break;
1728 }
1729 break;
1730 case 6:
1731 switch (o5)
1732 {
1733 case 3:
1734 anim_move('x', 3, 1, mesh, color, sock);
1735 anim_move('z', 1, 3, mesh, color, sock);
1736 anim_move('x', 3, 2, mesh, color, sock);
1737 anim_move('z', 1, 2, mesh, color, sock);
1738 anim_move('x', 3, 1, mesh, color, sock);
1739 break;
1740 case 4:
1741 anim_move('y', 3, 3, mesh, color, sock);
1742 anim_move('z', 1, 1, mesh, color, sock);
1743 anim_move('y', 3, 1, mesh, color, sock);
1744 anim_move('y', 1, 3, mesh, color, sock);
1745 anim_move('z', 1, 3, mesh, color, sock);
1746 anim_move('y', 1, 1, mesh, color, sock);
1747 break;
1748 case 5:
1749 anim_move('y', 2, 1, mesh, color, sock);
1750 anim_move('x', 3, 3, mesh, color, sock);
1751 anim_move('y', 2, 3, mesh, color, sock);
1752 break;
1753 }
1754 break;
1755 case 7:
1756 switch (o5)
1757 {
1758 case 0:
1759 anim_move('y', 1, 3, mesh, color, sock);
1760 anim_move('y', 3, 1, mesh, color, sock);
1761 anim_move('z', 1, 2, mesh, color, sock);
1762 anim_move('y', 3, 3, mesh, color, sock);
1763 anim_move('y', 1, 1, mesh, color, sock);
1764 break;
1765 case 1:
1766 anim_move('x', 1, 1, mesh, color, sock);
1767 anim_move('z', 1, 3, mesh, color, sock);
1768 anim_move('x', 1, 3, mesh, color, sock);
1769 anim_move('x', 3, 3, mesh, color, sock);
1770 anim_move('z', 1, 2, mesh, color, sock);
1771 anim_move('x', 3, 1, mesh, color, sock);
1772 break;
1773 case 2:
1774 anim_move('y', 3, 1, mesh, color, sock);
1775 anim_move('z', 1, 1, mesh, color, sock);
1776 anim_move('y', 3, 3, mesh, color, sock);
1777 anim_move('y', 1, 3, mesh, color, sock);
1778 anim_move('z', 1, 2, mesh, color, sock);
1779 anim_move('y', 1, 1, mesh, color, sock);
1780 break;
1781 }
1782 break;
1783 }
1784}
1785
1786void
1787move_to_c6(int i6, int o6,
1788 Mesh & mesh, GridFunction & color, socketstream & sock)
1789{
1790 switch (i6)
1791 {
1792 case 0:
1793 switch (o6)
1794 {
1795 case 3:
1796 anim_move('y', 3, 3, mesh, color, sock);
1797 anim_move('z', 1, 2, mesh, color, sock);
1798 anim_move('y', 3, 1, mesh, color, sock);
1799 break;
1800 case 4:
1801 anim_move('z', 1, 1, mesh, color, sock);
1802 anim_move('x', 2, 3, mesh, color, sock);
1803 anim_move('y', 3, 2, mesh, color, sock);
1804 anim_move('x', 2, 1, mesh, color, sock);
1805 break;
1806 case 5:
1807 anim_move('x', 3, 1, mesh, color, sock);
1808 anim_move('z', 1, 2, mesh, color, sock);
1809 anim_move('x', 3, 3, mesh, color, sock);
1810 break;
1811 }
1812 break;
1813 case 1:
1814 switch (o6)
1815 {
1816 case 0:
1817 anim_move('z', 1, 2, mesh, color, sock);
1818 anim_move('x', 2, 3, mesh, color, sock);
1819 anim_move('y', 3, 2, mesh, color, sock);
1820 anim_move('x', 2, 1, mesh, color, sock);
1821 break;
1822 case 1:
1823 anim_move('y', 3, 3, mesh, color, sock);
1824 anim_move('z', 1, 3, mesh, color, sock);
1825 anim_move('y', 3, 1, mesh, color, sock);
1826 break;
1827 case 2:
1828 anim_move('z', 1, 1, mesh, color, sock);
1829 anim_move('x', 3, 1, mesh, color, sock);
1830 anim_move('z', 1, 2, mesh, color, sock);
1831 anim_move('x', 3, 3, mesh, color, sock);
1832 break;
1833 }
1834 break;
1835 case 2:
1836 switch (o6)
1837 {
1838 case 3:
1839 anim_move('x', 3, 1, mesh, color, sock);
1840 anim_move('z', 1, 3, mesh, color, sock);
1841 anim_move('x', 3, 3, mesh, color, sock);
1842 break;
1843 case 4:
1844 anim_move('x', 3, 1, mesh, color, sock);
1845 anim_move('z', 1, 1, mesh, color, sock);
1846 anim_move('x', 3, 3, mesh, color, sock);
1847 anim_move('y', 3, 3, mesh, color, sock);
1848 anim_move('z', 1, 2, mesh, color, sock);
1849 anim_move('y', 3, 1, mesh, color, sock);
1850 break;
1851 case 5:
1852 anim_move('y', 3, 3, mesh, color, sock);
1853 anim_move('z', 1, 1, mesh, color, sock);
1854 anim_move('y', 3, 1, mesh, color, sock);
1855 break;
1856 }
1857 break;
1858 case 3:
1859 switch (o6)
1860 {
1861 case 0:
1862 anim_move('x', 2, 3, mesh, color, sock);
1863 anim_move('y', 3, 2, mesh, color, sock);
1864 anim_move('x', 2, 1, mesh, color, sock);
1865 break;
1866 case 1:
1867 anim_move('z', 1, 1, mesh, color, sock);
1868 anim_move('x', 2, 3, mesh, color, sock);
1869 anim_move('y', 3, 1, mesh, color, sock);
1870 anim_move('x', 2, 1, mesh, color, sock);
1871 break;
1872 case 2:
1873 anim_move('x', 3, 1, mesh, color, sock);
1874 anim_move('z', 1, 1, mesh, color, sock);
1875 anim_move('x', 3, 3, mesh, color, sock);
1876 break;
1877 }
1878 break;
1879 case 6:
1880 switch (o6)
1881 {
1882 case 1:
1883 anim_move('y', 3, 3, mesh, color, sock);
1884 anim_move('z', 1, 1, mesh, color, sock);
1885 anim_move('y', 3, 1, mesh, color, sock);
1886 anim_move('z', 1, 3, mesh, color, sock);
1887 anim_move('y', 3, 3, mesh, color, sock);
1888 anim_move('z', 1, 1, mesh, color, sock);
1889 anim_move('y', 3, 1, mesh, color, sock);
1890 break;
1891 case 2:
1892 anim_move('x', 3, 1, mesh, color, sock);
1893 anim_move('z', 1, 3, mesh, color, sock);
1894 anim_move('x', 3, 3, mesh, color, sock);
1895 anim_move('z', 1, 1, mesh, color, sock);
1896 anim_move('x', 3, 1, mesh, color, sock);
1897 anim_move('z', 1, 3, mesh, color, sock);
1898 anim_move('x', 3, 3, mesh, color, sock);
1899 break;
1900 }
1901 break;
1902 case 7:
1903 switch (o6)
1904 {
1905 case 3:
1906 anim_move('x', 2, 3, mesh, color, sock);
1907 anim_move('y', 3, 3, mesh, color, sock);
1908 anim_move('x', 2, 1, mesh, color, sock);
1909 break;
1910 case 4:
1911 anim_move('x', 1, 1, mesh, color, sock);
1912 anim_move('z', 1, 1, mesh, color, sock);
1913 anim_move('x', 1, 3, mesh, color, sock);
1914 anim_move('x', 3, 1, mesh, color, sock);
1915 anim_move('z', 1, 3, mesh, color, sock);
1916 anim_move('x', 3, 3, mesh, color, sock);
1917 break;
1918 case 5:
1919 anim_move('y', 3, 1, mesh, color, sock);
1920 anim_move('z', 1, 3, mesh, color, sock);
1921 anim_move('y', 3, 2, mesh, color, sock);
1922 anim_move('z', 1, 2, mesh, color, sock);
1923 anim_move('y', 3, 1, mesh, color, sock);
1924 break;
1925 }
1926 break;
1927 }
1928}
1929
1930void
1931move_to_c7(int i7, int o7,
1932 Mesh & mesh, GridFunction & color, socketstream & sock)
1933{
1934 switch (i7)
1935 {
1936 case 0:
1937 switch (o7)
1938 {
1939 case 0:
1940 anim_move('z', 1, 1, mesh, color, sock);
1941 anim_move('y', 3, 1, mesh, color, sock);
1942 anim_move('z', 1, 1, mesh, color, sock);
1943 anim_move('y', 3, 3, mesh, color, sock);
1944 anim_move('x', 1, 1, mesh, color, sock);
1945 anim_move('z', 1, 2, mesh, color, sock);
1946 anim_move('x', 1, 3, mesh, color, sock);
1947 break;
1948 case 1:
1949 anim_move('y', 3, 1, mesh, color, sock);
1950 anim_move('z', 1, 1, mesh, color, sock);
1951 anim_move('y', 3, 3, mesh, color, sock);
1952 break;
1953 case 2:
1954 anim_move('z', 1, 3, mesh, color, sock);
1955 anim_move('x', 1, 1, mesh, color, sock);
1956 anim_move('z', 1, 2, mesh, color, sock);
1957 anim_move('x', 1, 3, mesh, color, sock);
1958 break;
1959 }
1960 break;
1961 case 1:
1962 switch (o7)
1963 {
1964 case 3:
1965 anim_move('y', 3, 1, mesh, color, sock);
1966 anim_move('z', 1, 2, mesh, color, sock);
1967 anim_move('y', 3, 3, mesh, color, sock);
1968 break;
1969 case 4:
1970 anim_move('z', 1, 2, mesh, color, sock);
1971 anim_move('x', 1, 1, mesh, color, sock);
1972 anim_move('z', 1, 3, mesh, color, sock);
1973 anim_move('x', 1, 3, mesh, color, sock);
1974 anim_move('y', 3, 1, mesh, color, sock);
1975 anim_move('z', 1, 2, mesh, color, sock);
1976 anim_move('y', 3, 3, mesh, color, sock);
1977 break;
1978 case 5:
1979 anim_move('x', 1, 1, mesh, color, sock);
1980 anim_move('z', 1, 2, mesh, color, sock);
1981 anim_move('x', 1, 3, mesh, color, sock);
1982 break;
1983 }
1984 break;
1985 case 2:
1986 switch (o7)
1987 {
1988 case 0:
1989 anim_move('z', 1, 3, mesh, color, sock);
1990 anim_move('x', 1, 1, mesh, color, sock);
1991 anim_move('z', 1, 3, mesh, color, sock);
1992 anim_move('x', 1, 3, mesh, color, sock);
1993 anim_move('y', 3, 1, mesh, color, sock);
1994 anim_move('z', 1, 2, mesh, color, sock);
1995 anim_move('y', 3, 3, mesh, color, sock);
1996 break;
1997 case 1:
1998 anim_move('z', 1, 1, mesh, color, sock);
1999 anim_move('y', 3, 1, mesh, color, sock);
2000 anim_move('z', 1, 2, mesh, color, sock);
2001 anim_move('y', 3, 3, mesh, color, sock);
2002 break;
2003 case 2:
2004 anim_move('x', 1, 1, mesh, color, sock);
2005 anim_move('z', 1, 3, mesh, color, sock);
2006 anim_move('x', 1, 3, mesh, color, sock);
2007 break;
2008 }
2009 break;
2010 case 3:
2011 switch (o7)
2012 {
2013 case 3:
2014 anim_move('x', 1, 1, mesh, color, sock);
2015 anim_move('z', 1, 1, mesh, color, sock);
2016 anim_move('x', 1, 3, mesh, color, sock);
2017 break;
2018 case 4:
2019 anim_move('y', 3, 1, mesh, color, sock);
2020 anim_move('z', 1, 1, mesh, color, sock);
2021 anim_move('y', 3, 3, mesh, color, sock);
2022 anim_move('x', 1, 1, mesh, color, sock);
2023 anim_move('z', 1, 2, mesh, color, sock);
2024 anim_move('x', 1, 3, mesh, color, sock);
2025 break;
2026 case 5:
2027 anim_move('y', 3, 1, mesh, color, sock);
2028 anim_move('z', 1, 3, mesh, color, sock);
2029 anim_move('y', 3, 3, mesh, color, sock);
2030 break;
2031 }
2032 break;
2033 case 7:
2034 switch (o7)
2035 {
2036 case 1:
2037 anim_move('y', 3, 1, mesh, color, sock);
2038 anim_move('z', 1, 3, mesh, color, sock);
2039 anim_move('y', 3, 3, mesh, color, sock);
2040 anim_move('z', 1, 1, mesh, color, sock);
2041 anim_move('y', 3, 1, mesh, color, sock);
2042 anim_move('z', 1, 3, mesh, color, sock);
2043 anim_move('y', 3, 3, mesh, color, sock);
2044 break;
2045 case 2:
2046 anim_move('x', 1, 1, mesh, color, sock);
2047 anim_move('z', 1, 1, mesh, color, sock);
2048 anim_move('x', 1, 3, mesh, color, sock);
2049 anim_move('z', 1, 3, mesh, color, sock);
2050 anim_move('x', 1, 1, mesh, color, sock);
2051 anim_move('z', 1, 1, mesh, color, sock);
2052 anim_move('x', 1, 3, mesh, color, sock);
2053 break;
2054 }
2055 break;
2056 }
2057}
2058
2059void
2061{
2062 if (logging_ > 1)
2063 {
2064 cout << "Entering solve_top_corners" << endl;
2065 }
2066 if (logging_ > 2)
2067 {
2068 print_state(cout);
2069 }
2070
2071 // Locate first incorrectly filled corner location in the top tier
2072 int l4 = locate_corner(4);
2073 int i4 = l4 % 8;
2074 int o4 = l4 / 8;
2075 if (logging_ > 1)
2076 {
2077 cout << "Location of 4-th corner: " << i4
2078 << " with orientation " << o4 << endl;
2079 }
2080 if (i4 >= 0)
2081 {
2082 move_to_c4(i4, o4, mesh, color, sock);
2083 }
2084
2085 // Locate second incorrectly filled corner location in the top tier
2086 int l5 = locate_corner(5);
2087 int i5 = l5 % 8;
2088 int o5 = l5 / 8;
2089 if (logging_ > 1)
2090 {
2091 cout << "Location of 5-th corner: " << i5
2092 << " with orientation " << o5 << endl;
2093 }
2094 if (i5 >= 0)
2095 {
2096 move_to_c5(i5, o5, mesh, color, sock);
2097 }
2098
2099 // Locate third incorrectly filled corner location in the top tier
2100 int l6 = locate_corner(6);
2101 int i6 = l6 % 8;
2102 int o6 = l6 / 8;
2103 if (logging_ > 1)
2104 {
2105 cout << "Location of 6-th corner: " << i6
2106 << " with orientation " << o6 << endl;
2107 }
2108 if (i6 >= 0)
2109 {
2110 move_to_c6(i6, o6, mesh, color, sock);
2111 }
2112
2113 // Locate fourth incorrectly filled corner location in the top tier
2114 int l7 = locate_corner(7);
2115 int i7 = l7 % 8;
2116 int o7 = l7 / 8;
2117 if (logging_ > 1)
2118 {
2119 cout << "Location of 7-th corner: " << i7
2120 << " with orientation " << o7 << endl;
2121 }
2122 if (i7 >= 0)
2123 {
2124 move_to_c7(i7, o7, mesh, color, sock);
2125 }
2126}
2127
2128int
2130{
2131 for (int i=0; i<12; i++)
2132 {
2133 if ((rubik.edge_[2 * i + 0] == edge_colors_[2 * ind + 0] &&
2134 rubik.edge_[2 * i + 1] == edge_colors_[2 * ind + 1]))
2135 {
2136 return i;
2137 }
2138 if ((rubik.edge_[2 * i + 0] == edge_colors_[2 * ind + 1] &&
2139 rubik.edge_[2 * i + 1] == edge_colors_[2 * ind + 0]))
2140 {
2141 return -i - 1;
2142 }
2143 }
2144 return -99;
2145}
2146
2147void
2148move_to_e4(int i4, int o4,
2149 Mesh & mesh, GridFunction & color, socketstream & sock)
2150{
2151 if (o4 == 0)
2152 {
2153 switch (i4)
2154 {
2155 case 0:
2156 anim_move('y', 2, 1, mesh, color, sock);
2157 anim_move('x', 2, 1, mesh, color, sock);
2158 anim_move('y', 2, 3, mesh, color, sock);
2159 break;
2160 case 1:
2161 anim_move('x', 3, 1, mesh, color, sock);
2162 anim_move('y', 1, 1, mesh, color, sock);
2163 break;
2164 case 2:
2165 anim_move('y', 3, 2, mesh, color, sock);
2166 anim_move('z', 3, 2, mesh, color, sock);
2167 break;
2168 case 3:
2169 anim_move('x', 1, 2, mesh, color, sock);
2170 anim_move('z', 3, 3, mesh, color, sock);
2171 break;
2172 case 5:
2173 anim_move('z', 3, 1, mesh, color, sock);
2174 break;
2175 case 6:
2176 anim_move('y', 2, 1, mesh, color, sock);
2177 anim_move('x', 2, 3, mesh, color, sock);
2178 anim_move('y', 2, 3, mesh, color, sock);
2179 break;
2180 case 7:
2181 anim_move('y', 2, 3, mesh, color, sock);
2182 anim_move('z', 3, 1, mesh, color, sock);
2183 anim_move('y', 2, 1, mesh, color, sock);
2184 break;
2185 case 8:
2186 anim_move('y', 1, 3, mesh, color, sock);
2187 break;
2188 case 9:
2189 anim_move('z', 2, 1, mesh, color, sock);
2190 anim_move('y', 1, 3, mesh, color, sock);
2191 break;
2192 case 10:
2193 anim_move('y', 3, 1, mesh, color, sock);
2194 anim_move('z', 3, 2, mesh, color, sock);
2195 break;
2196 case 11:
2197 anim_move('x', 1, 3, mesh, color, sock);
2198 anim_move('z', 3, 3, mesh, color, sock);
2199 break;
2200 }
2201 }
2202 else
2203 {
2204 switch (i4)
2205 {
2206 case 0:
2207 anim_move('y', 1, 2, mesh, color, sock);
2208 break;
2209 case 1:
2210 anim_move('z', 1, 3, mesh, color, sock);
2211 anim_move('y', 1, 2, mesh, color, sock);
2212 break;
2213 case 2:
2214 anim_move('x', 2, 3, mesh, color, sock);
2215 anim_move('z', 3, 1, mesh, color, sock);
2216 anim_move('x', 2, 1, mesh, color, sock);
2217 anim_move('z', 3, 1, mesh, color, sock);
2218 break;
2219 case 3:
2220 anim_move('y', 2, 3, mesh, color, sock);
2221 anim_move('z', 3, 3, mesh, color, sock);
2222 anim_move('y', 2, 1, mesh, color, sock);
2223 break;
2224 case 4:
2225 anim_move('y', 1, 3, mesh, color, sock);
2226 anim_move('z', 2, 1, mesh, color, sock);
2227 anim_move('y', 1, 3, mesh, color, sock);
2228 break;
2229 case 5:
2230 anim_move('y', 2, 1, mesh, color, sock);
2231 anim_move('z', 3, 3, mesh, color, sock);
2232 anim_move('y', 2, 3, mesh, color, sock);
2233 break;
2234 case 6:
2235 anim_move('z', 3, 2, mesh, color, sock);
2236 break;
2237 case 7:
2238 anim_move('z', 3, 3, mesh, color, sock);
2239 break;
2240 case 8:
2241 anim_move('z', 2, 3, mesh, color, sock);
2242 anim_move('y', 1, 1, mesh, color, sock);
2243 break;
2244 case 9:
2245 anim_move('y', 1, 1, mesh, color, sock);
2246 break;
2247 case 10:
2248 anim_move('x', 3, 3, mesh, color, sock);
2249 anim_move('z', 3, 1, mesh, color, sock);
2250 break;
2251 case 11:
2252 anim_move('y', 3, 3, mesh, color, sock);
2253 anim_move('z', 3, 2, mesh, color, sock);
2254 break;
2255 }
2256 }
2257}
2258
2259void
2260move_to_e5(int i5, int o5,
2261 Mesh & mesh, GridFunction & color, socketstream & sock)
2262{
2263 if (o5 == 0)
2264 {
2265 switch (i5)
2266 {
2267 case 0:
2268 anim_move('y', 1, 3, mesh, color, sock);
2269 anim_move('x', 3, 1, mesh, color, sock);
2270 anim_move('y', 1, 1, mesh, color, sock);
2271 break;
2272 case 1:
2273 anim_move('x', 2, 3, mesh, color, sock);
2274 anim_move('y', 2, 1, mesh, color, sock);
2275 anim_move('x', 2, 1, mesh, color, sock);
2276 break;
2277 case 2:
2278 anim_move('z', 1, 1, mesh, color, sock);
2279 anim_move('x', 3, 2, mesh, color, sock);
2280 break;
2281 case 3:
2282 anim_move('z', 1, 2, mesh, color, sock);
2283 anim_move('x', 3, 2, mesh, color, sock);
2284 break;
2285 case 6:
2286 anim_move('y', 3, 3, mesh, color, sock);
2287 anim_move('x', 3, 3, mesh, color, sock);
2288 break;
2289 case 7:
2290 anim_move('x', 2, 1, mesh, color, sock);
2291 anim_move('y', 2, 3, mesh, color, sock);
2292 anim_move('x', 2, 3, mesh, color, sock);
2293 break;
2294 case 8:
2295 anim_move('z', 2, 3, mesh, color, sock);
2296 anim_move('x', 3, 1, mesh, color, sock);
2297 break;
2298 case 9:
2299 anim_move('x', 3, 1, mesh, color, sock);
2300 break;
2301 case 10:
2302 anim_move('z', 2, 1, mesh, color, sock);
2303 anim_move('x', 3, 1, mesh, color, sock);
2304 break;
2305 case 11:
2306 anim_move('y', 3, 2, mesh, color, sock);
2307 anim_move('x', 3, 3, mesh, color, sock);
2308 break;
2309 }
2310 }
2311 else
2312 {
2313 switch (i5)
2314 {
2315 case 0:
2316 anim_move('z', 1, 3, mesh, color, sock);
2317 anim_move('x', 3, 2, mesh, color, sock);
2318 break;
2319 case 1:
2320 anim_move('x', 3, 2, mesh, color, sock);
2321 break;
2322 case 2:
2323 anim_move('y', 3, 1, mesh, color, sock);
2324 anim_move('x', 3, 3, mesh, color, sock);
2325 break;
2326 case 3:
2327 anim_move('z', 1, 2, mesh, color, sock);
2328 anim_move('x', 2, 3, mesh, color, sock);
2329 anim_move('y', 2, 1, mesh, color, sock);
2330 anim_move('x', 2, 1, mesh, color, sock);
2331 break;
2332 case 5:
2333 anim_move('x', 3, 1, mesh, color, sock);
2334 anim_move('z', 2, 1, mesh, color, sock);
2335 anim_move('x', 3, 1, mesh, color, sock);
2336 break;
2337 case 6:
2338 anim_move('y', 1, 1, mesh, color, sock);
2339 anim_move('z', 3, 1, mesh, color, sock);
2340 anim_move('y', 1, 3, mesh, color, sock);
2341 break;
2342 case 7:
2343 anim_move('y', 1, 1, mesh, color, sock);
2344 anim_move('z', 3, 2, mesh, color, sock);
2345 anim_move('y', 1, 3, mesh, color, sock);
2346 break;
2347 case 8:
2348 anim_move('z', 2, 2, mesh, color, sock);
2349 anim_move('x', 3, 3, mesh, color, sock);
2350 break;
2351 case 9:
2352 anim_move('z', 2, 3, mesh, color, sock);
2353 anim_move('x', 3, 3, mesh, color, sock);
2354 break;
2355 case 10:
2356 anim_move('x', 3, 3, mesh, color, sock);
2357 break;
2358 case 11:
2359 anim_move('z', 2, 1, mesh, color, sock);
2360 anim_move('x', 3, 3, mesh, color, sock);
2361 break;
2362 }
2363 }
2364}
2365
2366void
2367move_to_e6(int i6, int o6,
2368 Mesh & mesh, GridFunction & color, socketstream & sock)
2369{
2370 if (o6 == 0)
2371 {
2372 switch (i6)
2373 {
2374 case 0:
2375 anim_move('z', 1, 2, mesh, color, sock);
2376 anim_move('y', 3, 2, mesh, color, sock);
2377 break;
2378 case 1:
2379 anim_move('z', 1, 3, mesh, color, sock);
2380 anim_move('y', 3, 2, mesh, color, sock);
2381 break;
2382 case 2:
2383 anim_move('y', 3, 1, mesh, color, sock);
2384 anim_move('z', 2, 3, mesh, color, sock);
2385 anim_move('y', 3, 3, mesh, color, sock);
2386 break;
2387 case 3:
2388 anim_move('x', 1, 3, mesh, color, sock);
2389 anim_move('y', 3, 3, mesh, color, sock);
2390 break;
2391 case 7:
2392 anim_move('z', 3, 1, mesh, color, sock);
2393 anim_move('y', 3, 1, mesh, color, sock);
2394 anim_move('z', 3, 3, mesh, color, sock);
2395 anim_move('y', 3, 3, mesh, color, sock);
2396 break;
2397 case 8:
2398 anim_move('z', 2, 1, mesh, color, sock);
2399 anim_move('y', 3, 3, mesh, color, sock);
2400 break;
2401 case 9:
2402 anim_move('z', 2, 2, mesh, color, sock);
2403 anim_move('y', 3, 3, mesh, color, sock);
2404 break;
2405 case 10:
2406 anim_move('z', 2, 3, mesh, color, sock);
2407 anim_move('y', 3, 3, mesh, color, sock);
2408 break;
2409 case 11:
2410 anim_move('y', 3, 3, mesh, color, sock);
2411 break;
2412 }
2413 }
2414 else
2415 {
2416 switch (i6)
2417 {
2418 case 0:
2419 anim_move('z', 1, 1, mesh, color, sock);
2420 anim_move('x', 1, 3, mesh, color, sock);
2421 anim_move('y', 3, 3, mesh, color, sock);
2422 break;
2423 case 1:
2424 anim_move('x', 2, 1, mesh, color, sock);
2425 anim_move('z', 1, 3, mesh, color, sock);
2426 anim_move('x', 2, 3, mesh, color, sock);
2427 break;
2428 case 2:
2429 anim_move('y', 3, 2, mesh, color, sock);
2430 break;
2431 case 3:
2432 anim_move('z', 1, 1, mesh, color, sock);
2433 anim_move('y', 3, 2, mesh, color, sock);
2434 break;
2435 case 6:
2436 anim_move('y', 3, 1, mesh, color, sock);
2437 anim_move('z', 2, 1, mesh, color, sock);
2438 anim_move('y', 3, 1, mesh, color, sock);
2439 break;
2440 case 7:
2441 anim_move('x', 1, 1, mesh, color, sock);
2442 anim_move('y', 3, 3, mesh, color, sock);
2443 break;
2444 case 8:
2445 anim_move('z', 2, 2, mesh, color, sock);
2446 anim_move('y', 3, 1, mesh, color, sock);
2447 break;
2448 case 9:
2449 anim_move('z', 2, 3, mesh, color, sock);
2450 anim_move('y', 3, 1, mesh, color, sock);
2451 break;
2452 case 10:
2453 anim_move('y', 3, 1, mesh, color, sock);
2454 break;
2455 case 11:
2456 anim_move('z', 2, 1, mesh, color, sock);
2457 anim_move('y', 3, 1, mesh, color, sock);
2458 break;
2459 }
2460 }
2461}
2462
2463void
2464move_to_e7(int i7, int o7,
2465 Mesh & mesh, GridFunction & color, socketstream & sock)
2466{
2467 if (o7 == 0)
2468 {
2469 switch (i7)
2470 {
2471 case 0:
2472 anim_move('z', 1, 1, mesh, color, sock);
2473 anim_move('x', 1, 2, mesh, color, sock);
2474 break;
2475 case 1:
2476 anim_move('z', 1, 2, mesh, color, sock);
2477 anim_move('x', 1, 2, mesh, color, sock);
2478 break;
2479 case 2:
2480 anim_move('y', 3, 3, mesh, color, sock);
2481 anim_move('x', 1, 3, mesh, color, sock);
2482 anim_move('y', 3, 1, mesh, color, sock);
2483 break;
2484 case 3:
2485 anim_move('x', 1, 1, mesh, color, sock);
2486 anim_move('z', 2, 1, mesh, color, sock);
2487 anim_move('x', 1, 3, mesh, color, sock);
2488 break;
2489 case 8:
2490 anim_move('x', 1, 1, mesh, color, sock);
2491 break;
2492 case 9:
2493 anim_move('z', 2, 1, mesh, color, sock);
2494 anim_move('x', 1, 1, mesh, color, sock);
2495 break;
2496 case 10:
2497 anim_move('z', 2, 2, mesh, color, sock);
2498 anim_move('x', 1, 1, mesh, color, sock);
2499 break;
2500 case 11:
2501 anim_move('z', 2, 3, mesh, color, sock);
2502 anim_move('x', 1, 1, mesh, color, sock);
2503 break;
2504 }
2505 }
2506 else
2507 {
2508 switch (i7)
2509 {
2510 case 0:
2511 anim_move('y', 1, 3, mesh, color, sock);
2512 anim_move('x', 1, 1, mesh, color, sock);
2513 anim_move('y', 1, 1, mesh, color, sock);
2514 break;
2515 case 1:
2516 anim_move('z', 1, 3, mesh, color, sock);
2517 anim_move('y', 3, 3, mesh, color, sock);
2518 anim_move('x', 1, 3, mesh, color, sock);
2519 anim_move('y', 3, 1, mesh, color, sock);
2520 break;
2521 case 2:
2522 anim_move('z', 1, 3, mesh, color, sock);
2523 anim_move('x', 1, 2, mesh, color, sock);
2524 break;
2525 case 3:
2526 anim_move('x', 1, 2, mesh, color, sock);
2527 break;
2528 case 7:
2529 anim_move('x', 1, 1, mesh, color, sock);
2530 anim_move('z', 2, 3, mesh, color, sock);
2531 anim_move('x', 1, 1, mesh, color, sock);
2532 break;
2533 case 8:
2534 anim_move('z', 2, 1, mesh, color, sock);
2535 anim_move('x', 1, 3, mesh, color, sock);
2536 break;
2537 case 9:
2538 anim_move('z', 2, 2, mesh, color, sock);
2539 anim_move('x', 1, 3, mesh, color, sock);
2540 break;
2541 case 10:
2542 anim_move('z', 2, 3, mesh, color, sock);
2543 anim_move('x', 1, 3, mesh, color, sock);
2544 break;
2545 case 11:
2546 anim_move('x', 1, 3, mesh, color, sock);
2547 break;
2548 }
2549 }
2550}
2551
2552void
2553move_to_e8(int i8, int o8,
2554 Mesh & mesh, GridFunction & color, socketstream & sock)
2555{
2556 if (o8 == 0)
2557 {
2558 switch (i8)
2559 {
2560 case 0: // Verified
2561 anim_move('z', 1, 2, mesh, color, sock);
2562 anim_move('y', 1, 1, mesh, color, sock);
2563 anim_move('z', 1, 3, mesh, color, sock);
2564 anim_move('y', 1, 3, mesh, color, sock);
2565 anim_move('x', 1, 1, mesh, color, sock);
2566 anim_move('y', 1, 3, mesh, color, sock);
2567 anim_move('x', 1, 3, mesh, color, sock);
2568 anim_move('y', 1, 1, mesh, color, sock);
2569 break;
2570 case 1: // Verified
2571 anim_move('z', 1, 3, mesh, color, sock);
2572 anim_move('y', 1, 1, mesh, color, sock);
2573 anim_move('z', 1, 3, mesh, color, sock);
2574 anim_move('y', 1, 3, mesh, color, sock);
2575 anim_move('x', 1, 1, mesh, color, sock);
2576 anim_move('y', 1, 3, mesh, color, sock);
2577 anim_move('x', 1, 3, mesh, color, sock);
2578 anim_move('y', 1, 1, mesh, color, sock);
2579 break;
2580 case 2: // Verified
2581 anim_move('z', 1, 1, mesh, color, sock);
2582 anim_move('x', 1, 3, mesh, color, sock);
2583 anim_move('z', 1, 1, mesh, color, sock);
2584 anim_move('x', 1, 1, mesh, color, sock);
2585 anim_move('y', 1, 3, mesh, color, sock);
2586 anim_move('x', 1, 1, mesh, color, sock);
2587 anim_move('y', 1, 1, mesh, color, sock);
2588 anim_move('x', 1, 3, mesh, color, sock);
2589 break;
2590 case 3: // Verified
2591 anim_move('z', 1, 2, mesh, color, sock);
2592 anim_move('x', 1, 3, mesh, color, sock);
2593 anim_move('z', 1, 1, mesh, color, sock);
2594 anim_move('x', 1, 1, mesh, color, sock);
2595 anim_move('y', 1, 3, mesh, color, sock);
2596 anim_move('x', 1, 1, mesh, color, sock);
2597 anim_move('y', 1, 1, mesh, color, sock);
2598 anim_move('x', 1, 3, mesh, color, sock);
2599 break;
2600 case 9: // Verified
2601 anim_move('x', 3, 3, mesh, color, sock);
2602 permute_edges(mesh, color, sock, false);
2603 anim_move('x', 3, 1, mesh, color, sock);
2604 anim_move('z', 1, 1, mesh, color, sock);
2605 anim_move('y', 1, 1, mesh, color, sock);
2606 permute_edges(mesh, color, sock, true);
2607 anim_move('y', 1, 3, mesh, color, sock);
2608 break;
2609 case 10: // Verified
2610 anim_move('z', 2, 1, mesh, color, sock);
2611 anim_move('y', 1, 2, mesh, color, sock);
2612 anim_move('z', 2, 3, mesh, color, sock);
2613 anim_move('y', 1, 2, mesh, color, sock);
2614 break;
2615 case 11: // Verified
2616 anim_move('y', 3, 1, mesh, color, sock);
2617 permute_edges(mesh, color, sock, true);
2618 anim_move('y', 3, 3, mesh, color, sock);
2619 anim_move('z', 1, 3, mesh, color, sock);
2620 anim_move('y', 1, 1, mesh, color, sock);
2621 permute_edges(mesh, color, sock, false);
2622 anim_move('y', 1, 3, mesh, color, sock);
2623 break;
2624 }
2625 }
2626 else
2627 {
2628 switch (i8)
2629 {
2630 case 0: // Verified
2631 anim_move('z', 1, 3, mesh, color, sock);
2632 anim_move('x', 1, 3, mesh, color, sock);
2633 anim_move('z', 1, 1, mesh, color, sock);
2634 anim_move('x', 1, 1, mesh, color, sock);
2635 anim_move('y', 1, 3, mesh, color, sock);
2636 anim_move('x', 1, 1, mesh, color, sock);
2637 anim_move('y', 1, 1, mesh, color, sock);
2638 anim_move('x', 1, 3, mesh, color, sock);
2639 break;
2640 case 1: // Verified
2641 anim_move('x', 1, 3, mesh, color, sock);
2642 anim_move('z', 1, 1, mesh, color, sock);
2643 anim_move('x', 1, 1, mesh, color, sock);
2644 anim_move('y', 1, 3, mesh, color, sock);
2645 anim_move('x', 1, 1, mesh, color, sock);
2646 anim_move('y', 1, 1, mesh, color, sock);
2647 anim_move('x', 1, 3, mesh, color, sock);
2648 break;
2649 case 2: // Verified
2650 anim_move('y', 1, 1, mesh, color, sock);
2651 anim_move('z', 1, 3, mesh, color, sock);
2652 anim_move('y', 1, 3, mesh, color, sock);
2653 anim_move('x', 1, 1, mesh, color, sock);
2654 anim_move('y', 1, 3, mesh, color, sock);
2655 anim_move('x', 1, 3, mesh, color, sock);
2656 anim_move('y', 1, 1, mesh, color, sock);
2657 break;
2658 case 3: // Verified
2659 anim_move('z', 1, 1, mesh, color, sock);
2660 anim_move('y', 1, 1, mesh, color, sock);
2661 anim_move('z', 1, 3, mesh, color, sock);
2662 anim_move('y', 1, 3, mesh, color, sock);
2663 anim_move('x', 1, 1, mesh, color, sock);
2664 anim_move('y', 1, 3, mesh, color, sock);
2665 anim_move('x', 1, 3, mesh, color, sock);
2666 anim_move('y', 1, 1, mesh, color, sock);
2667 break;
2668 case 8: // Verified
2669 anim_move('y', 1, 1, mesh, color, sock);
2670 anim_move('z', 1, 3, mesh, color, sock);
2671 anim_move('y', 1, 3, mesh, color, sock);
2672 anim_move('x', 1, 1, mesh, color, sock);
2673 anim_move('y', 1, 3, mesh, color, sock);
2674 anim_move('x', 1, 3, mesh, color, sock);
2675 anim_move('y', 1, 1, mesh, color, sock);
2676 anim_move('z', 1, 3, mesh, color, sock);
2677 anim_move('y', 1, 1, mesh, color, sock);
2678 anim_move('z', 1, 3, mesh, color, sock);
2679 anim_move('y', 1, 3, mesh, color, sock);
2680 anim_move('x', 1, 1, mesh, color, sock);
2681 anim_move('y', 1, 3, mesh, color, sock);
2682 anim_move('x', 1, 3, mesh, color, sock);
2683 anim_move('y', 1, 1, mesh, color, sock);
2684 break;
2685 case 9: // Verified
2686 anim_move('y', 1, 2, mesh, color, sock);
2687 anim_move('z', 1, 2, mesh, color, sock);
2688 anim_move('y', 1, 2, mesh, color, sock);
2689 anim_move('z', 1, 2, mesh, color, sock);
2690 anim_move('y', 1, 2, mesh, color, sock);
2691 break;
2692 case 10: // Verified
2693 anim_move('y', 3, 3, mesh, color, sock);
2694 permute_edges(mesh, color, sock, false);
2695 anim_move('y', 3, 1, mesh, color, sock);
2696 anim_move('z', 1, 3, mesh, color, sock);
2697 anim_move('y', 1, 1, mesh, color, sock);
2698 permute_edges(mesh, color, sock, true);
2699 anim_move('y', 1, 3, mesh, color, sock);
2700 break;
2701 case 11: // Verified
2702 anim_move('z', 2, 1, mesh, color, sock);
2703 anim_move('x', 1, 2, mesh, color, sock);
2704 anim_move('z', 2, 3, mesh, color, sock);
2705 anim_move('x', 1, 2, mesh, color, sock);
2706 break;
2707 }
2708 }
2709}
2710
2711void
2712move_to_e9(int i9, int o9,
2713 Mesh & mesh, GridFunction & color, socketstream & sock)
2714{
2715 if (o9 == 0)
2716 {
2717 switch (i9)
2718 {
2719 case 0: // Verified
2720 anim_move('z', 1, 1, mesh, color, sock);
2721 anim_move('x', 3, 3, mesh, color, sock);
2722 anim_move('z', 1, 3, mesh, color, sock);
2723 anim_move('x', 3, 1, mesh, color, sock);
2724 anim_move('y', 1, 1, mesh, color, sock);
2725 anim_move('x', 3, 1, mesh, color, sock);
2726 anim_move('y', 1, 3, mesh, color, sock);
2727 anim_move('x', 3, 3, mesh, color, sock);
2728 break;
2729 case 1: // Verified
2730 anim_move('z', 1, 2, mesh, color, sock);
2731 anim_move('x', 3, 3, mesh, color, sock);
2732 anim_move('z', 1, 3, mesh, color, sock);
2733 anim_move('x', 3, 1, mesh, color, sock);
2734 anim_move('y', 1, 1, mesh, color, sock);
2735 anim_move('x', 3, 1, mesh, color, sock);
2736 anim_move('y', 1, 3, mesh, color, sock);
2737 anim_move('x', 3, 3, mesh, color, sock);
2738 break;
2739 case 2: // Verified
2740 anim_move('y', 1, 3, mesh, color, sock);
2741 anim_move('z', 1, 1, mesh, color, sock);
2742 anim_move('y', 1, 1, mesh, color, sock);
2743 anim_move('x', 3, 1, mesh, color, sock);
2744 anim_move('y', 1, 1, mesh, color, sock);
2745 anim_move('x', 3, 3, mesh, color, sock);
2746 anim_move('y', 1, 3, mesh, color, sock);
2747 break;
2748 case 3: // Verified
2749 anim_move('z', 1, 1, mesh, color, sock);
2750 anim_move('y', 1, 3, mesh, color, sock);
2751 anim_move('z', 1, 1, mesh, color, sock);
2752 anim_move('y', 1, 1, mesh, color, sock);
2753 anim_move('x', 3, 1, mesh, color, sock);
2754 anim_move('y', 1, 1, mesh, color, sock);
2755 anim_move('x', 3, 3, mesh, color, sock);
2756 anim_move('y', 1, 3, mesh, color, sock);
2757 break;
2758 case 10: // Verified
2759 anim_move('y', 3, 3, mesh, color, sock);
2760 permute_edges(mesh, color, sock, true);
2761 anim_move('y', 3, 1, mesh, color, sock);
2762 anim_move('z', 1, 3, mesh, color, sock);
2763 anim_move('y', 1, 3, mesh, color, sock);
2764 permute_edges(mesh, color, sock, false);
2765 anim_move('y', 1, 1, mesh, color, sock);
2766 break;
2767 case 11: // Verified
2768 anim_move('z', 2, 1, mesh, color, sock);
2769 anim_move('x', 3, 2, mesh, color, sock);
2770 anim_move('z', 2, 3, mesh, color, sock);
2771 anim_move('x', 3, 2, mesh, color, sock);
2772 break;
2773 }
2774 }
2775 else
2776 {
2777 switch (i9)
2778 {
2779 case 0: // Verified
2780 anim_move('z', 1, 2, mesh, color, sock);
2781 anim_move('y', 1, 3, mesh, color, sock);
2782 anim_move('z', 1, 1, mesh, color, sock);
2783 anim_move('y', 1, 1, mesh, color, sock);
2784 anim_move('x', 3, 1, mesh, color, sock);
2785 anim_move('y', 1, 1, mesh, color, sock);
2786 anim_move('x', 3, 3, mesh, color, sock);
2787 anim_move('y', 1, 3, mesh, color, sock);
2788 break;
2789 case 1: // Verified
2790 anim_move('z', 1, 3, mesh, color, sock);
2791 anim_move('y', 1, 3, mesh, color, sock);
2792 anim_move('z', 1, 1, mesh, color, sock);
2793 anim_move('y', 1, 1, mesh, color, sock);
2794 anim_move('x', 3, 1, mesh, color, sock);
2795 anim_move('y', 1, 1, mesh, color, sock);
2796 anim_move('x', 3, 3, mesh, color, sock);
2797 anim_move('y', 1, 3, mesh, color, sock);
2798 break;
2799 case 2: // Verified
2800 anim_move('z', 1, 3, mesh, color, sock);
2801 anim_move('x', 3, 3, mesh, color, sock);
2802 anim_move('z', 1, 3, mesh, color, sock);
2803 anim_move('x', 3, 1, mesh, color, sock);
2804 anim_move('y', 1, 1, mesh, color, sock);
2805 anim_move('x', 3, 1, mesh, color, sock);
2806 anim_move('y', 1, 3, mesh, color, sock);
2807 anim_move('x', 3, 3, mesh, color, sock);
2808 break;
2809 case 3: // Verified
2810 anim_move('x', 3, 3, mesh, color, sock);
2811 anim_move('z', 1, 3, mesh, color, sock);
2812 anim_move('x', 3, 1, mesh, color, sock);
2813 anim_move('y', 1, 1, mesh, color, sock);
2814 anim_move('x', 3, 1, mesh, color, sock);
2815 anim_move('y', 1, 3, mesh, color, sock);
2816 anim_move('x', 3, 3, mesh, color, sock);
2817 break;
2818 case 9: // Verified
2819 anim_move('x', 3, 3, mesh, color, sock);
2820 anim_move('z', 1, 3, mesh, color, sock);
2821 anim_move('x', 3, 1, mesh, color, sock);
2822 anim_move('y', 1, 1, mesh, color, sock);
2823 anim_move('x', 3, 1, mesh, color, sock);
2824 anim_move('y', 1, 3, mesh, color, sock);
2825 anim_move('x', 3, 3, mesh, color, sock);
2826 anim_move('z', 1, 3, mesh, color, sock);
2827 anim_move('x', 3, 3, mesh, color, sock);
2828 anim_move('z', 1, 3, mesh, color, sock);
2829 anim_move('x', 3, 1, mesh, color, sock);
2830 anim_move('y', 1, 1, mesh, color, sock);
2831 anim_move('x', 3, 1, mesh, color, sock);
2832 anim_move('y', 1, 3, mesh, color, sock);
2833 anim_move('x', 3, 3, mesh, color, sock);
2834 break;
2835 case 10: // Verified
2836 anim_move('x', 3, 2, mesh, color, sock);
2837 anim_move('z', 1, 2, mesh, color, sock);
2838 anim_move('x', 3, 2, mesh, color, sock);
2839 anim_move('z', 1, 2, mesh, color, sock);
2840 anim_move('x', 3, 2, mesh, color, sock);
2841 break;
2842 case 11: // Verified
2843 anim_move('y', 3, 1, mesh, color, sock);
2844 permute_edges(mesh, color, sock, true);
2845 anim_move('y', 3, 3, mesh, color, sock);
2846 anim_move('z', 1, 3, mesh, color, sock);
2847 anim_move('y', 1, 3, mesh, color, sock);
2848 permute_edges(mesh, color, sock, false);
2849 anim_move('y', 1, 1, mesh, color, sock);
2850 break;
2851 }
2852 }
2853}
2854
2855void
2856move_to_e10(int i10, int o10,
2857 Mesh & mesh, GridFunction & color, socketstream & sock)
2858{
2859 if (o10 == 0)
2860 {
2861 switch (i10)
2862 {
2863 case 0: // Verified
2864 anim_move('y', 3, 3, mesh, color, sock);
2865 anim_move('z', 1, 3, mesh, color, sock);
2866 anim_move('y', 3, 1, mesh, color, sock);
2867 anim_move('x', 3, 3, mesh, color, sock);
2868 anim_move('y', 3, 1, mesh, color, sock);
2869 anim_move('x', 3, 1, mesh, color, sock);
2870 anim_move('y', 3, 3, mesh, color, sock);
2871 break;
2872 case 1: // Verified
2873 anim_move('z', 1, 1, mesh, color, sock);
2874 anim_move('y', 3, 3, mesh, color, sock);
2875 anim_move('z', 1, 3, mesh, color, sock);
2876 anim_move('y', 3, 1, mesh, color, sock);
2877 anim_move('x', 3, 3, mesh, color, sock);
2878 anim_move('y', 3, 1, mesh, color, sock);
2879 anim_move('x', 3, 1, mesh, color, sock);
2880 anim_move('y', 3, 3, mesh, color, sock);
2881 break;
2882 case 2: // Verified
2883 anim_move('z', 1, 3, mesh, color, sock);
2884 anim_move('x', 3, 1, mesh, color, sock);
2885 anim_move('z', 1, 1, mesh, color, sock);
2886 anim_move('x', 3, 3, mesh, color, sock);
2887 anim_move('y', 3, 1, mesh, color, sock);
2888 anim_move('x', 3, 3, mesh, color, sock);
2889 anim_move('y', 3, 3, mesh, color, sock);
2890 anim_move('x', 3, 1, mesh, color, sock);
2891 break;
2892 case 3: // Verified
2893 anim_move('x', 3, 1, mesh, color, sock);
2894 anim_move('z', 1, 1, mesh, color, sock);
2895 anim_move('x', 3, 3, mesh, color, sock);
2896 anim_move('y', 3, 1, mesh, color, sock);
2897 anim_move('x', 3, 3, mesh, color, sock);
2898 anim_move('y', 3, 3, mesh, color, sock);
2899 anim_move('x', 3, 1, mesh, color, sock);
2900 break;
2901 case 11: // Verified
2902 anim_move('y', 3, 1, mesh, color, sock);
2903 permute_edges(mesh, color, sock, true);
2904 anim_move('y', 3, 3, mesh, color, sock);
2905 anim_move('z', 1, 1, mesh, color, sock);
2906 anim_move('y', 3, 3, mesh, color, sock);
2907 permute_edges(mesh, color, sock, true);
2908 anim_move('y', 3, 1, mesh, color, sock);
2909 break;
2910 }
2911 }
2912 else
2913 {
2914 switch (i10)
2915 {
2916 case 0: // Verified
2917 anim_move('z', 1, 1, mesh, color, sock);
2918 anim_move('x', 3, 1, mesh, color, sock);
2919 anim_move('z', 1, 1, mesh, color, sock);
2920 anim_move('x', 3, 3, mesh, color, sock);
2921 anim_move('y', 3, 1, mesh, color, sock);
2922 anim_move('x', 3, 3, mesh, color, sock);
2923 anim_move('y', 3, 3, mesh, color, sock);
2924 anim_move('x', 3, 1, mesh, color, sock);
2925 break;
2926 case 1: // Verified
2927 anim_move('z', 1, 2, mesh, color, sock);
2928 anim_move('x', 3, 1, mesh, color, sock);
2929 anim_move('z', 1, 1, mesh, color, sock);
2930 anim_move('x', 3, 3, mesh, color, sock);
2931 anim_move('y', 3, 1, mesh, color, sock);
2932 anim_move('x', 3, 3, mesh, color, sock);
2933 anim_move('y', 3, 3, mesh, color, sock);
2934 anim_move('x', 3, 1, mesh, color, sock);
2935 break;
2936 case 2: // Verified
2937 anim_move('z', 1, 2, mesh, color, sock);
2938 anim_move('y', 3, 3, mesh, color, sock);
2939 anim_move('z', 1, 3, mesh, color, sock);
2940 anim_move('y', 3, 1, mesh, color, sock);
2941 anim_move('x', 3, 3, mesh, color, sock);
2942 anim_move('y', 3, 1, mesh, color, sock);
2943 anim_move('x', 3, 1, mesh, color, sock);
2944 anim_move('y', 3, 3, mesh, color, sock);
2945 break;
2946 case 3: // Verified
2947 anim_move('z', 1, 3, mesh, color, sock);
2948 anim_move('y', 3, 3, mesh, color, sock);
2949 anim_move('z', 1, 3, mesh, color, sock);
2950 anim_move('y', 3, 1, mesh, color, sock);
2951 anim_move('x', 3, 3, mesh, color, sock);
2952 anim_move('y', 3, 1, mesh, color, sock);
2953 anim_move('x', 3, 1, mesh, color, sock);
2954 anim_move('y', 3, 3, mesh, color, sock);
2955 break;
2956 case 10: // Verified
2957 anim_move('x', 3, 1, mesh, color, sock);
2958 anim_move('z', 1, 1, mesh, color, sock);
2959 anim_move('x', 3, 3, mesh, color, sock);
2960 anim_move('y', 3, 1, mesh, color, sock);
2961 anim_move('x', 3, 3, mesh, color, sock);
2962 anim_move('y', 3, 3, mesh, color, sock);
2963 anim_move('x', 3, 1, mesh, color, sock);
2964 anim_move('z', 1, 1, mesh, color, sock);
2965 anim_move('x', 3, 1, mesh, color, sock);
2966 anim_move('z', 1, 1, mesh, color, sock);
2967 anim_move('x', 3, 3, mesh, color, sock);
2968 anim_move('y', 3, 1, mesh, color, sock);
2969 anim_move('x', 3, 3, mesh, color, sock);
2970 anim_move('y', 3, 3, mesh, color, sock);
2971 anim_move('x', 3, 1, mesh, color, sock);
2972 break;
2973 case 11: // Verified
2974 anim_move('y', 3, 2, mesh, color, sock);
2975 anim_move('z', 1, 2, mesh, color, sock);
2976 anim_move('y', 3, 2, mesh, color, sock);
2977 anim_move('z', 1, 2, mesh, color, sock);
2978 anim_move('y', 3, 2, mesh, color, sock);
2979 break;
2980 }
2981 }
2982}
2983
2984void
2985move_to_e11(int i11, int o11,
2986 Mesh & mesh, GridFunction & color, socketstream & sock)
2987{
2988 if (o11 == 0)
2989 {
2990 switch (i11)
2991 {
2992 case 0: // Verified
2993 anim_move('z', 1, 3, mesh, color, sock);
2994 anim_move('x', 1, 1, mesh, color, sock);
2995 anim_move('z', 1, 3, mesh, color, sock);
2996 anim_move('x', 1, 3, mesh, color, sock);
2997 anim_move('y', 3, 3, mesh, color, sock);
2998 anim_move('x', 1, 3, mesh, color, sock);
2999 anim_move('y', 3, 1, mesh, color, sock);
3000 anim_move('x', 1, 1, mesh, color, sock);
3001 break;
3002 case 1: // Verified
3003 anim_move('x', 1, 1, mesh, color, sock);
3004 anim_move('z', 1, 3, mesh, color, sock);
3005 anim_move('x', 1, 3, mesh, color, sock);
3006 anim_move('y', 3, 3, mesh, color, sock);
3007 anim_move('x', 1, 3, mesh, color, sock);
3008 anim_move('y', 3, 1, mesh, color, sock);
3009 anim_move('x', 1, 1, mesh, color, sock);
3010 break;
3011 case 2: // Verified
3012 anim_move('z', 1, 2, mesh, color, sock);
3013 anim_move('y', 3, 1, mesh, color, sock);
3014 anim_move('z', 1, 1, mesh, color, sock);
3015 anim_move('y', 3, 3, mesh, color, sock);
3016 anim_move('x', 1, 3, mesh, color, sock);
3017 anim_move('y', 3, 3, mesh, color, sock);
3018 anim_move('x', 1, 1, mesh, color, sock);
3019 anim_move('y', 3, 1, mesh, color, sock);
3020 break;
3021 case 3: // Verified
3022 anim_move('z', 1, 3, mesh, color, sock);
3023 anim_move('y', 3, 1, mesh, color, sock);
3024 anim_move('z', 1, 1, mesh, color, sock);
3025 anim_move('y', 3, 3, mesh, color, sock);
3026 anim_move('x', 1, 3, mesh, color, sock);
3027 anim_move('y', 3, 3, mesh, color, sock);
3028 anim_move('x', 1, 1, mesh, color, sock);
3029 anim_move('y', 3, 1, mesh, color, sock);
3030 break;
3031 }
3032 }
3033 else
3034 {
3035 switch (i11)
3036 {
3037 case 0: // Verified
3038 anim_move('y', 3, 1, mesh, color, sock);
3039 anim_move('z', 1, 1, mesh, color, sock);
3040 anim_move('y', 3, 3, mesh, color, sock);
3041 anim_move('x', 1, 3, mesh, color, sock);
3042 anim_move('y', 3, 3, mesh, color, sock);
3043 anim_move('x', 1, 1, mesh, color, sock);
3044 anim_move('y', 3, 1, mesh, color, sock);
3045 break;
3046 case 1: // Verified
3047 anim_move('z', 1, 1, mesh, color, sock);
3048 anim_move('y', 3, 1, mesh, color, sock);
3049 anim_move('z', 1, 1, mesh, color, sock);
3050 anim_move('y', 3, 3, mesh, color, sock);
3051 anim_move('x', 1, 3, mesh, color, sock);
3052 anim_move('y', 3, 3, mesh, color, sock);
3053 anim_move('x', 1, 1, mesh, color, sock);
3054 anim_move('y', 3, 1, mesh, color, sock);
3055 break;
3056 case 2: // Verified
3057 anim_move('z', 1, 1, mesh, color, sock);
3058 anim_move('x', 1, 1, mesh, color, sock);
3059 anim_move('z', 1, 3, mesh, color, sock);
3060 anim_move('x', 1, 3, mesh, color, sock);
3061 anim_move('y', 3, 3, mesh, color, sock);
3062 anim_move('x', 1, 3, mesh, color, sock);
3063 anim_move('y', 3, 1, mesh, color, sock);
3064 anim_move('x', 1, 1, mesh, color, sock);
3065 break;
3066 case 3: // Verified
3067 anim_move('z', 1, 2, mesh, color, sock);
3068 anim_move('x', 1, 1, mesh, color, sock);
3069 anim_move('z', 1, 3, mesh, color, sock);
3070 anim_move('x', 1, 3, mesh, color, sock);
3071 anim_move('y', 3, 3, mesh, color, sock);
3072 anim_move('x', 1, 3, mesh, color, sock);
3073 anim_move('y', 3, 1, mesh, color, sock);
3074 anim_move('x', 1, 1, mesh, color, sock);
3075 break;
3076 case 11: // Verified
3077 anim_move('x', 1, 1, mesh, color, sock);
3078 anim_move('z', 1, 3, mesh, color, sock);
3079 anim_move('x', 1, 3, mesh, color, sock);
3080 anim_move('y', 3, 3, mesh, color, sock);
3081 anim_move('x', 1, 3, mesh, color, sock);
3082 anim_move('y', 3, 1, mesh, color, sock);
3083 anim_move('x', 1, 1, mesh, color, sock);
3084 anim_move('z', 1, 3, mesh, color, sock);
3085 anim_move('x', 1, 1, mesh, color, sock);
3086 anim_move('z', 1, 3, mesh, color, sock);
3087 anim_move('x', 1, 3, mesh, color, sock);
3088 anim_move('y', 3, 3, mesh, color, sock);
3089 anim_move('x', 1, 3, mesh, color, sock);
3090 anim_move('y', 3, 1, mesh, color, sock);
3091 anim_move('x', 1, 1, mesh, color, sock);
3092 break;
3093 }
3094 }
3095}
3096
3097void
3099{
3100 if (logging_ > 1)
3101 {
3102 cout << "Entering solve_top_edges" << endl;
3103 }
3104 if (logging_ > 2)
3105 {
3106 print_state(cout);
3107 }
3108
3109 // Locate fourth edge in the top tier
3110 {
3111 int l4 = locate_edge(4);
3112 int i4 = max(l4,-1-l4);
3113 int o4 = (l4 >= 0) ? 0 : 1;
3114 if (logging_ > 1)
3115 {
3116 cout << "Location of 4-th edge: " << i4
3117 << " with orientation " << o4 << endl;
3118 }
3119 if (i4 < 12 && ((i4 < 4) ||
3120 (i4 > 4 && o4 == 0) ||
3121 (o4 == 1) ))
3122 {
3123 move_to_e4(i4, o4, mesh, color, sock);
3124 }
3125 }
3126
3127 // Locate fifth edge in the top tier
3128 {
3129 int l5 = locate_edge(5);
3130 int i5 = max(l5,-1-l5);
3131 int o5 = (l5 >= 0) ? 0 : 1;
3132 if (logging_ > 1)
3133 {
3134 cout << "Location of 5-th edge: " << i5
3135 << " with orientation " << o5 << endl;
3136 }
3137 if (i5 < 12 && ((i5 < 4) ||
3138 (i5 > 5 && o5 == 0) ||
3139 (i5 > 4 && o5 == 1) ))
3140 {
3141 move_to_e5(i5, o5, mesh, color, sock);
3142 }
3143 }
3144
3145 // Locate sixth edge in the top tier
3146 {
3147 int l6 = locate_edge(6);
3148 int i6 = max(l6,-1-l6);
3149 int o6 = (l6 >= 0) ? 0 : 1;
3150 if (logging_ > 1)
3151 {
3152 cout << "Location of 6-th edge: " << i6
3153 << " with orientation " << o6 << endl;
3154 }
3155 if (i6 < 12 && ((i6 < 4) ||
3156 (i6 > 6 && o6 == 0) ||
3157 (i6 > 5 && o6 == 1) ))
3158 {
3159 move_to_e6(i6, o6, mesh, color, sock);
3160 }
3161 }
3162
3163 // Locate seventh edge in the top tier
3164 {
3165 int l7 = locate_edge(7);
3166 int i7 = max(l7,-1-l7);
3167 int o7 = (l7 >= 0) ? 0 : 1;
3168 if (logging_ > 1)
3169 {
3170 cout << "Location of 7-th edge: " << i7
3171 << " with orientation " << o7 << endl;
3172 }
3173 if (i7 < 12 && ((i7 < 4) ||
3174 (i7 > 7 && o7 == 0) ||
3175 (i7 > 6 && o7 == 1) ))
3176 {
3177 move_to_e7(i7, o7, mesh, color, sock);
3178 }
3179 }
3180}
3181
3182void
3184{
3185 if (logging_ > 1)
3186 {
3187 cout << "Entering solve_mid_edges" << endl;
3188 }
3189 if (logging_ > 2)
3190 {
3191 print_state(cout);
3192 }
3193
3194 // Locate eighth edge
3195 {
3196 int l8 = locate_edge(8);
3197 int i8 = max(l8,-1-l8);
3198 int o8 = (l8 >= 0) ? 0 : 1;
3199 if (logging_ > 1)
3200 {
3201 cout << "Location of 8-th edge: " << i8
3202 << " with orientation " << o8 << endl;
3203 }
3204 if (i8 >= 4 && i8 < 8)
3205 {
3206 cout << "Moving edges from top tier to middle tier is not supported."
3207 << endl;
3208 }
3209 else if (i8 < 12 && ((i8 < 4) ||
3210 (i8 > 8 && o8 == 0) ||
3211 (i8 > 7 && o8 == 1) ))
3212 {
3213 move_to_e8(i8, o8, mesh, color, sock);
3214 }
3215 }
3216
3217 // Locate ninth edge
3218 {
3219 int l9 = locate_edge(9);
3220 int i9 = max(l9,-1-l9);
3221 int o9 = (l9 >= 0) ? 0 : 1;
3222 if (logging_ > 1)
3223 {
3224 cout << "Location of 9-th edge: " << i9
3225 << " with orientation " << o9 << endl;
3226 }
3227 if (i9 >= 4 && i9 < 8)
3228 {
3229 cout << "Moving edges from top tier to middle tier is not supported."
3230 << endl;
3231 }
3232 else if (i9 < 12 && ((i9 < 4) ||
3233 (i9 > 9 && o9 == 0) ||
3234 (i9 > 8 && o9 == 1) ))
3235 {
3236 move_to_e9(i9, o9, mesh, color, sock);
3237 }
3238 }
3239
3240 // Locate tenth edge
3241 {
3242 int l10 = locate_edge(10);
3243 int i10 = max(l10,-1-l10);
3244 int o10 = (l10 >= 0) ? 0 : 1;
3245 if (logging_ > 1)
3246 {
3247 cout << "Location of 10-th edge: " << i10
3248 << " with orientation " << o10 << endl;
3249 }
3250 if (i10 >= 4 && i10 < 8)
3251 {
3252 cout << "Moving edges from top tier to middle tier is not supported."
3253 << endl;
3254 }
3255 else if (i10 < 12 && ((i10 < 4) ||
3256 (i10 > 10 && o10 == 0) ||
3257 (i10 > 9 && o10 == 1) ))
3258 {
3259 move_to_e10(i10, o10, mesh, color, sock);
3260 }
3261 }
3262
3263 // Locate eleventh edge
3264 {
3265 int l11 = locate_edge(11);
3266 int i11 = max(l11,-1-l11);
3267 int o11 = (l11 >= 0) ? 0 : 1;
3268 if (logging_ > 1)
3269 {
3270 cout << "Location of 11-th edge: " << i11
3271 << " with orientation " << o11 << endl;
3272 }
3273 if (i11 >= 4 && i11 < 8)
3274 {
3275 cout << "Moving edges from top tier to middle tier is not supported."
3276 << endl;
3277 }
3278 else if (i11 < 12 && ((i11 < 4) ||
3279 (i11 > 11 && o11 == 0) ||
3280 (i11 > 10 && o11 == 1) ))
3281 {
3282 move_to_e11(i11, o11, mesh, color, sock);
3283 }
3284 }
3285}
3286
3287void
3289 int * c0, int * c1)
3290{
3291 if (logging_ > 1)
3292 {
3293 cout << "Entering swap_corners" << endl;
3294 }
3295
3296 if (c0 != NULL)
3297 {
3298 // Locate first incorrectly filled corner location
3299 int i0 = -1;
3300 for (int i=0; i<8; i++)
3301 {
3302 if ((rubik.corn_[3 * i] == c0[0] &&
3303 rubik.corn_[3 * i + 1] == c0[1] &&
3304 rubik.corn_[3 * i + 2] == c0[2]) ||
3305 (rubik.corn_[3 * i] == c0[1] &&
3306 rubik.corn_[3 * i + 1] == c0[2] &&
3307 rubik.corn_[3 * i + 2] == c0[0]) ||
3308 (rubik.corn_[3 * i] == c0[2] &&
3309 rubik.corn_[3 * i + 1] == c0[0] &&
3310 rubik.corn_[3 * i + 2] == c0[1]) ||
3311 (rubik.corn_[3 * i] == c0[2] &&
3312 rubik.corn_[3 * i + 1] == c0[1] &&
3313 rubik.corn_[3 * i + 2] == c0[0]) ||
3314 (rubik.corn_[3 * i] == c0[1] &&
3315 rubik.corn_[3 * i + 1] == c0[0] &&
3316 rubik.corn_[3 * i + 2] == c0[2]) ||
3317 (rubik.corn_[3 * i] == c0[0] &&
3318 rubik.corn_[3 * i + 1] == c0[2] &&
3319 rubik.corn_[3 * i + 2] == c0[1]))
3320 {
3321 i0 = i;
3322 break;
3323 }
3324 }
3325 if (logging_ > 1)
3326 {
3327 cout << "Location of c0 = {"<<c0[0]<<","<<c0[1]<<","<<c0[2]<<"}: "
3328 << i0 << endl;
3329 }
3330
3331 switch (i0)
3332 {
3333 case 0:
3334 swap_corners(mesh, color, sock, NULL, c1);
3335 break;
3336 case 1:
3337 case 2:
3338 case 3:
3339 anim_move('z', 1, i0, mesh, color, sock);
3340 swap_corners(mesh, color, sock, NULL, c1);
3341 anim_move('z', 1, 4-i0, mesh, color, sock);
3342 break;
3343 case 4:
3344 anim_move('x', 1, 3, mesh, color, sock);
3345 swap_corners(mesh, color, sock, NULL, c1);
3346 anim_move('x', 1, 1, mesh, color, sock);
3347 break;
3348 case 5:
3349 anim_move('y', 1, 2, mesh, color, sock);
3350 swap_corners(mesh, color, sock, NULL, c1);
3351 anim_move('y', 1, 2, mesh, color, sock);
3352 break;
3353 case 6:
3354 anim_move('z', 3, 2, mesh, color, sock);
3355 anim_move('x', 1, 3, mesh, color, sock);
3356 swap_corners(mesh, color, sock, NULL, c1);
3357 anim_move('x', 1, 1, mesh, color, sock);
3358 anim_move('z', 3, 2, mesh, color, sock);
3359 break;
3360 case 7:
3361 anim_move('x', 1, 2, mesh, color, sock);
3362 swap_corners(mesh, color, sock, NULL, c1);
3363 anim_move('x', 1, 2, mesh, color, sock);
3364 break;
3365 }
3366 }
3367 else if (c1 != NULL)
3368 {
3369 // Locate corner piece which belongs at i0
3370 int i1 = -1;
3371 for (int i=1; i<8; i++)
3372 {
3373 if ((rubik.corn_[3 * i] == c1[0] &&
3374 rubik.corn_[3 * i + 1] == c1[1] &&
3375 rubik.corn_[3 * i + 2] == c1[2]) ||
3376 (rubik.corn_[3 * i] == c1[1] &&
3377 rubik.corn_[3 * i + 1] == c1[2] &&
3378 rubik.corn_[3 * i + 2] == c1[0]) ||
3379 (rubik.corn_[3 * i] == c1[2] &&
3380 rubik.corn_[3 * i + 1] == c1[0] &&
3381 rubik.corn_[3 * i + 2] == c1[1]) ||
3382 (rubik.corn_[3 * i] == c1[2] &&
3383 rubik.corn_[3 * i + 1] == c1[1] &&
3384 rubik.corn_[3 * i + 2] == c1[0]) ||
3385 (rubik.corn_[3 * i] == c1[1] &&
3386 rubik.corn_[3 * i + 1] == c1[0] &&
3387 rubik.corn_[3 * i + 2] == c1[2]) ||
3388 (rubik.corn_[3 * i] == c1[0] &&
3389 rubik.corn_[3 * i + 1] == c1[2] &&
3390 rubik.corn_[3 * i + 2] == c1[1]))
3391 {
3392 i1 = i;
3393 break;
3394 }
3395 }
3396 if (logging_ > 1)
3397 {
3398 cout << "Location of piece belonging at " << 0 << " (c1) is "
3399 << i1 << endl;
3400 }
3401
3402 switch (i1)
3403 {
3404 case 1:
3405 swap_corners(mesh, color, sock, NULL, NULL);
3406 break;
3407 case 2:
3408 anim_move('x', 3, 1, mesh, color, sock);
3409 swap_corners(mesh, color, sock, NULL, NULL);
3410 anim_move('x', 3, 3, mesh, color, sock);
3411 break;
3412 case 3:
3413 anim_move('y', 3, 1, mesh, color, sock);
3414 anim_move('x', 3, 1, mesh, color, sock);
3415 swap_corners(mesh, color, sock, NULL, NULL);
3416 anim_move('x', 3, 3, mesh, color, sock);
3417 anim_move('y', 3, 3, mesh, color, sock);
3418 break;
3419 case 4:
3420 anim_move('z', 3, 3, mesh, color, sock);
3421 anim_move('x', 3, 3, mesh, color, sock);
3422 swap_corners(mesh, color, sock, NULL, NULL);
3423 anim_move('x', 3, 1, mesh, color, sock);
3424 anim_move('z', 3, 1, mesh, color, sock);
3425 break;
3426 case 5:
3427 anim_move('x', 3, 3, mesh, color, sock);
3428 swap_corners(mesh, color, sock, NULL, NULL);
3429 anim_move('x', 3, 1, mesh, color, sock);
3430 break;
3431 case 6:
3432 anim_move('x', 3, 2, mesh, color, sock);
3433 swap_corners(mesh, color, sock, NULL, NULL);
3434 anim_move('x', 3, 2, mesh, color, sock);
3435 break;
3436 case 7:
3437 anim_move('z', 3, 2, mesh, color, sock);
3438 anim_move('x', 3, 3, mesh, color, sock);
3439 swap_corners(mesh, color, sock, NULL, NULL);
3440 anim_move('x', 3, 1, mesh, color, sock);
3441 anim_move('z', 3, 2, mesh, color, sock);
3442 break;
3443 }
3444 }
3445 else
3446 {
3447 anim_move('x', 3, 3, mesh, color, sock);
3448 anim_move('z', 1, 1, mesh, color, sock);
3449 anim_move('x', 3, 1, mesh, color, sock);
3450 anim_move('y', 1, 3, mesh, color, sock);
3451 anim_move('z', 1, 3, mesh, color, sock);
3452 anim_move('y', 1, 1, mesh, color, sock);
3453 anim_move('x', 3, 3, mesh, color, sock);
3454 anim_move('z', 1, 3, mesh, color, sock);
3455 anim_move('x', 3, 1, mesh, color, sock);
3456 anim_move('z', 1, 2, mesh, color, sock);
3457 }
3458}
3459
3460void
3462{
3463 if (logging_ > 1)
3464 {
3465 cout << "Entering solve_corner_locations" << endl;
3466 }
3467 if (logging_ > 2)
3468 {
3469 print_state(cout);
3470 }
3471
3472 // Locate first incorrectly filled corner location
3473 int i0 = -1;
3474 for (int i=0; i<8; i++)
3475 {
3476 if (!((rubik.corn_[3 * i + 0] == corn_colors_[3 * i + 0] &&
3477 rubik.corn_[3 * i + 1] == corn_colors_[3 * i + 1] &&
3478 rubik.corn_[3 * i + 2] == corn_colors_[3 * i + 2]) ||
3479 (rubik.corn_[3 * i + 0] == corn_colors_[3 * i + 1] &&
3480 rubik.corn_[3 * i + 1] == corn_colors_[3 * i + 2] &&
3481 rubik.corn_[3 * i + 2] == corn_colors_[3 * i + 0]) ||
3482 (rubik.corn_[3 * i + 0] == corn_colors_[3 * i + 2] &&
3483 rubik.corn_[3 * i + 1] == corn_colors_[3 * i + 0] &&
3484 rubik.corn_[3 * i + 2] == corn_colors_[3 * i + 1]) ||
3485 (rubik.corn_[3 * i + 0] == corn_colors_[3 * i + 2] &&
3486 rubik.corn_[3 * i + 1] == corn_colors_[3 * i + 1] &&
3487 rubik.corn_[3 * i + 2] == corn_colors_[3 * i + 0]) ||
3488 (rubik.corn_[3 * i + 0] == corn_colors_[3 * i + 1] &&
3489 rubik.corn_[3 * i + 1] == corn_colors_[3 * i + 0] &&
3490 rubik.corn_[3 * i + 2] == corn_colors_[3 * i + 2]) ||
3491 (rubik.corn_[3 * i + 0] == corn_colors_[3 * i + 0] &&
3492 rubik.corn_[3 * i + 1] == corn_colors_[3 * i + 2] &&
3493 rubik.corn_[3 * i + 2] == corn_colors_[3 * i + 1])))
3494 {
3495 i0 = i;
3496 break;
3497 }
3498 }
3499 if (logging_ > 1)
3500 {
3501 cout << "First incorrectly filled corner location: " << i0 << endl;
3502 }
3503
3504 if (i0 < 0) { return; }
3505
3506 // Locate corner piece which belongs at i0
3507 int l1 = locate_corner(i0);
3508 int i1 = l1 % 8;
3509 if (logging_ > 1)
3510 {
3511 cout << "Location of piece belonging at " << i0 << " is " << i1 << endl;
3512 }
3513
3514 if (i1 < 0)
3515 {
3516 cout << "Invalid configuration of corners" << endl;
3517 return;
3518 }
3519
3520 int c0[3] = {rubik.corn_[3 * i0],
3521 rubik.corn_[3 * i0 + 1],
3522 rubik.corn_[3 * i0 + 2]
3523 };
3524 int c1[3] = {rubik.corn_[3 * i1],
3525 rubik.corn_[3 * i1 + 1],
3526 rubik.corn_[3 * i1 + 2]
3527 };
3528
3529 swap_corners(mesh, color, sock, c0, c1);
3530
3531 solve_corner_locations(mesh, color, sock);
3532}
3533
3534void
3536 socketstream & sock)
3537{
3538 if (logging_ > 1)
3539 {
3540 cout << "Entering solve_bot_corner_locations" << endl;
3541 }
3542 if (logging_ > 2)
3543 {
3544 print_state(cout);
3545 }
3546
3547 // Locate first corner in the bottom tier
3548 {
3549 int l0 = locate_corner(0);
3550 int i0 = l0 % 8;
3551 if (logging_ > 1)
3552 {
3553 cout << "Location of piece belonging at 0 is " << i0 << endl;
3554 }
3555 if (i0 != 0)
3556 {
3557 anim_move('z', 1, i0, mesh, color, sock);
3558 }
3559 }
3560
3561 // Locate second corner in bottom tier
3562 {
3563 int l1 = locate_corner(1);
3564 int i1 = l1 % 8;
3565 if (logging_ > 1)
3566 {
3567 cout << "Location of piece belonging at 1 is " << i1 << endl;
3568 }
3569
3570 if (i1 < 0)
3571 {
3572 cout << "Invalid configuration of corners" << endl;
3573 }
3574
3575 switch (i1)
3576 {
3577 case 2:
3578 anim_move('y', 3, 3, mesh, color, sock);
3579 anim_move('z', 1, 1, mesh, color, sock);
3580 anim_move('y', 3, 1, mesh, color, sock);
3581 anim_move('x', 3, 1, mesh, color, sock);
3582 anim_move('z', 1, 3, mesh, color, sock);
3583 anim_move('x', 3, 3, mesh, color, sock);
3584 anim_move('y', 3, 3, mesh, color, sock);
3585 anim_move('z', 1, 3, mesh, color, sock);
3586 anim_move('y', 3, 1, mesh, color, sock);
3587 anim_move('z', 1, 2, mesh, color, sock);
3588 break;
3589 case 3:
3590 anim_move('y', 3, 3, mesh, color, sock);
3591 anim_move('z', 1, 1, mesh, color, sock);
3592 anim_move('y', 3, 1, mesh, color, sock);
3593 anim_move('x', 3, 1, mesh, color, sock);
3594 anim_move('z', 1, 2, mesh, color, sock);
3595 anim_move('x', 3, 3, mesh, color, sock);
3596 anim_move('y', 3, 3, mesh, color, sock);
3597 anim_move('z', 1, 3, mesh, color, sock);
3598 anim_move('y', 3, 1, mesh, color, sock);
3599 anim_move('z', 1, 3, mesh, color, sock);
3600 break;
3601 }
3602 }
3603
3604 // Locate second corner in bottom tier
3605 {
3606 int l2 = locate_corner(2);
3607 int i2 = l2 % 8;
3608 if (logging_ > 1)
3609 {
3610 cout << "Location of piece belonging at 2 is " << i2 << endl;
3611 }
3612
3613 if (i2 < 0)
3614 {
3615 cout << "Invalid configuration of corners" << endl;
3616 }
3617
3618 if (i2 == 3)
3619 {
3620 anim_move('x', 1, 1, mesh, color, sock);
3621 anim_move('z', 1, 1, mesh, color, sock);
3622 anim_move('x', 1, 3, mesh, color, sock);
3623 anim_move('y', 3, 1, mesh, color, sock);
3624 anim_move('z', 1, 3, mesh, color, sock);
3625 anim_move('y', 3, 3, mesh, color, sock);
3626 anim_move('x', 1, 1, mesh, color, sock);
3627 anim_move('z', 1, 3, mesh, color, sock);
3628 anim_move('x', 1, 3, mesh, color, sock);
3629 anim_move('z', 1, 2, mesh, color, sock);
3630 }
3631 }
3632}
3633
3634void
3636 bool cw, int * c0, int * c1, int * c2)
3637{
3638 if (c0 != NULL)
3639 {
3640 // Locate corner corresponding to c0
3641 int i0 = -1;
3642 for (int i=0; i<8; i++)
3643 {
3644 if ((rubik.corn_[3 * i] == c0[0] &&
3645 rubik.corn_[3 * i + 1] == c0[1] &&
3646 rubik.corn_[3 * i + 2] == c0[2]) ||
3647 (rubik.corn_[3 * i] == c0[1] &&
3648 rubik.corn_[3 * i + 1] == c0[2] &&
3649 rubik.corn_[3 * i + 2] == c0[0]) ||
3650 (rubik.corn_[3 * i] == c0[2] &&
3651 rubik.corn_[3 * i + 1] == c0[0] &&
3652 rubik.corn_[3 * i + 2] == c0[1]) ||
3653 (rubik.corn_[3 * i] == c0[2] &&
3654 rubik.corn_[3 * i + 1] == c0[1] &&
3655 rubik.corn_[3 * i + 2] == c0[0]) ||
3656 (rubik.corn_[3 * i] == c0[1] &&
3657 rubik.corn_[3 * i + 1] == c0[0] &&
3658 rubik.corn_[3 * i + 2] == c0[2]) ||
3659 (rubik.corn_[3 * i] == c0[0] &&
3660 rubik.corn_[3 * i + 1] == c0[2] &&
3661 rubik.corn_[3 * i + 2] == c0[1]))
3662 {
3663 i0 = i;
3664 break;
3665 }
3666 }
3667 if (logging_ > 1)
3668 {
3669 cout << "Location of c0 = {"<<c0[0]<<","<<c0[1]<<","<<c0[2]<<"}: "
3670 << i0 << endl;
3671 }
3672
3673 switch (i0)
3674 {
3675 case 0:
3676 twist_corners(mesh, color, sock, cw, NULL, c1, c2);
3677 break;
3678 case 1:
3679 case 2:
3680 case 3:
3681 anim_move('z', 1, i0, mesh, color, sock);
3682 twist_corners(mesh, color, sock, cw, NULL, c1, c2);
3683 anim_move('z', 1, 4-i0, mesh, color, sock);
3684 break;
3685 case 4:
3686 anim_move('x', 1, 3, mesh, color, sock);
3687 twist_corners(mesh, color, sock, cw, NULL, c1, c2);
3688 anim_move('x', 1, 1, mesh, color, sock);
3689 break;
3690 case 5:
3691 anim_move('y', 1, 2, mesh, color, sock);
3692 twist_corners(mesh, color, sock, cw, NULL, c1, c2);
3693 anim_move('y', 1, 2, mesh, color, sock);
3694 break;
3695 case 6:
3696 anim_move('z', 3, 2, mesh, color, sock);
3697 anim_move('x', 1, 3, mesh, color, sock);
3698 twist_corners(mesh, color, sock, cw, NULL, c1, c2);
3699 anim_move('x', 1, 1, mesh, color, sock);
3700 anim_move('z', 3, 2, mesh, color, sock);
3701 break;
3702 case 7:
3703 anim_move('x', 1, 2, mesh, color, sock);
3704 twist_corners(mesh, color, sock, cw, NULL, c1, c2);
3705 anim_move('x', 1, 2, mesh, color, sock);
3706 break;
3707 }
3708
3709 }
3710 else if (c1 != NULL)
3711 {
3712 // Locate corner piece corresponding to c1
3713 int i1 = -1;
3714 for (int i=1; i<8; i++)
3715 {
3716 if ((rubik.corn_[3 * i] == c1[0] &&
3717 rubik.corn_[3 * i + 1] == c1[1] &&
3718 rubik.corn_[3 * i + 2] == c1[2]) ||
3719 (rubik.corn_[3 * i] == c1[1] &&
3720 rubik.corn_[3 * i + 1] == c1[2] &&
3721 rubik.corn_[3 * i + 2] == c1[0]) ||
3722 (rubik.corn_[3 * i] == c1[2] &&
3723 rubik.corn_[3 * i + 1] == c1[0] &&
3724 rubik.corn_[3 * i + 2] == c1[1]) ||
3725 (rubik.corn_[3 * i] == c1[2] &&
3726 rubik.corn_[3 * i + 1] == c1[1] &&
3727 rubik.corn_[3 * i + 2] == c1[0]) ||
3728 (rubik.corn_[3 * i] == c1[1] &&
3729 rubik.corn_[3 * i + 1] == c1[0] &&
3730 rubik.corn_[3 * i + 2] == c1[2]) ||
3731 (rubik.corn_[3 * i] == c1[0] &&
3732 rubik.corn_[3 * i + 1] == c1[2] &&
3733 rubik.corn_[3 * i + 2] == c1[1]))
3734 {
3735 i1 = i;
3736 break;
3737 }
3738 }
3739 if (logging_ > 1)
3740 {
3741 cout << "Location of c1 = {"<<c1[0]<<","<<c1[1]<<","<<c1[2]<<"}: "
3742 << i1 << endl;
3743 }
3744
3745 if (c2 != NULL)
3746 {
3747 switch (i1)
3748 {
3749 case 1:
3750 twist_corners(mesh, color, sock, cw, NULL, NULL, c2);
3751 break;
3752 case 2:
3753 anim_move('x', 3, 1, mesh, color, sock);
3754 twist_corners(mesh, color, sock, cw, NULL, NULL, c2);
3755 anim_move('x', 3, 3, mesh, color, sock);
3756 break;
3757 case 3:
3758 anim_move('y', 3, 1, mesh, color, sock);
3759 anim_move('x', 3, 1, mesh, color, sock);
3760 twist_corners(mesh, color, sock, cw, NULL, NULL, c2);
3761 anim_move('x', 3, 3, mesh, color, sock);
3762 anim_move('y', 3, 3, mesh, color, sock);
3763 break;
3764 case 4:
3765 anim_move('z', 3, 3, mesh, color, sock);
3766 anim_move('x', 3, 3, mesh, color, sock);
3767 twist_corners(mesh, color, sock, cw, NULL, NULL, c2);
3768 anim_move('x', 3, 1, mesh, color, sock);
3769 anim_move('z', 3, 1, mesh, color, sock);
3770 break;
3771 case 5:
3772 anim_move('x', 3, 3, mesh, color, sock);
3773 twist_corners(mesh, color, sock, cw, NULL, NULL, c2);
3774 anim_move('x', 3, 1, mesh, color, sock);
3775 break;
3776 case 6:
3777 anim_move('x', 3, 2, mesh, color, sock);
3778 twist_corners(mesh, color, sock, cw, NULL, NULL, c2);
3779 anim_move('x', 3, 2, mesh, color, sock);
3780 break;
3781 case 7:
3782 anim_move('z', 3, 2, mesh, color, sock);
3783 anim_move('x', 3, 3, mesh, color, sock);
3784 twist_corners(mesh, color, sock, cw, NULL, NULL, c2);
3785 anim_move('x', 3, 1, mesh, color, sock);
3786 anim_move('z', 3, 2, mesh, color, sock);
3787 break;
3788 }
3789 }
3790 else
3791 {
3792 switch (i1)
3793 {
3794 case 3:
3795 twist_corners(mesh, color, sock, cw, NULL, NULL, c2);
3796 break;
3797 case 2:
3798 anim_move('y', 3, 3, mesh, color, sock);
3799 twist_corners(mesh, color, sock, cw, NULL, NULL, c2);
3800 anim_move('y', 3, 1, mesh, color, sock);
3801 break;
3802 case 1:
3803 anim_move('x', 3, 3, mesh, color, sock);
3804 anim_move('y', 3, 3, mesh, color, sock);
3805 twist_corners(mesh, color, sock, cw, NULL, NULL, c2);
3806 anim_move('y', 3, 1, mesh, color, sock);
3807 anim_move('x', 3, 1, mesh, color, sock);
3808 break;
3809 case 4:
3810 anim_move('z', 3, 1, mesh, color, sock);
3811 anim_move('y', 3, 1, mesh, color, sock);
3812 twist_corners(mesh, color, sock, cw, NULL, NULL, c2);
3813 anim_move('y', 3, 3, mesh, color, sock);
3814 anim_move('z', 3, 3, mesh, color, sock);
3815 break;
3816 case 5:
3817 anim_move('z', 3, 2, mesh, color, sock);
3818 anim_move('y', 3, 1, mesh, color, sock);
3819 twist_corners(mesh, color, sock, cw, NULL, NULL, c2);
3820 anim_move('y', 3, 3, mesh, color, sock);
3821 anim_move('z', 3, 2, mesh, color, sock);
3822 break;
3823 case 6:
3824 anim_move('y', 3, 2, mesh, color, sock);
3825 twist_corners(mesh, color, sock, cw, NULL, NULL, c2);
3826 anim_move('y', 3, 2, mesh, color, sock);
3827 break;
3828 case 7:
3829 anim_move('y', 3, 1, mesh, color, sock);
3830 twist_corners(mesh, color, sock, cw, NULL, NULL, c2);
3831 anim_move('y', 3, 3, mesh, color, sock);
3832 break;
3833 }
3834 }
3835 }
3836 else if (c2 != NULL)
3837 {
3838 // Locate corner piece corresponding to c2
3839 int i2 = -1;
3840 for (int i=2; i<8; i++)
3841 {
3842 if ((rubik.corn_[3 * i] == c2[0] &&
3843 rubik.corn_[3 * i + 1] == c2[1] &&
3844 rubik.corn_[3 * i + 2] == c2[2]) ||
3845 (rubik.corn_[3 * i] == c2[1] &&
3846 rubik.corn_[3 * i + 1] == c2[2] &&
3847 rubik.corn_[3 * i + 2] == c2[0]) ||
3848 (rubik.corn_[3 * i] == c2[2] &&
3849 rubik.corn_[3 * i + 1] == c2[0] &&
3850 rubik.corn_[3 * i + 2] == c2[1]) ||
3851 (rubik.corn_[3 * i] == c2[2] &&
3852 rubik.corn_[3 * i + 1] == c2[1] &&
3853 rubik.corn_[3 * i + 2] == c2[0]) ||
3854 (rubik.corn_[3 * i] == c2[1] &&
3855 rubik.corn_[3 * i + 1] == c2[0] &&
3856 rubik.corn_[3 * i + 2] == c2[2]) ||
3857 (rubik.corn_[3 * i] == c2[0] &&
3858 rubik.corn_[3 * i + 1] == c2[2] &&
3859 rubik.corn_[3 * i + 2] == c2[1]))
3860 {
3861 i2 = i;
3862 break;
3863 }
3864 }
3865 if (logging_ > 1)
3866 {
3867 cout << "Location of c2 = {"<<c2[0]<<","<<c2[1]<<","<<c2[2]<<"}: "
3868 << i2 << endl;
3869 }
3870
3871 switch (i2)
3872 {
3873 case 2:
3874 twist_corners(mesh, color, sock, cw, NULL, NULL, NULL);
3875 break;
3876 case 3:
3877 anim_move('y', 3, 1, mesh, color, sock);
3878 twist_corners(mesh, color, sock, cw, NULL, NULL, NULL);
3879 anim_move('y', 3, 3, mesh, color, sock);
3880 break;
3881 case 4:
3882 anim_move('z', 3, 2, mesh, color, sock);
3883 anim_move('y', 3, 3, mesh, color, sock);
3884 twist_corners(mesh, color, sock, cw, NULL, NULL, NULL);
3885 anim_move('y', 3, 1, mesh, color, sock);
3886 anim_move('z', 3, 2, mesh, color, sock);
3887 break;
3888 case 5:
3889 anim_move('z', 3, 3, mesh, color, sock);
3890 anim_move('y', 3, 3, mesh, color, sock);
3891 twist_corners(mesh, color, sock, cw, NULL, NULL, NULL);
3892 anim_move('y', 3, 1, mesh, color, sock);
3893 anim_move('z', 3, 1, mesh, color, sock);
3894 break;
3895 case 6:
3896 anim_move('y', 3, 3, mesh, color, sock);
3897 twist_corners(mesh, color, sock, cw, NULL, NULL, NULL);
3898 anim_move('y', 3, 1, mesh, color, sock);
3899 break;
3900 case 7:
3901 anim_move('y', 3, 2, mesh, color, sock);
3902 twist_corners(mesh, color, sock, cw, NULL, NULL, NULL);
3903 anim_move('y', 3, 2, mesh, color, sock);
3904 break;
3905 }
3906 }
3907 else
3908 {
3909 if (cw)
3910 {
3911 if (logging_ > 1)
3912 {
3913 cout << "twist_corners performing clockwise twist" << endl;
3914 }
3915 anim_move('x', 3, 1, mesh, color, sock);
3916 anim_move('z', 1, 3, mesh, color, sock);
3917 anim_move('x', 3, 3, mesh, color, sock);
3918 anim_move('z', 1, 3, mesh, color, sock);
3919 anim_move('x', 3, 1, mesh, color, sock);
3920 anim_move('z', 1, 2, mesh, color, sock);
3921 anim_move('x', 3, 3, mesh, color, sock);
3922 anim_move('z', 1, 2, mesh, color, sock);
3923 }
3924 else
3925 {
3926 if (logging_ > 1)
3927 {
3928 cout << "twist_corners performing counter-clockwise twist" << endl;
3929 }
3930 anim_move('y', 1, 1, mesh, color, sock);
3931 anim_move('z', 1, 1, mesh, color, sock);
3932 anim_move('y', 1, 3, mesh, color, sock);
3933 anim_move('z', 1, 1, mesh, color, sock);
3934 anim_move('y', 1, 1, mesh, color, sock);
3935 anim_move('z', 1, 2, mesh, color, sock);
3936 anim_move('y', 1, 3, mesh, color, sock);
3937 anim_move('z', 1, 2, mesh, color, sock);
3938 }
3939 }
3940}
3941
3942void
3944 socketstream & sock)
3945{
3946 if (logging_ > 1)
3947 {
3948 cout << "Entering solve_corner_orientations" << endl;
3949 }
3950 if (logging_ > 2)
3951 {
3952 print_state(cout);
3953 }
3954
3955 // Locate first incorrectly oriented corner
3956 int i0 = -1;
3957 bool cw = true;
3958 for (int i=0; i<8; i++)
3959 {
3960 if (rubik.corn_[3 * i + 0] != corn_colors_[3 * i + 0])
3961 {
3962 i0 = i;
3963 switch (i0)
3964 {
3965 case 0:
3966 case 2:
3967 case 5:
3968 case 7:
3969 cw = rubik.corn_[3 * i0 + 0] == corn_colors_[3 * i0 + 1];
3970 break;
3971 case 1:
3972 case 3:
3973 case 4:
3974 case 6:
3975 cw = rubik.corn_[3 * i0 + 0] == corn_colors_[3 * i0 + 2];
3976 break;
3977 }
3978 break;
3979 }
3980 }
3981
3982 if (i0 < 0) { return; }
3983
3984 if (logging_ > 1)
3985 {
3986 cout << "First incorrectly oriented corner: " << i0 << endl;
3987 }
3988
3989 // Locate second incorrectly oriented corner
3990 int i1 = -1;
3991 for (int i=i0+1; i<8; i++)
3992 {
3993 if (rubik.corn_[3 * i + 0] != corn_colors_[3 * i + 0])
3994 {
3995 i1 = i;
3996 break;
3997 }
3998 }
3999 if (logging_ > 1)
4000 {
4001 cout << "Second incorrectly oriented corner: " << i1 << endl;
4002 }
4003
4004 // Locate third incorrectly oriented corner (if such exists)
4005 int i2 = -1;
4006 // int i3 = -1;
4007 for (int i=i1+1; i<8; i++)
4008 {
4009 if (rubik.corn_[3 * i + 0] != corn_colors_[3 * i + 0])
4010 {
4011 i2 = i;
4012 break;
4013 }
4014 }
4015 if (i2 > 0)
4016 {
4017 if (logging_ > 1)
4018 {
4019 cout << "Third incorrectly oriented corner: " << i2 << endl;
4020 }
4021
4022 // Three incorrectly oriented corners were found
4023 int c0[3] = {rubik.corn_[3 * i0],
4024 rubik.corn_[3 * i0 + 1],
4025 rubik.corn_[3 * i0 + 2]
4026 };
4027 int c1[3] = {rubik.corn_[3 * i1],
4028 rubik.corn_[3 * i1 + 1],
4029 rubik.corn_[3 * i1 + 2]
4030 };
4031 int c2[3] = {rubik.corn_[3 * i2],
4032 rubik.corn_[3 * i2 + 1],
4033 rubik.corn_[3 * i2 + 2]
4034 };
4035
4036 twist_corners(mesh, color, sock, cw, c0, c1, c2);
4037 }
4038 else
4039 {
4040 // Two incorrectly oriented corners were found
4041 int c0[3] = {rubik.corn_[3 * i0],
4042 rubik.corn_[3 * i0 + 1],
4043 rubik.corn_[3 * i0 + 2]
4044 };
4045 int c1[3] = {rubik.corn_[3 * i1],
4046 rubik.corn_[3 * i1 + 1],
4047 rubik.corn_[3 * i1 + 2]
4048 };
4049 twist_corners(mesh, color, sock, cw, c0, c1);
4050 }
4051
4052 solve_corner_orientations(mesh, color, sock);
4053}
4054
4055void
4057 int * e0, int * e1, int * e2)
4058{
4059 if (logging_ > 1)
4060 {
4061 cout << "Entering permute_edges" << endl;
4062 }
4063
4064 if (e0 != NULL)
4065 {
4066 // Locate first incorrectly filled edge location
4067 int i0 = -1;
4068 for (int i=0; i<12; i++)
4069 {
4070 if ((rubik.edge_[2 * i] == e0[0] &&
4071 rubik.edge_[2 * i + 1] == e0[1]) ||
4072 (rubik.edge_[2 * i] == e0[1] &&
4073 rubik.edge_[2 * i + 1] == e0[0]))
4074 {
4075 i0 = i;
4076 break;
4077 }
4078 }
4079 if (logging_ > 1)
4080 {
4081 cout << "Location of e0 = {"<<e0[0]<<","<<e0[1]<<"}: " << i0 << endl;
4082 }
4083
4084 switch (i0)
4085 {
4086 case 0:
4087 permute_edges(mesh, color, sock, NULL, e1, e2);
4088 break;
4089 case 1:
4090 case 2:
4091 case 3:
4092 anim_move('z', 1, i0, mesh, color, sock);
4093 permute_edges(mesh, color, sock, NULL, e1, e2);
4094 anim_move('z', 1, 4-i0, mesh, color, sock);
4095 break;
4096 case 4:
4097 anim_move('x', 2, 3, mesh, color, sock);
4098 permute_edges(mesh, color, sock, NULL, e1, e2);
4099 anim_move('x', 2, 1, mesh, color, sock);
4100 break;
4101 case 5:
4102 anim_move('y', 2, 3, mesh, color, sock);
4103 permute_edges(mesh, color, sock, NULL, e1, e2);
4104 anim_move('y', 2, 1, mesh, color, sock);
4105 break;
4106 case 6:
4107 anim_move('x', 2, 2, mesh, color, sock);
4108 permute_edges(mesh, color, sock, NULL, e1, e2);
4109 anim_move('x', 2, 2, mesh, color, sock);
4110 break;
4111 case 7:
4112 anim_move('y', 2, 1, mesh, color, sock);
4113 permute_edges(mesh, color, sock, NULL, e1, e2);
4114 anim_move('y', 2, 3, mesh, color, sock);
4115 break;
4116 case 8:
4117 anim_move('y', 1, 1, mesh, color, sock);
4118 permute_edges(mesh, color, sock, NULL, e1, e2);
4119 anim_move('y', 1, 3, mesh, color, sock);
4120 break;
4121 case 9:
4122 anim_move('y', 1, 3, mesh, color, sock);
4123 permute_edges(mesh, color, sock, NULL, e1, e2);
4124 anim_move('y', 1, 1, mesh, color, sock);
4125 break;
4126 case 10:
4127 anim_move('x', 3, 1, mesh, color, sock);
4128 permute_edges(mesh, color, sock, NULL, e1, e2);
4129 anim_move('x', 3, 3, mesh, color, sock);
4130 break;
4131 case 11:
4132 anim_move('x', 1, 1, mesh, color, sock);
4133 permute_edges(mesh, color, sock, NULL, e1, e2);
4134 anim_move('x', 1, 3, mesh, color, sock);
4135 break;
4136 }
4137 }
4138 else if (e1 != NULL)
4139 {
4140 // Locate edge piece which belongs at e0
4141 int i1 = -1;
4142 for (int i=1; i<12; i++)
4143 {
4144 if ((rubik.edge_[2 * i] == e1[0] &&
4145 rubik.edge_[2 * i + 1] == e1[1]) ||
4146 (rubik.edge_[2 * i] == e1[1] &&
4147 rubik.edge_[2 * i + 1] == e1[0]))
4148 {
4149 i1 = i;
4150 break;
4151 }
4152 }
4153 if (logging_ > 1)
4154 {
4155 cout << "Location of piece belonging at " << 0 << " (e1) is "
4156 << i1 << endl;
4157 }
4158
4159 switch (i1)
4160 {
4161 case 1:
4162 permute_edges(mesh, color, sock, NULL, NULL, e2);
4163 break;
4164 case 2:
4165 case 3:
4166 anim_move('y', 1, 1, mesh, color, sock);
4167 anim_move('z', 1, i1-1, mesh, color, sock);
4168 anim_move('y', 1, 3, mesh, color, sock);
4169 permute_edges(mesh, color, sock, NULL, NULL, e2);
4170 anim_move('y', 1, 1, mesh, color, sock);
4171 anim_move('z', 1, 5-i1, mesh, color, sock);
4172 anim_move('y', 1, 3, mesh, color, sock);
4173 break;
4174 case 4:
4175 case 5:
4176 case 6:
4177 case 7:
4178 anim_move('z', 3, (i1-1)%4, mesh, color, sock);
4179 anim_move('x', 3, 2, mesh, color, sock);
4180 permute_edges(mesh, color, sock, NULL, NULL, e2);
4181 anim_move('x', 3, 2, mesh, color, sock);
4182 anim_move('z', 3, (9-i1)%4, mesh, color, sock);
4183 break;
4184 case 8:
4185 case 9:
4186 case 10:
4187 case 11:
4188 anim_move('z', 2, (i1-5)%4, mesh, color, sock);
4189 anim_move('x', 3, 3, mesh, color, sock);
4190 permute_edges(mesh, color, sock, NULL, NULL, e2);
4191 anim_move('x', 3, 1, mesh, color, sock);
4192 anim_move('z', 2, (13-i1)%4, mesh, color, sock);
4193 break;
4194 }
4195 }
4196 else if (e2 != NULL)
4197 {
4198 // Locate a third incorrect edge
4199 int i2 = -1;
4200 for (int i=2; i<12; i++)
4201 {
4202 if ((rubik.edge_[2 * i] == e2[0] &&
4203 rubik.edge_[2 * i + 1] == e2[1]) ||
4204 (rubik.edge_[2 * i] == e2[1] &&
4205 rubik.edge_[2 * i + 1] == e2[0]))
4206 {
4207 i2 = i;
4208 break;
4209 }
4210 }
4211 if (logging_ > 1)
4212 {
4213 cout << "Location of e2: " << i2 << endl;
4214 }
4215
4216 switch (i2)
4217 {
4218 case 2:
4219 permute_edges(mesh, color, sock, NULL, NULL, NULL);
4220 break;
4221 case 3:
4222 anim_move('x', 1, 3, mesh, color, sock);
4223 anim_move('y', 3, 1, mesh, color, sock);
4224 permute_edges(mesh, color, sock, NULL, NULL, NULL);
4225 anim_move('y', 3, 3, mesh, color, sock);
4226 anim_move('x', 1, 1, mesh, color, sock);
4227 break;
4228 case 4:
4229 case 5:
4230 case 6:
4231 case 7:
4232 anim_move('z', 3, (i2-2)%4, mesh, color, sock);
4233 anim_move('y', 3, 2, mesh, color, sock);
4234 permute_edges(mesh, color, sock, NULL, NULL, NULL);
4235 anim_move('y', 3, 2, mesh, color, sock);
4236 anim_move('z', 3, (10-i2)%4, mesh, color, sock);
4237 break;
4238 case 8:
4239 case 9:
4240 case 10:
4241 case 11:
4242 anim_move('z', 2, (i2-6)%4, mesh, color, sock);
4243 anim_move('y', 3, 3, mesh, color, sock);
4244 permute_edges(mesh, color, sock, NULL, NULL, NULL);
4245 anim_move('y', 3, 1, mesh, color, sock);
4246 anim_move('z', 2, (14-i2)%4, mesh, color, sock);
4247 break;
4248 }
4249 }
4250 else
4251 {
4252 permute_edges(mesh, color, sock, true);
4253 }
4254}
4255
4256void
4257permute_edges(Mesh & mesh, GridFunction & color, socketstream & sock, bool cw)
4258{
4259 if (cw)
4260 {
4261 anim_move('y', 2, 1, mesh, color, sock);
4262 anim_move('z', 1, 1, mesh, color, sock);
4263 anim_move('y', 2, 3, mesh, color, sock);
4264 anim_move('z', 1, 2, mesh, color, sock);
4265 anim_move('y', 2, 1, mesh, color, sock);
4266 anim_move('z', 1, 1, mesh, color, sock);
4267 anim_move('y', 2, 3, mesh, color, sock);
4268 }
4269 else
4270 {
4271 anim_move('y', 2, 1, mesh, color, sock);
4272 anim_move('z', 1, 3, mesh, color, sock);
4273 anim_move('y', 2, 3, mesh, color, sock);
4274 anim_move('z', 1, 2, mesh, color, sock);
4275 anim_move('y', 2, 1, mesh, color, sock);
4276 anim_move('z', 1, 3, mesh, color, sock);
4277 anim_move('y', 2, 3, mesh, color, sock);
4278 }
4279}
4280
4281void
4283{
4284 if (logging_ > 1)
4285 {
4286 cout << "Entering solve_edge_locations" << endl;
4287 }
4288 if (logging_ > 2)
4289 {
4290 print_state(cout);
4291 }
4292
4293 // Locate first incorrectly filled edge location
4294 int i0 = -1;
4295 for (int i=0; i<12; i++)
4296 {
4297 if (!((rubik.edge_[2 * i] == edge_colors_[2 * i] &&
4298 rubik.edge_[2 * i + 1] == edge_colors_[2 * i + 1]) ||
4299 (rubik.edge_[2 * i] == edge_colors_[2 * i + 1] &&
4300 rubik.edge_[2 * i + 1] == edge_colors_[2 * i])))
4301 {
4302 i0 = i;
4303 break;
4304 }
4305 }
4306 if (logging_ > 1)
4307 {
4308 cout << "First incorrectly filled edge location: " << i0 << endl;
4309 }
4310
4311 if (i0 < 0) { return; }
4312
4313 // Locate edge piece which belongs at e0
4314 int i1 = locate_edge(i0);
4315 if (i1 < 0 ) { i1 = -1 - i1; }
4316 if (logging_ > 1)
4317 {
4318 cout << "Location of piece belonging at " << i0 << " is " << i1 << endl;
4319 }
4320
4321 // Locate a third incorrect edge
4322 int i2 = -1;
4323 for (int i=i0+1; i<12; i++)
4324 {
4325 if (i == i1) { continue; }
4326 if (!((rubik.edge_[2 * i + 0] == edge_colors_[2 * i + 0] &&
4327 rubik.edge_[2 * i + 1] == edge_colors_[2 * i + 1]) ||
4328 (rubik.edge_[2 * i + 0] == edge_colors_[2 * i + 1] &&
4329 rubik.edge_[2 * i + 1] == edge_colors_[2 * i + 0])))
4330 {
4331 i2 = i;
4332 break;
4333 }
4334 }
4335 if (logging_ > 1)
4336 {
4337 cout << "Another incorrectly filled edge location: " << i2 << endl;
4338 }
4339
4340 if (i1 < 0 || i2 <0)
4341 {
4342 cout << "Invalid configuration of edges" << endl;
4343 return;
4344 }
4345
4346 int e0[2] = {rubik.edge_[2 * i0], rubik.edge_[2 * i0 + 1]};
4347 int e1[2] = {rubik.edge_[2 * i1], rubik.edge_[2 * i1 + 1]};
4348 int e2[2] = {rubik.edge_[2 * i2], rubik.edge_[2 * i2 + 1]};
4349
4350 permute_edges(mesh, color, sock, e0, e1, e2);
4351
4352 solve_edge_locations(mesh, color, sock);
4353}
4354
4355void
4357 int n, int * e0, int * e1, int * e2, int * e3)
4358{
4359 if (n == 2)
4360 {
4361 if (e0 != NULL)
4362 {
4363 // Locate first incorrectly oriented edge
4364 int i0 = -1;
4365 for (int i=0; i<12; i++)
4366 {
4367 if ((rubik.edge_[2 * i] == e0[0] &&
4368 rubik.edge_[2 * i + 1] == e0[1]) ||
4369 (rubik.edge_[2 * i] == e0[1] &&
4370 rubik.edge_[2 * i + 1] == e0[0]))
4371 {
4372 i0 = i;
4373 break;
4374 }
4375 }
4376 if (logging_ > 1)
4377 {
4378 cout << "Location of e0 = {"<<e0[0]<<","<<e0[1]<<"}: " << i0 << endl;
4379 }
4380
4381 switch (i0)
4382 {
4383 case 0:
4384 flip_edges(mesh, color, sock, 2, NULL, e1);
4385 break;
4386 case 1:
4387 case 2:
4388 case 3:
4389 anim_move('z', 1, i0, mesh, color, sock);
4390 flip_edges(mesh, color, sock, 2, NULL, e1);
4391 anim_move('z', 1, 4-i0, mesh, color, sock);
4392 break;
4393 case 4:
4394 anim_move('x', 2, 3, mesh, color, sock);
4395 flip_edges(mesh, color, sock, 2, NULL, e1);
4396 anim_move('x', 2, 1, mesh, color, sock);
4397 break;
4398 case 5:
4399 anim_move('y', 2, 3, mesh, color, sock);
4400 flip_edges(mesh, color, sock, 2, NULL, e1);
4401 anim_move('y', 2, 1, mesh, color, sock);
4402 break;
4403 case 6:
4404 anim_move('x', 2, 2, mesh, color, sock);
4405 flip_edges(mesh, color, sock, 2, NULL, e1);
4406 anim_move('x', 2, 2, mesh, color, sock);
4407 break;
4408 case 7:
4409 anim_move('y', 2, 1, mesh, color, sock);
4410 flip_edges(mesh, color, sock, 2, NULL, e1);
4411 anim_move('y', 2, 3, mesh, color, sock);
4412 break;
4413 case 8:
4414 anim_move('y', 1, 1, mesh, color, sock);
4415 flip_edges(mesh, color, sock, 2, NULL, e1);
4416 anim_move('y', 1, 3, mesh, color, sock);
4417 break;
4418 case 9:
4419 anim_move('y', 1, 3, mesh, color, sock);
4420 flip_edges(mesh, color, sock, 2, NULL, e1);
4421 anim_move('y', 1, 1, mesh, color, sock);
4422 break;
4423 case 10:
4424 anim_move('x', 3, 1, mesh, color, sock);
4425 flip_edges(mesh, color, sock, 2, NULL, e1);
4426 anim_move('x', 3, 3, mesh, color, sock);
4427 break;
4428 case 11:
4429 anim_move('x', 1, 1, mesh, color, sock);
4430 flip_edges(mesh, color, sock, 2, NULL, e1);
4431 anim_move('x', 1, 3, mesh, color, sock);
4432 break;
4433 }
4434 }
4435 else if (e1 != NULL)
4436 {
4437 // Locate second incorrectly oriented edge
4438 int i1 = -1;
4439 for (int i=1; i<12; i++)
4440 {
4441 if ((rubik.edge_[2 * i] == e1[0] &&
4442 rubik.edge_[2 * i + 1] == e1[1]) ||
4443 (rubik.edge_[2 * i] == e1[1] &&
4444 rubik.edge_[2 * i + 1] == e1[0]))
4445 {
4446 i1 = i;
4447 break;
4448 }
4449 }
4450 if (logging_ > 1)
4451 {
4452 cout << "Location of e1: " << i1 << endl;
4453 }
4454
4455 switch (i1)
4456 {
4457 case 1:
4458 anim_move('x', 3, 3, mesh, color, sock);
4459 anim_move('y', 3, 3, mesh, color, sock);
4460 flip_edges(mesh, color, sock, 2, NULL, NULL);
4461 anim_move('y', 3, 1, mesh, color, sock);
4462 anim_move('x', 3, 1, mesh, color, sock);
4463 break;
4464 case 2:
4465 flip_edges(mesh, color, sock, 2, NULL, NULL);
4466 break;
4467 case 3:
4468 anim_move('x', 1, 3, mesh, color, sock);
4469 anim_move('y', 3, 1, mesh, color, sock);
4470 flip_edges(mesh, color, sock, 2, NULL, NULL);
4471 anim_move('y', 3, 3, mesh, color, sock);
4472 anim_move('x', 1, 1, mesh, color, sock);
4473 break;
4474 case 4:
4475 case 5:
4476 case 6:
4477 case 7:
4478 anim_move('z', 3, (i1-2)%4, mesh, color, sock);
4479 anim_move('y', 3, 2, mesh, color, sock);
4480 flip_edges(mesh, color, sock, 2, NULL, NULL);
4481 anim_move('y', 3, 2, mesh, color, sock);
4482 anim_move('z', 3, (10-i1)%4, mesh, color, sock);
4483 break;
4484 case 8:
4485 case 9:
4486 case 10:
4487 case 11:
4488 anim_move('z', 2, (i1-6)%4, mesh, color, sock);
4489 anim_move('y', 3, 3, mesh, color, sock);
4490 flip_edges(mesh, color, sock, 2, NULL, NULL);
4491 anim_move('y', 3, 1, mesh, color, sock);
4492 anim_move('z', 2, (14-i1)%4, mesh, color, sock);
4493 break;
4494 }
4495 }
4496 else
4497 {
4498 anim_move('x', 2, 3, mesh, color, sock);
4499 anim_move('z', 1, 3, mesh, color, sock);
4500 anim_move('x', 2, 1, mesh, color, sock);
4501 anim_move('z', 1, 3, mesh, color, sock);
4502 anim_move('x', 2, 3, mesh, color, sock);
4503 anim_move('z', 1, 3, mesh, color, sock);
4504 anim_move('x', 2, 1, mesh, color, sock);
4505 anim_move('z', 1, 3, mesh, color, sock);
4506 anim_move('x', 2, 3, mesh, color, sock);
4507 anim_move('z', 1, 2, mesh, color, sock);
4508 anim_move('x', 2, 1, mesh, color, sock);
4509 anim_move('z', 1, 3, mesh, color, sock);
4510 anim_move('x', 2, 3, mesh, color, sock);
4511 anim_move('z', 1, 3, mesh, color, sock);
4512 anim_move('x', 2, 1, mesh, color, sock);
4513 anim_move('z', 1, 3, mesh, color, sock);
4514 anim_move('x', 2, 3, mesh, color, sock);
4515 anim_move('z', 1, 3, mesh, color, sock);
4516 anim_move('x', 2, 1, mesh, color, sock);
4517 anim_move('z', 1, 2, mesh, color, sock);
4518 }
4519 }
4520 else if (n == 4)
4521 {
4522 if (e0 != NULL)
4523 {
4524 // Locate first incorrectly oriented edge
4525 int i0 = -1;
4526 for (int i=0; i<12; i++)
4527 {
4528 if ((rubik.edge_[2 * i] == e0[0] &&
4529 rubik.edge_[2 * i + 1] == e0[1]) ||
4530 (rubik.edge_[2 * i] == e0[1] &&
4531 rubik.edge_[2 * i + 1] == e0[0]))
4532 {
4533 i0 = i;
4534 break;
4535 }
4536 }
4537 if (logging_ > 1)
4538 {
4539 cout << "Location of e0 = {"<<e0[0]<<","<<e0[1]<<"}: " << i0 << endl;
4540 }
4541
4542 switch (i0)
4543 {
4544 case 0:
4545 flip_edges(mesh, color, sock, 4, NULL, e1, e2, e3);
4546 break;
4547 case 1:
4548 case 2:
4549 case 3:
4550 anim_move('z', 1, i0, mesh, color, sock);
4551 flip_edges(mesh, color, sock, 4, NULL, e1, e2, e3);
4552 anim_move('z', 1, 4-i0, mesh, color, sock);
4553 break;
4554 case 4:
4555 anim_move('x', 2, 3, mesh, color, sock);
4556 flip_edges(mesh, color, sock, 4, NULL, e1, e2, e3);
4557 anim_move('x', 2, 1, mesh, color, sock);
4558 break;
4559 case 5:
4560 anim_move('y', 2, 3, mesh, color, sock);
4561 flip_edges(mesh, color, sock, 4, NULL, e1, e2, e3);
4562 anim_move('y', 2, 1, mesh, color, sock);
4563 break;
4564 case 6:
4565 anim_move('x', 2, 2, mesh, color, sock);
4566 flip_edges(mesh, color, sock, 4, NULL, e1, e2, e3);
4567 anim_move('x', 2, 2, mesh, color, sock);
4568 break;
4569 case 7:
4570 anim_move('y', 2, 1, mesh, color, sock);
4571 flip_edges(mesh, color, sock, 4, NULL, e1, e2, e3);
4572 anim_move('y', 2, 3, mesh, color, sock);
4573 break;
4574 case 8:
4575 anim_move('y', 1, 1, mesh, color, sock);
4576 flip_edges(mesh, color, sock, 4, NULL, e1, e2, e3);
4577 anim_move('y', 1, 3, mesh, color, sock);
4578 break;
4579 case 9:
4580 anim_move('y', 1, 3, mesh, color, sock);
4581 flip_edges(mesh, color, sock, 4, NULL, e1, e2, e3);
4582 anim_move('y', 1, 1, mesh, color, sock);
4583 break;
4584 case 10:
4585 anim_move('x', 3, 1, mesh, color, sock);
4586 flip_edges(mesh, color, sock, 4, NULL, e1, e2, e3);
4587 anim_move('x', 3, 3, mesh, color, sock);
4588 break;
4589 case 11:
4590 anim_move('x', 1, 1, mesh, color, sock);
4591 flip_edges(mesh, color, sock, 4, NULL, e1, e2, e3);
4592 anim_move('x', 1, 3, mesh, color, sock);
4593 break;
4594 }
4595 }
4596 else if (e1 != NULL)
4597 {
4598 // Locate second incorrectly oriented edge
4599 int i1 = -1;
4600 for (int i=1; i<12; i++)
4601 {
4602 if ((rubik.edge_[2 * i] == e1[0] &&
4603 rubik.edge_[2 * i + 1] == e1[1]) ||
4604 (rubik.edge_[2 * i] == e1[1] &&
4605 rubik.edge_[2 * i + 1] == e1[0]))
4606 {
4607 i1 = i;
4608 break;
4609 }
4610 }
4611 if (logging_ > 1)
4612 {
4613 cout << "Location of e1: " << i1 << endl;
4614 }
4615
4616 switch (i1)
4617 {
4618 case 1:
4619 flip_edges(mesh, color, sock, 4, NULL, NULL, e2, e3);
4620 break;
4621 case 2:
4622 anim_move('y', 3, 1, mesh, color, sock);
4623 anim_move('x', 3, 1, mesh, color, sock);
4624 flip_edges(mesh, color, sock, 4, NULL, NULL, e2, e3);
4625 anim_move('x', 3, 3, mesh, color, sock);
4626 anim_move('y', 3, 3, mesh, color, sock);
4627 break;
4628 case 3:
4629 anim_move('y', 2, 1, mesh, color, sock);
4630 flip_edges(mesh, color, sock, 4, NULL, NULL, e2, e3);
4631 anim_move('y', 2, 3, mesh, color, sock);
4632 break;
4633 case 4:
4634 case 5:
4635 case 6:
4636 case 7:
4637 anim_move('z', 3, (i1-1)%4, mesh, color, sock);
4638 anim_move('x', 3, 2, mesh, color, sock);
4639 flip_edges(mesh, color, sock, 4, NULL, NULL, e2, e3);
4640 anim_move('x', 3, 2, mesh, color, sock);
4641 anim_move('z', 3, (9-i1)%4, mesh, color, sock);
4642 break;
4643 case 8:
4644 case 9:
4645 case 10:
4646 case 11:
4647 anim_move('z', 2, (i1-5)%4, mesh, color, sock);
4648 anim_move('x', 3, 3, mesh, color, sock);
4649 flip_edges(mesh, color, sock, 4, NULL, NULL, e2, e3);
4650 anim_move('x', 3, 1, mesh, color, sock);
4651 anim_move('z', 2, (13-i1)%4, mesh, color, sock);
4652 break;
4653 }
4654 }
4655 else if (e2 != NULL)
4656 {
4657 // Locate third incorrectly oriented edge
4658 int i2 = -1;
4659 for (int i=2; i<12; i++)
4660 {
4661 if ((rubik.edge_[2 * i] == e2[0] &&
4662 rubik.edge_[2 * i + 1] == e2[1]) ||
4663 (rubik.edge_[2 * i] == e2[1] &&
4664 rubik.edge_[2 * i + 1] == e2[0]))
4665 {
4666 i2 = i;
4667 break;
4668 }
4669 }
4670 if (logging_ > 1)
4671 {
4672 cout << "Location of e2: " << i2 << endl;
4673 }
4674
4675 switch (i2)
4676 {
4677 case 2:
4678 flip_edges(mesh, color, sock, 4, NULL, NULL, NULL, e3);
4679 break;
4680 case 3:
4681 anim_move('x', 1, 3, mesh, color, sock);
4682 anim_move('y', 3, 1, mesh, color, sock);
4683 flip_edges(mesh, color, sock, 4, NULL, NULL, NULL, e3);
4684 anim_move('y', 3, 3, mesh, color, sock);
4685 anim_move('x', 1, 1, mesh, color, sock);
4686 break;
4687 case 4:
4688 case 5:
4689 case 6:
4690 case 7:
4691 anim_move('z', 3, (i2-2)%4, mesh, color, sock);
4692 anim_move('y', 3, 2, mesh, color, sock);
4693 flip_edges(mesh, color, sock, 4, NULL, NULL, NULL, e3);
4694 anim_move('y', 3, 2, mesh, color, sock);
4695 anim_move('z', 3, (10-i2)%4, mesh, color, sock);
4696 break;
4697 case 8:
4698 case 9:
4699 case 10:
4700 case 11:
4701 anim_move('z', 2, (i2-6)%4, mesh, color, sock);
4702 anim_move('y', 3, 3, mesh, color, sock);
4703 flip_edges(mesh, color, sock, 4, NULL, NULL, NULL, e3);
4704 anim_move('y', 3, 1, mesh, color, sock);
4705 anim_move('z', 2, (14-i2)%4, mesh, color, sock);
4706 break;
4707 }
4708 }
4709 else if (e3 != NULL)
4710 {
4711 // Locate fourth incorrectly oriented edge
4712 int i3 = -1;
4713 for (int i=3; i<12; i++)
4714 {
4715 if ((rubik.edge_[2 * i] == e3[0] &&
4716 rubik.edge_[2 * i + 1] == e3[1]) ||
4717 (rubik.edge_[2 * i] == e3[1] &&
4718 rubik.edge_[2 * i + 1] == e3[0]))
4719 {
4720 i3 = i;
4721 break;
4722 }
4723 }
4724 if (logging_ > 1)
4725 {
4726 cout << "Location of e3: " << i3 << endl;
4727 }
4728
4729 switch (i3)
4730 {
4731 case 3:
4732 flip_edges(mesh, color, sock, 4, NULL, NULL, NULL, NULL);
4733 break;
4734 case 4:
4735 case 5:
4736 case 6:
4737 case 7:
4738 anim_move('z', 3, (i3-3)%4, mesh, color, sock);
4739 anim_move('x', 1, 2, mesh, color, sock);
4740 flip_edges(mesh, color, sock, 4, NULL, NULL, NULL, NULL);
4741 anim_move('x', 1, 2, mesh, color, sock);
4742 anim_move('z', 3, (7-i3)%4, mesh, color, sock);
4743 break;
4744 case 8:
4745 case 9:
4746 case 10:
4747 case 11:
4748 anim_move('z', 2, (i3-4)%4, mesh, color, sock);
4749 anim_move('x', 1, 3, mesh, color, sock);
4750 flip_edges(mesh, color, sock, 4, NULL, NULL, NULL, NULL);
4751 anim_move('x', 1, 1, mesh, color, sock);
4752 anim_move('z', 2, (12-i3)%4, mesh, color, sock);
4753 break;
4754 }
4755 }
4756 else
4757 {
4758 anim_move('x', 2, 3, mesh, color, sock);
4759 anim_move('z', 1, 2, mesh, color, sock);
4760 anim_move('x', 2, 1, mesh, color, sock);
4761 anim_move('z', 1, 2, mesh, color, sock);
4762 anim_move('x', 2, 3, mesh, color, sock);
4763 anim_move('z', 1, 3, mesh, color, sock);
4764 anim_move('x', 2, 1, mesh, color, sock);
4765 anim_move('z', 1, 2, mesh, color, sock);
4766 anim_move('x', 2, 3, mesh, color, sock);
4767 anim_move('z', 1, 2, mesh, color, sock);
4768 anim_move('x', 2, 1, mesh, color, sock);
4769 anim_move('z', 1, 1, mesh, color, sock);
4770 }
4771 }
4772}
4773
4774void
4776{
4777 if (logging_ > 1)
4778 {
4779 cout << "Entering solve_edge_orientations" << endl;
4780 }
4781 if (logging_ > 2)
4782 {
4783 print_state(cout);
4784 }
4785
4786 // Locate first incorrectly oriented edge
4787 int i0 = -1;
4788 for (int i=0; i<12; i++)
4789 {
4790 if (rubik.edge_[2 * i] != edge_colors_[2 * i])
4791 {
4792 i0 = i;
4793 break;
4794 }
4795 }
4796 if (logging_ > 1)
4797 {
4798 cout << "First incorrectly oriented edge location: " << i0 << endl;
4799 }
4800
4801 if (i0 < 0) { return; }
4802
4803 // Locate second incorrectly oriented edge
4804 int i1 = -1;
4805 for (int i=i0+1; i<12; i++)
4806 {
4807 if (rubik.edge_[2 * i] != edge_colors_[2 * i])
4808 {
4809 i1 = i;
4810 break;
4811 }
4812 }
4813 if (logging_ > 1)
4814 {
4815 cout << "Second incorrectly oriented edge location: " << i1 << endl;
4816 }
4817
4818 // Locate third incorrectly oriented edge (if such exists)
4819 int i2 = -1;
4820 int i3 = -1;
4821 for (int i=i1+1; i<12; i++)
4822 {
4823 if (rubik.edge_[2 * i] != edge_colors_[2 * i])
4824 {
4825 i2 = i;
4826 break;
4827 }
4828 }
4829 if (i2 > 0)
4830 {
4831 if (logging_ > 1)
4832 {
4833 cout << "Third incorrectly oriented edge location: " << i2 << endl;
4834 }
4835
4836 // Locate fourth incorrectly oriented edge (if such exists)
4837 for (int i=i2+1; i<12; i++)
4838 {
4839 if (rubik.edge_[2 * i] != edge_colors_[2 * i])
4840 {
4841 i3 = i;
4842 break;
4843 }
4844 }
4845 if (logging_ > 1)
4846 {
4847 cout << "Fourth incorrectly oriented edge location: " << i3 << endl;
4848 }
4849 }
4850
4851 int e0[2] = {rubik.edge_[2 * i0], rubik.edge_[2 * i0 + 1]};
4852 int e1[2] = {rubik.edge_[2 * i1], rubik.edge_[2 * i1 + 1]};
4853 int e2[2] = {rubik.edge_[2 * max(i2,0)], rubik.edge_[2 * max(i2,0) + 1]};
4854 int e3[2] = {rubik.edge_[2 * max(i3,0)], rubik.edge_[2 * max(i3,0) + 1]};
4855
4856 if (i2 == -1)
4857 {
4858 flip_edges(mesh, color, sock, 2, e0, e1);
4859 }
4860 else
4861 {
4862 flip_edges(mesh, color, sock, 4, e0, e1, e2, e3);
4863 }
4864
4865 solve_edge_orientations(mesh, color, sock);
4866}
4867
4868void
4869solve_top(Mesh & mesh, GridFunction & color, socketstream & sock)
4870{
4871 count_ = 0;
4872 if (logging_ > 0)
4873 {
4874 cout << "Solving top center block..." << endl;
4875 }
4876 solve_top_center(mesh, color, sock);
4877 if (logging_ > 0)
4878 {
4879 cout << "Solving top tier edges..." << endl;
4880 }
4881 solve_top_edges(mesh, color, sock);
4882 if (logging_ > 0)
4883 {
4884 cout << "Solving center blocks..." << endl;
4885 }
4886 if (logging_ > 0)
4887 {
4888 cout << "Solving top tier corners..." << endl;
4889 }
4890 solve_top_corners(mesh, color, sock);
4891
4892 cout << "Move count: " << count_ << endl;
4893}
4894
4895void
4896solve_mid(Mesh & mesh, GridFunction & color, socketstream & sock)
4897{
4898 count_ = 0;
4899 if (logging_ > 0)
4900 {
4901 cout << "Solving center blocks in the middle tier..." << endl;
4902 }
4903 solve_centers(mesh, color, sock);
4904 if (logging_ > 0)
4905 {
4906 cout << "Solving edge blocks in the middle tier..." << endl;
4907 }
4908 solve_mid_edges(mesh, color, sock);
4909
4910 cout << "Move count: " << count_ << endl;
4911}
4912
4913void
4914solve_bot(Mesh & mesh, GridFunction & color, socketstream & sock)
4915{
4916 if (logging_ > 0)
4917 {
4918 cout << "Solving corner block locations in the bottom tier..." << endl;
4919 }
4920 solve_bot_corner_locations(mesh, color, sock);
4921 if (logging_ > 0)
4922 {
4923 cout << "Solving corner block orientations..." << endl;
4924 }
4925 solve_corner_orientations(mesh, color, sock);
4926 if (logging_ > 0)
4927 {
4928 cout << "Solving edge block locations..." << endl;
4929 }
4930 solve_edge_locations(mesh, color, sock);
4931 if (logging_ > 0)
4932 {
4933 cout << "Solving edge block orientations..." << endl;
4934 }
4935 solve_edge_orientations(mesh, color, sock);
4936}
4937
4938void
4939solve(Mesh & mesh, GridFunction & color, socketstream & sock)
4940{
4941 count_ = 0;
4942 if (logging_ > 0)
4943 {
4944 cout << "Solving top center block..." << endl;
4945 }
4946 solve_top_center(mesh, color, sock);
4947 if (logging_ > 0)
4948 {
4949 cout << "Solving top tier edges..." << endl;
4950 }
4951 solve_top_edges(mesh, color, sock);
4952 if (logging_ > 0)
4953 {
4954 cout << "Solving top tier corners..." << endl;
4955 }
4956 solve_top_corners(mesh, color, sock);
4957 if (logging_ > 0)
4958 {
4959 cout << "Solving center blocks in the middle tier..." << endl;
4960 }
4961 solve_centers(mesh, color, sock);
4962 if (logging_ > 0)
4963 {
4964 cout << "Solving edge blocks in the middle tier..." << endl;
4965 }
4966 solve_mid_edges(mesh, color, sock);
4967 if (logging_ > 0)
4968 {
4969 cout << "Solving corner block locations in the bottom tier..." << endl;
4970 }
4971 solve_bot_corner_locations(mesh, color, sock);
4972 if (logging_ > 0)
4973 {
4974 cout << "Solving corner block orientations..." << endl;
4975 }
4976 solve_corner_orientations(mesh, color, sock);
4977 if (logging_ > 0)
4978 {
4979 cout << "Solving edge block locations..." << endl;
4980 }
4981 solve_edge_locations(mesh, color, sock);
4982 if (logging_ > 0)
4983 {
4984 cout << "Solving edge block orientations..." << endl;
4985 }
4986 solve_edge_orientations(mesh, color, sock);
4987
4988 cout << "Move count: " << count_ << endl;
4989}
int Size() const
Return the logical size of the array.
Definition array.hpp:147
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Definition fespace.hpp:244
Class for grid function - Vector with associated FE space.
Definition gridfunc.hpp:31
virtual void ProjectCoefficient(Coefficient &coeff)
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
Arbitrary order "L2-conforming" discontinuous finite elements.
Definition fe_coll.hpp:346
Mesh data type.
Definition mesh.hpp:64
void GetBdrElementVertices(int i, Array< int > &v) const
Returns the indices of the vertices of boundary element i.
Definition mesh.hpp:1512
int GetAttribute(int i) const
Return the attribute of element i.
Definition mesh.hpp:1389
void GetElementVertices(int i, Array< int > &v) const
Returns the indices of the vertices of element i.
Definition mesh.hpp:1508
void SetAttribute(int i, int attr)
Set the attribute of element i.
Definition mesh.cpp:7629
void FinalizeTopology(bool generate_bdr=true)
Finalize the construction of the secondary topology (connectivity) data of a Mesh.
Definition mesh.cpp:3362
virtual void Print(std::ostream &os=mfem::out, const std::string &comments="") const
Definition mesh.hpp:2433
int AddVertex(real_t x, real_t y=0.0, real_t z=0.0)
Definition mesh.cpp:1873
int GetNE() const
Returns number of elements.
Definition mesh.hpp:1282
void GetBdrElementAdjacentElement(int bdr_el, int &el, int &info) const
For the given boundary element, bdr_el, return its adjacent element and its info, i....
Definition mesh.cpp:7584
int AddHex(int v1, int v2, int v3, int v4, int v5, int v6, int v7, int v8, int attr=1)
Adds a hexahedron to the mesh given by 8 vertices v1 through v8.
Definition mesh.cpp:2021
int GetNBE() const
Returns number of boundary elements.
Definition mesh.hpp:1285
const real_t * GetVertex(int i) const
Return pointer to vertex i's coordinates.
Definition mesh.hpp:1321
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
void PrintUsage(std::ostream &out) const
Print the usage message.
void PrintOptions(std::ostream &out) const
Print the options.
void AddOption(bool *var, const char *enable_short_name, const char *enable_long_name, const char *disable_short_name, const char *disable_long_name, const char *description, bool required=false)
Add a boolean option and set 'var' to receive the value. Enable/disable tags are used to set the bool...
Definition optparser.hpp:82
bool Good() const
Return true if the command line options were parsed successfully.
A piecewise constant coefficient with the constants keyed off the element attribute numbers.
Vector data type.
Definition vector.hpp:82
int main()
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Definition globals.hpp:66
float real_t
Definition config.hpp:43
const char vishost[]
void rotate_step(char axis, int incr, real_t *x)
Definition rubik.cpp:1004
void permute_edges(Mesh &mesh, GridFunction &color, socketstream &sock, int *e0, int *e1, int *e2)
Definition rubik.cpp:4056
bool validate_corners(const int max_ind=8)
void move_to_c7(int i7, int o7, Mesh &mesh, GridFunction &color, socketstream &sock)
Definition rubik.cpp:1931
void interactive_help()
Definition rubik.cpp:361
void update_edges(char axis, int tier, int incr)
Definition rubik.cpp:730
void solve(Mesh &mesh, GridFunction &color, socketstream &sock)
Definition rubik.cpp:4939
void move_to_e4(int i4, int o4, Mesh &mesh, GridFunction &color, socketstream &sock)
Definition rubik.cpp:2148
void move_to_e9(int i9, int o9, Mesh &mesh, GridFunction &color, socketstream &sock)
Definition rubik.cpp:2712
void twist_corners(Mesh &mesh, GridFunction &color, socketstream &sock, bool cw, int *c0=NULL, int *c1=NULL, int *c2=NULL)
Definition rubik.cpp:3635
void solve_mid(Mesh &mesh, GridFunction &color, socketstream &sock)
Definition rubik.cpp:4896
int locate_corner(int ind)
Definition rubik.cpp:1372
void update_corners(char axis, int tier, int incr)
Definition rubik.cpp:589
void mark_elements(Mesh &mesh, char axis, int tier)
Definition rubik.cpp:1105
void move_to_c5(int i5, int o5, Mesh &mesh, GridFunction &color, socketstream &sock)
Definition rubik.cpp:1615
void solve_top_edges(Mesh &mesh, GridFunction &color, socketstream &sock)
Definition rubik.cpp:3098
void move_to_e6(int i6, int o6, Mesh &mesh, GridFunction &color, socketstream &sock)
Definition rubik.cpp:2367
void solve_edge_orientations(Mesh &mesh, GridFunction &color, socketstream &sock)
Definition rubik.cpp:4775
void swap_corners(Mesh &mesh, GridFunction &color, socketstream &sock, int *c0=NULL, int *c1=NULL)
Definition rubik.cpp:3288
void solve_bot_corner_locations(Mesh &mesh, GridFunction &color, socketstream &sock)
Definition rubik.cpp:3535
void init_hex_mesh(Mesh &mesh)
Definition rubik.cpp:407
bool validate_edges(const int max_ind=12)
void solve_top(Mesh &mesh, GridFunction &color, socketstream &sock)
Definition rubik.cpp:4869
void init_state()
Definition rubik.cpp:553
void move_to_e10(int i10, int o10, Mesh &mesh, GridFunction &color, socketstream &sock)
Definition rubik.cpp:2856
void solve_corner_locations(Mesh &mesh, GridFunction &color, socketstream &sock)
Definition rubik.cpp:3461
bool anim_step(char axis, int incr, Mesh &mesh)
Definition rubik.cpp:1077
void move_to_e5(int i5, int o5, Mesh &mesh, GridFunction &color, socketstream &sock)
Definition rubik.cpp:2260
void solve_corner_orientations(Mesh &mesh, GridFunction &color, socketstream &sock)
Definition rubik.cpp:3943
void solve_edge_locations(Mesh &mesh, GridFunction &color, socketstream &sock)
Definition rubik.cpp:4282
void move_to_c4(int i4, int o4, Mesh &mesh, GridFunction &color, socketstream &sock)
Definition rubik.cpp:1417
void determine_random_moves(Array< Move > &moves)
Definition rubik.cpp:1172
void move_to_e8(int i8, int o8, Mesh &mesh, GridFunction &color, socketstream &sock)
Definition rubik.cpp:2553
void update_state(char axis, int tier, int incr)
Definition rubik.cpp:857
bool validate_centers(const int max_ind=6)
void solve_bot(Mesh &mesh, GridFunction &color, socketstream &sock)
Definition rubik.cpp:4914
void move_to_c6(int i6, int o6, Mesh &mesh, GridFunction &color, socketstream &sock)
Definition rubik.cpp:1787
void anim_move(char axis, int tier, int increment, Mesh &mesh, GridFunction &color, socketstream &sock)
Definition rubik.cpp:1160
void repaint_cube(Mesh &mesh, GridFunction &color, socketstream &sock)
Definition rubik.cpp:903
void solve_top_center(Mesh &mesh, GridFunction &color, socketstream &sock)
Definition rubik.cpp:1216
int locate_edge(int ind)
Definition rubik.cpp:2129
void move_to_e11(int i11, int o11, Mesh &mesh, GridFunction &color, socketstream &sock)
Definition rubik.cpp:2985
void solve_top_corners(Mesh &mesh, GridFunction &color, socketstream &sock)
Definition rubik.cpp:2060
void solve_centers(Mesh &mesh, GridFunction &color, socketstream &sock)
Definition rubik.cpp:1251
void solve_mid_edges(Mesh &mesh, GridFunction &color, socketstream &sock)
Definition rubik.cpp:3183
void flip_edges(Mesh &mesh, GridFunction &color, socketstream &sock, int n, int *e0=NULL, int *e1=NULL, int *e2=NULL, int *e3=NULL)
Definition rubik.cpp:4356
void move_to_e7(int i7, int o7, Mesh &mesh, GridFunction &color, socketstream &sock)
Definition rubik.cpp:2464
void update_centers(char axis, int incr)
Definition rubik.cpp:561
void print_state(ostream &out)
Definition rubik.cpp:877