24 template <
int w
idth,
int height>
33 for (
size_t x = 0; x <
size(); x++)
40 for (
size_t x = 0; x <
size(); x++)
51 for (
size_t x = 0; x <
size(); x++)
58 std::array<int, width*height>
puzzle;
64 template <
int w,
int h>
70 for (
int x = 0; x < w*h; x++)
71 hash = hash*w*h + k.
puzzle[x];
88 template <
int w
idth,
int height>
92 for (
size_t x = 0; x <
loc.size(); x++)
93 out <<
loc.puzzle[x] <<
" ";
101 case kLeft: out <<
"Left";
break;
102 case kRight: out <<
"Right";
break;
103 case kUp: out <<
"Up";
break;
104 case kDown: out <<
"Down";
break;
110 template <
int w
idth,
int height>
113 for (
unsigned int x = 0; x < l1.
size(); x++)
122 template <
int w
idth,
int height>
136 template <
int w
idth,
int height>
140 MNPuzzle(
const std::vector<slideDir> op_order);
167 int count,
const std::vector<int> &
pattern,
168 std::vector<int> &dual);
186 fprintf(stderr,
"ERROR: Call to Get_Goal when no goal stored\n");
192 virtual const std::string
GetName();
260 template <
int w
idth,
int height>
271 template <
int w
idth,
int height>
276 Change_Op_Order(Get_Op_Order_From_Hash(15));
278 use_manhattan =
true;
281 template <
int w
idth,
int height>
284 Change_Op_Order(op_order);
286 use_manhattan =
true;
290 template <
int w
idth,
int height>
296 template <
int w
idth,
int height>
300 ops_in_order.clear();
303 bool down_act =
false;
304 bool left_act =
false;
305 bool right_act =
false;
307 if (op_order.size() != 4)
309 fprintf(stderr,
"ERROR: Not enough operators in operator sequence for construction of MNPuzzle\n");
313 for (
unsigned int op_num = 0; op_num < 4; op_num++)
315 if (op_order[op_num] ==
kUp)
319 else if (op_order[op_num] ==
kDown)
323 else if (op_order[op_num] ==
kLeft)
327 else if (op_order[op_num] ==
kRight)
333 if (!up_act || !down_act || !left_act || !right_act)
335 fprintf(stderr,
"ERROR: Invalid operator sequence for construction of MNPuzzle\n");
339 for (
unsigned i = 0; i < op_order.size(); i++)
341 ops_in_order.push_back(op_order[i]);
345 std::vector<slideDir> ops(4);
346 for (
unsigned int blank = 0; blank <
width*
height; blank++) {
349 for (
unsigned int op_num = 0; op_num < 4; op_num++)
351 if (op_order[op_num] ==
kUp && blank >
width - 1)
355 if (op_order[op_num] ==
kLeft && blank %
width > 0)
357 ops.push_back(
kLeft);
365 ops.push_back(
kDown);
369 operators.push_back(ops);
373 template <
int w
idth,
int height>
375 std::string s =
"STP(";
376 s += std::to_string(
width);
378 s += std::to_string(
height);
416 template <
int w
idth,
int height>
422 for (
int x = 0; x < 362880; x++)
430 for (
int x = 0; x < 362880; x++)
434 std::vector<slideDir> moves;
435 GetActions(t, moves);
437 for (
unsigned int y = 0; y < moves.size(); y++)
439 ApplyAction(t, moves[y]);
440 uint64_t hash = GetStateHash(t);
441 InvertAction(moves[y]);
442 ApplyAction(t, moves[y]);
475 template <
int w
idth,
int height>
485 goal_tester[i] =
false;
490 goal_tester[s.
puzzle[i]] =
true;
497 printf(
"INVALID GOAL\n");
498 assert(goal_tester[i]);
511 for (
unsigned goal_pos = 0; goal_pos <
width*
height; goal_pos++)
513 unsigned tile = s.
puzzle[goal_pos];
519 h_increment[tile][pos] = abs((
int) (goal_pos %
width) - (
int)(pos %
width));
520 h_increment[tile][pos] += abs((
int) (goal_pos /
width) - (
int)(pos /
width));
529 template <
int w
idth,
int height>
535 template <
int w
idth,
int height>
550 template <
int w
idth,
int height>
556 for (
unsigned int i = 0; i < operators[stateID.
blank].size(); i++)
558 neighbors.push_back(stateID);
559 ApplyAction(neighbors.back(), operators[stateID.
blank][i]);
563 template <
int w
idth,
int height>
567 for (
unsigned int i = 0; i < operators[stateID.
blank].size(); i++)
569 actions.push_back(operators[stateID.
blank][i]);
573 template <
int w
idth,
int height>
591 template <
int w
idth,
int height>
607 printf(
"Invalid up operator\n");
621 printf(
"Invalid down operator\n");
635 printf(
"Invalid right operator\n");
649 printf(
"Invalid left operator\n");
657 template <
int w
idth,
int height>
670 template <
int w
idth,
int height>
673 return DefaultH(state1);
676 template <
int w
idth,
int height>
680 return HCost(state1);
702 for (
unsigned int x = 0; x <
width; x++)
704 for (
unsigned int y = 0; y <
height; y++)
710 for (
unsigned int x = 0; x <
width; x++)
712 for (
unsigned int y = 0; y <
height; y++)
716 double absDist = (abs((
int)(xloc[state1.
puzzle[x + y*
width]] - x))
717 + abs((
int)(yloc[state1.
puzzle[x + y*
width]] - y)));
722 case kUnitPlusFrac: man_dist += absDist*(1.0+1.0/(1.0+movingTile));
break;
723 case kSquared: man_dist += absDist*(movingTile)*(movingTile);
break;
724 case kSquareRoot: man_dist += absDist*sqrt(movingTile);
break;
727 double tmp = movingTile;
728 tmp = sqrt(tmp*tmp+1);
729 man_dist += tmp*absDist;
755 template <
int w
idth,
int height>
771 3, 5, 4, 7, 10, 5, 3, 3, 8, 9, 2, 10, 10, 1, 2, 1, 1, 4, 7, 9, 6, 10, 2, 8, 8
792 template <
int w
idth,
int height>
813 template <
int w
idth,
int height>
817 this->pattern[x] =
false;
818 for (
int i : pattern)
819 this->pattern[i] =
true;
822 template <
int w
idth,
int height>
827 return pattern[tile] ==
true;
830 template <
int w
idth,
int height>
844 template <
int w
idth,
int height>
892 assert(!
"Illegal move");
897 template <
int w
idth,
int height>
900 return (state == theGoal);
903 template <
int w
idth,
int height>
909 case kDown:
return 1;
911 case kLeft:
return 3;
916 template <
int w
idth,
int height>
918 int count,
const std::vector<int> &pattern,
919 std::vector<int> &dual)
921 uint64_t hashVal = hash;
922 dual.resize(pattern.size());
924 int numEntriesLeft = count-pattern.size()+1;
925 for (
int x = pattern.size()-1; x >= 0; x--)
927 dual[x] = hashVal%numEntriesLeft;
928 hashVal /= numEntriesLeft;
930 for (
int y = x+1; y < pattern.size(); y++)
932 if (dual[y] >= dual[x])
938 for (
int x = 0; x < dual.size(); x++)
940 s.
puzzle[dual[x]] = pattern[x];
947 template <
int w
idth,
int height>
952 void DrawTile(
float x,
float y,
char c1,
char c2,
int w,
int h);
955 template <
int w
idth,
int height>
959 squareSize = 2.0f/squareSize;
960 float xOrigin = (0-((float)
width)/2.0f)*squareSize;
961 float yOrigin = (0-((float)
height)/2.0f)*squareSize;
965 for (
unsigned int y = 0; y <
height; y++)
967 for (
unsigned int x = 0; x <
width; x++)
972 display.
FillRect({xOrigin+x*squareSize, yOrigin+y*squareSize, xOrigin+(x+1)*squareSize, yOrigin+(y+1)*squareSize},
Colors::white);
973 display.
FrameRect({xOrigin+x*squareSize, yOrigin+y*squareSize, xOrigin+(x+1)*squareSize, yOrigin+(y+1)*squareSize},
Colors::darkblue, 0.01*squareSize);
976 {xOrigin+x*squareSize+squareSize/2.f, yOrigin+y*squareSize+squareSize/2.f},
983 template <
int w
idth,
int height>
986 int hitx=-1, hity=-1;
990 squareSize = 2.0f/squareSize;
991 float xOrigin = (0-((float)
width)/2.0f)*squareSize;
992 float yOrigin = (0-((float)
height)/2.0f)*squareSize;
994 for (
unsigned int y = 0; y <
height; y++)
996 for (
unsigned int x = 0; x <
width; x++)
1000 Graphics::rect r = {xOrigin+x*squareSize, yOrigin+y*squareSize, xOrigin+(x+1)*squareSize, yOrigin+(y+1)*squareSize};
1011 if (hitx == -1 || hity == -1)
1014 int x = hitx, y = hity;
1017 std::vector<slideDir> acts;
1018 GetActions(s, acts);
1022 ApplyAction(tmp, a);
1024 if (tmp.puzzle[x+y*
width] == 0)
1028 this->UndoAction(tmp, a);
1034 template <
int w
idth,
int height>
1038 squareSize = 2.0f/squareSize;
1039 float xOrigin = (0-((float)
width)/2.0f)*squareSize;
1040 float yOrigin = (0-((float)
height)/2.0f)*squareSize;
1044 for (
unsigned int y = 0; y <
height; y++)
1046 for (
unsigned int x = 0; x <
width; x++)
1053 display.
FillRect({xOrigin+x*squareSize, yOrigin+y*squareSize, xOrigin+(x+1)*squareSize, yOrigin+(y+1)*squareSize},
Colors::white);
1054 display.
FrameRect({xOrigin+x*squareSize, yOrigin+y*squareSize, xOrigin+(x+1)*squareSize, yOrigin+(y+1)*squareSize},
Colors::darkblue, 0.01*squareSize);
1063 switch (GetAction(s1, s2))
1066 p2 = {xOrigin+x*squareSize, yOrigin+(y+1)*squareSize};
1069 p2 = {xOrigin+x*squareSize, yOrigin+(y-1)*squareSize};
1072 p2 = {xOrigin+(x+1)*squareSize, yOrigin+(y)*squareSize};
1075 p2 = {xOrigin+(x-1)*squareSize, yOrigin+(y)*squareSize};
1078 default: assert(!
"action not found");
1092 template <
int w
idth,
int height>
1095 glEnable(GL_LINE_SMOOTH);
1096 for (
unsigned int y = 0; y <
height; y++)
1098 for (
unsigned int x = 0; x <
width; x++)
1113 template <
int w
idth,
int height>
1116 glEnable(GL_LINE_SMOOTH);
1117 for (
unsigned int y = 0; y <
height; y++)
1119 for (
unsigned int x = 0; x <
width; x++)
1134 switch (GetAction(s1, s2))
1140 default: assert(!
"action not found");
1169 template <
int w
idth,
int height>
1174 std::vector<std::vector<int> > permutations;
1178 for (
unsigned i = 0; i < permutations.size(); i++)
1184 new_state.
puzzle[j] = permutations[i][j];
1185 if (new_state.
puzzle[j] == 0)
1186 new_state.
blank = j;
1188 puzzles.push_back(new_state);
1193 template <
int w
idth,
int height>
1197 for (
int x = 0; x < count ; x++)
1203 template <
int w
idth,
int height>
1207 puzzle.GetStateFromHash(a, state1);
1208 puzzle.GetStateFromHash(b, state2);
1209 double val = puzzle.HCost(a, b);
1211 for (
unsigned int i=0; i < heuristics.size(); i++)
1213 double hval = heuristics[i][state1]-heuristics[i][state2];
1228 template <
int w
idth,
int height>
1234 for (
unsigned i = 0; i < permutation.size(); i++)
1236 new_puzz.
puzzle[i] = permutation[i];
1237 if (permutation[i] == 0)
1244 template <
int w
idth,
int height>
1250 uint64_t hashVal = hash;
1254 int numEntriesLeft = count-countm2+1;
1255 for (
int x = countm2-1; x >= 0; x--)
1257 dual[x] = hashVal%numEntriesLeft;
1258 hashVal /= numEntriesLeft;
1260 for (
int y = x+1; y < countm2; y++)
1262 if (dual[y] >= dual[x])
1267 for (
int x = 0; x < count; x++)
1272 for (
int x = 0; x < countm2; x++)
1282 int loc1 = -1, loc2 = -1;
1283 for (; x < count; x++)
1292 for (; x < count; x++)
1300 assert(loc1 != -1 && loc2 != -1);
1305 s.
puzzle[loc1] = countm2;
1306 s.
puzzle[loc2] = countm2+1;
1311 s.
puzzle[loc1] = countm2+1;
1312 s.
puzzle[loc2] = countm2;
1315 else if (GetParity(s) == 1)
1317 s.
puzzle[loc1] = countm2+1;
1318 s.
puzzle[loc2] = countm2;
1333 template <
int w
idth,
int height>
1337 std::array<int, width*height> dual;
1350 uint64_t hashVal = 0;
1364 if (locs[y] > locs[x])
1371 template <
int w
idth,
int height>
1381 template <
int w
idth,
int height>
1387 if (state.
puzzle[x] == 0)
1391 if (state.
puzzle[y] == 0)
1398 if ((
width % 2) == 1)
1407 template <
int w
idth,
int height>
1410 std::map<uint64_t, uint64_t> puzzle_map;
1415 unsigned goal_parity = GetParity(goal);
1417 while (count < num_puzzles)
1422 if (puzzle_map.find(next_hash) != puzzle_map.end())
1428 if (GetParity(next) == goal_parity)
1430 puzzle_map[next_hash] = next_hash;
1431 puzzle_vector.push_back(next);
1438 template <
int w
idth,
int height>
1459 template <
int w
idth,
int height>
1462 std::vector<slideDir> ops;
1463 assert(order_num <= 23);
1464 assert(order_num >= 0);
1467 std::vector<int> op_nums(4);
1470 for (
int x = 3; x >= 0; x--)
1472 op_nums[x] = order_num % num_left;
1473 order_num /= num_left;
1476 for (
int y = x+1; y < 4; y++)
1478 if (op_nums[y] >= op_nums[x])
1485 bool up_act =
false;
1486 bool down_act =
false;
1487 bool left_act =
false;
1488 bool right_act =
false;
1490 printf(
"Op order: ");
1491 for (
unsigned i = 0; i < 4; i++)
1493 if (op_nums[i] == 0)
1499 else if (op_nums[i] == 1)
1502 ops.push_back(
kLeft);
1505 else if (op_nums[i] == 2)
1511 else if (op_nums[i] == 3)
1514 ops.push_back(
kDown);