HOG2
RubiksCube.cpp
Go to the documentation of this file.
1 //
2 // RubiksCube.cpp
3 // hog2 glut
4 //
5 // Created by Nathan Sturtevant on 4/6/13.
6 // Copyright (c) 2013 University of Denver. All rights reserved.
7 //
8 
9 #include "RubiksCube.h"
10 #include <cassert>
11 #include <cstdio>
12 #include <algorithm>
13 #include <string>
14 
15 void RubiksCube::GetSuccessors(const RubiksState &nodeID, std::vector<RubiksState> &neighbors) const
16 {
17  neighbors.resize(18);
18  for (int x = 0; x < 18; x++)
19  {
20  GetNextState(nodeID, x, neighbors[x]);
21  }
22 }
23 
24 void RubiksCube::GetPrunedActions(const RubiksState &nodeID, RubiksAction lastAction, std::vector<RubiksAction> &actions) const
25 {
26  actions.resize(0);
27  for (int x = 0; x < 18; x++)
28  {
29  // 1. after any face you can't turn the same face again
30  if (x/3 == lastAction/3)
31  continue;
32 
33  // 2. after faces 5, 4, 3 you can't turn 0, 2, 1 respectively
34  if ((1 == (lastAction/3)%2) &&
35  (x/3+1 == lastAction/3))
36  continue;
37 
38  actions.push_back(x);
39  }
40 }
41 
42 
43 void RubiksCube::GetActions(const RubiksState &nodeID, std::vector<RubiksAction> &actions) const
44 {
45  actions.resize(0);
46  if (!pruneSuccessors || history.size() == 0)
47  {
48  for (int x = 0; x < 18; x++)
49  actions.push_back(x);
50  }
51  else {
52  // 0, 5, 2, 4, 1, 3
53 
54  for (int x = 0; x < 18; x++)
55  {
56  // 1. after any face you can't turn the same face again
57  if (x/3 == history.back()/3)
58  continue;
59 
60  // 2. after faces 5, 4, 3 you can't turn 0, 2, 1 respectively
61  if ((1 == (history.back()/3)%2) &&
62  (x/3+1 == history.back()/3))
63  continue;
64 
65  actions.push_back(x);
66  }
67  }
68 // std::random_shuffle(actions.begin(), actions.end());
69 }
70 
72 {
73  //std::vector<RubiksAction> succ;
74  //GetActions(s1, succ);
75  RubiksState tmp;
76  for (int x = 0; x < 18; x++)
77  {
78  GetNextState(s1, x, tmp);
79  if (tmp == s2)
80  return x;
81  }
82  assert(false);
83  return 0;
84 }
85 
87 {
88  c.ApplyAction(s.corner, a);
89  e.ApplyAction(s.edge, a);
90  //e7.ApplyAction(s.edge7, a);
91  if (pruneSuccessors)
92  history.push_back(a);
93 }
94 
96 {
97  if (pruneSuccessors && history.size() > 0)
98  {
99  assert(history.back() == a);
100  history.pop_back();
101  }
102  InvertAction(a);
103  c.ApplyAction(s.corner, a);
104  e.ApplyAction(s.edge, a);
105  //e7.ApplyAction(s.edge7, a);
106 
107 }
108 
110 {
111  s2 = s1;
112  ApplyAction(s2, a);
113 }
114 
116 {
117  // This code was tested for speed but not correctness.
118  // It didn't speed things up, so it's commented out for now.
119 // switch (a)
120 // {
121 // case 0: a = 1; return true;
122 // case 1: a = 0; return true;
123 // case 2: return true;
124 // case 3: a = 4; return true;
125 // case 4: a = 3; return true;
126 // case 5: return true;
127 // case 6: a = 7; return true;
128 // case 7: a = 6; return true;
129 // case 8: return true;
130 // case 9: a = 10; return true;
131 // case 10: a = 9; return true;
132 // case 11: return true;
133 // case 12: a = 13; return true;
134 // case 13: a = 12; return true;
135 // case 14: return true;
136 // case 15: a = 16; return true;
137 // case 16: a = 15; return true;
138 // case 17: return true;
139 // default: return false;
140 // }
141  if (2 == a%3)
142  return true;
143  if (1 == a%3)
144  {
145  a -= 1;
146  return true;
147  }
148  a += 1;
149  return true;
150  return false;
151 }
152 
153 double RubiksCube::HCost(const RubiksState &node1, const RubiksState &node2, double parentHCost) const
154 {
155  return HCost(node1, node2);
156 // double val = 0;
157 //
158 // // corner PDB
159 // uint64_t hash = c.GetStateHash(node1.corner);
160 // val = cornerPDB.Get(hash);
161 // if (val > parentHCost)
162 // {
163 // return val;
164 // }
165 //
166 // if (minBloomFilter)
167 // {
168 // int bloom = minBloom->Contains(node1.edge.state);
169 // if (bloom == 0xF) // not found
170 // bloom = 10;
171 // edgeDist[bloom]++;
172 // return max(val, double(bloom));
173 // }
174 // if (bloomFilter)
175 // {
176 // hash = node1.edge.state;//e.GetStateHash(node1.edge);
177 //
178 // // our maximum is 10
179 // if (val >= 10)
180 // {
181 // //if (val != HCost(node1, node2))
182 // //{ printf("Error! (1.5) [%f vs %f (%f)]\n", val, HCost(node1, node2), parentHCost); exit(0); }
183 // return val;
184 // }
185 // if (val < parentHCost-1) // we determined the heuristic
186 // {
187 // if (parentHCost >= 10)
188 // {
189 // if (depth9->Contains(hash))
190 // {
191 // val = max(val, 9);
192 // edgeDist[9]++;
193 // }
194 // else {
195 // val = max(val, 10);
196 // edgeDist[10]++;
197 // }
198 // // not an error - might be a 'faulty' bloom filter!
199 // //if (val != HCost(node1, node2))
200 // //{ printf("Error! (2) [%f vs %f (%f)]\n", val, HCost(node1, node2), parentHCost); exit(0); }
201 // return val;
202 // }
203 // else if (parentHCost == 9)
204 // {
205 // if (depth8->Contains(hash))
206 // {
207 // val = max(val, 8);
208 // edgeDist[8]++;
209 // }
210 // else if (depth9->Contains(hash))
211 // {
212 // val = max(val, 9);
213 // edgeDist[9]++;
214 // }
215 // else {
216 // val = max(val, 10);
217 // edgeDist[10]++;
218 // }
219 // //if (val != HCost(node1, node2))
220 // //{ printf("Error! (3) [%f vs %f (%f)]\n", val, HCost(node1, node2), parentHCost); exit(0); }
221 // return val;
222 // }
223 //
224 // }
225 //
226 // auto depthLoc = depthTable.find(hash);
227 // if (depthLoc != depthTable.end())
228 // {
229 // val = max(val, depthLoc->second);
230 // edgeDist[depthLoc->second]++;
231 // }
232 // else if (depth8->Contains(hash))
233 // {
234 // val = max(val, 8);
235 // edgeDist[8]++;
236 // }
237 // else if (depth9->Contains(hash))
238 // {
239 // val = max(val, 9);
240 // edgeDist[9]++;
241 // }
242 // else {
243 // val = max(val, 10);
244 // edgeDist[10]++;
245 // }
246 // //if (val != HCost(node1, node2))
247 // //{ printf("Error! (4) [%f vs %f (%f)]\n", val, HCost(node1, node2), parentHCost); exit(0); }
248 // return val;
249 // }
250 // if (minCompression)
251 // {
252 // // edge PDB
253 // hash = e.GetStateHash(node1.edge);
254 //
255 // // // edge PDB
256 // double val2 = edgePDB.Get(hash/compressionFactor);
257 // val = max(val, val2);
258 //
259 // node1.edge.GetDual(dual);
260 // hash = e.GetStateHash(dual);
261 //
262 // val2 = edgePDB.Get(hash/compressionFactor);
263 // val = max(val, val2);
264 // }
265 // else if (!minCompression) // interleave
266 // {
284 // }
285 //
286 // return val;
287 }
288 
290 double RubiksCube::HCost(const RubiksState &node1, const RubiksState &node2) const
291 {
292  return 0;
293 // double val = 0;
294 //
295 // // corner PDB
296 // uint64_t hash = c.GetStateHash(node1.corner);
297 // val = cornerPDB.Get(hash);
298 //
299 // // load PDB values directly from disk!
300 // // make sure that "data" is initialized with the right constructor calls for the data
301 // //int64_t r1, r2;
302 // //e.rankPlayer(node1.edge, 0, r1, r2);
303 // //double edge = f.ReadFileDepth(data[r1].bucketID, data[r1].bucketOffset+r2);
304 // //edgeDist[edge]++;
307 // //val = max(val, edge);
308 // //return val;
309 //
310 // if (minBloomFilter)
311 // {
312 // int bloom = minBloom->Contains(node1.edge.state);
313 // if (bloom == 0xF) // not found
314 // bloom = 10;
315 // return max(val, double(bloom));
316 // }
317 // if (bloomFilter)
318 // {
319 // /* if (edge != depthLoc->second)
320 // {
321 // printf("Error - table doesn't match loaded PDB. table: %1.0f pdb: %1.0f\n", depthLoc->second, edge);
322 // exit(0);
323 // }*/
324 //
325 // hash = node1.edge.state;//e.GetStateHash(node1.edge);
326 //
327 // auto depthLoc = depthTable.find(hash);
328 // if (depthLoc != depthTable.end())
329 // {
330 // val = max(val, depthLoc->second);
331 // edgeDist[depthLoc->second]++;
332 // }
333 // else if (depth8->Contains(hash))
334 // {
335 // val = max(val, 8);
336 // edgeDist[8]++;
337 // }
338 // else if (depth9->Contains(hash))
339 // {
340 // val = max(val, 9);
341 // edgeDist[9]++;
342 // }
343 // else {
344 // val = max(val, 10);
345 // edgeDist[10]++;
346 // }
347 // return val;
348 // }
349 //
350 // if (minCompression)
351 // {
352 // // edge PDB
353 // hash = e.GetStateHash(node1.edge);
354 //
355 // // // edge PDB
356 // double val2 = edgePDB.Get(hash/compressionFactor);
357 // val = max(val, val2);
358 // if (0)
359 // {
360 // node1.edge.GetDual(dual);
361 // hash = e.GetStateHash(dual);
362 //
363 // val2 = edgePDB.Get(hash/compressionFactor);
364 // val = max(val, val2);
365 // }
366 // }
367 // else if (!minCompression) // interleave
368 // {
386 // }
387 // return val;
388 }
389 
392 double RubiksCube::HCost(const RubiksState &node) const
393 {
394  return HCost(node, node);
395 }
396 
397 bool RubiksCube::GoalTest(const RubiksState &node, const RubiksState &goal) const
398 {
399  return (node.corner == goal.corner &&
400  node.edge == goal.edge);
401 }
402 
405 {
406  assert(false);
407  return false;
408 }
409 
411 {
412  uint64_t hash = c.GetStateHash(node.corner);
413  hash *= e.getMaxSinglePlayerRank();
414  hash += e.GetStateHash(node.edge);
415  return hash;
416 }
417 
419 {
420  return c.GetStateHash(node.corner);
421 }
422 
424 {
425  return e.GetStateHash(node.edge);
426 }
427 
428 void RubiksCube::GetStateFromHash(uint64_t cornerHash, uint64_t edgeHash, RubiksState &node) const
429 {
430  c.GetStateFromHash(cornerHash, node.corner);
431  e.GetStateFromHash(edgeHash, node.edge);
432 }
433 
434 void RubiksCube::GetStateFromHash(uint64_t hash, RubiksState &node) const
435 {
438 }
439 
441 {
442 }
443 
445 {
446  e.OpenGLDraw(s.edge);
447  c.OpenGLDraw(s.corner);
450 }
451 
453 {
454  c.OpenGLDraw(s.corner);
457 }
458 
460 {
461 // Rubik7EdgeState e7tmp;
462 // s.edge7.GetDual(e7tmp);
463  e.OpenGLDraw(s.edge);
466 }
467 
469 {
470  s.edge.GetDual(dual);
471  e.OpenGLDraw(dual);
474 }
475 
477 {
478 // return;
479 
480  float scale = 0.3;
481  float offset = 0.95*scale/3.0;
482  glBegin(GL_QUADS);
483 
484  glColor3f(0,0,0);
485  offset = scale/3.0;
486  scale*=0.99;
487  glVertex3f(-3.0*offset, -scale, -3.0*offset);
488  glVertex3f(3.0*offset, -scale, -3.0*offset);
489  glVertex3f(3.0*offset, -scale, 3.0*offset);
490  glVertex3f(-3.0*offset, -scale, 3.0*offset);
491 
492  glVertex3f(-3.0*offset, scale, -3.0*offset);
493  glVertex3f(3.0*offset, scale, -3.0*offset);
494  glVertex3f(3.0*offset, scale, 3.0*offset);
495  glVertex3f(-3.0*offset, scale, 3.0*offset);
496 
497  glVertex3f(-scale, -3.0*offset, -3.0*offset);
498  glVertex3f(-scale, 3.0*offset, -3.0*offset);
499  glVertex3f(-scale, 3.0*offset, 3.0*offset);
500  glVertex3f(-scale, -3.0*offset, 3.0*offset);
501 
502  // SetFaceColor(3);
503  glVertex3f(scale, -3.0*offset, -3.0*offset);
504  glVertex3f(scale, 3.0*offset, -3.0*offset);
505  glVertex3f(scale, 3.0*offset, 3.0*offset);
506  glVertex3f(scale, -3.0*offset, 3.0*offset);
507 
508  // SetFaceColor(2);
509  glVertex3f(-3.0*offset, -3.0*offset, -scale);
510  glVertex3f(3.0*offset, -3.0*offset, -scale);
511  glVertex3f(3.0*offset, 3.0*offset, -scale);
512  glVertex3f(-3.0*offset, 3.0*offset, -scale);
513 
514  // SetFaceColor(4);
515  glVertex3f(-3.0*offset, -3.0*offset, scale);
516  glVertex3f(3.0*offset, -3.0*offset, scale);
517  glVertex3f(3.0*offset, 3.0*offset, scale);
518  glVertex3f(-3.0*offset, 3.0*offset, scale);
519  glEnd();
520 }
521 
523 {
524  glBegin(GL_QUADS);
525  OpenGLDrawCube(4);
526  OpenGLDrawCube(10);
527  OpenGLDrawCube(12);
528  OpenGLDrawCube(14);
529  OpenGLDrawCube(16);
530  OpenGLDrawCube(22);
531  glEnd();
532 }
533 
534 void RubiksCube::OpenGLDrawCube(int cube) const
535 {
536  float scale = 0.3;
537  float offset = 0.95*scale/3.0;
538  const float offset2 = scale/3.0;
539  const float epsilon = 0.002;
540 
541  switch (cube)
542  {
543  case 4:
544  {
545  SetFaceColor(0);
546  glVertex3f(-offset, -scale, -offset);
547  glVertex3f(offset, -scale, -offset);
548  glVertex3f(offset, -scale, offset);
549  glVertex3f(-offset, -scale, offset);
550 
551  SetFaceColor(-1);
552  glVertex3f(-offset2, -scale+epsilon, -offset2);
553  glVertex3f(offset2, -scale+epsilon, -offset2);
554  glVertex3f(offset2, -scale+epsilon, offset2);
555  glVertex3f(-offset2, -scale+epsilon, offset2);
556 
557  } break;
558  case 22:
559  {
560  SetFaceColor(5);
561  glVertex3f(-offset, scale, -offset);
562  glVertex3f(offset, scale, -offset);
563  glVertex3f(offset, scale, offset);
564  glVertex3f(-offset, scale, offset);
565 
566  SetFaceColor(-1);
567  glVertex3f(-offset2, scale-epsilon, -offset2);
568  glVertex3f(offset2, scale-epsilon, -offset2);
569  glVertex3f(offset2, scale-epsilon, offset2);
570  glVertex3f(-offset2, scale-epsilon, offset2);
571  } break;
572  case 12:
573  {
574  SetFaceColor(1);
575  glVertex3f(-scale, -offset, -offset);
576  glVertex3f(-scale, offset, -offset);
577  glVertex3f(-scale, offset, offset);
578  glVertex3f(-scale, -offset, offset);
579 
580  SetFaceColor(-1);
581  glVertex3f(-scale+epsilon, -offset2, -offset2);
582  glVertex3f(-scale+epsilon, offset2, -offset2);
583  glVertex3f(-scale+epsilon, offset2, offset2);
584  glVertex3f(-scale+epsilon, -offset2, offset2);
585 
586  } break;
587  case 16:
588  {
589  SetFaceColor(4);
590  glVertex3f(-offset, -offset, scale);
591  glVertex3f(offset, -offset, scale);
592  glVertex3f(offset, offset, scale);
593  glVertex3f(-offset, offset, scale);
594 
595  SetFaceColor(-1);
596  glVertex3f(-offset2, -offset2, scale-epsilon);
597  glVertex3f(offset2, -offset2, scale-epsilon);
598  glVertex3f(offset2, offset2, scale-epsilon);
599  glVertex3f(-offset2, offset2, scale-epsilon);
600 
601  } break;
602  case 10:
603  {
604  SetFaceColor(2);
605  glVertex3f(-offset, -offset, -scale);
606  glVertex3f(offset, -offset, -scale);
607  glVertex3f(offset, offset, -scale);
608  glVertex3f(-offset, offset, -scale);
609 
610  SetFaceColor(-1);
611  glVertex3f(-offset2, -offset2, -scale+epsilon);
612  glVertex3f(offset2, -offset2, -scale+epsilon);
613  glVertex3f(offset2, offset2, -scale+epsilon);
614  glVertex3f(-offset2, offset2, -scale+epsilon);
615  } break;
616  case 14:
617  {
618  SetFaceColor(3);
619  glVertex3f(scale, -offset, -offset);
620  glVertex3f(scale, offset, -offset);
621  glVertex3f(scale, offset, offset);
622  glVertex3f(scale, -offset, offset);
623 
624  SetFaceColor(-1);
625  glVertex3f(scale-epsilon, -offset2, -offset2);
626  glVertex3f(scale-epsilon, offset2, -offset2);
627  glVertex3f(scale-epsilon, offset2, offset2);
628  glVertex3f(scale-epsilon, -offset2, offset2);
629  } break;
630  }
631 }
632 
633 void RubiksCube::SetFaceColor(int theColor) const
634 {
635  switch (theColor)
636  {
637  case -1: glColor3f(0.0, 0.0, 0.0); break;
638  case 0: glColor3f(1.0, 0.0, 0.0); break;
639  case 1: glColor3f(0.0, 1.0, 0.0); break;
640  case 2: glColor3f(0.0, 0.0, 1.0); break;
641  case 3: glColor3f(1.0, 1.0, 0.0); break;
642  case 4: glColor3f(1.0, 0.75, 0.0); break;
643  case 5: glColor3f(1.0, 1.0, 1.0); break;
644  default: assert(false);
645  }
646 }
647 
648 
650 void RubiksCube::OpenGLDraw(const RubiksState &s1, const RubiksState &s2, float t) const
651 {
652 // glEnable( GL_POLYGON_SMOOTH );
653 // glHint( GL_POLYGON_SMOOTH_HINT, GL_NICEST );
654  int vals[3] = {-90, 90, 180};
655  RubiksAction a = GetAction(s1, s2);
656  switch (a/3)
657  {
658  case 0: // 0
659  {
660  glPushMatrix();
661  glRotatef(vals[a%3]*t, 0, 1, 0); // parameterize
662  glBegin(GL_QUADS);
663  for (int x = 0; x < 9; x++)
664  {
665  e.OpenGLDrawCube(s1.edge, x);
666  c.OpenGLDrawCube(s1.corner, x);
667  OpenGLDrawCube(x);
668  }
669  glEnd();
670  glPopMatrix();
671 
672  glBegin(GL_QUADS);
673  for (int x = 9; x < 27; x++)
674  {
675  e.OpenGLDrawCube(s1.edge, x);
676  c.OpenGLDrawCube(s1.corner, x);
677  OpenGLDrawCube(x);
678  }
679  glEnd();
680  } break;
681  case 1: // 5
682  {
683  glPushMatrix();
684  glRotatef(vals[a%3]*t, 0, 1, 0); // parameterize
685  glBegin(GL_QUADS);
686  for (int x = 18; x < 27; x++)
687  {
688  e.OpenGLDrawCube(s1.edge, x);
689  c.OpenGLDrawCube(s1.corner, x);
690  OpenGLDrawCube(x);
691  }
692  glEnd();
693  glPopMatrix();
694 
695  glBegin(GL_QUADS);
696  for (int x = 0; x < 18; x++)
697  {
698  e.OpenGLDrawCube(s1.edge, x);
699  c.OpenGLDrawCube(s1.corner, x);
700  OpenGLDrawCube(x);
701  }
702  glEnd();
703  } break;
704  case 2: // 2
705  {
706  int which[9] = {0, 1, 2, 9, 10, 11, 18, 19, 20};
707  int others[18] = {3, 4, 5, 6, 7, 8, 12, 13, 14, 15, 16, 17, 21, 22, 23, 24, 25, 26};
708  glPushMatrix();
709  glRotatef(vals[a%3]*t, 0, 0, -1); // parameterize
710  glBegin(GL_QUADS);
711  for (int x = 0; x < 9; x++)
712  {
713  e.OpenGLDrawCube(s1.edge, which[x]);
714  c.OpenGLDrawCube(s1.corner, which[x]);
715  OpenGLDrawCube(which[x]);
716  }
717  glEnd();
718  glPopMatrix();
719 
720  glBegin(GL_QUADS);
721  for (int x = 0; x < 18; x++)
722  {
723  e.OpenGLDrawCube(s1.edge, others[x]);
724  c.OpenGLDrawCube(s1.corner, others[x]);
725  OpenGLDrawCube(others[x]);
726  }
727  glEnd();
728  } break;
729  case 3: // 4
730  {
731  int which[9] = {6, 7, 8, 15, 16, 17, 24, 25, 26};
732  int others[18] = {3, 4, 5, 0, 1, 2, 12, 13, 14, 9, 10, 11, 21, 22, 23, 18, 19, 20};
733  glPushMatrix();
734  glRotatef(vals[a%3]*t, 0, 0, 1); // parameterize
735  glBegin(GL_QUADS);
736  for (int x = 0; x < 9; x++)
737  {
738  e.OpenGLDrawCube(s1.edge, which[x]);
739  c.OpenGLDrawCube(s1.corner, which[x]);
740  OpenGLDrawCube(which[x]);
741  }
742  glEnd();
743  glPopMatrix();
744 
745  glBegin(GL_QUADS);
746  for (int x = 0; x < 18; x++)
747  {
748  e.OpenGLDrawCube(s1.edge, others[x]);
749  c.OpenGLDrawCube(s1.corner, others[x]);
750  OpenGLDrawCube(others[x]);
751  }
752  glEnd();
753  } break;
754  case 4: // 1
755  {
756  int which[9] = {0, 3, 6, 9, 12, 15, 18, 21, 24};
757  int others[18] = {1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26};
758  glPushMatrix();
759  glRotatef(vals[a%3]*t, -1, 0, 0); // parameterize
760  glBegin(GL_QUADS);
761  for (int x = 0; x < 9; x++)
762  {
763  e.OpenGLDrawCube(s1.edge, which[x]);
764  c.OpenGLDrawCube(s1.corner, which[x]);
765  OpenGLDrawCube(which[x]);
766  }
767  glEnd();
768  glPopMatrix();
769 
770  glBegin(GL_QUADS);
771  for (int x = 0; x < 18; x++)
772  {
773  e.OpenGLDrawCube(s1.edge, others[x]);
774  c.OpenGLDrawCube(s1.corner, others[x]);
775  OpenGLDrawCube(others[x]);
776  }
777  glEnd();
778 
779  } break;
780  case 5: // 3
781  {
782  int which[9] = {2, 5, 8, 11, 14, 17, 20, 23, 26};
783  int others[18] = {0, 1, 3, 4, 6, 7, 9, 10, 12, 13, 15, 16, 18, 19, 21, 22, 24, 25};
784  glPushMatrix();
785  glRotatef(vals[a%3]*t, 1, 0, 0); // parameterize
786  glBegin(GL_QUADS);
787  for (int x = 0; x < 9; x++)
788  {
789  e.OpenGLDrawCube(s1.edge, which[x]);
790  c.OpenGLDrawCube(s1.corner, which[x]);
791  OpenGLDrawCube(which[x]);
792  }
793  glEnd();
794  glPopMatrix();
795 
796  glBegin(GL_QUADS);
797  for (int x = 0; x < 18; x++)
798  {
799  e.OpenGLDrawCube(s1.edge, others[x]);
800  c.OpenGLDrawCube(s1.corner, others[x]);
801  OpenGLDrawCube(others[x]);
802  }
803  glEnd();
804  } break;
805  }
806 }
807 
809 {
810 
811 }
812 
814 {
815  if (f == 0)
816  f = new DiskBitFile("/data/rubik/res/RC");
817  int64_t bucket;
818  int64_t offset;
819  e.rankPlayer(s.edge, 0, bucket, offset);
820  return f->ReadFileDepth(data[bucket].bucketID, data[bucket].bucketOffset+offset);
821 }
822 
823 
824 RubikPDB::RubikPDB(RubiksCube *e, const RubiksState &s, std::vector<int> distinctEdges, std::vector<int> distinctCorners)
825 :PDBHeuristic(e), ePDB(&e->e, s.edge, distinctEdges), cPDB(&e->c, s.corner, distinctCorners), edges(distinctEdges), corners(distinctCorners)
826 {
827  SetGoal(s);
828  //PDBHeuristic<RubiksState, RubiksAction, RubiksCube, RubiksState, 4>::goalState = s;
829 }
830 
831 uint64_t RubikPDB::GetStateHash(const RubiksState &s) const
832 {
833  //assert(!"Not implemented - need 66 bits!");
834  return 0;
835 }
836 
837 void RubikPDB::GetStateFromHash(RubiksState &s, uint64_t hash) const
838 {
839  //assert(!"Not implemented - need 66 bits!");
840  ePDB.GetStateFromHash(s.edge, hash);
841  cPDB.GetStateFromHash(s.corner, hash);
842 }
843 
844 uint64_t RubikPDB::GetPDBSize() const
845 {
846  return ePDB.GetPDBSize()*cPDB.GetPDBSize();
847 }
848 
849 uint64_t RubikPDB::GetPDBHash(const RubiksState &s, int threadID) const
850 {
851  return ePDB.GetPDBHash(s.edge, threadID)*cPDB.GetPDBSize()+cPDB.GetPDBHash(s.corner, threadID);
852 }
853 
854 void RubikPDB::GetStateFromPDBHash(uint64_t hash, RubiksState &s, int threadID) const
855 {
856  uint64_t cornerHash = hash%cPDB.GetPDBSize();
857  uint64_t edgeHash = hash/cPDB.GetPDBSize();
858  ePDB.GetStateFromPDBHash(edgeHash, s.edge, threadID);
859  cPDB.GetStateFromPDBHash(cornerHash, s.corner, threadID);
860 }
861 
862 //const char *RubikPDB::GetName()
863 //{
864 // static std::string s = "";
865 // s += ePDB.GetName();
866 // s += cPDB.GetName();
867 // s += ".pdb";
868 // return s.c_str();
869 //}
870 
871 bool RubikPDB::Load(const char *prefix)
872 {
873  FILE *f = fopen(GetFileName(prefix).c_str(), "rb");
874  if (f == 0)
875  {
876  std::cout << "Could not load PDB: " << GetFileName(prefix) << "\n";
877  return false;
878  }
879  bool result = Load(f);
880  fclose(f);
881  if (result)
882  std::cout << "Successfully loaded PDB: " << GetFileName(prefix) << "\n";
883  else
884  std::cout << "Could not load PDB: " << GetFileName(prefix) << "\n";
885  return result;
886 }
887 
888 void RubikPDB::Save(const char *prefix)
889 {
890  FILE *f = fopen(GetFileName(prefix).c_str(), "w+b");
891  Save(f);
892  fclose(f);
893  std::cout << "Saved PDB: " << GetFileName(prefix) << "\n";
894 }
895 
896 bool RubikPDB::Load(FILE *f)
897 {
898  size_t numEdges;
899  if (fread(&numEdges, sizeof(numEdges), 1, f) != 1)
900  return false;
901  edges.resize(numEdges);
902  if (fread(&edges[0], sizeof(edges[0]), edges.size(), f) != edges.size())
903  return false;
904  size_t numCorners;
905  if (fread(&numCorners, sizeof(numCorners), 1, f) != 1)
906  return false;
907  corners.resize(numCorners);
908  if (fread(&corners[0], sizeof(corners[0]), corners.size(), f) != corners.size())
909  return false;
910  if (ePDB.Load(f) == false)
911  return false;
912  if (cPDB.Load(f) == false)
913  return false;
915  return false;
916  return true;
917 }
918 
919 void RubikPDB::Save(FILE *f)
920 {
921  size_t numEdges = edges.size();
922  fwrite(&numEdges, sizeof(numEdges), 1, f);
923  fwrite(&edges[0], sizeof(edges[0]), edges.size(), f);
924  size_t numCorners = corners.size();
925  fwrite(&numCorners, sizeof(numCorners), 1, f);
926  fwrite(&corners[0], sizeof(corners[0]), corners.size(), f);
927  ePDB.Save(f);
928  cPDB.Save(f);
930 }
931 
932 std::string RubikPDB::GetFileName(const char *prefix)
933 {
934  std::string fileName;
935  fileName += prefix;
936  // For unix systems, the prefix should always end in a trailing slash
937  if (fileName.back() != '/' && prefix[0] != 0)
938  fileName+='/';
939 
940  fileName += ePDB.GetFileName("");
941  for (int x = 0; x < 4; x++) // remove ".pdb"
942  fileName.pop_back();
943  fileName += "-";
944  fileName += cPDB.GetFileName("");
945 
946 // fileName += "RC-E-";
947 // // origin state
948 // for (int x = 0; x < 12; x++)
949 // {
950 // fileName += std::to_string(goalState.edge.GetCubeInLoc(x));
951 // fileName += ".";
952 // fileName += std::to_string(goalState.edge.GetCubeOrientation(goalState.edge.GetCubeInLoc(x)));
953 // fileName += ";";
954 // }
955 // fileName.pop_back();
956 // fileName += "-";
957 // // pattern
958 // bool added = false;
959 // for (int x = 0; x < edges.size(); x++)
960 // {
961 // added = true;
962 // fileName += std::to_string(edges[x]);
963 // fileName += ";";
964 // }
965 // if (added)
966 // fileName.pop_back(); // remove colon
967 //
968 //
969 // fileName += "-C-";
970 // // origin state
971 // for (int x = 0; x < 8; x++)
972 // {
973 // fileName += std::to_string(goalState.corner.GetCubeInLoc(x));
974 // fileName += ".";
975 // fileName += std::to_string(goalState.corner.GetCubeOrientation(goalState.corner.GetCubeInLoc(x)));
976 // fileName += ";";
977 // }
978 // fileName.pop_back();
979 // // pattern
980 // added = false;
981 // for (int x = 0; x < corners.size(); x++)
982 // {
983 // added = true;
984 // fileName += std::to_string(corners[x]);
985 // fileName += ";";
986 // }
987 // if (added)
988 // fileName.pop_back(); // remove colon
989 // fileName += ".pdb";
990 
991  return fileName;
992 
993 }
994 
996 :pdb(pdb)
997 {
998 
999 }
1000 
1001 double RubikDualPDB::HCost(const RubiksState &a, const RubiksState &b) const
1002 {
1003  // starts as desired goal
1004  RubiksState start(b);
1005 // for (int x = 0; x < 8; x++)
1006 // printf("%d ", b.corner.GetCubeInLoc(x));
1007 // printf("-- ");
1008 // for (int x = 0; x < 12; x++)
1009 // printf("%d ", b.edge.GetCubeInLoc(x));
1010 // printf("\n");
1011  for (int x = 0; x < 8; x++)
1012  {
1013  start.corner.SetCubeInLoc(b.corner.GetCubeInLoc(x), x);
1015  }
1016  for (int x = 0; x < 12; x++)
1017  {
1018  start.edge.SetCubeInLoc(b.edge.GetCubeInLoc(x), x);
1020  }
1021 // std::cout << "Our dual: " << start << "\n";
1022 // for (int x = 0; x < 8; x++)
1023 // printf("%d ", start.corner.GetCubeInLoc(x));
1024 // printf("-- ");
1025 // for (int x = 0; x < 12; x++)
1026 // printf("%d ", start.edge.GetCubeInLoc(x));
1027 // printf("\n");
1028 
1029  return pdb->HCost(start, a);
1030 }
1031 
1033 :pdb(pdb)
1034 {
1035 
1036 }
1037 
1038 double RubikArbitraryGoalPDB::HCost(const RubiksState &a, const RubiksState &b) const
1039 {
1040  static const RubiksState goal;
1041  RubiksState tmp(a);
1042  int dual[12];
1043  int rotation[12];
1044  for (int x = 0; x < 8; x++)
1045  {
1046  dual[b.corner.GetCubeInLoc(x)] = x;
1048  }
1049  for (int x = 0; x < 8; x++)
1050  {
1051  tmp.corner.SetCubeInLoc(x, dual[a.corner.GetCubeInLoc(x)]);
1053  }
1054 
1055  for (int x = 0; x < 12; x++)
1056  {
1057  dual[b.edge.GetCubeInLoc(x)] = x;
1059  }
1060  for (int x = 0; x < 12; x++)
1061  {
1062  tmp.edge.SetCubeInLoc(x, dual[a.edge.GetCubeInLoc(x)]);
1064  }
1065 
1066  return pdb->HCost(tmp, goal);
1067 
1068 }
RubiksCube::GoalTest
virtual bool GoalTest(const RubiksState &node, const RubiksState &goal) const
Definition: RubiksCube.cpp:397
RubikEdgePDB::GetStateFromPDBHash
void GetStateFromPDBHash(uint64_t hash, RubikEdgeState &s, int threadID=0) const
Definition: RubiksCubeEdges.cpp:1398
RubikCornerPDB::GetPDBHash
uint64_t GetPDBHash(const RubiksCornerState &s, int threadID=0) const
Definition: RubiksCubeCorners.cpp:1218
RubikArbitraryGoalPDB::pdb
RubikPDB * pdb
Definition: RubiksCube.h:265
RubiksCube::GetCornerHash
virtual uint64_t GetCornerHash(const RubiksState &node) const
Definition: RubiksCube.cpp:418
RubiksCube::OpenGLDrawCube
void OpenGLDrawCube(int cube) const
Definition: RubiksCube.cpp:534
RubikArbitraryGoalPDB::RubikArbitraryGoalPDB
RubikArbitraryGoalPDB(RubikPDB *pdb)
Definition: RubiksCube.cpp:1032
RubikEdgePDB::GetFileName
std::string GetFileName(const char *prefix)
Definition: RubiksCubeEdges.cpp:1537
RubiksCornerStateArray::GetCubeOrientation
uint64_t GetCubeOrientation(unsigned int whichLoc) const
Definition: RubiksCubeCorners.cpp:248
RubiksCube::data
std::vector< bucketInfo > data
Definition: RubiksCube.h:212
RubiksCube::c
RubiksCorner c
Definition: RubiksCube.h:200
RubiksCube
Definition: RubiksCube.h:106
RubiksCorner::OpenGLDrawCube
void OpenGLDrawCube(const RubiksCornerState &s, int cube) const
Definition: RubiksCubeCorners.cpp:766
RubiksCube::OpenGLDrawCorners
virtual void OpenGLDrawCorners(const RubiksState &) const
Definition: RubiksCube.cpp:452
RubiksCube::GetNextState
virtual void GetNextState(const RubiksState &, RubiksAction, RubiksState &) const
Definition: RubiksCube.cpp:109
RubiksCube::UndoAction
virtual void UndoAction(RubiksState &s, RubiksAction a) const
Definition: RubiksCube.cpp:95
RubikCornerPDB::GetStateFromPDBHash
void GetStateFromPDBHash(uint64_t hash, RubiksCornerState &s, int threadID=0) const
Definition: RubiksCubeCorners.cpp:1283
RubikEdgePDB::Load
bool Load(const char *prefix)
Definition: RubiksCubeEdges.cpp:1483
RubiksAction
int RubiksAction
Definition: RubiksCube.h:72
RubikEdge::OpenGLDraw
virtual void OpenGLDraw() const
Definition: RubiksCubeEdges.cpp:834
RubiksCube::OpenGLDrawEdgeDual
virtual void OpenGLDrawEdgeDual(const RubiksState &) const
Definition: RubiksCube.cpp:468
RubiksCube::GetPrunedActions
virtual void GetPrunedActions(const RubiksState &nodeID, RubiksAction lastAction, std::vector< RubiksAction > &actions) const
Definition: RubiksCube.cpp:24
rotation
float rotation[3][3]
Definition: RC.cpp:21
DiskBitFile::ReadFileDepth
int ReadFileDepth(int bucket, int64_t offset)
Definition: DiskBitFile.cpp:115
RubikCornerPDB::GetFileName
virtual std::string GetFileName(const char *prefix)
Definition: RubiksCubeCorners.cpp:1417
RubikPDB::Save
void Save(const char *prefix)
Definition: RubiksCube.cpp:888
RubikDualPDB::HCost
virtual double HCost(const RubiksState &a, const RubiksState &b) const
Definition: RubiksCube.cpp:1001
RubiksCorner::GetStateHash
uint64_t GetStateHash(const RubiksCornerState &node) const
Definition: RubiksCubeCorners.cpp:586
RubiksCube::GetEdgeHash
virtual uint64_t GetEdgeHash(const RubiksState &node) const
Definition: RubiksCube.cpp:423
RubiksState::corner
RubiksCornerState corner
Definition: RubiksCube.h:40
RubikPDB::ePDB
RubikEdgePDB ePDB
Definition: RubiksCube.h:246
RubiksState::edge
RubikEdgeState edge
Definition: RubiksCube.h:41
RubikEdgeStateArray::SetCubeInLoc
void SetCubeInLoc(int whichLoc, int cube)
Definition: RubiksCubeEdges.cpp:141
RubikPDB::corners
std::vector< int > corners
Definition: RubiksCube.h:249
RubikPDB::RubikPDB
RubikPDB(RubiksCube *e, const RubiksState &s, std::vector< int > distinctEdges, std::vector< int > distinctCorners)
Definition: RubiksCube.cpp:824
RubikDualPDB::RubikDualPDB
RubikDualPDB(RubikPDB *pdb)
Definition: RubiksCube.cpp:995
RubikPDB::GetPDBHash
uint64_t GetPDBHash(const RubiksState &s, int threadID=0) const
Definition: RubiksCube.cpp:849
RubiksCornerStateArray::SetCubeInLoc
void SetCubeInLoc(unsigned int whichLoc, int cube)
Definition: RubiksCubeCorners.cpp:243
RubiksCube::history
std::vector< RubiksAction > history
Definition: RubiksCube.h:199
RubikEdgeStateArray::GetCubeInLoc
int GetCubeInLoc(int whichLoc) const
Definition: RubiksCubeEdges.cpp:136
RubikCornerPDB::Load
virtual bool Load(const char *prefix)
Definition: RubiksCubeCorners.cpp:1365
RubikArbitraryGoalPDB::HCost
virtual double HCost(const RubiksState &a, const RubiksState &b) const
Definition: RubiksCube.cpp:1038
RubiksCorner::ApplyAction
virtual void ApplyAction(RubiksCornerState &s, RubiksCornersAction a) const
Definition: RubiksCubeCorners.cpp:315
PDBHeuristic
Definition: PDBHeuristic.h:39
RubiksCube::f
DiskBitFile * f
Definition: RubiksCube.h:211
RubikCornerPDB::Save
virtual void Save(const char *prefix)
Definition: RubiksCubeCorners.cpp:1378
RubiksCube::dual
RubikEdgeState dual
Definition: RubiksCube.h:202
RubikEdge::getMaxSinglePlayerRank
int64_t getMaxSinglePlayerRank() const
Definition: RubiksCubeEdges.cpp:598
RubikEdge::OpenGLDrawCube
void OpenGLDrawCube(const RubikEdgeState &s, int cube) const
Definition: RubiksCubeEdges.cpp:866
RubikDualPDB::pdb
RubikPDB * pdb
Definition: RubiksCube.h:257
RubiksCube::HCost
virtual double HCost(const RubiksState &node1, const RubiksState &node2) const
Heuristic value between two arbitrary nodes.
Definition: RubiksCube.cpp:290
RubikEdge::rankPlayer
int64_t rankPlayer(RubikEdgeState &s, int who)
Definition: RubiksCubeEdges.h:173
RubikEdge::ApplyAction
virtual void ApplyAction(RubikEdgeStateArray &s, RubikEdgeAction a) const
Definition: RubiksCubeEdges.cpp:516
PDBHeuristic::Save
virtual void Save(const char *prefix)=0
RubiksState
Definition: RubiksCube.h:27
RubiksCube::GetStateHash
virtual uint64_t GetStateHash(const RubiksState &node) const
Definition: RubiksCube.cpp:410
RubikCornerPDB::GetPDBSize
uint64_t GetPDBSize() const
Definition: RubiksCubeCorners.cpp:1207
RubiksCube::InvertAction
virtual bool InvertAction(RubiksAction &a) const
Definition: RubiksCube.cpp:115
RubiksCorner::OpenGLDraw
virtual void OpenGLDraw() const
Definition: RubiksCubeCorners.cpp:741
RubiksCornerStateArray::GetCubeInLoc
int GetCubeInLoc(unsigned int whichLoc) const
Definition: RubiksCubeCorners.cpp:238
RubiksCube::OpenGLDrawCenters
virtual void OpenGLDrawCenters() const
Definition: RubiksCube.cpp:522
PDBHeuristic< RubiksState, RubiksAction, RubiksCube, RubiksState, 4 >::SetGoal
void SetGoal(const RubiksState &goal)
Definition: PDBHeuristic.h:45
RubikPDB::cPDB
RubikCornerPDB cPDB
Definition: RubiksCube.h:247
RubiksCube::GetAction
virtual RubiksAction GetAction(const RubiksState &s1, const RubiksState &s2) const
Definition: RubiksCube.cpp:71
RubiksCube::Edge12PDBDist
int Edge12PDBDist(const RubiksState &s)
Definition: RubiksCube.cpp:813
RubiksCube::e
RubikEdge e
Definition: RubiksCube.h:201
RubiksCornerStateArray::SetCubeOrientation
void SetCubeOrientation(unsigned int whichLoc, int orient)
Definition: RubiksCubeCorners.cpp:254
RubikEdgeStateArray::SetCubeOrientation
void SetCubeOrientation(int whichLoc, bool flip)
Definition: RubiksCubeEdges.cpp:156
RubikPDB::GetPDBSize
uint64_t GetPDBSize() const
Definition: RubiksCube.cpp:844
RubiksCube::GetStateFromHash
virtual void GetStateFromHash(uint64_t hash, RubiksState &node) const
Definition: RubiksCube.cpp:434
RubikEdgePDB::GetStateFromHash
static void GetStateFromHash(RubikEdgeState &s, uint64_t hash)
Definition: RubiksCubeEdges.cpp:1295
PDBHeuristic::HCost
virtual double HCost(const state &a, const state &b) const
Definition: PDBHeuristic.h:163
RubikPDB::edges
std::vector< int > edges
Definition: RubiksCube.h:248
RubikPDB::GetFileName
std::string GetFileName(const char *prefix)
Definition: RubiksCube.cpp:932
RubikCornerPDB::GetStateFromHash
static void GetStateFromHash(RubiksCornerState &s, uint64_t hash)
Definition: RubiksCubeCorners.cpp:1201
RubiksCube::GetSuccessors
virtual void GetSuccessors(const RubiksState &nodeID, std::vector< RubiksState > &neighbors) const
Definition: RubiksCube.cpp:15
RubikPDB::GetStateHash
uint64_t GetStateHash(const RubiksState &s) const
Definition: RubiksCube.cpp:831
RubikPDB::Load
bool Load(const char *prefix)
Definition: RubiksCube.cpp:871
RubikEdgeStateArray::GetCubeOrientation
bool GetCubeOrientation(int whichLoc) const
Definition: RubiksCubeEdges.cpp:151
RubiksCube::pruneSuccessors
bool pruneSuccessors
Definition: RubiksCube.h:215
RubiksCube.h
RubikEdgePDB::GetPDBSize
uint64_t GetPDBSize() const
Definition: RubiksCubeEdges.cpp:1326
RubiksCube::OpenGLDraw
virtual void OpenGLDraw() const
Definition: RubiksCube.cpp:440
RubiksCorner::GetStateFromHash
void GetStateFromHash(uint64_t hash, RubiksCornerState &node) const
Definition: RubiksCubeCorners.cpp:670
RubiksCube::ApplyAction
virtual void ApplyAction(RubiksState &s, RubiksAction a) const
Definition: RubiksCube.cpp:86
RubikPDB::GetStateFromPDBHash
void GetStateFromPDBHash(uint64_t hash, RubiksState &s, int threadID=0) const
Definition: RubiksCube.cpp:854
RubikEdge::GetStateHash
virtual uint64_t GetStateHash(const RubikEdgeState &node) const
Definition: RubiksCubeEdges.cpp:647
RubikEdgePDB::GetPDBHash
uint64_t GetPDBHash(const RubikEdgeState &s, int threadID=0) const
Definition: RubiksCubeEdges.cpp:1337
RubiksCube::SetFaceColor
void SetFaceColor(int face) const
Definition: RubiksCube.cpp:633
RubikPDB::GetStateFromHash
void GetStateFromHash(RubiksState &s, uint64_t hash) const
Definition: RubiksCube.cpp:837
DiskBitFile
Definition: DiskBitFile.h:23
RubikPDB
Definition: RubiksCube.h:219
RubiksCube::OpenGLDrawCubeBackground
virtual void OpenGLDrawCubeBackground() const
Definition: RubiksCube.cpp:476
RubikEdgeStateArray::GetDual
void GetDual(RubikEdgeStateArray &s) const
Definition: RubiksCubeEdges.cpp:175
node
Nodes to be stored within a Graph.
Definition: Graph.h:170
RubikEdge::GetStateFromHash
virtual void GetStateFromHash(uint64_t hash, RubikEdgeState &node) const
Definition: RubiksCubeEdges.cpp:715
RubiksCube::GetActions
virtual void GetActions(const RubiksState &nodeID, std::vector< RubiksAction > &actions) const
Definition: RubiksCube.cpp:43
RubikEdgePDB::Save
void Save(const char *prefix)
Definition: RubiksCubeEdges.cpp:1496
edge
Edge class for connections between node in a Graph.
Definition: Graph.h:129
RubiksCube::OpenGLDrawEdges
virtual void OpenGLDrawEdges(const RubiksState &) const
Definition: RubiksCube.cpp:459