From 9c07f56c218d069a4aebcf820ff93a4252b512c4 Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Sun, 1 Dec 2024 16:08:34 +0800 Subject: [PATCH] refactor: enhance BasicRanges and AllCases module --- src/core/all_cases/all_cases.h | 10 +++---- src/core/all_cases/all_cases_fwd.h | 12 +++++++++ src/core/all_cases/internal/all_cases.cc | 24 +++++++---------- src/core/all_cases/internal/basic_ranges.cc | 30 +++++---------------- 4 files changed, 31 insertions(+), 45 deletions(-) create mode 100644 src/core/all_cases/all_cases_fwd.h diff --git a/src/core/all_cases/all_cases.h b/src/core/all_cases/all_cases.h index 6aca0da..1227eea 100644 --- a/src/core/all_cases/all_cases.h +++ b/src/core/all_cases/all_cases.h @@ -13,7 +13,7 @@ /// situations. Therefore, each combination can produce different permutations, /// after mathematical calculations, there are a total of `7311885` possible /// permutations. The goal of BasicRanges is to find these permutations, sort -/// them and store in a uint32_t array. +/// them and store in an uint32_t array. /// AllCases is used to generate all valid CommonCodes, its works based on all /// permutations generated by BasicRanges, which will use different 2x2 block @@ -29,7 +29,7 @@ /// 16 17 18 19 12 13 14 /// After all the work is done, we will have 29334498 cases, distributed in 16 -/// arrays. Each of them is a uint32_t array storing the ranges, which can be +/// arrays. Each of them is an uint32_t array storing the ranges, which can be /// used to save memory, otherwise the 64-bit length must be consumed. /// By the way, due to the performance considerations of the checking process, @@ -42,13 +42,9 @@ #include #include "utils/utility.h" +#include "ranges/ranges_fwd.h" #include "internal/constant.inl" -namespace klotski::cases { -class Ranges; -class RangesUnion; -} // namespace klotski::cases - namespace klotski::cases { // ----------------------------------------------------------------------------------------- // diff --git a/src/core/all_cases/all_cases_fwd.h b/src/core/all_cases/all_cases_fwd.h new file mode 100644 index 0000000..ac05b85 --- /dev/null +++ b/src/core/all_cases/all_cases_fwd.h @@ -0,0 +1,12 @@ +/// Klotski Engine by Dnomd343 @2024 + +#pragma once + +#include "internal/constant.inl" + +namespace klotski::cases { + +class AllCases; +class BasicRanges; + +} // namespace klotski::cases diff --git a/src/core/all_cases/internal/all_cases.cc b/src/core/all_cases/internal/all_cases.cc index 5f82087..f20c206 100644 --- a/src/core/all_cases/internal/all_cases.cc +++ b/src/core/all_cases/internal/all_cases.cc @@ -1,27 +1,21 @@ +#include "ranges/ranges.h" #include "all_cases/all_cases.h" -using klotski::range_reverse; using klotski::cases::Ranges; using klotski::cases::AllCases; using klotski::cases::BasicRanges; -using klotski::cases::ALL_CASES_NUM; -typedef std::array Heads; +using klotski::range_reverse; +using klotski::cases::ALL_CASES_NUM; /// Generate all possible klotski heads. -static consteval Heads get_heads() { - Heads heads {}; - for (int i = 0, head = 0; head < 15; ++head) { - if (head % 4 != 3) { - heads[i++] = head; - } - } - return heads; +static consteval std::array get_heads() { + // TODO: why faster than using `constexpr` directly + return {0x0, 0x1, 0x2, 0x4, 0x5, 0x6, 0x8, 0x9, 0xA, 0xC, 0xD, 0xE}; } /// Build all valid ranges of the specified head. -static void build_cases(const std::vector &ranges, - const std::vector &reversed, Ranges &release, const int head) { +static void build_cases(const Ranges &ranges, const Ranges &reversed, Ranges &release, const int head) { release.clear(); release.reserve(ALL_CASES_NUM[head]); @@ -60,7 +54,7 @@ void AllCases::build() { } const auto &ranges = BasicRanges::instance().fetch(); - std::vector reversed {ranges}; + Ranges reversed {ranges}; for (auto &x : reversed) { x = range_reverse(x); } @@ -84,7 +78,7 @@ void AllCases::build_async(Executor &&executor, Notifier &&callback) { } auto &ranges = BasicRanges::instance().fetch(); - auto reversed = std::make_shared>(ranges); + auto reversed = std::make_shared(ranges); for (auto &x : *reversed) { x = range_reverse(x); } diff --git a/src/core/all_cases/internal/basic_ranges.cc b/src/core/all_cases/internal/basic_ranges.cc index c79d256..f7a6470 100644 --- a/src/core/all_cases/internal/basic_ranges.cc +++ b/src/core/all_cases/internal/basic_ranges.cc @@ -6,31 +6,15 @@ using klotski::cases::Ranges; using klotski::cases::BasicRanges; + +using klotski::group::BLOCK_NUM; using klotski::group::TYPE_ID_LIMIT; -using RangesIter = Ranges::iterator ; -using RangeType = std::tuple ; -using RangeTypeUnion = std::array; - -/// Generate all possible basic-ranges permutations. -consteval static RangeTypeUnion range_types() { - RangeTypeUnion data; - for (int i = 0, n = 0; n <= 7; ++n) { // 1x2 + 2x1 -> 0 ~ 7 - for (int n_2x1 = 0; n_2x1 <= n; ++n_2x1) { // 2x1 -> 0 ~ n - if (n_2x1 == 7) { - break; - } - for (int n_1x1 = 0; n_1x1 <= (14 - n * 2); ++n_1x1) { // 1x1 -> 0 ~ (14 - 2n) - data[i++] = {n, n_2x1, n_1x1}; - } - } - } - return data; -} +using RangesIter = Ranges::iterator; /// Combine two consecutive sorted arrays into one sorted arrays. static void inplace_merge(RangesIter begin, RangesIter mid, const RangesIter end) { - std::vector tmp {begin, mid}; // left array backup + std::vector tmp {begin, mid}; // left array backup for (auto p = tmp.begin();;) { if (*p <= *mid) { *(begin++) = *(p++); // stored in original span @@ -59,7 +43,7 @@ void BasicRanges::build() { auto &ranges = get_ranges(); ranges.clear(); ranges.reserve(BASIC_RANGES_NUM_); - for (auto [n, n_2x1, n_1x1] : range_types()) { + for (auto [n, n_2x1, n_1x1] : BLOCK_NUM) { ranges.spawn(n, n_2x1, n_1x1); } @@ -106,7 +90,7 @@ void BasicRanges::build_async(Executor &&executor, Notifier &&callback) { for (uint32_t i = 0; i < TYPE_ID_LIMIT; ++i) { (*cache)[i].reserve(BASIC_RANGES_NUM[i]); worker.post([cache, i] { - auto [n, n_2x1, n_1x1] = range_types()[i]; + auto [n, n_2x1, n_1x1] = BLOCK_NUM[i]; (*cache)[i].spawn(n, n_2x1, n_1x1); }); } @@ -146,6 +130,6 @@ void BasicRanges::build_async(Executor &&executor, Notifier &&callback) { self(self); // next sort round }); }; - inner_sort(inner_sort); // TODO: using `this auto &&self` in new version + inner_sort(inner_sort); // TODO: using `this auto &&self` in new compiler }); }