Browse Source

update: Core namespace klotski

master
Dnomd343 1 year 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_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) {

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
/// 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 <utility>
#include <functional>
class Core {
public:
/// 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
};
namespace klotski {
class Core {
public:
/// Release with code and mask
typedef std::function<void(uint64_t, uint64_t)> 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);
};
}

8
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<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);
});
@ -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);

Loading…
Cancel
Save