mirror of https://github.com/dnomd343/klotski.git
8 changed files with 269 additions and 8 deletions
@ -0,0 +1,18 @@ |
|||
#include "analyse/analyse.h" |
|||
|
|||
#include <print> |
|||
|
|||
using klotski::codec::RawCode; |
|||
using klotski::mover::MaskMover; |
|||
using klotski::analyse::AnalysePro; |
|||
|
|||
void AnalysePro::build_all() { |
|||
auto mover = MaskMover([this](const RawCode code, const uint64_t mask) { |
|||
try_emplace(code, mask); |
|||
}); |
|||
|
|||
while (!seeker_.is_ending()) { |
|||
// std::println("layer: {}", seeker_.layer_num());
|
|||
spawn_next(mover); |
|||
} |
|||
} |
@ -0,0 +1,79 @@ |
|||
#pragma once |
|||
|
|||
namespace klotski { |
|||
|
|||
template <typename T> |
|||
requires std::is_trivial_v<T> |
|||
LayerQueuePro<T>::LayerQueuePro(std::initializer_list<T> first_layer, const size_t max_size) |
|||
: layer_end_(first_layer.size()), queue_end_(0) { |
|||
data_ = static_cast<T*>(std::malloc(sizeof(T) * max_size)); |
|||
for (const auto node : first_layer) { |
|||
emplace(node); |
|||
} |
|||
layer_offset_.reserve(232); // TODO: confirm the max layer number |
|||
layer_offset_.emplace_back(layer_end_); |
|||
} |
|||
|
|||
template <typename T> |
|||
requires std::is_trivial_v<T> |
|||
LayerQueuePro<T>::~LayerQueuePro() { |
|||
std::free(data_); |
|||
} |
|||
|
|||
template <typename T> |
|||
requires std::is_trivial_v<T> |
|||
T LayerQueuePro<T>::current() const { |
|||
return data_[queue_begin_]; |
|||
} |
|||
|
|||
template <typename T> |
|||
requires std::is_trivial_v<T> |
|||
void LayerQueuePro<T>::emplace(T node) { |
|||
data_[queue_end_] = node; |
|||
++queue_end_; |
|||
} |
|||
|
|||
template <typename T> |
|||
requires std::is_trivial_v<T> |
|||
void LayerQueuePro<T>::next() { |
|||
++queue_begin_; |
|||
if (queue_begin_ == layer_end_ && !is_ending()) { |
|||
layer_begin_ = layer_end_; |
|||
layer_end_ = queue_end_; |
|||
layer_offset_.emplace_back(layer_end_); |
|||
} |
|||
} |
|||
|
|||
template <typename T> |
|||
requires std::is_trivial_v<T> |
|||
[[nodiscard]] bool LayerQueuePro<T>::is_ending() const { |
|||
return queue_begin_ == queue_end_; |
|||
} |
|||
|
|||
// template <typename T> |
|||
// requires std::is_trivial_v<T> |
|||
// [[nodiscard]] bool LayerQueuePro<T>::is_new_layer() const { |
|||
// return queue_begin_ == layer_begin_; |
|||
// } |
|||
|
|||
// template <typename T> |
|||
// requires std::is_trivial_v<T> |
|||
// std::vector<T> LayerQueuePro<T>::last_layer() const { |
|||
// return {data_ + layer_begin_, data_ + layer_end_}; |
|||
// } |
|||
|
|||
// template <typename T> |
|||
// requires std::is_trivial_v<T> |
|||
// std::vector<std::vector<T>> LayerQueuePro<T>::all_layers() const { |
|||
// std::vector<std::vector<T>> result; |
|||
// result.reserve(layer_offset_.size() - 1); |
|||
// for (size_t i = 0; i < layer_offset_.size() - 1; ++i) { |
|||
// result.emplace_back(std::vector<T> { |
|||
// data_ + layer_offset_[i], |
|||
// data_ + layer_offset_[i + 1] |
|||
// }); |
|||
// } |
|||
// return result; |
|||
// } |
|||
|
|||
} // namespace klotski |
@ -0,0 +1,60 @@ |
|||
/// Klotski Engine by Dnomd343 @2024
|
|||
|
|||
#pragma once |
|||
|
|||
#include <vector> |
|||
|
|||
namespace klotski { |
|||
|
|||
template <typename T> |
|||
requires std::is_trivial_v<T> |
|||
class LayerQueuePro final { |
|||
public: |
|||
~LayerQueuePro(); |
|||
|
|||
/// Construct from first layer nodes and reserve size.
|
|||
LayerQueuePro(std::initializer_list<T> first_layer, size_t max_size); |
|||
|
|||
// ------------------------------------------------------------------------------------- //
|
|||
|
|||
/// Pop the head of the queue.
|
|||
void next(); |
|||
|
|||
/// Obtain the current working node.
|
|||
T current() const; |
|||
|
|||
/// Emplace new node at the end of the queue.
|
|||
void emplace(T node); |
|||
|
|||
// ------------------------------------------------------------------------------------- //
|
|||
|
|||
/// Whether the queue is empty.
|
|||
[[nodiscard]] bool is_ending() const; |
|||
|
|||
/// Whether the queue front is on new layer.
|
|||
// [[nodiscard]] bool is_new_layer() const;
|
|||
|
|||
// ------------------------------------------------------------------------------------- //
|
|||
|
|||
/// Get the nodes of the last layer.
|
|||
// std::vector<T> last_layer() const;
|
|||
|
|||
/// Get all the nodes of each layer.
|
|||
// std::vector<std::vector<T>> all_layers() const;
|
|||
|
|||
// ------------------------------------------------------------------------------------- //
|
|||
|
|||
[[nodiscard]] size_t layer_num() const { |
|||
return layer_offset_.size(); |
|||
} |
|||
|
|||
private: |
|||
T *data_ {nullptr}; |
|||
size_t layer_begin_ {0}, layer_end_; |
|||
size_t queue_begin_ {0}, queue_end_; |
|||
std::vector<size_t> layer_offset_ {0}; |
|||
}; |
|||
|
|||
} // namespace klotski
|
|||
|
|||
#include "internal/layer_queue.inl" |
@ -0,0 +1,27 @@ |
|||
#include <benchmark/benchmark.h> |
|||
|
|||
#include "analyse/analyse.h" |
|||
#include "common_code/common_code.h" |
|||
|
|||
using klotski::Analyse; |
|||
using klotski::analyse::AnalysePro; |
|||
|
|||
static void AnalyseBenchmark(benchmark::State &state) { |
|||
|
|||
auto code = klotski::codec::CommonCode::unsafe_create(0x1A9BF0C00).to_raw_code(); |
|||
|
|||
for (auto _ : state) { |
|||
|
|||
// auto analyse = Analyse {code};
|
|||
// analyse.build();
|
|||
|
|||
auto analyse = AnalysePro {code}; |
|||
analyse.build_all(); |
|||
|
|||
} |
|||
|
|||
} |
|||
|
|||
BENCHMARK(AnalyseBenchmark)->Unit(benchmark::kMillisecond); |
|||
|
|||
BENCHMARK_MAIN(); |
Loading…
Reference in new issue