-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSolver.class.cpp
118 lines (106 loc) · 3.87 KB
/
Solver.class.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
/* ************************************************************************** */
/* */
/* :::::::: */
/* Solver.class.cpp :+: :+: */
/* +:+ */
/* By: pacovali <[email protected]> +#+ */
/* +#+ */
/* Created: 2020/08/15 02:33:35 by pacovali #+# #+# */
/* Updated: 2020/08/30 11:31:40 by pacovali ######## odam.nl */
/* */
/* ************************************************************************** */
#include "Solver.class.hpp"
using namespace std;
Solver::Solver( const std::string& mix ) {
vector<char> commands;
string allowedChars = "FRUBLD2' ";
for ( auto c = mix.begin(); c < mix.end(); c++ ) {
if ( find(allowedChars.begin(), allowedChars.end(), *c) == allowedChars.end() ) {
throw out_of_range("Forbidden character found");
}
while ( *c == ' ' ) {
c++;
}
if ( c == mix.end() ) {
break ;
}
char current = *c;
if ( find(allowedChars.begin() + 6, allowedChars.end(), current) != allowedChars.end() ) {
throw logic_error("Command not well formatted");
}
commands.push_back(current);
c++;
if ( c == mix.end() ) {
break ;
} else if ( *c == '2' ) {
commands.push_back(current);
c++;
} else if ( *c == '\'' ) {
commands.push_back(current);
commands.push_back(current);
c++;
}
if ( *c != ' ' && c != mix.end() ) {
throw logic_error("Command doesn't end with a space");
}
}
if ( commands.size() < 1 ) {
throw range_error("Command list is empty");
}
head_.setInitialState(commands);
}
Solver::Solver( const int& len ) {
vector<char> commands;
vector<char> allowed = {'F', 'R', 'U', 'B', 'L', 'D'};
if ( len < 1 ) {
throw range_error("Lenght of random command list must be positive");
}
srand((int)time(nullptr));
cerr << "Random mix of length " << len << ": ";
for ( int i = 0; i < len; i++ ) {
commands.push_back(allowed[rand() % 6]);
cerr << *(commands.end() - 1) << " ";
}
cerr << endl;
head_.setInitialState(commands);
}
void Solver::solve( const int& searchType ) {
allStates_.insert( head_.getState() );
openStates_.insert( {head_.getWeight() * (searchType & 1 ? 1 : 0) + head_.getCost() * (searchType & 2 ? 1 : 0), &head_} );
while ( openStates_.size() > 0 ) {
auto begin = openStates_.begin();
auto state = begin->second;
if ( state->getState() == solution ) {
printSolution( state );
exit (0);
}
state->setChildren();
auto newChildren = state->getChildren();
for ( auto& child : *newChildren ) {
if ( allStates_.count(child.getState()) < 1 ) {
allStates_.insert( child.getState() );
openStates_.insert( {child.getWeight() * (searchType & 1) + child.getCost() * (searchType & 2), &child} );
}
}
openStates_.erase( begin );
}
}
void Solver::printSolution( Rubik *solution ) const {
vector<pair<char, char>> commands;
vector<char> mods = {'\0', '2', '\''};
while ( solution->getParent() != nullptr ) {
commands.insert( commands.begin(), {solution->getCommand(), solution->getCommandModifier()} );
// print all states from solution to initial mix
// cout << "W: " << solution->getWeight() << " ";
// cout << " : " << solution->getCommand() << solution->getCommandModifier() << " : ";
// for (int i = 8; i < 128; i++) {
// cout << (((i - 2) % 6) ? '\0' : ' ') << ((uint8_t)(solution->getState() >> (127 - i)) & 1);
// }
// cout << endl;
solution = solution->getParent();
}
for ( auto c = commands.begin(); c < commands.end(); c++ ) {
cout << c->first << c->second << ' ';
}
cout << endl;
}