Browse Source

update: Core module

legacy
Dnomd343 2 years ago
parent
commit
7e4f50105e
  1. 84
      src/klotski_core/core/core.cc
  2. 14
      src/klotski_core/core/core.h

84
src/klotski_core/core/core.cc

@ -2,16 +2,16 @@
#include "common.h" #include "common.h"
/// block move direction /// block move direction
#define UP (-4 * 3) #define DIR_UP (-4 * 3)
#define LEFT (-1 * 3) #define DIR_LEFT (-1 * 3)
#define DOWN (+4 * 3) #define DIR_DOWN (+4 * 3)
#define RIGHT (+1 * 3) #define DIR_RIGHT (+1 * 3)
/// block direction limit /// block direction limit
#define ALLOW_UP (filter != -UP) #define ALLOW_UP (filter != -DIR_UP)
#define ALLOW_DOWN (filter != -DOWN) #define ALLOW_DOWN (filter != -DIR_DOWN)
#define ALLOW_LEFT (filter != -LEFT) #define ALLOW_LEFT (filter != -DIR_LEFT)
#define ALLOW_RIGHT (filter != -RIGHT) #define ALLOW_RIGHT (filter != -DIR_RIGHT)
/// horizontal restraints /// horizontal restraints
#define NOT_COLUMN_0 ((addr & 3) != 0b00) #define NOT_COLUMN_0 ((addr & 3) != 0b00)
@ -19,10 +19,10 @@
#define NOT_COLUMN_3 ((addr & 3) != 0b01) #define NOT_COLUMN_3 ((addr & 3) != 0b01)
/// try to move block /// try to move block
#define MOVE_UP (next_addr = addr + UP) #define MOVE_UP (next_addr = addr + DIR_UP)
#define MOVE_DOWN (next_addr = addr + DOWN) #define MOVE_DOWN (next_addr = addr + DIR_DOWN)
#define MOVE_LEFT (next_addr = addr + LEFT) #define MOVE_LEFT (next_addr = addr + DIR_LEFT)
#define MOVE_RIGHT (next_addr = addr + RIGHT) #define MOVE_RIGHT (next_addr = addr + DIR_RIGHT)
/// vertical restraints /// vertical restraints
#define TOP_LIMIT(ADDR) (addr >= ADDR * 3) #define TOP_LIMIT(ADDR) (addr >= ADDR * 3)
@ -61,28 +61,28 @@ cache_insert(cache_t { \
#define BFS_INIT \ #define BFS_INIT \
int next_addr; \ int next_addr; \
int current = 0; \ int current = 0; \
cache[0].addr = addr; cache_[0].addr = addr;
#define BFS_LOAD \ #define BFS_LOAD \
code = cache[current].code; \ code = cache_[current].code; \
addr = cache[current].addr; \ addr = cache_[current].addr; \
int filter = cache[current++].filter; int filter = cache_[current++].filter;
#define BFS_STOP (current == cache_size) #define BFS_STOP (current == cache_size_)
/////////////////////////////////////////////// ///////////////////////////////////////////////
using klotski::Core; using klotski::Core;
inline void Core::cache_insert(cache_t next_case) { // try to insert into cache 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) {
return; // already exist -> insert failed return; // already exist -> insert failed
} }
} }
*cache_ptr = next_case; // cache push back *cache_ptr = next_case; // cache push back
++cache_size; ++cache_size_;
} }
void Core::move_1x1(uint64_t code, int addr) { // try to move target 1x1 block void Core::move_1x1(uint64_t code, int addr) { // try to move target 1x1 block
@ -90,16 +90,16 @@ void Core::move_1x1(uint64_t code, int addr) { // try to move target 1x1 block
while (!BFS_STOP) { // bfs search process while (!BFS_STOP) { // bfs search process
BFS_LOAD BFS_LOAD
if (ALLOW_UP && TOP_LIMIT(4) && CHECK_UP(F_1x1)) { if (ALLOW_UP && TOP_LIMIT(4) && CHECK_UP(F_1x1)) {
RELEASE_1x1(UP) // 1x1 block move up RELEASE_1x1(DIR_UP) // 1x1 block move up
} }
if (ALLOW_DOWN && BOTTOM_LIMIT(15) && CHECK_DOWN(F_1x1)) { if (ALLOW_DOWN && BOTTOM_LIMIT(15) && CHECK_DOWN(F_1x1)) {
RELEASE_1x1(DOWN) // 1x1 block move down RELEASE_1x1(DIR_DOWN) // 1x1 block move down
} }
if (ALLOW_LEFT && NOT_COLUMN_0 && CHECK_LEFT(F_1x1)) { if (ALLOW_LEFT && NOT_COLUMN_0 && CHECK_LEFT(F_1x1)) {
RELEASE_1x1(LEFT) // 1x1 block move left RELEASE_1x1(DIR_LEFT) // 1x1 block move left
} }
if (ALLOW_RIGHT && NOT_COLUMN_3 && CHECK_RIGHT(F_1x1)) { if (ALLOW_RIGHT && NOT_COLUMN_3 && CHECK_RIGHT(F_1x1)) {
RELEASE_1x1(RIGHT) // 1x1 block move right RELEASE_1x1(DIR_RIGHT) // 1x1 block move right
} }
} }
} }
@ -109,16 +109,16 @@ void Core::move_1x2(uint64_t code, int addr) { // try to move target 1x2 block
while (!BFS_STOP) { // bfs search process while (!BFS_STOP) { // bfs search process
BFS_LOAD BFS_LOAD
if (ALLOW_UP && TOP_LIMIT(4) && CHECK_UP(F_1x2)) { if (ALLOW_UP && TOP_LIMIT(4) && CHECK_UP(F_1x2)) {
RELEASE_1x2(UP) // 1x2 block move up RELEASE_1x2(DIR_UP) // 1x2 block move up
} }
if (ALLOW_DOWN && BOTTOM_LIMIT(14) && CHECK_DOWN(F_1x2)) { if (ALLOW_DOWN && BOTTOM_LIMIT(14) && CHECK_DOWN(F_1x2)) {
RELEASE_1x2(DOWN) // 1x2 block move down RELEASE_1x2(DIR_DOWN) // 1x2 block move down
} }
if (ALLOW_LEFT && NOT_COLUMN_0 && CHECK_LEFT(F_1x1)) { if (ALLOW_LEFT && NOT_COLUMN_0 && CHECK_LEFT(F_1x1)) {
RELEASE_1x2(LEFT) // 1x2 block move left RELEASE_1x2(DIR_LEFT) // 1x2 block move left
} }
if (ALLOW_RIGHT && NOT_COLUMN_2 && CHECK_RIGHT(F_1x1_R)) { if (ALLOW_RIGHT && NOT_COLUMN_2 && CHECK_RIGHT(F_1x1_R)) {
RELEASE_1x2(RIGHT) // 1x2 block move right RELEASE_1x2(DIR_RIGHT) // 1x2 block move right
} }
} }
} }
@ -128,16 +128,16 @@ void Core::move_2x1(uint64_t code, int addr) { // try to move target 2x1 block
while (!BFS_STOP) { // bfs search process while (!BFS_STOP) { // bfs search process
BFS_LOAD BFS_LOAD
if (ALLOW_UP && TOP_LIMIT(4) && CHECK_UP(F_1x1)) { if (ALLOW_UP && TOP_LIMIT(4) && CHECK_UP(F_1x1)) {
RELEASE_2x1(UP) // 2x1 block move up RELEASE_2x1(DIR_UP) // 2x1 block move up
} }
if (ALLOW_DOWN && BOTTOM_LIMIT(11) && CHECK_DOWN(F_1x1_D)) { if (ALLOW_DOWN && BOTTOM_LIMIT(11) && CHECK_DOWN(F_1x1_D)) {
RELEASE_2x1(DOWN) // 2x1 block move down RELEASE_2x1(DIR_DOWN) // 2x1 block move down
} }
if (ALLOW_LEFT && NOT_COLUMN_0 && CHECK_LEFT(F_2x1)) { if (ALLOW_LEFT && NOT_COLUMN_0 && CHECK_LEFT(F_2x1)) {
RELEASE_2x1(LEFT) // 2x1 block move left RELEASE_2x1(DIR_LEFT) // 2x1 block move left
} }
if (ALLOW_RIGHT && NOT_COLUMN_3 && CHECK_RIGHT(F_2x1)) { if (ALLOW_RIGHT && NOT_COLUMN_3 && CHECK_RIGHT(F_2x1)) {
RELEASE_2x1(RIGHT) // 2x1 block move right RELEASE_2x1(DIR_RIGHT) // 2x1 block move right
} }
} }
} }
@ -147,23 +147,23 @@ void Core::move_2x2(uint64_t code, int addr) { // try to move target 2x2 block
while (!BFS_STOP) { // bfs search process while (!BFS_STOP) { // bfs search process
BFS_LOAD BFS_LOAD
if (ALLOW_UP && TOP_LIMIT(4) && CHECK_UP(F_1x2)) { if (ALLOW_UP && TOP_LIMIT(4) && CHECK_UP(F_1x2)) {
RELEASE_2x2(UP) // 2x2 block move up RELEASE_2x2(DIR_UP) // 2x2 block move up
} }
if (ALLOW_DOWN && BOTTOM_LIMIT(10) && CHECK_DOWN(F_1x2_D)) { if (ALLOW_DOWN && BOTTOM_LIMIT(10) && CHECK_DOWN(F_1x2_D)) {
RELEASE_2x2(DOWN) // 2x2 block move down RELEASE_2x2(DIR_DOWN) // 2x2 block move down
} }
if (ALLOW_LEFT && NOT_COLUMN_0 && CHECK_LEFT(F_2x1)) { if (ALLOW_LEFT && NOT_COLUMN_0 && CHECK_LEFT(F_2x1)) {
RELEASE_2x2(LEFT) // 2x2 block move left RELEASE_2x2(DIR_LEFT) // 2x2 block move left
} }
if (ALLOW_RIGHT && NOT_COLUMN_2 && CHECK_RIGHT(F_2x1_R)) { if (ALLOW_RIGHT && NOT_COLUMN_2 && CHECK_RIGHT(F_2x1_R)) {
RELEASE_2x2(RIGHT) // 2x2 block move right RELEASE_2x2(DIR_RIGHT) // 2x2 block move right
} }
} }
} }
void Core::next_cases(uint64_t code, uint64_t mask) { // search next step cases void Core::next_cases(uint64_t code, uint64_t mask) { // search next step cases
cache[0].filter = 0; // without filter cache_[0].filter = 0; // without filter
cache[0].code = code; // bfs root code cache_[0].code = code; // bfs root code
auto range = code | mask; auto range = code | mask;
for (int addr = 0; range; addr += 3, range >>= 3) { // traverse every 3-bits for (int addr = 0; range; addr += 3, range >>= 3) { // traverse every 3-bits
@ -183,11 +183,11 @@ void Core::next_cases(uint64_t code, uint64_t mask) { // search next step cases
default: default:
continue; // B_space or B_fill continue; // B_space or B_fill
} }
if (cache_size != 1) { // found one or more next cases if (cache_size_ != 1) { // found one or more next cases
for (int i = 1; i < cache_size; ++i) { for (int i = 1; i < cache_size_; ++i) {
Core::release(cache[i].code, cache[i].mask); // release next cases Core::release_(cache_[i].code, cache_[i].mask); // release next cases
} }
cache_size = 1; // reset cache size cache_size_ = 1; // reset cache size
} }
} }
} }

14
src/klotski_core/core/core.h

@ -47,6 +47,7 @@
#include <functional> #include <functional>
namespace klotski { namespace klotski {
class Core { class Core {
public: public:
/// Release with code and mask /// Release with code and mask
@ -54,19 +55,19 @@ namespace klotski {
/// Core interface /// Core interface
void next_cases(uint64_t code, uint64_t mask); void next_cases(uint64_t code, uint64_t mask);
explicit Core(release_t release_func) : release(std::move(release_func)) {} explicit Core(release_t release_func) : release_(std::move(release_func)) {}
private: private:
struct cache_t { struct cache_t {
uint64_t code; uint64_t code;
uint64_t mask; /// (000) or (111) uint64_t mask; /// (000) or (111)
int filter; /// UP | DOWN | LEFT | RIGHT int filter; /// DIR_UP | DIR_DOWN | DIR_LEFT | DIR_RIGHT
int addr; /// (0 ~ 19) * 3 int addr; /// (0 ~ 19) * 3
}; };
int cache_size = 1; int cache_size_ = 1;
cache_t cache[16]{}; cache_t cache_[16]{};
release_t release; // release function release_t release_; // release function
void move_1x1(uint64_t code, int addr); void move_1x1(uint64_t code, int addr);
void move_1x2(uint64_t code, int addr); void move_1x2(uint64_t code, int addr);
@ -74,4 +75,5 @@ namespace klotski {
void move_2x2(uint64_t code, int addr); void move_2x2(uint64_t code, int addr);
inline void cache_insert(cache_t next_case); inline void cache_insert(cache_t next_case);
}; };
}
} // namespace klotski

Loading…
Cancel
Save