HOG2
RC.cpp
Go to the documentation of this file.
1 //
2 // RC.cpp (Alternate Rubik's Cube implementation)
3 //
4 // Created by Nathan Sturtevant on 7/9/21.
5 //
6 
7 #include "RC.h"
8 #include <cassert>
9 #include <cstdio>
10 #include <algorithm>
11 #include <string>
12 #include <iostream>
13 
14 // Helpers (for calculation)
15 void EditPointMult(float (&vec)[3][3], Graphics::point & p);
16 void MakeMatrixRotX(float (&a)[3][3], float angle);
17 void MakeMatrixRotY(float (&a)[3][3], float angle);
18 void MakeMatrixRotZ(float (&a)[3][3], float angle);
19 int findInArray(int arr[], int elem, int lower, int upper);
20 float array3 [3] = {0,0,0};
21 float rotation [3][3] = { {0,0,0}, {0,0,0}, {0,0,0} };
22 std::vector<int> furthestZ(0);
23 
24 const int edgesOnFace[6][4] =
25 {
26  {0, 6, 4, 2}, //0
27  {2, 3, 9, 1}, //1
28  {0, 1, 8, 7}, //2
29  {6, 7, 11, 5}, //3
30  {4, 5, 10, 3}, //4
31  {9, 10, 11, 8} //5
32 };
33 // int cornersOnFace[6][4] =
34 // {
35 // {4 +11, 3 +11, 2 +11, 1 +11}, //0
36 // {1 +11, 2 +11, 6 +11, 5 +11}, //1
37 // {4 +11, 1 +11, 5 +11, 8 +11}, //2
38 // {3 +11, 4 +11, 8 +11, 7 +11}, //3
39 // {2 +11, 3 +11, 7 +11, 6 +11}, //4
40 // {5 +11, 6 +11, 7 +11, 8 +11} //5
41 // };
42 const int cornersOnFace[6][4] =
43 {
44  {15, 14, 13, 12}, //0
45  {16, 12, 13, 17}, //1
46  {15, 12, 16, 19}, //2
47  {15, 19, 18, 14}, //3
48  {13, 14, 18, 17}, //4
49  {16, 17, 18, 19} //5
50 };
51 //std::vector<std::vector<float>> rotation(3,std::vector<float>(3));
52 
53 /*===============================================================================================================================================================================
54  * CUBIE CLASS
55  ===============================================================================================================================================================================*/
56 
57 /* Called when cubie is initialized via the RCState
58  *
59  */
60 void Cubie::Initialize(int RCpos, int RCind, int RCrot)
61 {
62  RCindex = RCind; // TEMP
63  // Reset previous data
64  basePoints.clear();
65  baseFacePoints.clear();
66  points.clear();
67  facePoints.clear();
68 
69  // Edge or corner
70  bool isCorner = false;
71  if (RCind >= 12) isCorner = true;
72 
73  // Position of the cubie on the cube (x, y, z) -------------------------------------------
74  int xPos = 0, yPos = 0, zPos = 0;
75  int xAdd[8] = {3, 4, 5, 10, 13, 14, 17, 18}; //Orange
76  int xSubt[8] = {0, 1, 7, 8, 12, 15, 16, 19}; //Red
77  int yAdd[8] = {8, 9, 10, 11, 16, 17, 18, 19}; //Yellow
78  int ySubt[8] = {0, 2, 4, 6, 12, 13, 14, 15}; //White
79  int zAdd[8] = {5, 6, 7, 11, 14, 15, 18, 19}; //Green
80  int zSubt[8] = {1, 2, 3, 9, 12, 13, 16, 17}; //Blue
81 
82  // Modify array search range
83  int starti = 0, endi = 4;
84  if (isCorner)
85  {
86  starti = 4;
87  endi = 8;
88  }
89 
90  // Search within arrays and modify
91  if (findInArray(xAdd, RCpos, starti, endi) != -1)
92  {
93  xPos = 1;
94  } else if (findInArray(xSubt, RCpos, starti, endi) != -1)
95  {
96  xPos = -1;
97  }
98  if (findInArray(yAdd, RCpos, starti, endi) != -1)
99  {
100  yPos = 1;
101  } else if (findInArray(ySubt, RCpos, starti, endi) != -1)
102  {
103  yPos = -1;
104  }
105  if (findInArray(zAdd, RCpos, starti, endi) != -1)
106  {
107  zPos = 1;
108  } else if (findInArray(zSubt, RCpos, starti, endi) != -1)
109  {
110  zPos = -1;
111  }
112 
113  // Visibible Faces -------------------------------------------------------------------------
114  // Init faces
115  for (int i = 0; i < 6; i++)
116  {
117  faceCols[i] = inCol;
118  facesShown[i] = false;
119  }
120 
121  // Do face visibility and colors depending on corner/edge
122  if (isCorner)
123  {
124  for (int i = 0; i < 3; i++)
125  {
126  facesShown[facesShowing[RCpos][i]] = true;
127  // This is a colored face, update the color
128  int indToEdit;
129  if (RCrot == 0)
130  {
131  // "Correct" rotation: White/Yellow faces White/Yellow
132  indToEdit = i;
133  } else if (RCrot == 1)
134  {
135  // Clockwise rotation from "Correct" rotation, add 1 to i
136  indToEdit = (i + 1) % 3;
137  } else
138  {
139  // Counterclockwise rotation from "Correct" rotation, subtract 1 from i
140  indToEdit = (i + 2) % 3;
141  }
142  // Change the color
143  faceCols[facesShowing[RCpos][indToEdit]] = faceColors[facesShowing[RCind][i]];
144  }
145  } else
146  { // Edge
147  for (int i = 0; i < 2; i++)
148  {
149  facesShown[facesShowing[RCpos][i]] = true;
150  // This is a colored face, update the color
151  if (RCrot != 2)
152  {
153  // (i + RCrot)%2 : Swap index 0/1 if the incorrect RCrot (RCrot == 1)
154  faceCols[facesShowing[RCpos][i]] = faceColors[facesShowing[RCind][(i + RCrot)%2]];
155 
156  } else
157  {
158  std::cout << "ERROR: 2 OUT OF BOUNDS [Cubie::Initialize(int RCpos, int RCind, int RCrot)]" << '\n';
159  }
160  }
161  }
162 
163  // The following is the same code as with Cubie::Initialize(int ind)
164  //Initialize the 8 points
165  for (int i = 0; i < 8; i++)
166  {
167  points.push_back(Graphics::point(0,0,0));
168  points[i].x = -0.5f * sideLen;// + xPos * sideLen;
169  if ((i%4) == 1 || (i%4) == 2)
170  points[i].x += 1.f * sideLen;
171  points[i].y = (-0.5f + (1.f * ((i/2)%2))) * sideLen;// + yPos * sideLen; //y
172  points[i].z = (-0.5f + (1.f * (i/4))) * sideLen;// + zPos * sideLen; //z
173 
174  basePoints.push_back(Graphics::point(points[i].x,points[i].y,points[i].z));
175  }
176  //Initialize the 4 face points for all 6 faces (24)
177  for (int i = 0; i < 6; i++)
178  {
179  facePoints.push_back(std::vector<Graphics::point>());
180  baseFacePoints.push_back(std::vector<Graphics::point>());
181  for (int j = 0; j < 4; j++)
182  {
183  float x, y, z;
184  if (i == 2 || i == 4) x = 1.0f;
185  else x = faceSize;
186  if (i == 0 || i == 5) y = 1.0f;
187  else y = faceSize;
188  if (i == 1 || i == 3) z = 1.0f;
189  else z = faceSize;
190 
192  x *= p.x;
193  y *= p.y;
194  z *= p.z;
195  facePoints[i].push_back(Graphics::point(x,y,z));
196  baseFacePoints[i].push_back(Graphics::point(x,y,z));
197  }
198  }
199  //Move all points (faces and cube) by coord
200  for (int i = 0; i < 8; i++)
201  {
202  points[i].x += xPos * sideLen;
203  points[i].y += yPos * sideLen;
204  points[i].z += zPos * sideLen;
205  basePoints[i].x += xPos * sideLen;
206  basePoints[i].y += yPos * sideLen;
207  basePoints[i].z += zPos * sideLen;
208  }
209  for (int i = 0; i < 6; i++)
210  {
211  for (int j = 0; j < 4; j++)
212  {
213  facePoints[i][j].x += xPos * sideLen;
214  facePoints[i][j].y += yPos * sideLen;
215  facePoints[i][j].z += zPos * sideLen;
216  baseFacePoints[i][j].x += xPos * sideLen;
217  baseFacePoints[i][j].y += yPos * sideLen;
218  baseFacePoints[i][j].z += zPos * sideLen;
219  }
220  }
221 }
222 
223 
224 void Cubie::Initialize(int ind)
225 {
226  index = ind;
227  int xPos = 0, yPos = 0, zPos = 0;
228  //Cube index (out of 26)
229 
230  int in = index;
231  if (in >= 13) in++; //Readd middle cubie for init ease
232  //Initialize face colors, determine position based on index
233  for (int i = 0; i < 6; i++)
234  {
235  faceCols[i] = inCol;
236  facesShown[i] = false;
237  }
238  //If its cube #0,1,2,9,10,11,18,19,20, make face 0 white
239  for (int i = 0; i < 3; i++)
240  {
241  if (in >= i*9 && in <= i*9 + 2)
242  {
243  faceCols[0] = faceColors[0];
244  facesShown[0] = true;
245  yPos--;
246  }
247  }
248  //If its cube #0-8, make face 1 blue
249  if (in >= 0 && in <= 8)
250  {
251  faceCols[1] = faceColors[1];
252  facesShown[1] = true;
253  zPos--;
254  }
255  //If its cube # is a multiple of 3 (including 0), make face 2 red
256  if (in % 3 == 0)
257  {
258  faceCols[2] = faceColors[2];
259  facesShown[2] = true;
260  xPos--;
261  }
262  //If its cube #18-26, make face 3 green
263  if (in >= 18 && in <= 26)
264  {
265  faceCols[3] = faceColors[3];
266  facesShown[3] = true;
267  zPos++;
268  //std::cout << in << '\n';
269  }
270  //If its cube # - 2 is multiple of 3, make face 4 orange
271  if ((in-2) % 3 == 0)
272  {
273  faceCols[4] = faceColors[4];
274  facesShown[4] = true;
275  xPos++;
276  }
277  //If its cube #6,7,8,15,16,17,24,25,26, make face 5 yellow
278  for (int i = 0; i < 3; i++)
279  {
280  if (in >= i*9 + 6 && in <= i*9 + 8)
281  {
282  faceCols[5] = faceColors[5];
283  facesShown[5] = true;
284  yPos++;
285  }
286  }
287 
288  //Initialize the 8 points
289  for (int i = 0; i < 8; i++)
290  {
291  points.push_back(Graphics::point(0,0,0));
292  points[i].x = -0.5f * sideLen;// + xPos * sideLen;
293  if ((i%4) == 1 || (i%4) == 2)
294  points[i].x += 1.f * sideLen;
295  points[i].y = (-0.5f + (1.f * ((i/2)%2))) * sideLen;// + yPos * sideLen; //y
296  points[i].z = (-0.5f + (1.f * (i/4))) * sideLen;// + zPos * sideLen; //z
297 
298  basePoints.push_back(Graphics::point(points[i].x,points[i].y,points[i].z));
299  }
300  //Initialize the 4 face points for all 6 faces (24)
301  for (int i = 0; i < 6; i++)
302  {
303  facePoints.push_back(std::vector<Graphics::point>());
304  baseFacePoints.push_back(std::vector<Graphics::point>());
305  for (int j = 0; j < 4; j++)
306  {
307  float x, y, z;
308  if (i == 2 || i == 4) x = 1.0f;
309  else x = faceSize;
310  if (i == 0 || i == 5) y = 1.0f;
311  else y = faceSize;
312  if (i == 1 || i == 3) z = 1.0f;
313  else z = faceSize;
314 
316  x *= p.x;
317  y *= p.y;
318  z *= p.z;
319  facePoints[i].push_back(Graphics::point(x,y,z));
320  baseFacePoints[i].push_back(Graphics::point(x,y,z));
321  }
322  }
323  //Move all points (faces and cube) by coord
324  for (int i = 0; i < 8; i++)
325  {
326  points[i].x += xPos * sideLen;
327  points[i].y += yPos * sideLen;
328  points[i].z += zPos * sideLen;
329  basePoints[i].x += xPos * sideLen;
330  basePoints[i].y += yPos * sideLen;
331  basePoints[i].z += zPos * sideLen;
332  }
333  for (int i = 0; i < 6; i++)
334  {
335  for (int j = 0; j < 4; j++)
336  {
337  facePoints[i][j].x += xPos * sideLen;
338  facePoints[i][j].y += yPos * sideLen;
339  facePoints[i][j].z += zPos * sideLen;
340  baseFacePoints[i][j].x += xPos * sideLen;
341  baseFacePoints[i][j].y += yPos * sideLen;
342  baseFacePoints[i][j].z += zPos * sideLen;
343  }
344  }
345 }
346 
347 /*
348  *
349  */
350 void Cubie::Draw(Graphics::Display &display) const
351 {
352  //Test
353 // if (RCindex == 19 || RCindex == 0)
354 // {
355 // //Test
356 // std::cout << "start " << RCindex << "\n";
357 // for (int i = 0; i < 8; i++)
358 // {
359 // std::cout << "p" << i << RCindex << "\n";
360 // std::cout << "x " << points[i].x << "\n";
361 // std::cout << "y " << points[i].y << "\n";
362 // std::cout << "z " << points[i].z << "\n";
363 // }
364 // std::cout << "\n\n";
365 // }
366 
367  // Identify which faces will be hidden from sight (Find which points are the furthest back)
368  float highest;
369  furthestZ.clear();
370  furthestZ.push_back(0);
371  highest = points[0].z;
372  for (int i = 1; i < 8; i++)
373  {
374  if (points[i].z > highest) {
375  furthestZ.clear();
376  furthestZ.push_back(i);
377  highest = points[i].z;
378  continue;
379  }
380  if (points[i].z == highest) {
381  furthestZ.push_back(i);
382  }
383  }
384  int facesDrawn = 0;
385  for (int i = 0; i < 6; i++)
386  {
387  if (facesShown[i])
388  {
389  bool drawThis = true;
390 
391  for (int pInd : pointsOnFace[i])
392  {
393  for (int check : furthestZ)
394  {
395  if (pInd == check)
396  {
397  //This face shouldn't be shown
398  drawThis = false;
399  break;
400  }
401  }
402  }
403 
404  //Draw face if not on the back
405  if (drawThis)
406  {
407  facesDrawn++;
408  DrawFace(display, i);
409  }
410  }
411  }
412 }
413 
414 /* Given points (in a correct order)
415  * Draw a polygon (face of a cubie)
416  */
417 void Cubie::DrawFace(Graphics::Display &display, int index) const //face Index (0-5)
418 {
419  display.FillTriangle( points[pointsOnFace[index][0]], points[pointsOnFace[index][1]],
420  points[pointsOnFace[index][2]], outCol);
421  display.FillTriangle( points[pointsOnFace[index][0]], points[pointsOnFace[index][2]],
422  points[pointsOnFace[index][3]], outCol);
423 
424  display.FillTriangle( facePoints[index][0], facePoints[index][1],
425  facePoints[index][2], faceCols[index]);
426  display.FillTriangle( facePoints[index][0], facePoints[index][2],
427  facePoints[index][3], faceCols[index]);
428 }
429 
430 /*
431  *
432  */
433 void Cubie::RotateRelative(const float angle[3])
434 {
435  for (Graphics::point & point : points)
436  {
437  MakeMatrixRotX(rotation, angle[0]);
438  EditPointMult(rotation, point);
439  MakeMatrixRotY(rotation, angle[1]);
440  EditPointMult(rotation, point);
441  MakeMatrixRotZ(rotation, angle[2]);
442  EditPointMult(rotation, point);
443  }
444  for (int i = 0; i < 6; i++)
445  {
446  MakeMatrixRotX(rotation, angle[0]);
447  for (int j = 0; j < 4; j++)
449  MakeMatrixRotY(rotation, angle[1]);
450  for (int j = 0; j < 4; j++)
452  MakeMatrixRotZ(rotation, angle[2]);
453  for (int j = 0; j < 4; j++)
455  }
456 }
457 
458 /*
459  *
460  */
461 void Cubie::RotateBase(float angle [3])
462 {
463  for (Graphics::point & point : basePoints)
464  {
465  MakeMatrixRotX(rotation, angle[0]);
466  EditPointMult(rotation, point);
467  MakeMatrixRotY(rotation, angle[1]);
468  EditPointMult(rotation, point);
469  MakeMatrixRotZ(rotation, angle[2]);
470  EditPointMult(rotation, point);
471  }
472  for (int i = 0; i < 6; i++)
473  {
474  MakeMatrixRotX(rotation, angle[0]);
475  for (int j = 0; j < 4; j++)
477  MakeMatrixRotY(rotation, angle[1]);
478  for (int j = 0; j < 4; j++)
480  MakeMatrixRotZ(rotation, angle[2]);
481  for (int j = 0; j < 4; j++)
483  }
484 }
485 
486 /*
487  *
488  */
489 void Cubie::RotateFacePos(bool clockwise, int axis)
490 {
491  int temp;
492  if (clockwise)
493  {
494  temp = faceInPos[faceOrderByAxis[axis][3]];
495  for (int i = 3; i > 0; i--)
496  {
497  faceInPos[faceOrderByAxis[axis][i]] = faceInPos[faceOrderByAxis[axis][i-1]];
498  }
499  faceInPos[faceOrderByAxis[axis][0]] = temp;
500  } else
501  {
502  temp = faceInPos[faceOrderByAxis[axis][0]];
503  for (int i = 0; i < 3; i++)
504  {
505  faceInPos[faceOrderByAxis[axis][i]] = faceInPos[faceOrderByAxis[axis][i+1]];
506  }
507  faceInPos[faceOrderByAxis[axis][3]] = temp;
508  }
509 }
510 
511 /*
512  *
513  */
515 {
516  for (int i = 0; i < 8; i++)
517  {
518  points[i].x = basePoints[i].x;
519  points[i].y = basePoints[i].y;
520  points[i].z = basePoints[i].z;
521  }
522  for (int i = 0; i < 6; i++)
523  {
524  for (int j = 0; j < 4; j++)
525  {
526  facePoints[i][j].x = baseFacePoints[i][j].x;
527  facePoints[i][j].y = baseFacePoints[i][j].y;
528  facePoints[i][j].z = baseFacePoints[i][j].z;
529  }
530  }
531 }
532 
533 /*
534  *
535  */
537 {
538  if (blackFaceToReset != -1)
539  {
541  blackFaceToReset = -1;
542  }
543 }
544 
545 /* Called when a rotation is made. cubies must make an inner black face
546  * visible while rotation is in motion (which must be invisible once it's complete)
547  */
548 void Cubie::SetFacePositionVisible(bool toggle, int position)
549 {
550  facesShown[faceInPos[position]] = toggle;
551  blackFaceToReset = position;
552 }
553 
554 /* For testing purposes, prints all of the Cubie's non-constant data
555  *
556  */
558 {
559  std::cout << "Index: " << index << std::endl;
560 
561  std::cout << "BlackFaceToReset: " << blackFaceToReset << std::endl;
562 
563  std::cout << "faceCols: ";
564  for (int i = 0; i < 6; i ++)
565  {
566  //std::cout << faceCols[i] << ", ";
567  } std::cout << std::endl;
568 
569  std::cout << "facesShown: ";
570  for (int i = 0; i < 6; i ++)
571  {
572  std::cout << facesShown[i] << ", ";
573  } std::cout << std::endl;
574 
575  std::cout << "faceInPos: ";
576  for (int i = 0; i < 6; i ++)
577  {
578  std::cout << faceInPos[i] << ", ";
579  } std::cout << std::endl;
580 
581  std::cout << "points: ";
582  for (int i = 0; i < 8; i ++)
583  {
584  std::cout << points[i] << ", ";
585  } std::cout << std::endl;
586 
587  std::cout << "basePoints: ";
588  for (int i = 0; i < 8; i ++)
589  {
590  std::cout << points[i] << ", ";
591  } std::cout << std::endl;
592 
593  std::cout << "facePoints: " << std::endl;
594  for (int i = 0; i < 6; i ++)
595  {
596  std::cout << " Face " << i << ": ";
597  for (int j = 0; j < 8; j++)
598  {
599  std::cout << facePoints[i][j] << ", ";
600  } std::cout << std::endl;
601  } std::cout << std::endl;
602 
603  std::cout << "baseFacePoints: " << std::endl;
604  for (int i = 0; i < 6; i ++)
605  {
606  std::cout << " Face " << i << ": ";
607  for (int j = 0; j < 8; j++)
608  {
609  std::cout << baseFacePoints[i][j] << ", ";
610  } std::cout << std::endl;
611  } std::cout << std::endl;
612 }
613 
614 /*===============================================================================================================================================================================
615  * RCSTATE CLASS
616  ===============================================================================================================================================================================*/
617 
618 /*
619  *
620  */
621 void RCState::RotateFace(int face, int move)
622 {
623  // TODO: DELETE
624 
625  // Move the cubes
626  if (move != 2)
627  {
628  //Rotate the Cubes
629  RotateEdges(face, move);
630  RotateCorners(face, move);
631 
632  bool forward;
633  if (move == 0) forward = true;
634  else forward = false;
635 
636  ShiftPositions(edgesOnFace[face], forward);
637  ShiftPositions(cornersOnFace[face], forward);
638  } else //180* turn
639  {
640  SwapPositions(edgesOnFace[face][0], edgesOnFace[face][2]);
641  SwapPositions(edgesOnFace[face][1], edgesOnFace[face][3]);
642  SwapPositions(cornersOnFace[face][0], cornersOnFace[face][2]);
643  SwapPositions(cornersOnFace[face][1], cornersOnFace[face][3]);
644  }
645 }
646 
647 /*
648  *
649  */
650 void RCState::RotateFace(int move)
651 {
652  switch(move)
653  {
654  case 0: // Face 0, CW
655  // No change in rotation
658  break;
659  case 1: // CCW
660  // No change in rotation
663  break;
664  case 3: // Face 1, CW
665  RotateEdges(move);
666  RotateCorners(move);
667 
670  break;
671  case 4: // CCW
672  RotateEdges(move);
673  RotateCorners(move);
674 
677  break;
678  case 6: // Face 2, CW
679  RotateCorners(move);
680 
683  break;
684  case 7: // CCW
685  RotateCorners(move);
686 
689  break;
690  case 9: // Face 3, CW
691  RotateEdges(move);
692  RotateCorners(move);
693 
696  break;
697  case 10: // CCW
698  RotateEdges(move);
699  RotateCorners(move);
700 
703  break;
704  case 12: // Face 4, CW
705  RotateCorners(move);
706 
709  break;
710  case 13: // CCW
711  RotateCorners(move);
712 
715  break;
716  case 15: // Face 5, CW
717  // No change in rotation
718 
721  break;
722  case 16: // CCW
723  // No change in rotation
724 
727  break;
728  case 2: // All faces 180
729  case 5:
730  case 8:
731  case 11:
732  case 14:
733  case 17:
734  // No change in rotation
735 
736  int face = move/3;
737  SwapPositions(edgesOnFace[face][0], edgesOnFace[face][2]);
738  SwapPositions(edgesOnFace[face][1], edgesOnFace[face][3]);
739  SwapPositions(cornersOnFace[face][0], cornersOnFace[face][2]);
740  SwapPositions(cornersOnFace[face][1], cornersOnFace[face][3]);
741  break;
742  }
743 }
744 
745 /*
746  *
747  */
748 void RCState::RotateEdges(int move)
749 {
750  int face = move/3;
751  rotation[edgesOnFace[face][0]] = 1 - rotation[edgesOnFace[face][0]];
752  rotation[edgesOnFace[face][1]] = 1 - rotation[edgesOnFace[face][1]];
753  rotation[edgesOnFace[face][2]] = 1 - rotation[edgesOnFace[face][2]];
754  rotation[edgesOnFace[face][3]] = 1 - rotation[edgesOnFace[face][3]];
755 }
756 
757 /*
758  *
759  */
760 void RCState::RotateEdges(int face, int move)
761 {
762  // TODO: move is already checked to not be 2
763  if (move != 2 && (face == 1 || face == 3))
764  {
765  for (int i = 0; i < 4; i++)
766  {
767  rotation[edgesOnFace[face][i]] = 1 - rotation[edgesOnFace[face][i]];
768  }
769  }
770 }
771 
772 /*
773  *
774  */
776 {
777  // cornersOnFace[face][0] will ALWAYS be a special corner,
778  // cannot be an index A face (face =/ 0, 5)
779  int face = move/3;
780  // For standard corners, the amount of rotation is equal to the faceIndex (0-2)
781  int add = 2 - (face % 2); // Standard corners
782  rotation[cornersOnFace[face][1]] += add;
783  rotation[cornersOnFace[face][1]] %= 3;
784  rotation[cornersOnFace[face][3]] += add;
785  rotation[cornersOnFace[face][3]] %= 3;
786 
787  add = 3 - add; // Special corners
788  rotation[cornersOnFace[face][0]] += add;
789  rotation[cornersOnFace[face][0]] %= 3;
790  rotation[cornersOnFace[face][2]] += add;
791  rotation[cornersOnFace[face][2]] %= 3;
792 }
793 
794 /*
795  *
796  */
797 void RCState::RotateCorners(int face, int move)
798 {
799  // TODO: move is already checked to not be 2
800  // If 180 turn or index A face, do not change rotation
801  if (move != 2)
802  {
803  int index;
804  if (face % 5 == 0) index = 0;
805  else if (face % 2 == 1) index = 1;
806  else index = 2;
807 
808  // If index A face, do not change rotation
809  if (index != 0)
810  {
811  int specialCorners[4] = {13, 15, 16, 18};
812 
813  // Rotate each corner in the face
814  for (int i = 0; i < 4; i++)
815  {
816  // Determine whether this cubie is a special corner
817  bool special = false;
818  for(int j = 0; j < 4; j++){
819  if(cornersOnFace[face][i] == specialCorners[j]){
820  special = true;
821  break;
822  }
823  }
824  // if Shaded corner cubie:
825  // B Face: rot += 2
826  // C Face: rot += 1
827  // if Unshaded corner cubie:
828  // B Face: rot += 1
829  // C Face: rot += 2
830  int add = index;
831  if (special) add = 3-add;
832 
833  rotation[cornersOnFace[face][i]] += add;
834  // Loop to start of rotation if rotation goes over 2
835  rotation[cornersOnFace[face][i]] = rotation[cornersOnFace[face][i]] % 3;
836  }
837  }
838  }
839 }
840 
841 /*
842  *
843  */
844 void RCState::SwapPositions(int p1, int p2)
845 {
846  int temp = indices[p1];
847  indices[p1] = indices[p2];
848  indices[p2] = temp;
849  // Also swap rotations
850  temp = rotation[p1];
851  rotation[p1] = rotation[p2];
852  rotation[p2] = temp;
853 }
854 
855 /*
856  *
857  */
858 void RCState::ShiftPositionsCW(const int (&arr)[4])
859 {
860  // Shift rotations as well
861  int temp;
862  int tempR;
863  temp = indices[arr[3]];
864  tempR = rotation[arr[3]];
865 
866  int i = 3;
867  indices[arr[i]] = indices[arr[i-1]];
868  rotation[arr[i]] = rotation[arr[i-1]];
869  i--;
870  indices[arr[i]] = indices[arr[i-1]];
871  rotation[arr[i]] = rotation[arr[i-1]];
872  i--;
873  indices[arr[i]] = indices[arr[i-1]];
874  rotation[arr[i]] = rotation[arr[i-1]];
875 
876  indices[arr[0]] = temp;
877  rotation[arr[0]] = tempR;
878 }
879 
880 /*
881  *
882  */
883 void RCState::ShiftPositionsCCW(const int (&arr)[4])
884 {
885  // Shift rotations as well
886  int temp;
887  int tempR;
888  temp = indices[arr[0]];
889  tempR = rotation[arr[0]];
890 
891  int i = 0;
892  indices[arr[i]] = indices[arr[i+1]];
893  rotation[arr[i]] = rotation[arr[i+1]];
894  i++;
895  indices[arr[i]] = indices[arr[i+1]];
896  rotation[arr[i]] = rotation[arr[i+1]];
897  i++;
898  indices[arr[i]] = indices[arr[i+1]];
899  rotation[arr[i]] = rotation[arr[i+1]];
900 
901  indices[arr[3]] = temp;
902  rotation[arr[3]] = tempR;
903 }
904 
905 /*
906  *
907  */
908 void RCState::ShiftPositions(const int (&arr)[4], bool forward)
909 {
910  //std::cout << "Shifting positions " << arr[0] << ", " << arr[1] << ", " << arr[2] << ", " << arr[3] << std::endl;
911 
912  // Shift rotations as well
913  int temp;
914  int tempR;
915  if (forward) // clockwise
916  {
917  temp = indices[arr[3]];
918  tempR = rotation[arr[3]];
919  for (int i = 3; i > 0; i--)
920  {
921  indices[arr[i]] = indices[arr[i-1]];
922  rotation[arr[i]] = rotation[arr[i-1]];
923  }
924  indices[arr[0]] = temp;
925  rotation[arr[0]] = tempR;
926  } else //CCW
927  {
928  temp = indices[arr[0]];
929  tempR = rotation[arr[0]];
930  for (int i = 0; i < 3; i++)
931  {
932  indices[arr[i]] = indices[arr[i+1]];
933  rotation[arr[i]] = rotation[arr[i+1]];
934  }
935  indices[arr[3]] = temp;
936  rotation[arr[3]] = tempR;
937  }
938 }
939 
941 {
942  // Print the two arrays: indices[] and rotation[]
943  std::cout << "Indices: [";
944  for (int i = 0; i < 20; i++)
945  {
946  std::cout << indices[i] << ", ";
947  }
948  std::cout << "]" << std::endl;
949  std::cout << "Rotation: [";
950  for (int i = 0; i < 20; i++)
951  {
952  std::cout << rotation[i] << ", ";
953  }
954  std::cout << "]" << std::endl;
955 }
956 
957 /*===============================================================================================================================================================================
958  * RC CLASS
959  ===============================================================================================================================================================================*/
960 
961 /*
962  *
963  */
964 void RC::DrawCubies(Graphics::Display &display) const
965 {
966  if (rotating)
967  {
968  DrawCubiesRotating(display);
969  } else
970  {
971  for (int i = 0; i < 26; i++)
972  {
973  cubies[i].Draw(display);
974  }
975  }
976 }
977 
978 /*
979  *
980  */
982 {
983  bool jumped = false;
984  if (rotatingFaceBehind)
985  {
986  goto drawFace;
987  } else goto drawCubie;
988 
989  drawFace:
990  for (int i = 0; i < 9; i++)
992  if (!jumped)
993  {
994  jumped = true;
995  goto drawCubie;
996  }
997  return;
998  drawCubie:
999  for (int i = 0; i < 17; i++)
1001  if (!jumped)
1002  {
1003  jumped = true;
1004  goto drawFace;
1005  }
1006  return;
1007 }
1008 
1009 /*
1010  *
1011  */
1012 void RC::RotateCubies(float add[3])
1013 {
1014  for (int i = 0; i < 3; i++)
1015  {
1016  rotationTotal[i] += add[i];
1017  }
1018  for (int i = 0; i < 26; i++)
1019  {
1020  cubies[i].ResetToBase();
1022  }
1023 }
1024 
1025 /*
1026  *
1027  */
1028 void RC::RotateFace(int face, int move)
1029 {
1030  if (!rotating)
1031  {
1032  bool clockwise = true;
1033  int axis;
1034  turnArr[0] = 0;
1035  turnArr[1] = 0;
1036  turnArr[2] = 0;
1037  rotating = true;
1038  faceTurning = face;
1039  rotProgress = 0;
1040 
1041  float add = piOver2;
1042  if (face == 0 || face == 3 || face == 4)
1043  {
1044  add *= -1;
1045  }
1046  if (face == 5 || face == 3 || face == 4 )
1047  {
1048  clockwise = !clockwise;
1049  }
1050 
1051  // Move cubies on face
1052  int temp, temp2;
1053 
1054  if (move == 0) //CW
1055  {
1056  temp = cubieInPos[cubiesOnFace[face][edgeOrder[3]]];
1057  temp2 = cubieInPos[cubiesOnFace[face][cornerOrder[3]]];
1058  for (int i = 3; i > 0; i--)
1059  {
1062  }
1063  cubieInPos[cubiesOnFace[face][edgeOrder[0]]] = temp;
1064  cubieInPos[cubiesOnFace[face][cornerOrder[0]]] = temp2;
1065  } else if (move == 1) //CCW
1066  {
1067  add *= -1;
1068 
1069  temp = cubieInPos[cubiesOnFace[face][edgeOrder[0]]];
1070  temp2 = cubieInPos[cubiesOnFace[face][cornerOrder[0]]];
1071  for (int i = 0; i < 3; i++)
1072  {
1075  }
1076  cubieInPos[cubiesOnFace[face][edgeOrder[3]]] = temp;
1077  cubieInPos[cubiesOnFace[face][cornerOrder[3]]] = temp2;
1078 
1079  clockwise = !clockwise;
1080  } else //180
1081  {
1082  add *= 2;
1083 
1084  for (int i = 0; i < 2; i++)
1085  {
1086  temp = cubieInPos[cubiesOnFace[face][edgeOrder[i]]];
1087  temp2 = cubieInPos[cubiesOnFace[face][cornerOrder[i]]];
1090  cubieInPos[cubiesOnFace[face][edgeOrder[i+2]]] = temp;
1091  cubieInPos[cubiesOnFace[face][cornerOrder[i+2]]] = temp2;
1092  }
1093  }
1094  //Set direction and distance of turn
1095  if (face%5 == 0) {
1096  turnArr[1] = add;
1097  axis = 1;
1098  } else if (face == 1 || face == 3) {
1099  turnArr[2] = add;
1100  axis = 2;
1101  } else {
1102  turnArr[0] = add;
1103  axis = 0;
1104  }
1105  for (int i = 0; i < 9; i++)
1106  {
1107  //Edit the base to be FULLY rotated
1109 
1110  //Rotate Cubie face positions
1111  cubies[cubieInPos[cubiesOnFace[faceTurning][i]]].RotateFacePos(clockwise, axis);
1112  if (move == 2) cubies[cubieInPos[cubiesOnFace[faceTurning][i]]].RotateFacePos(clockwise, axis);
1113 
1114  //Set black face to be visible on each rotated cubie
1116 
1117  //Set black face to be visible on each cubie now exposed by the turn face rotating
1118  int toEdit = cubiesOnFace[faceTurning][i];
1119  if (toEdit >= 13) toEdit++;
1120  toEdit += fromFaceToCenter[faceTurning];
1121  if (toEdit != 13)
1122  {
1123  if (toEdit >= 14) toEdit--;
1125  }
1126  }
1127  }
1128 }
1129 
1130 /*
1131  *
1132  */
1133 void RC::InterpFaceRot(float progress)
1134 {
1135  for (int i = 0; i < 3; i++)
1136  {
1137  //Inbetween val
1138  interpArr[i] = turnArr[i] * (1-progress) * -1;
1139  }
1140  // Only turns the 9 face cubies
1141  for (int i = 0; i < 9; i++)
1142  {
1143  //Reset Rotation
1145  //Apply interpolated face rotation to straight-on cubie
1147  //Apply total rotation back
1149  }
1150  //Turn the rest of the cubie to match
1151  for (int i = 0; i < 17; i++)
1152  {
1155  }
1156 
1157  //Determing whether the center cubie of the face is behind a z of 0
1158  float centerCubieZ = (cubies[cubieInPos[cubiesOnFace[faceTurning][4]]].points[0].z -
1160  cubies[cubieInPos[cubiesOnFace[faceTurning][4]]].points[6].z;
1161  rotatingFaceBehind = (centerCubieZ >= 0); //if it is behind (larger than) 0, it is drawn second
1162 }
1163 
1164 /*
1165  *
1166  */
1168 {
1169  float testRot [3] = {0, 0, 0};
1170  if (passiveRot)
1171  {
1172 // for (int i = 0; i < 3; i++)
1173 // {
1174 // //if (i == 1)
1175 // testRot[i] = 0.03f;
1176 // }
1177  testRot[0] = 0.01f;
1178  testRot[1] = 0.02f;
1179  testRot[2] = 0.03f;
1180  }
1181 
1182  if (rotating)
1183  {
1184  for (int i = 0; i < 3; i++)
1185  {
1186  rotationTotal[i] += testRot[i];
1187  }
1188 
1189  rotProgress += turnSpd;
1190  if (rotProgress > 1)
1191  {
1192  rotating = false;
1193  rotProgress = 1;
1194  for (int i = 0; i < 26; i++)
1195  {
1196  cubies[i].ResetVisibleFace();
1197  }
1198  }
1200  } else
1201  {
1202  RotateCubies(testRot);
1203  }
1204 }
1205 
1206 void RC::GetSuccessors(const RCState &nodeID, std::vector<RCState> &neighbors) const
1207 {
1208  neighbors.resize(18);
1209  for (int x = 0; x < 18; x++)
1210  {
1211  GetNextState(nodeID, x, neighbors[x]);
1212  }
1213 }
1214 
1215 void RC::GetPrunedActions(const RCState &nodeID, RCAction lastAction, std::vector<RCAction> &actions) const
1216 {
1217  assert(false);
1218 // actions.resize(0);
1219 // for (int x = 0; x < 18; x++)
1220 // {
1221 // // 1. after any face you can't turn the same face again
1222 // if (x/3 == lastAction/3)
1223 // continue;
1224 //
1225 // // 2. after faces 5, 4, 3 you can't turn 0, 2, 1 respectively
1226 // if ((1 == (lastAction/3)%2) &&
1227 // (x/3+1 == lastAction/3))
1228 // continue;
1229 //
1230 // actions.push_back(x);
1231 // }
1232 }
1233 
1234 
1235 void RC::GetActions(const RCState &nodeID, std::vector<RCAction> &actions) const
1236 {
1237  actions.resize(0);
1238  if (!pruneSuccessors || history.size() == 0)
1239  {
1240  for (int x = 0; x < 18; x++)
1241  actions.push_back(x);
1242  }
1243  else {
1244  // 1-3, 2-4, 0-5
1245  // 0, 5, 2, 4, 1, 3
1246  //int firstFace[6] = {true, true, false, false, true, false};
1247  int firstFace[6] = {-1, -1, -1, 1, 2, 0};
1248  for (int x = 0; x < 18; x++)
1249  {
1250  // 1. after any face you can't turn the same face again
1251  if (x/3 == history.back()/3)
1252  continue;
1253 
1254  // 2. after faces 0, 1, 2 you can't turn 4, 3, 5 respectively
1255  if (firstFace[x/3] == history.back()/3)
1256  continue;
1257 // if ((1 == (history.back()/3)%2) &&
1258 // (x/3+1 == history.back()/3))
1259 // continue;
1260 
1261  actions.push_back(x);
1262  }
1263  }
1264 // std::random_shuffle(actions.begin(), actions.end());
1265 }
1266 
1267 RCAction RC::GetAction(const RCState &s1, const RCState &s2) const
1268 {
1269  //std::vector<RCAction> succ;
1270  //GetActions(s1, succ);
1271  RCState tmp;
1272  for (int x = 0; x < 18; x++)
1273  {
1274  GetNextState(s1, x, tmp);
1275  if (tmp == s2)
1276  return x;
1277  }
1278  assert(false);
1279  return 0;
1280 }
1281 
1283 {
1284  s.RotateFace(a/3, a%3);
1285  if (pruneSuccessors)
1286  history.push_back(a);
1287 }
1288 
1290 {
1291  if (pruneSuccessors)
1292  {
1293  assert(history.back() == a);
1294  history.pop_back();
1295  }
1296  InvertAction(a);
1297  s.RotateFace(a/3, a%3);
1298 // assert(false);
1299 // // TODO: verify
1300 // s.RotateFace(a/3, 2-(a%3));
1301 }
1302 
1303 void RC::GetNextState(const RCState &s1, RCAction a, RCState &s2) const
1304 {
1305  s2 = s1;
1306  ApplyAction(s2, a);
1307 }
1308 
1310 {
1311  if (2 == a%3)
1312  return true;
1313  if (1 == a%3)
1314  {
1315  a -= 1;
1316  return true;
1317  }
1318  a += 1;
1319  return true;
1320  return false;
1321 }
1322 
1323 double RC::HCost(const RCState &node1, const RCState &node2, double parentHCost) const
1324 {
1325  return HCost(node1, node2);
1326 }
1327 
1329 double RC::HCost(const RCState &node1, const RCState &node2) const
1330 {
1331  return 0;
1332 }
1333 
1336 double RC::HCost(const RCState &node) const
1337 {
1338  return HCost(node, node);
1339 }
1340 
1341 bool RC::GoalTest(const RCState &node, const RCState &goal) const
1342 {
1343  return node == goal;
1344 }
1345 
1347 bool RC::GoalTest(const RCState &node) const
1348 {
1349  for (int x = 0; x < 20; x++)
1350  {
1351  if (node.indices[x] != x)
1352  return false;
1353  if (node.rotation[x] != 0)
1354  return false;
1355  }
1356  return false;
1357 }
1358 
1359 uint64_t RC::GetStateHash(const RCState &node) const
1360 {
1361  // TODO: write
1362  return 0;
1363 }
1364 
1365 void RC::GetStateFromHash(uint64_t hash, RCState &node) const
1366 {
1367 // TODO: write
1368 }
1369 
1370 void RC::OpenGLDraw() const
1371 {}
1372 
1373 void RC::OpenGLDraw(const RCState&s) const
1374 {}
1375 
1376 void RC::OpenGLDrawCorners(const RCState&s) const
1377 {}
1378 
1379 void RC::OpenGLDrawEdges(const RCState&s) const
1380 {}
1381 
1382 void RC::OpenGLDrawEdgeDual(const RCState&s) const
1383 {}
1384 
1386 {}
1387 
1389 {}
1390 
1391 void RC::OpenGLDrawCube(int cube) const
1392 {}
1393 
1394 void RC::SetFaceColor(int theColor) const
1395 {}
1396 
1397 
1399 void RC::OpenGLDraw(const RCState &s1, const RCState &s2, float t) const
1400 {}
1401 
1402 void RC::OpenGLDraw(const RCState&, const RCAction&) const
1403 {
1404 
1405 }
1406 
1407 // Draw a RCState. Internally do the 3d transform for the drawing.
1408 void RC::Draw(Graphics::Display &display, const RCState &state) const
1409 {
1410  // TEMP: Refresh the cube EVERY FRAME (BAD)
1411  for (int i = 0; i < 20; i++)
1412  {
1413  cubies[convertStatePos[i]].Initialize(i, state.indices[i], state.rotation[i]);
1414  }
1415 
1416  // For every cubie, return it to its original draw angle, and then apply the needed rotation
1417  // This codeblock is a section from RotateCubies(), consider creating a new function
1418  for (int i = 0; i < 26; i++)
1419  {
1420  cubies[i].ResetToBase();
1422  }
1423 
1424  // Draw the newly reset and rotated cubies
1425  DrawCubies(display);
1426 }
1427 
1428 
1429 /*
1430  *
1431  */
1432 void EditPointMult(float (&vec)[3][3], Graphics::point & p)
1433 {
1434  int vecCols = 3;
1435  int vecRows = 3;
1436 
1437  array3[0] = p.x;
1438  array3[1] = p.y;
1439  array3[2] = p.z;
1440 
1441  for (int i = 0; i < vecRows; i++)
1442  {
1443  float sum = 0.f;
1444 
1445  for (int j = 0; j < vecCols; j++)
1446  {
1447  sum += vec[i][j] * array3[j];
1448  }
1449 
1450  switch (i)
1451  {
1452  case 0: p.x = sum;
1453  break;
1454  case 1: p.y = sum;
1455  break;
1456  case 2: p.z = sum;
1457  break;
1458  }
1459  }
1460 }
1461 
1462 /* Edit an existing 3x3 vector to become the
1463  * X rotation multiplication matrix for a given angle
1464  */
1465 //void MakeMatrixRotX(std::vector<std::vector<float>> & a, float angle) {
1466 void MakeMatrixRotX(float (&a)[3][3], float angle) {
1467  a[0][0] = 1;
1468  a[0][1] = 0;
1469  a[0][2] = 0;
1470 
1471  a[1][0] = 0;
1472  a[1][1] = cos(angle);
1473  a[1][2] = -sin(angle);
1474 
1475  a[2][0] = 0;
1476  a[2][1] = sin(angle);
1477  a[2][2] = cos(angle);
1478 }
1479 
1480 /* Edit an existing 3x3 vector to become the
1481  * Y rotation multiplication matrix for a given angle
1482  */
1483 //void MakeMatrixRotY(std::vector<std::vector<float>> & a, float angle) {
1484 void MakeMatrixRotY(float (&a)[3][3], float angle) {
1485  a[0][0] = cosf(angle);
1486  a[0][1] = 0;
1487  a[0][2] = -sin(angle);
1488 
1489  a[1][0] = 0;
1490  a[1][1] = 1;
1491  a[1][2] = 0;
1492 
1493  a[2][0] = sin(angle);
1494  a[2][1] = 0;
1495  a[2][2] = cos(angle);
1496 }
1497 
1498 /* Edit an existing 3x3 vector to become the
1499  * Z rotation multiplication matrix for a given angle
1500  */
1501 //void MakeMatrixRotZ(std::vector<std::vector<float>> & a, float angle) {
1502 void MakeMatrixRotZ(float (&a)[3][3], float angle) {
1503  a[0][0] = cosf(angle);
1504  a[0][1] = -sin(angle);
1505  a[0][2] = 0;
1506 
1507  a[1][0] = sin(angle);
1508  a[1][1] = cos(angle);
1509  a[1][2] = 0;
1510 
1511  a[2][0] = 0;
1512  a[2][1] = 0;
1513  a[2][2] = 1;
1514 }
1515 
1516 /* Returns the index of the integer element within the given bounds of an array
1517  * Returns -1 if not found
1518  */
1519 int findInArray(int arr[], int elem, int lower, int upper)
1520 {
1521  for (int i = lower; i < upper; i++)
1522  {
1523  if (arr[i] == elem) return i;
1524  }
1525  return -1;
1526  // TODO: binary search
1527 }
1528 
1529 /*===============================================================================================================================================================================
1530  * RANKING (CORNERS)
1531  ===============================================================================================================================================================================*/
1532 
1533 uint64_t RC::GetPDBSizeCorner() const
1534 {
1535  uint64_t answer[] = {1, 24, 504, 9072, 136080, 1632960, 14696640, 88179840, 88179840};
1536  return 2187; //answer[corners.size()];
1537 }
1538 
1539 uint64_t RC::GetPDBHashCorner(const RCState &s, int threadID) const
1540 {
1541  // Initialize variables
1542  int puzzle[8];
1543  int dual[16];
1544  int cornerSize = corners.size();
1545  int lastPiece = 8-(int)corners.size();
1546  for (int x = 0; x < 8; x++)
1547  dual[s.indices[x+12]-12] = x;
1548  for (int x = 0; x < cornerSize; x++)
1549  puzzle[x] = dual[corners[x]];
1550 
1551  uint64_t hashVal = 0;
1552  uint64_t part2 = 0;
1553  int numEntriesLeft = 8;
1554 // for (unsigned int x = 0; x < cornerSize; x++)
1555 // {
1556 // hashVal += puzzle[x] * FactorialUpperK(numEntriesLeft-1, lastPiece);
1557 //
1558 // numEntriesLeft--;
1559 // for (unsigned y = x; y < cornerSize; y++)
1560 // {
1561 // if (puzzle[y] > puzzle[x])
1562 // puzzle[y]--;
1563 // }
1564 // }
1565 
1566  int limit = std::min((int)cornerSize, 7);
1567  for (int x = 0; x < limit; x++)
1568  {
1569  part2 = part2*3 + s.rotation[corners[x]];
1570  }
1571 
1572  return part2; //* FactorialUpperK(8, lastPiece)+hashVal;
1573 }
1574 
1575 
1576 void RC::GetStateFromPDBHashCorner(uint64_t hash, RCState &s, int threadID) const
1577 {
1578  int lastPiece = 8-(int)corners.size();
1579  int cornerSize = corners.size();
1580  int puzzle[12];
1581  int dual[16];
1582  uint64_t hashVal = hash;
1583 
1584 // hash /= FactorialUpperK(8, lastPiece); // for rotations
1585 // hashVal = hashVal%FactorialUpperK(8, lastPiece); // for pieces
1586 //
1587 // int numEntriesLeft = lastPiece+1;
1588 // for (int x = corners.size()-1; x >= 0; x--)
1589 // {
1590 // puzzle[x] = hashVal % numEntriesLeft;
1591 // hashVal /= numEntriesLeft;
1592 // numEntriesLeft++;
1593 // for (int y = x+1; y < cornerSize; y++)
1594 // {
1595 // if (puzzle[y] >= puzzle[x])
1596 // puzzle[y]++;
1597 // }
1598 // }
1599 
1600  for (int x = 0; x < 8; x++)
1601  {
1602  s.indices[x+12] = 0xF;
1603  s.rotation[x+12] = x;
1604  }
1605 
1606  for (int x = 0; x < cornerSize; x++)
1607  {
1608  s.indices[puzzle[x]] = corners[x];
1609  dual[corners[x]] = puzzle[x];
1610  }
1611 
1612  int cnt = 0;
1613  int limit = std::min((int)corners.size(), 7);
1614  for (int x = limit-1; x >= 0; x--)
1615  {
1616  s.rotation[corners[x]] = hash%3;
1617  cnt += hash%3;
1618  hash/=3;
1619  }
1620  if (corners.size() == 8)
1621  s.rotation[corners[7]] = (3-(cnt%3)); // 0->0 2->1 1->2
1622 }
1623 
1624 // KEEP
1626 {
1627  uint64_t hashVal = 0;
1628  for (int x = 0; x < 7; x++)
1629  {
1630  hashVal = (hashVal<<1) + s.rotation[19-x];
1631  }
1632  return hashVal;
1633 }
1634 
1635 /*===============================================================================================================================================================================
1636  * RANKING (EDGES)
1637  ===============================================================================================================================================================================*/
1638 //
1639 //uint64_t RC::GetPDBSizeEdge() const
1640 //{
1641 // // last tile is symmetric
1642 // uint64_t power2[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 2048};
1643 // int elts = (int)edges.size();
1644 // return FactorialUpperK(12, 12-elts)*power2[elts];
1646 //}
1647 //
1648 //uint64_t RC::GetPDBHashEdge(const RCState &s, int threadID) const
1649 //{
1650 // int puzzle[12];
1651 // int dual[16]; // seamlessly handle 0xF entries (no cube)
1652 // int lastPiece = 12-(int)edges.size();
1653 // //std::cout << "!" << s << "\n";
1654 // for (int x = 0; x < 12; x++)
1655 // dual[s.GetCubeInLoc(x)] = x;
1656 // for (int x = 0; x < edges.size(); x++)
1657 // puzzle[x] = dual[edges[x]];
1658 //
1659 // uint64_t hashVal = 0;
1660 // uint64_t part2 = 0;
1661 // int numEntriesLeft = 12;
1662 // for (unsigned int x = 0; x < edges.size(); x++)
1663 // {
1664 // hashVal += puzzle[x]*FactorialUpperK(numEntriesLeft-1, lastPiece);
1665 //
1666 // numEntriesLeft--;
1667 // for (unsigned y = x; y < edges.size(); y++)
1668 // {
1669 // if (puzzle[y] > puzzle[x])
1670 // puzzle[y]--;
1671 // }
1672 // }
1673 // int limit = std::min((int)edges.size(), 11);
1674 // for (int x = 0; x < limit; x++)
1675 // {
1676 // part2 = part2*2+(s.GetCubeOrientation(edges[x])?1:0);
1677 // //part2 = part2*3+s.GetCubeOrientation(dual[corners[x]]);
1678 // }
1679 // return part2*FactorialUpperK(12, lastPiece)+hashVal;
1680 //}
1681 //
1682 //void RC::GetStateFromPDBHashEdge(uint64_t hash, RCState &s, int threadID) const
1683 //{
1684 // int lastPiece = 12-(int)edges.size();
1685 // int puzzle[12];
1686 // int dual[16];
1687 // uint64_t hashVal = hash;
1688 // hash /= FactorialUpperK(12, lastPiece); // for rotations
1689 // hashVal = hashVal%FactorialUpperK(12, lastPiece); // for pieces
1690 //
1691 // int numEntriesLeft = lastPiece+1;
1692 // for (int x = edges.size()-1; x >= 0; x--)
1693 // {
1694 // puzzle[x] = hashVal%numEntriesLeft;
1695 // hashVal /= numEntriesLeft;
1696 // numEntriesLeft++;
1697 // for (int y = x+1; y < edges.size(); y++)
1698 // {
1699 // if (puzzle[y] >= puzzle[x])
1700 // puzzle[y]++;
1701 // }
1702 // }
1703 // for (int x = 0; x < 12; x++)
1704 // {
1705 // s.SetCubeInLoc(x, 0xF);
1706 // s.SetCubeOrientation(x, 0);
1707 // }
1708 //
1709 // for (int x = 0; x < edges.size(); x++)
1710 // {
1711 // s.SetCubeInLoc(puzzle[x], edges[x]);
1712 // dual[edges[x]] = puzzle[x];
1713 // }
1714 //
1715 // int cnt = 0;
1716 // int limit = std::min((int)edges.size(), 11);
1717 // for (int x = limit-1; x >= 0; x--)
1718 // {
1719 // s.SetCubeOrientation(edges[x], hash%2);
1720 // //s.SetCubeOrientation(dual[corners[x]], hash%3);
1721 // cnt += hash%2;
1722 // hash/=2;
1723 // }
1724 // if (edges.size() == 12)
1725 // s.SetCubeOrientation(edges[11], cnt%2);
1726 //}
1727 //
1728 //
1730 //uint64_t RC::GetStateHashEdge(const RCState &s)
1731 //{
1732 // uint64_t hashVal = 0;
1733 // for (int x = 0; x < 11; x++)
1734 // {
1735 // hashVal = (hashVal<<1)+s.GetCubeOrientation(11-x);
1736 // }
1737 // return hashVal;
1738 //}
1739 
1740 uint64_t RC::FactorialUpperK(int n, int k) const
1741 {
1742  const uint64_t result[9][9] = {
1743  {1}, // n = 0
1744  {1, 1}, // n = 1
1745  {2, 2, 1}, // n = 2
1746  {6, 6, 3, 1}, // n = 3
1747  {24, 24, 12, 4, 1}, // n = 4
1748  {120, 120, 60, 20, 5, 1}, // n = 5
1749  {720, 720, 360, 120, 30, 6, 1}, // n = 6
1750  {5040, 5040, 2520, 840, 210, 42, 7, 1}, // n = 7
1751  {40320, 40320, 20160, 6720, 1680, 336, 56, 8, 1}, // n = 8
1752  };
1753  return result[n][k];
1754 }
1755 
1756 
1757 
1758 // PDB Class
1759 
1761  const std::array<bool, 12> &edgeRotations, const std::array<bool, 12> &edgeLocations,
1762  const std::array<bool, 8> &cornerRotations, const std::array<bool, 8> &cornerLocations)
1763 :PDBHeuristic(e)
1764 {
1765  for (int x = 0; x < 12; x++)
1766  {
1767  if (edgeRotations.at(x))
1768  this->edgeRotations.push_back(x);
1769  if (edgeLocations.at(x))
1770  this->edgeLocations.push_back(x);
1771  }
1772  for (int x = 0; x < 8; x++)
1773  {
1774  if (cornerRotations.at(x))
1775  this->cornerRotations.push_back(x);
1776  if (cornerLocations.at(x))
1777  this->cornerLocations.push_back(x);
1778  }
1779 }
1780 
1781 uint64_t RCPDB::GetStateHash(const RCState &s) const
1782 {
1783  assert(false); // not implemented currently
1784 }
1785 
1786 void RCPDB::GetStateFromHash(RCState &s, uint64_t hash) const
1787 {
1788  assert(false);
1789 }
1790 
1791 uint64_t RCPDB::GetPDBSize() const
1792 {
1794 // return 4478976; // 2^11 * 3^7
1795 }
1796 
1797 uint64_t RCPDB::GetPDBHash(const RCState &s, int threadID) const
1798 {
1799  uint64_t hash = 0;
1800  hash = GetEdgeLocationHash(s); // edge loc
1801  hash *= GetEdgeRotationSize(); // make space for edge rot
1802  hash += GetEdgeRotationHash(s); // edge rot
1803  hash *= GetCornerLocationSize(); // make space for corner loc
1804  hash += GetCornerLocationHash(s); // corner loc
1805  hash *= GetCornerRotationSize(); // make space for corner rot
1806  hash += GetCornerRotationHash(s); // corner rot
1807 // std::cout << "Hashes: el:" << GetEdgeLocationHash(s) << " er:" << GetEdgeRotationHash(s) <<
1808 // " cl:" << GetCornerLocationHash(s) << " cr:" << GetCornerRotationHash(s) << "\n";
1809  return hash;
1810 
1811 // // NOTE: Assuming edges + corners for now
1812 // // int indices[20]; //Index of cubie in position
1813 // // int rotation[20]; //Rotation of cubie in position
1814 // uint64_t hash = 0;
1815 // for (int x = 0; x < 11; x++)
1816 // hash = 2*hash + s.rotation[x];
1817 // for (int x = 12; x < 19; x++)
1818 // hash = 3*hash + s.rotation[x];
1819 // return hash;
1820 }
1821 
1822 void RCPDB::GetStateFromPDBHash(uint64_t hash, RCState &s, int threadID) const
1823 {
1824 // hash = GetEdgeLocationHash(s); // edge loc
1825 // hash *= GetEdgeRotationSize(); // make space for edge rot
1826 // hash += GetEdgeRotationHash(s); // edge rot
1827 // hash *= GetCornerLocationSize(); // make space for corner loc
1828 // hash += GetCornerLocationHash(s); // corner loc
1829 // hash *= GetCornerRotationSize(); // make space for corner rot
1830 // hash += GetCornerRotationHash(s); // corner rot
1831 
1832 
1834 // std::cout << "unrank cr:" << hash%GetCornerRotationSize();
1835  hash /= GetCornerRotationSize();
1837 // std::cout << " cl:" << hash%GetCornerLocationSize();
1838  hash /= GetCornerLocationSize();
1840 // std::cout << " er:" << hash%GetEdgeRotationSize();
1841  hash /= GetEdgeRotationSize();
1843 // std::cout << " el:" << hash << "\n";
1844 
1845 // int two = 0;
1846 // int three = 0;
1847 // for (int x = 18; x >= 12; x--)
1848 // {
1849 // s.rotation[x] = hash%3;
1850 // three += s.rotation[x];
1851 // hash /= 3;
1852 // }
1853 // // fill in s.rotation[19]
1854 // s.rotation[19] = (3-(two%3))%3;
1855 // for (int x = 10; x >= 0; x--)
1856 // {
1857 // s.rotation[x] = hash%2;
1858 // two += s.rotation[x];
1859 // hash /= 2;
1860 // }
1861 // // fill in s.rotation[11]
1862 // s.rotation[11] = two%2;
1863 }
1864 
1866 {
1867  int limit = std::min((int)edgeRotations.size(), 11);
1868  return 1ull<<limit;
1869 }
1870 
1872 {
1873  return FactorialUpperK(12, 12-(int)edgeLocations.size());
1874 }
1875 
1877 {
1878  uint64_t answer[] = {1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683};
1879  int limit = std::min((int)cornerRotations.size(), 7);
1880  return answer[limit];
1881 }
1882 
1884 {
1885  return FactorialUpperK(8, 8-(int)cornerLocations.size());
1886 }
1887 
1888 uint64_t RCPDB::GetEdgeRotationHash(const RCState &s) const
1889 {
1890  int limit = std::min((int)edgeRotations.size(), 11);
1891  uint64_t hash = 0;
1892  for (int x = 0; x < limit; x++)
1893  {
1894  hash = hash*2+(s.rotation[edgeRotations[x]]?1:0);
1895  //part2 = part2*3+s.GetCubeOrientation(dual[corners[x]]);
1896  }
1897  return hash;
1898 }
1899 
1900 uint64_t RCPDB::GetEdgeLocationHash(const RCState &s) const
1901 {
1902  if (edgeLocations.size() == 0)
1903  return 0;
1904  int puzzle[12];
1905  int dual[16]; // seamlessly handle 0xF entries (no cube)
1906  int lastPiece = 12-(int)edgeLocations.size();
1907  //std::cout << "!" << s << "\n";
1908  for (int x = 0; x < 12; x++)
1909  dual[s.indices[x]] = x;
1910  for (int x = 0; x < edgeLocations.size(); x++)
1911  puzzle[x] = dual[edgeLocations[x]];
1912 
1913  uint64_t hashVal = 0;
1914  int numEntriesLeft = 12;
1915  for (unsigned int x = 0; x < edgeLocations.size(); x++)
1916  {
1917  hashVal += puzzle[x]*FactorialUpperK(numEntriesLeft-1, lastPiece);
1918 
1919  numEntriesLeft--;
1920  for (unsigned y = x; y < edgeLocations.size(); y++)
1921  {
1922  if (puzzle[y] > puzzle[x])
1923  puzzle[y]--;
1924  }
1925  }
1926  return hashVal;
1927 
1928 }
1929 
1930 uint64_t RCPDB::GetCornerRotationHash(const RCState &s) const
1931 {
1932  int limit = std::min((int)cornerRotations.size(), 7);
1933  uint64_t hash = 0;
1934  for (int x = 0; x < limit; x++)
1935  {
1936  hash = hash*3+s.rotation[12+cornerRotations[x]];
1937  //part2 = part2*3+s.GetCubeOrientation(dual[corners[x]]);
1938  }
1939  return hash;
1940 }
1941 
1942 uint64_t RCPDB::GetCornerLocationHash(const RCState &s) const
1943 {
1944  if (cornerLocations.size() == 0)
1945  return 0;
1946  // TODO: handle fewer according to pattern
1947  int puzzle[8];
1948  int dual[16]; // seamlessly handle 0xF entries (no cube)
1949  int cornerSize = (int)cornerLocations.size();
1950  int lastPiece = 8-(int)cornerLocations.size();
1951  for (int x = 0; x < 8; x++)
1952  dual[s.indices[12+x]-12] = x;
1953  for (int x = 0; x < cornerLocations.size(); x++)
1954  puzzle[x] = dual[cornerLocations[x]];
1955 
1956  uint64_t hashVal = 0;
1957  int numEntriesLeft = 8;
1958  for (unsigned int x = 0; x < cornerSize; x++)
1959  {
1960  hashVal += puzzle[x]*FactorialUpperK(numEntriesLeft-1, lastPiece);
1961 
1962  numEntriesLeft--;
1963  for (unsigned y = x; y < cornerLocations.size(); y++)
1964  {
1965  if (puzzle[y] > puzzle[x])
1966  puzzle[y]--;
1967  }
1968  }
1969  return hashVal;
1970 // return part2*FactorialUpperK(8, lastPiece)+hashVal;
1971 }
1972 
1973 void RCPDB::GetStateFromEdgeRotationHash(RCState &s, uint64_t hash) const
1974 {
1975  for (int x = 0; x < 12; x++)
1976  {
1977 // s.SetCubeInLoc(x, 0xF);
1978 // s.SetCubeOrientation(x, 0);
1979  s.rotation[x] = 0;
1980  }
1981 
1982  int cnt = 0;
1983  int limit = std::min((int)edgeRotations.size(), 11);
1984  for (int x = limit-1; x >= 0; x--)
1985  {
1986  s.rotation[edgeRotations[x]] = hash%2;
1987 // s.SetCubeOrientation(edgeRotations[x], hash%2);
1988  //s.SetCubeOrientation(dual[corners[x]], hash%3);
1989  cnt += hash%2;
1990  hash/=2;
1991  }
1992  if (edgeRotations.size() == 12)
1993  s.rotation[edgeRotations[11]] = cnt%2;
1994 // s.SetCubeOrientation(edges[11], cnt%2);
1995 
1996 }
1997 
1998 void RCPDB::GetStateFromEdgeLocationHash(RCState &s, uint64_t hash) const
1999 {
2000  int lastPiece = 12-(int)edgeLocations.size();
2001  int puzzle[12];
2002  int dual[16];
2003  uint64_t hashVal = hash;
2004  hash /= FactorialUpperK(12, lastPiece); // for rotations
2005  hashVal = hashVal%FactorialUpperK(12, lastPiece); // for pieces
2006 
2007  int numEntriesLeft = lastPiece+1;
2008  for (int x = (int) edgeLocations.size()-1; x >= 0; x--)
2009  {
2010  puzzle[x] = hashVal%numEntriesLeft;
2011  hashVal /= numEntriesLeft;
2012  numEntriesLeft++;
2013  for (int y = x+1; y < edgeLocations.size(); y++)
2014  {
2015  if (puzzle[y] >= puzzle[x])
2016  puzzle[y]++;
2017  }
2018  }
2019  for (int x = 0; x < 12; x++)
2020  {
2021  s.indices[x] = 0xF;
2022 // s.SetCubeInLoc(x, 0xF);
2023 // s.SetCubeOrientation(x, 0);
2024  }
2025 
2026  for (int x = 0; x < edgeLocations.size(); x++)
2027  {
2028  s.indices[puzzle[x]] = edgeLocations[x];
2029  //s.SetCubeInLoc(puzzle[x], edgeLocations[x]);
2030  dual[edgeLocations[x]] = puzzle[x];
2031  }
2032 
2033 }
2034 
2035 void RCPDB::GetStateFromCornerRotationHash(RCState &s, uint64_t hash) const
2036 {
2037  for (int x = 0; x < 8; x++)
2038  {
2039  s.rotation[12+x] = 0;
2040  }
2041  int cnt = 0;
2042  int limit = std::min((int)cornerRotations.size(), 7);
2043  for (int x = limit-1; x >= 0; x--)
2044  {
2045  s.rotation[12+cornerRotations[x]] = hash%3;
2046 // s.SetCubeOrientation(cornerRotations[x], hash%3);
2047  cnt += hash%3;
2048  hash/=3;
2049  }
2050  if (cornerRotations.size() == 8)
2051  {
2052  s.rotation[12+cornerRotations[7]] = (3-(cnt%3))%3; // 0->0 2->1 1->2
2053  cnt += s.rotation[12+cornerRotations[7]];
2054  }
2055  assert((cnt%3) == 0);
2056 }
2057 
2058 void RCPDB::GetStateFromCornerLocationHash(RCState &s, uint64_t hash) const
2059 {
2060  int lastPiece = 8-(int)cornerLocations.size();
2061  int cornerSize = (int)cornerLocations.size();
2062  int puzzle[12];
2063 // int dual[16];
2064  uint64_t hashVal = hash;
2065  hash /= FactorialUpperK(8, lastPiece); // for rotations
2066  hashVal = hashVal%FactorialUpperK(8, lastPiece); // for pieces
2067 
2068  int numEntriesLeft = lastPiece+1;
2069  for (int x = (int)cornerLocations.size()-1; x >= 0; x--)
2070  {
2071  puzzle[x] = hashVal%numEntriesLeft;
2072  hashVal /= numEntriesLeft;
2073  numEntriesLeft++;
2074  for (int y = x+1; y < cornerSize; y++)
2075  {
2076  if (puzzle[y] >= puzzle[x])
2077  puzzle[y]++;
2078  }
2079  }
2080  for (int x = 0; x < 8; x++)
2081  {
2082  s.indices[12+x] = 0xF;
2083 // s.SetCubeInLoc(x, 0xF);
2084 // s.SetCubeOrientation(x, 0);
2085  }
2086 
2087  for (int x = 0; x < cornerSize; x++)
2088  {
2089  s.indices[12+puzzle[x]] = 12+cornerLocations[x];
2090 // s.SetCubeInLoc(puzzle[x], cornerLocations[x]);
2091 // dual[cornerLocations[x]] = puzzle[x];
2092  }
2093 }
2094 
2095 uint64_t RCPDB::FactorialUpperK(int n, int k) const
2096 {
2097  const uint64_t result[13][13] = {
2098  {1}, // n = 0
2099  {1, 1}, // n = 1
2100  {2, 2, 1}, // n = 2
2101  {6, 6, 3, 1}, // n = 3
2102  {24, 24, 12, 4, 1}, // n = 4
2103  {120, 120, 60, 20, 5, 1}, // n = 5
2104  {720, 720, 360, 120, 30, 6, 1}, // n = 6
2105  {5040, 5040, 2520, 840, 210, 42, 7, 1}, // n = 7
2106  {40320, 40320, 20160, 6720, 1680, 336, 56, 8, 1}, // n = 8
2107  {362880, 362880, 181440, 60480, 15120, 3024, 504, 72, 9, 1}, // n = 9
2108  {3628800, 3628800, 1814400, 604800, 151200, 30240, 5040, 720, 90, 10, 1}, // n = 10
2109  {39916800, 39916800, 19958400, 6652800, 1663200, 332640, 55440, 7920, 990, 110, 11, 1}, // n = 11
2110  {479001600, 479001600, 239500800, 79833600, 19958400, 3991680, 665280, 95040, 11880, 1320, 132, 12, 1} // n = 12
2111  };
2112  return result[n][k];
2113 }
2114 
RC::turnArr
float turnArr[3]
Definition: RC.h:301
Cubie::faceColors
const rgbColor faceColors[6]
Definition: RC.h:60
RCPDB::GetEdgeRotationSize
uint64_t GetEdgeRotationSize() const
Definition: RC.cpp:1865
Graphics::point
Definition: Graphics.h:32
RCAction
int RCAction
Definition: RC.h:202
RCState::RotateEdges
void RotateEdges(int move)
Definition: RC.cpp:748
Graphics::point::y
float y
Definition: Graphics.h:36
RC::UndoAction
void UndoAction(RCState &s, RCAction a) const
Definition: RC.cpp:1289
RC::GetAction
RCAction GetAction(const RCState &s1, const RCState &s2) const
Definition: RC.cpp:1267
Cubie::faceOrderByAxis
const int faceOrderByAxis[3][4]
Definition: RC.h:69
RC::rotating
bool rotating
Definition: RC.h:298
RCPDB::GetStateFromEdgeRotationHash
void GetStateFromEdgeRotationHash(RCState &s, uint64_t hash) const
Definition: RC.cpp:1973
min
double min(double a, double b)
Definition: FPUtil.h:35
RC::DrawCubiesRotating
void DrawCubiesRotating(Graphics::Display &display) const
Definition: RC.cpp:981
furthestZ
std::vector< int > furthestZ(0)
RC::piOver2
const float piOver2
Definition: RC.h:263
RC::GetStateFromPDBHashCorner
void GetStateFromPDBHashCorner(uint64_t hash, RCState &s, int threadID) const
Definition: RC.cpp:1576
RC::OpenGLDrawEdges
void OpenGLDrawEdges(const RCState &) const
Definition: RC.cpp:1379
RCPDB::GetStateFromHash
void GetStateFromHash(RCState &s, uint64_t hash) const
Definition: RC.cpp:1786
RC::GetStateFromHash
void GetStateFromHash(uint64_t hash, RCState &node) const
Definition: RC.cpp:1365
Cubie::Initialize
void Initialize(int ind)
Definition: RC.cpp:224
RC::RotateFace
void RotateFace(int face, int move)
Definition: RC.cpp:1028
RCPDB::GetEdgeLocationSize
uint64_t GetEdgeLocationSize() const
Definition: RC.cpp:1871
RC::faceTurning
int faceTurning
Definition: RC.h:296
RCPDB::GetEdgeRotationHash
uint64_t GetEdgeRotationHash(const RCState &s) const
Definition: RC.cpp:1888
RC
Definition: RC.h:244
RC::faceBlackUnderside
const int faceBlackUnderside[6]
Definition: RC.h:259
Cubie::facesShowing
const int facesShowing[20][3]
Definition: RC.h:75
RCState::ShiftPositionsCCW
void ShiftPositionsCCW(const int(&arr)[4])
Definition: RC.cpp:883
RCPDB::GetCornerLocationSize
uint64_t GetCornerLocationSize() const
Definition: RC.cpp:1883
EditPointMult
void EditPointMult(float(&vec)[3][3], Graphics::point &p)
Definition: RC.cpp:1432
RC::pruneSuccessors
bool pruneSuccessors
Definition: RC.h:431
RCPDB::edgeLocations
std::vector< int > edgeLocations
Definition: RC.h:488
RC::InterpFaceRot
void InterpFaceRot(float progress)
Definition: RC.cpp:1133
rotation
float rotation[3][3]
Definition: RC.cpp:21
Cubie::ResetVisibleFace
void ResetVisibleFace()
Definition: RC.cpp:536
RC::passiveRot
bool passiveRot
Definition: RC.h:303
RC::cubieInPos
int cubieInPos[26]
Definition: RC.h:295
RCPDB::GetCornerRotationSize
uint64_t GetCornerRotationSize() const
Definition: RC.cpp:1876
RCState::PrintState
void PrintState()
Definition: RC.cpp:940
Cubie::RCindex
int RCindex
Definition: RC.h:36
RC::OpenGLDrawCorners
void OpenGLDrawCorners(const RCState &) const
Definition: RC.cpp:1376
RCState::indices
int indices[20]
Definition: RC.h:153
RC::fromFaceToCenter
const int fromFaceToCenter[6]
Definition: RC.h:253
RC::OpenGLDrawCubeBackground
void OpenGLDrawCubeBackground() const
Definition: RC.cpp:1385
RC::cubies
Cubie cubies[26]
Definition: RC.h:292
RCState::rotation
int rotation[20]
Definition: RC.h:154
RC::GetPrunedActions
void GetPrunedActions(const RCState &nodeID, RCAction lastAction, std::vector< RCAction > &actions) const
Definition: RC.cpp:1215
RC::rotProgress
float rotProgress
Definition: RC.h:300
RCPDB::GetEdgeLocationHash
uint64_t GetEdgeLocationHash(const RCState &s) const
Definition: RC.cpp:1900
Cubie::facePoints
std::vector< std::vector< Graphics::point > > facePoints
Definition: RC.h:33
RCPDB::GetStateFromPDBHash
void GetStateFromPDBHash(uint64_t hash, RCState &s, int threadID=0) const
Definition: RC.cpp:1822
RC::FactorialUpperK
uint64_t FactorialUpperK(int n, int k) const
Definition: RC.cpp:1740
Cubie::faceInPos
int faceInPos[6]
Definition: RC.h:39
RC::GetActions
void GetActions(const RCState &nodeID, std::vector< RCAction > &actions) const
Definition: RC.cpp:1235
RCPDB::GetStateFromCornerLocationHash
void GetStateFromCornerLocationHash(RCState &s, uint64_t hash) const
Definition: RC.cpp:2058
MakeMatrixRotZ
void MakeMatrixRotZ(float(&a)[3][3], float angle)
Definition: RC.cpp:1502
RCPDB::GetStateHash
uint64_t GetStateHash(const RCState &s) const
Definition: RC.cpp:1781
RC::GetPDBHashCorner
uint64_t GetPDBHashCorner(const RCState &s, int threadID) const
Definition: RC.cpp:1539
RCState::RotateCorners
void RotateCorners(int move)
Definition: RC.cpp:775
Cubie::pointsOnFace
const int pointsOnFace[6][4]
Definition: RC.h:51
RC::rotationTotal
float rotationTotal[3]
Definition: RC.h:293
Cubie::sideLen
const float sideLen
Definition: RC.h:42
RC::SetFaceColor
void SetFaceColor(int face) const
Definition: RC.cpp:1394
RC::notInFaceTurning
int notInFaceTurning[6][17]
Definition: RC.h:297
RC::GoalTest
bool GoalTest(const RCState &node, const RCState &goal) const
Definition: RC.cpp:1341
RCPDB::GetCornerLocationHash
uint64_t GetCornerLocationHash(const RCState &s) const
Definition: RC.cpp:1942
RC::interpArr
float interpArr[3]
Definition: RC.h:302
RCState::ShiftPositionsCW
void ShiftPositionsCW(const int(&arr)[4])
Definition: RC.cpp:858
RCPDB::RCPDB
RCPDB(RC *e, const std::array< bool, 12 > &edgeRotations, const std::array< bool, 12 > &edgeLocations, const std::array< bool, 8 > &cornerRotations, const std::array< bool, 8 > &cornerLocations)
Definition: RC.cpp:1760
RCPDB::cornerLocations
std::vector< int > cornerLocations
Definition: RC.h:490
PDBHeuristic
Definition: PDBHeuristic.h:39
Graphics::Display
Definition: Graphics.h:146
RCPDB::edgeRotations
std::vector< int > edgeRotations
Definition: RC.h:487
RC::rotatingFaceBehind
bool rotatingFaceBehind
Definition: RC.h:299
Cubie::Draw
void Draw(Graphics::Display &display) const
Definition: RC.cpp:350
Cubie::RotateRelative
void RotateRelative(const float angle[3])
Definition: RC.cpp:433
edgesOnFace
const int edgesOnFace[6][4]
Definition: RC.cpp:24
RC::cubiesOnFace
int cubiesOnFace[6][9]
Definition: RC.h:294
Cubie::facesShown
bool facesShown[6]
Definition: RC.h:37
RC::InvertAction
bool InvertAction(RCAction &a) const
Definition: RC.cpp:1309
RCState
Definition: RC.h:136
RCPDB::GetStateFromCornerRotationHash
void GetStateFromCornerRotationHash(RCState &s, uint64_t hash) const
Definition: RC.cpp:2035
RCState::RotateFace
void RotateFace(int move)
Definition: RC.cpp:650
Cubie::RotateFacePos
void RotateFacePos(bool clockwise, int axis)
Definition: RC.cpp:489
Cubie::inCol
const rgbColor inCol
Definition: RC.h:45
Cubie::points
std::vector< Graphics::point > points
Definition: RC.h:32
RC::GetSuccessors
void GetSuccessors(const RCState &nodeID, std::vector< RCState > &neighbors) const
Definition: RC.cpp:1206
RC::DrawCubies
void DrawCubies(Graphics::Display &display) const
Definition: RC.cpp:964
Cubie::basePoints
std::vector< Graphics::point > basePoints
Definition: RC.h:30
RC::OpenGLDrawCube
void OpenGLDrawCube(int cube) const
Definition: RC.cpp:1391
RCPDB::GetPDBHash
uint64_t GetPDBHash(const RCState &s, int threadID=0) const
Definition: RC.cpp:1797
RC::corners
std::vector< int > corners
Definition: RC.h:248
RC.h
RC::GetStateHash
uint64_t GetStateHash(const RCState &node) const
Definition: RC.cpp:1359
RC::ApplyAction
void ApplyAction(RCState &s, RCAction a) const
Definition: RC.cpp:1282
RC::turnSpd
const float turnSpd
Definition: RC.h:264
cornersOnFace
const int cornersOnFace[6][4]
Definition: RC.cpp:42
Cubie::faceCols
rgbColor faceCols[6]
Definition: RC.h:34
RC::Draw
void Draw(Graphics::Display &display, const RCState &) const
Definition: RC.cpp:1408
RC::convertStatePos
const int convertStatePos[20]
Definition: RC.h:267
array3
float array3[3]
Definition: RC.cpp:20
RC::GetStateHashCorner
uint64_t GetStateHashCorner(const RCState &s)
Definition: RC.cpp:1625
Graphics::point::x
float x
Definition: Graphics.h:36
RCState::ShiftPositions
void ShiftPositions(const int(&arr)[4], bool forward)
Definition: RC.cpp:908
Graphics::point::z
float z
Definition: Graphics.h:36
Cubie::ResetToBase
void ResetToBase()
Definition: RC.cpp:514
Cubie::index
int index
Definition: RC.h:35
Cubie::blackFaceToReset
int blackFaceToReset
Definition: RC.h:38
Cubie::RotateBase
void RotateBase(float angle[3])
Definition: RC.cpp:461
Cubie::baseFacePoints
std::vector< std::vector< Graphics::point > > baseFacePoints
Definition: RC.h:31
RC::OpenGLDraw
void OpenGLDraw() const
Definition: RC.cpp:1370
RC::HCost
double HCost(const RCState &node1, const RCState &node2) const
Heuristic value between two arbitrary nodes.
Definition: RC.cpp:1329
Cubie::PrintData
void PrintData()
Definition: RC.cpp:557
RC::history
std::vector< RCAction > history
Definition: RC.h:429
MakeMatrixRotY
void MakeMatrixRotY(float(&a)[3][3], float angle)
Definition: RC.cpp:1484
RC::GetPDBSizeCorner
uint64_t GetPDBSizeCorner() const
Definition: RC.cpp:1533
RC::OpenGLDrawCenters
void OpenGLDrawCenters() const
Definition: RC.cpp:1388
RCState::SwapPositions
void SwapPositions(int p1, int p2)
Definition: RC.cpp:844
findInArray
int findInArray(int arr[], int elem, int lower, int upper)
Definition: RC.cpp:1519
Cubie::DrawFace
void DrawFace(Graphics::Display &display, int index) const
Definition: RC.cpp:417
RC::OpenGLDrawEdgeDual
void OpenGLDrawEdgeDual(const RCState &) const
Definition: RC.cpp:1382
RCPDB::GetStateFromEdgeLocationHash
void GetStateFromEdgeLocationHash(RCState &s, uint64_t hash) const
Definition: RC.cpp:1998
Cubie::SetFacePositionVisible
void SetFacePositionVisible(bool toggle, int position)
Definition: RC.cpp:548
RCPDB::GetPDBSize
uint64_t GetPDBSize() const
Definition: RC.cpp:1791
RC::RotateCubies
void RotateCubies(float add[3])
Definition: RC.cpp:1012
RCPDB::FactorialUpperK
uint64_t FactorialUpperK(int n, int k) const
Definition: RC.cpp:2095
RC::edgeOrder
const int edgeOrder[4]
Definition: RC.h:265
node
Nodes to be stored within a Graph.
Definition: Graph.h:170
RC::GetNextState
void GetNextState(const RCState &, RCAction, RCState &) const
Definition: RC.cpp:1303
MakeMatrixRotX
void MakeMatrixRotX(float(&a)[3][3], float angle)
Definition: RC.cpp:1466
RCPDB::cornerRotations
std::vector< int > cornerRotations
Definition: RC.h:489
RC::cornerOrder
const int cornerOrder[4]
Definition: RC.h:266
RCPDB::GetCornerRotationHash
uint64_t GetCornerRotationHash(const RCState &s) const
Definition: RC.cpp:1930
Cubie::faceSize
const float faceSize
Definition: RC.h:43
RC::TestUpdate
void TestUpdate()
Definition: RC.cpp:1167