Browse Source

update: Core namespace klotski

legacy
Dnomd343 2 years ago
parent
commit
61aa8b5ce7
  1. 10
      src/klotski_core/core/core.cc
  2. 68
      src/klotski_core/core/core.h
  3. 8
      src/klotski_core/ffi/tmain.cc

10
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_2x1 ((code & ~(F_2x1 << addr)) | (C_2x1 << next_addr))
#define NEXT_CODE_2x2 ((code & ~(F_2x2 << addr)) | (C_2x2 << next_addr)) #define NEXT_CODE_2x2 ((code & ~(F_2x2 << addr)) | (C_2x2 << next_addr))
//////////////////////////////////////// ///////////////////////////////////////////////
#define RELEASE(NEXT_CODE, FILTER) \ #define RELEASE(NEXT_CODE, FILTER) \
cache_insert(cache_t { \ cache_insert(cache_t { \
@ -56,7 +56,7 @@ cache_insert(cache_t { \
.addr = next_addr \ .addr = next_addr \
}); });
//////////////////////////////////////// ///////////////////////////////////////////////
#define BFS_INIT \ #define BFS_INIT \
int next_addr; \ int next_addr; \
@ -70,9 +70,11 @@ int filter = cache[current++].filter;
#define BFS_STOP (current == cache_size) #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; auto *cache_ptr = cache;
for (; cache_ptr < cache + cache_size; ++cache_ptr) { for (; cache_ptr < cache + cache_size; ++cache_ptr) {
if (cache_ptr->code == next_case.code) { if (cache_ptr->code == next_case.code) {

68
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 /// 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. /// 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 <cstdint> #include <cstdint>
#include <utility> #include <utility>
#include <functional> #include <functional>
class Core { namespace klotski {
public: class Core {
/// Release with code and mask public:
typedef std::function<void(uint64_t, uint64_t)> release_t; /// Release with code and mask
typedef std::function<void(uint64_t, uint64_t)> 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
};
int cache_size = 1; /// Core interface
cache_t cache[16]{}; void next_cases(uint64_t code, uint64_t mask);
release_t release; // release function explicit Core(release_t release_func) : release(std::move(release_func)) {}
void move_1x1(uint64_t code, int addr); private:
void move_1x2(uint64_t code, int addr); struct cache_t {
void move_2x1(uint64_t code, int addr); uint64_t code;
void move_2x2(uint64_t code, int addr); uint64_t mask; /// (000) or (111)
inline void cache_insert(Core::cache_t next_case); 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);
};
}

8
src/klotski_core/ffi/tmain.cc

@ -11,8 +11,6 @@
#include "all_cases.h" #include "all_cases.h"
#include "common_code.h" #include "common_code.h"
using namespace klotski;
void tmain() { void tmain() {
printf("tmain start\n"); printf("tmain start\n");
@ -30,7 +28,7 @@ void tmain() {
std::vector<uint64_t> next; std::vector<uint64_t> next;
auto core = Core([&next](uint64_t code, uint64_t) { auto core = klotski::Core([&next](uint64_t code, uint64_t) {
next.emplace_back(code); next.emplace_back(code);
}); });
@ -44,9 +42,9 @@ void tmain() {
for (uint64_t head = 0; head < 16; ++head) { 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); all_cases.emplace_back(raw_code);

Loading…
Cancel
Save