mirror of https://github.com/dnomd343/klotski.git
Dnomd343
2 months ago
9 changed files with 154 additions and 123 deletions
@ -1,110 +1,119 @@ |
|||||
#include "mover/mover.h" |
#include "utils/common.h" |
||||
#include "group/group.h" |
|
||||
#include "fast_cal/fast_cal.h" |
#include "fast_cal/fast_cal.h" |
||||
|
|
||||
using klotski::codec::RawCode; |
using klotski::BLOCK_MSK; |
||||
using klotski::codec::CommonCode; |
using klotski::BLOCK_CE_2x2; |
||||
using klotski::cases::RangesUnion; |
|
||||
|
|
||||
|
using klotski::codec::RawCode; |
||||
using klotski::mover::MaskMover; |
using klotski::mover::MaskMover; |
||||
using klotski::cases::GroupUnion; |
using klotski::fast_cal::FastCal; |
||||
|
|
||||
|
// ----------------------------------------------------------------------------------------- //
|
||||
|
|
||||
|
void FastCal::build_all() { |
||||
|
auto mover = MaskMover([this](const RawCode code, const uint64_t mask) { |
||||
|
try_emplace(code, mask); |
||||
|
}); |
||||
|
while (!seeker_.is_ending()) { |
||||
|
spawn_next(mover); |
||||
|
} |
||||
|
} |
||||
|
|
||||
using klotski::fast_cal::FastCalPro; |
std::vector<RawCode> FastCal::furthest() { |
||||
|
if (!seeker_.is_ending()) { |
||||
|
build_all(); |
||||
|
} |
||||
|
return seeker_.last_layer(); |
||||
|
} |
||||
|
|
||||
static KLSK_INLINE bool is_solved(RawCode raw_code) { |
// ----------------------------------------------------------------------------------------- //
|
||||
return ((raw_code.unwrap() >> 39) & 0b111) == 0b100; |
|
||||
|
std::vector<std::vector<RawCode>> FastCal::exports() const { |
||||
|
return seeker_.all_layers(); |
||||
} |
} |
||||
|
|
||||
std::optional<RawCode> FastCalPro::solve() { |
std::vector<RawCode> FastCal::backtrack(RawCode code) const { |
||||
// if (is_solved(root_.unwrap())) {
|
if (const auto match = cases_.find(code); match == cases_.end()) { |
||||
// return root_;
|
return {}; // case not found
|
||||
// }
|
} |
||||
|
std::vector<RawCode> path; |
||||
|
while (code != 0) { |
||||
|
path.emplace_back(code); |
||||
|
code = cases_.find(code)->second.parent; |
||||
|
} |
||||
|
std::reverse(path.begin(), path.end()); |
||||
|
return path; |
||||
|
} |
||||
|
|
||||
|
// ----------------------------------------------------------------------------------------- //
|
||||
|
|
||||
|
static KLSK_INLINE bool is_solved(const RawCode raw_code) { |
||||
|
return ((raw_code.unwrap() >> 39) & BLOCK_MSK) == BLOCK_CE_2x2; |
||||
|
} |
||||
|
|
||||
|
std::optional<RawCode> FastCal::solve() { |
||||
|
if (is_solved(seeker_.current())) { |
||||
|
return seeker_.current(); // root case solved
|
||||
|
} |
||||
|
|
||||
uint64_t solution = 0; |
RawCode solution {nil}; |
||||
auto mover = MaskMover([this, &solution](RawCode code, uint64_t mask) { |
auto mover = MaskMover([this, &solution](const RawCode code, const uint64_t mask) { |
||||
if (try_emplace(code, mask) && is_solved(code)) { |
if (try_emplace(code, mask) && is_solved(code)) { |
||||
solution = code.unwrap(); |
solution = code; |
||||
} |
} |
||||
}); |
}); |
||||
while (!codes_.is_ending()) { |
|
||||
|
while (!seeker_.is_ending()) { |
||||
spawn_next(mover); |
spawn_next(mover); |
||||
if (solution != 0) { |
if (solution != nil) { |
||||
return RawCode::unsafe_create(solution); |
return solution; |
||||
} |
} |
||||
} |
} |
||||
return std::nullopt; |
return std::nullopt; |
||||
} |
} |
||||
|
|
||||
std::optional<RawCode> FastCalPro::search(std::function<bool(RawCode)> &&match) { |
std::optional<RawCode> FastCal::search(std::function<bool(RawCode)> &&match) { |
||||
// TODO: check root case
|
if (match(seeker_.current())) { |
||||
|
return seeker_.current(); // root case matched
|
||||
|
} |
||||
|
|
||||
uint64_t target = 0; |
RawCode target {nil}; |
||||
auto mover = MaskMover([this, &target, match = std::move(match)](RawCode code, uint64_t mask) { |
auto mover = MaskMover([this, &target, match = std::move(match)](const RawCode code, const uint64_t mask) { |
||||
if (try_emplace(code, mask) && match(code)) { |
if (try_emplace(code, mask) && match(code)) { |
||||
target = code.unwrap(); |
target = code; |
||||
} |
} |
||||
}); |
}); |
||||
while (!codes_.is_ending()) { |
|
||||
|
while (!seeker_.is_ending()) { |
||||
spawn_next(mover); |
spawn_next(mover); |
||||
if (target != 0) { |
if (target != nil) { |
||||
return RawCode::unsafe_create(target); |
return target; |
||||
} |
} |
||||
} |
} |
||||
return std::nullopt; |
return std::nullopt; |
||||
} |
} |
||||
|
|
||||
std::vector<RawCode> FastCalPro::solve_multi() { |
std::vector<RawCode> FastCal::solve_multi() { |
||||
// TODO: check root case
|
if (is_solved(seeker_.current())) { |
||||
|
return {seeker_.current()}; // root case solved
|
||||
|
} |
||||
|
|
||||
bool stop_flag = false; |
bool stop_flag = false; |
||||
std::vector<RawCode> results {}; |
std::vector<RawCode> results {}; |
||||
|
auto mover = MaskMover([this, &stop_flag, &results](const RawCode code, const uint64_t mask) { |
||||
auto mover = MaskMover([this, &stop_flag, &results](RawCode code, uint64_t mask) { |
|
||||
if (try_emplace(code, mask) && is_solved(code)) { |
if (try_emplace(code, mask) && is_solved(code)) { |
||||
stop_flag = true; |
stop_flag = true; |
||||
results.emplace_back(code); |
results.emplace_back(code); |
||||
} |
} |
||||
}); |
}); |
||||
|
|
||||
while (!codes_.is_ending()) { |
while (!seeker_.is_ending()) { |
||||
spawn_next(mover); |
spawn_next(mover); |
||||
if (stop_flag && (codes_.is_new_layer() || codes_.is_ending())) { |
if (stop_flag && (seeker_.is_new_layer() || seeker_.is_ending())) { |
||||
return results; |
return results; |
||||
} |
} |
||||
|
|
||||
} |
} |
||||
return {}; |
return {}; |
||||
} |
} |
||||
|
|
||||
void FastCalPro::build() { |
// ----------------------------------------------------------------------------------------- //
|
||||
auto mover = MaskMover([this](RawCode code, uint64_t mask) { |
|
||||
try_emplace(code, mask); |
|
||||
}); |
|
||||
while (!codes_.is_ending()) { |
|
||||
spawn_next(mover); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
std::vector<RawCode> FastCalPro::furthest() { |
|
||||
if (!codes_.is_ending()) { |
|
||||
build(); |
|
||||
} |
|
||||
return codes_.last_layer(); |
|
||||
} |
|
||||
|
|
||||
std::vector<RawCode> FastCalPro::backtrack(RawCode code) const { |
|
||||
if (const auto match = cases_.find(code); match == cases_.end()) { |
|
||||
return {}; // case not found
|
|
||||
} |
|
||||
std::vector<RawCode> path; |
|
||||
while (code != 0) { |
|
||||
path.emplace_back(code); |
|
||||
code = cases_.find(code)->second.back; |
|
||||
} |
|
||||
std::reverse(path.begin(), path.end()); |
|
||||
return path; |
|
||||
} |
|
||||
|
|
||||
std::vector<std::vector<RawCode>> FastCalPro::exports() const { |
|
||||
return codes_.all_layers(); |
|
||||
} |
|
||||
|
Loading…
Reference in new issue