华容道高性能计算引擎
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

83 lines
2.6 KiB

#include <algorithm>
#include "core.h"
#include "common.h"
#include "fast_cal.h"
#include "raw_code.h"
/// klotski resolved -> 2x2 block at address 13 (aka 0xD)
auto resolved = [](uint64_t code) {
return ((code >> (3 * 0xD)) & 0b111) == B_2x2; // check 2x2 block address
};
RawCode FastCal::solve(const RawCode &code) {
return FastCal::target(code, resolved);
}
std::vector<RawCode> FastCal::solve_multi(const RawCode &code) {
return FastCal::target_multi(code, resolved);
}
std::vector<RawCode> FastCal::resolve(const RawCode &start) {
return FastCal::search(start, resolved);
}
std::vector<std::vector<RawCode>> FastCal::resolve_multi(const RawCode &start) {
return FastCal::search_multi(start, resolved);
}
/// backtrack of FastCal tree
int FastCal::step_num(const RawCode &code) {
auto tmp = cases.find((uint64_t)code);
if (tmp == cases.end()) {
return -1; // code not exist
}
int num = 0; // step number
auto node = &tmp->second; // backtrack entry
while ((node = node->last) != nullptr) {
++num;
}
return num;
}
std::vector<RawCode> FastCal::backtrack(const RawCode &code) {
auto tmp = cases.find((uint64_t)code);
if (tmp == cases.end()) {
return std::vector<RawCode>{}; // code not exist
}
auto node = &tmp->second; // backtrack entry
std::vector<RawCode> path; // backtrack path
while (node != nullptr) {
path.emplace_back(RawCode::unsafe_create(node->code)); // record path info
node = node->last;
}
std::reverse(path.begin(), path.end()); // reverse path cases
return path;
}
/// static BFS search functions
std::vector<std::vector<RawCode>> FastCal::to_furthest(const RawCode &start) {
auto fc = FastCal();
std::vector<std::vector<RawCode>> result;
for (const auto &furthest : fc.furthest(start)) {
result.emplace_back(fc.backtrack(furthest)); // backtrack every furthest cases
}
return result;
}
std::vector<RawCode> FastCal::search(const RawCode &start, const match_t &match) {
auto fc = FastCal();
auto result = fc.target(start, match);
if (result == FC_NOT_FOUND) {
return std::vector<RawCode>{}; // target not matched
}
return fc.backtrack(result); // backtrack target path
}
std::vector<std::vector<RawCode>> FastCal::search_multi(const RawCode &start, const match_t &match) {
auto fc = FastCal();
std::vector<std::vector<RawCode>> result;
for (const auto &target : fc.target_multi(start, match)) {
result.emplace_back(fc.backtrack(target)); // backtrack every target
}
return result;
}