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