-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathalg.cpp
132 lines (97 loc) · 3.77 KB
/
alg.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include "alg.hpp"
#include "alg_impl.hpp"
#include <ostream>
#include "cube.hpp"
#include "mini_cube.hpp"
#include "edge_cubies.hpp"
#include <stack>
#include <vector>
#include <functional>
#include <utility>
#include <array>
#include <array>
#include <filesystem>
std::pair<std::vector<Cube>, uint64_t> idaStar(Cube start) {
struct Node {
Cube cube;
int depth;
Node* prev;
};
//PDB<EdgeCubies> firstEdgeCubieDB(deserializePdb("pdb/7_edge_cubies_first.pdb"));
PDB<EdgeCubies<12>> edgeCubie12DB(deserializePdb("../pdb/edge_cubies_no_orient.pdb"));
//PDB<EdgeCubies> secondEdgeCubieDB(deserializePdb("pdb/edge_cubies_second.pdb"));
PDB<EdgeCubies<7>> firstEdgeCubieDB(deserializePdb("../pdb/7_edge_cubies_first.pdb"));
//PDB<EdgeCubies<6>> secondEdgeCubieDB(deserializePdb("../pdb/edge_cubies_second.pdb"));
PDB<MiniCube> cornerCubieDB(deserializePdb("../pdb/corner_cubies.pdb"));
std::cout << "Solving cube:" << std::endl;
auto heuristic = [&](Cube const& cube) {
MiniCube cornerCubies(cube);
EdgeCubies edgeCubies12 = EdgeCubies<12>(cube, false, true);
EdgeCubies firstEdgeSet = EdgeCubies<7>(cube);
//EdgeCubies secondEdgeSet = EdgeCubies<6>(cube, true, false);
return std::max({
cornerCubieDB.getDist(cornerCubies.getIdx()),
edgeCubie12DB.getDist(edgeCubies12.getIdx()),
firstEdgeCubieDB.getDist(firstEdgeSet.getIdx()),
//secondEdgeCubieDB.getDist(secondEdgeSet.getIdx()),
});
};
constexpr int SKYDADDYS_NUMBER = 20;
uint64_t nodesGenerated = 0;
for (int depthLim = heuristic(start); depthLim <= SKYDADDYS_NUMBER; depthLim++) {
std::cout << "Depth " << depthLim << std::endl;
std::function<std::vector<Cube>(Node)> idaStarInner;
idaStarInner = [&depthLim, &idaStarInner, &heuristic, &nodesGenerated](Node node) -> std::vector<Cube> {
if (node.cube.isSolved()) {
std::vector<Cube> sol;
Node* curr = &node;
while (curr->prev != nullptr) {
sol.insert(sol.begin(), curr->cube);
curr = curr->prev;
}
sol.insert(sol.begin(), curr->cube);
return sol;
}
//Reduce branching factor
for (Cube const& neighbor : node.cube.getNeighbors()) {
nodesGenerated++;
if (node.depth+1 + heuristic(neighbor) <= depthLim) {
auto result = idaStarInner(Node{neighbor, node.depth+1, &node});
if (!result.empty())
return result;
}
}
return std::vector<Cube>();
};
std::vector<Cube> result = idaStarInner(Node{start, 0, nullptr});
if (!result.empty()) {
return std::make_pair(result, nodesGenerated);
}
}
}
//AI generated lol
std::vector<uint8_t> deserializePdb(std::string filename) {
std::ifstream is(filename, std::ios::binary);
if (!is.good()) { throw std::runtime_error("Cannot open file for reading"); }
//No longer used anymore
uint32_t oldSizeHeader;
is.read(reinterpret_cast<char*>(&oldSizeHeader), sizeof(oldSizeHeader));
if (!is.good()) { throw std::runtime_error("Error reading size"); }
std::filesystem::path file(filename);
uint64_t size = std::filesystem::file_size(file) - 4;
std::vector<uint8_t> bytes(size);
//std::cout << "size: " << size;
is.read(reinterpret_cast<char*>(bytes.data()), size);
if (!is.good()) { throw std::runtime_error("Error reading bytes"); }
return bytes;
}
void serializePdb(std::vector<uint8_t> const& data, std::string filename) {
std::ofstream os(filename, std::ios::binary);
if (!os.good()) { throw std::runtime_error("Cannot open file for writing"); }
uint32_t size = data.size();
os.write(reinterpret_cast<const char*>(&size), sizeof(size));
if (!os.good()) { throw std::runtime_error("Error writing size"); }
os.write(reinterpret_cast<const char*>(data.data()), size);
if (!os.good()) { throw std::runtime_error("Error writing bytes"); }
os.close();
}