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 "group/group.h" |
|||
#include "utils/common.h" |
|||
#include "fast_cal/fast_cal.h" |
|||
|
|||
using klotski::codec::RawCode; |
|||
using klotski::codec::CommonCode; |
|||
using klotski::cases::RangesUnion; |
|||
using klotski::BLOCK_MSK; |
|||
using klotski::BLOCK_CE_2x2; |
|||
|
|||
using klotski::codec::RawCode; |
|||
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() { |
|||
// if (is_solved(root_.unwrap())) {
|
|||
// return root_;
|
|||
// }
|
|||
std::vector<RawCode> FastCal::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.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; |
|||
auto mover = MaskMover([this, &solution](RawCode code, uint64_t mask) { |
|||
RawCode solution {nil}; |
|||
auto mover = MaskMover([this, &solution](const RawCode code, const uint64_t mask) { |
|||
if (try_emplace(code, mask) && is_solved(code)) { |
|||
solution = code.unwrap(); |
|||
solution = code; |
|||
} |
|||
}); |
|||
while (!codes_.is_ending()) { |
|||
|
|||
while (!seeker_.is_ending()) { |
|||
spawn_next(mover); |
|||
if (solution != 0) { |
|||
return RawCode::unsafe_create(solution); |
|||
if (solution != nil) { |
|||
return solution; |
|||
} |
|||
} |
|||
return std::nullopt; |
|||
} |
|||
|
|||
std::optional<RawCode> FastCalPro::search(std::function<bool(RawCode)> &&match) { |
|||
// TODO: check root case
|
|||
std::optional<RawCode> FastCal::search(std::function<bool(RawCode)> &&match) { |
|||
if (match(seeker_.current())) { |
|||
return seeker_.current(); // root case matched
|
|||
} |
|||
|
|||
uint64_t target = 0; |
|||
auto mover = MaskMover([this, &target, match = std::move(match)](RawCode code, uint64_t mask) { |
|||
RawCode target {nil}; |
|||
auto mover = MaskMover([this, &target, match = std::move(match)](const RawCode code, const uint64_t mask) { |
|||
if (try_emplace(code, mask) && match(code)) { |
|||
target = code.unwrap(); |
|||
target = code; |
|||
} |
|||
}); |
|||
while (!codes_.is_ending()) { |
|||
|
|||
while (!seeker_.is_ending()) { |
|||
spawn_next(mover); |
|||
if (target != 0) { |
|||
return RawCode::unsafe_create(target); |
|||
if (target != nil) { |
|||
return target; |
|||
} |
|||
} |
|||
return std::nullopt; |
|||
} |
|||
|
|||
std::vector<RawCode> FastCalPro::solve_multi() { |
|||
// TODO: check root case
|
|||
std::vector<RawCode> FastCal::solve_multi() { |
|||
if (is_solved(seeker_.current())) { |
|||
return {seeker_.current()}; // root case solved
|
|||
} |
|||
|
|||
bool stop_flag = false; |
|||
std::vector<RawCode> results {}; |
|||
|
|||
auto mover = MaskMover([this, &stop_flag, &results](RawCode code, uint64_t mask) { |
|||
auto mover = MaskMover([this, &stop_flag, &results](const RawCode code, const uint64_t mask) { |
|||
if (try_emplace(code, mask) && is_solved(code)) { |
|||
stop_flag = true; |
|||
results.emplace_back(code); |
|||
} |
|||
}); |
|||
|
|||
while (!codes_.is_ending()) { |
|||
while (!seeker_.is_ending()) { |
|||
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 {}; |
|||
} |
|||
|
|||
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