From 61aa8b5ce7af47e0b33bdecfc5c3e6546dae76c9 Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Sat, 25 Feb 2023 19:47:24 +0800 Subject: [PATCH] update: Core namespace klotski --- src/klotski_core/core/core.cc | 10 +++--- src/klotski_core/core/core.h | 68 ++++++++++++++++++++++------------- src/klotski_core/ffi/tmain.cc | 8 ++--- 3 files changed, 52 insertions(+), 34 deletions(-) diff --git a/src/klotski_core/core/core.cc b/src/klotski_core/core/core.cc index c10afcd..079cfc8 100644 --- a/src/klotski_core/core/core.cc +++ b/src/klotski_core/core/core.cc @@ -46,7 +46,7 @@ #define NEXT_CODE_2x1 ((code & ~(F_2x1 << addr)) | (C_2x1 << next_addr)) #define NEXT_CODE_2x2 ((code & ~(F_2x2 << addr)) | (C_2x2 << next_addr)) -//////////////////////////////////////// +/////////////////////////////////////////////// #define RELEASE(NEXT_CODE, FILTER) \ cache_insert(cache_t { \ @@ -56,7 +56,7 @@ cache_insert(cache_t { \ .addr = next_addr \ }); -//////////////////////////////////////// +/////////////////////////////////////////////// #define BFS_INIT \ int next_addr; \ @@ -70,9 +70,11 @@ int filter = cache[current++].filter; #define BFS_STOP (current == cache_size) -//////////////////////////////////////// +/////////////////////////////////////////////// -inline void Core::cache_insert(Core::cache_t next_case) { // try to insert into cache +using klotski::Core; + +inline void Core::cache_insert(cache_t next_case) { // try to insert into cache auto *cache_ptr = cache; for (; cache_ptr < cache + cache_size; ++cache_ptr) { if (cache_ptr->code == next_case.code) { diff --git a/src/klotski_core/core/core.h b/src/klotski_core/core/core.h index e9529d0..4ebab3a 100644 --- a/src/klotski_core/core/core.h +++ b/src/klotski_core/core/core.h @@ -26,34 +26,52 @@ /// 16. By performing such a search on each block in the layout, we can get all the next-step /// layouts, which have a minimum of 0 and a maximum of 68. +/// For a single block, search for the situation after it has moved one grid, `addr` is its current +/// position information, which is (0 ~ 19) * 3. When moving up and down, judge the value of `addr` +/// to confirm whether it is out of bounds; when moving left and right, get its remainder to `4` +/// to judge whether it will be out of bounds. After confirming that it will not cross the boundary, +/// it is necessary to judge whether it will collide with other blocks after moving, that is, the +/// target position needs to be empty, which is represented as `000` in the RawCode, and the template +/// will be used to perform bit operations here to confirm whether it is feasible. + +/// Finally, in order to improve efficiency, the `filter` option is added. For the direction of the +/// last movement, it will be ignored in the next search, so as to optimize BFS. After confirming +/// that it can be moved, the moved layout can be directly obtained by means of bit operations, and +/// a mask will be obtained at the same time, which marks the moved block as `111`, which will speed +/// up subsequent calculations. The generated layout will be inserted into the cache, and after the +/// BFS search for each block is completed, the core will use the callback function to output these +/// results. + #include #include #include -class Core { -public: - /// Release with code and mask - typedef std::function release_t; - - /// Core interface - void next_cases(uint64_t code, uint64_t mask); - explicit Core(release_t release_func) : release(std::move(release_func)) {} - -private: - struct cache_t { - uint64_t code; - uint64_t mask; /// 000 or 111 - int filter; /// UP | DOWN | LEFT | RIGHT - int addr; /// (0 ~ 19) * 3 - }; +namespace klotski { + class Core { + public: + /// Release with code and mask + typedef std::function release_t; - int cache_size = 1; - cache_t cache[16]{}; - release_t release; // release function + /// Core interface + void next_cases(uint64_t code, uint64_t mask); + explicit Core(release_t release_func) : release(std::move(release_func)) {} - void move_1x1(uint64_t code, int addr); - void move_1x2(uint64_t code, int addr); - void move_2x1(uint64_t code, int addr); - void move_2x2(uint64_t code, int addr); - inline void cache_insert(Core::cache_t next_case); -}; + private: + struct cache_t { + uint64_t code; + uint64_t mask; /// (000) or (111) + int filter; /// UP | DOWN | LEFT | RIGHT + int addr; /// (0 ~ 19) * 3 + }; + + int cache_size = 1; + cache_t cache[16]{}; + release_t release; // release function + + void move_1x1(uint64_t code, int addr); + void move_1x2(uint64_t code, int addr); + void move_2x1(uint64_t code, int addr); + void move_2x2(uint64_t code, int addr); + inline void cache_insert(cache_t next_case); + }; +} diff --git a/src/klotski_core/ffi/tmain.cc b/src/klotski_core/ffi/tmain.cc index 34e1b6d..31b1538 100644 --- a/src/klotski_core/ffi/tmain.cc +++ b/src/klotski_core/ffi/tmain.cc @@ -11,8 +11,6 @@ #include "all_cases.h" #include "common_code.h" -using namespace klotski; - void tmain() { printf("tmain start\n"); @@ -30,7 +28,7 @@ void tmain() { std::vector next; - auto core = Core([&next](uint64_t code, uint64_t) { + auto core = klotski::Core([&next](uint64_t code, uint64_t) { next.emplace_back(code); }); @@ -44,9 +42,9 @@ void tmain() { for (uint64_t head = 0; head < 16; ++head) { - for (const auto &range : AllCases::fetch()[head]) { + for (const auto &range : klotski::AllCases::fetch()[head]) { - uint64_t raw_code = RawCode::from_common_code(head << 32 | range).unwrap(); + uint64_t raw_code = klotski::RawCode::from_common_code(head << 32 | range).unwrap(); all_cases.emplace_back(raw_code);