Browse Source

feat: core module

master
Dnomd343 2 years ago
parent
commit
3db74fbe6f
  1. 9
      src/CMakeLists.txt
  2. 3
      src/core/CMakeLists.txt
  3. 16
      src/core/bfs.h
  4. 162
      src/core/core.cc
  5. 43
      src/core/core.h
  6. 4
      src/core_demo.cc
  7. 8
      src/main.cc
  8. 10
      src/raw_code/raw_code.h

9
src/CMakeLists.txt

@ -1,5 +1,6 @@
cmake_minimum_required(VERSION 3.0)
include_directories(core)
include_directories(common)
include_directories(all_cases)
@ -7,6 +8,7 @@ include_directories(raw_code)
include_directories(short_code)
include_directories(common_code)
add_subdirectory(core)
add_subdirectory(common)
add_subdirectory(all_cases)
@ -14,8 +16,11 @@ add_subdirectory(raw_code)
add_subdirectory(short_code)
add_subdirectory(common_code)
#add_executable(klotski main.cc)
add_executable(klotski main.cc core_demo.cc)
add_executable(klotski main.cc)
#add_executable(klotski main.cc core_demo.cc)
target_link_libraries(klotski core)
target_link_libraries(klotski common)
target_link_libraries(klotski all_cases)
target_link_libraries(klotski raw_code)

3
src/core/CMakeLists.txt

@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 3.0)
add_library(core core.cc)

16
src/core/bfs.h

@ -0,0 +1,16 @@
#pragma once
#define BFS_INIT \
int next_addr; \
cache_size = 1; \
int current = 0; \
cache[0].code = code; \
cache[0].addr = addr; \
cache[0].filter = 0;
#define BFS_LOAD \
code = cache[current].code; \
addr = cache[current].addr; \
int filter = cache[current++].filter;
#define BFS_STOP (current == cache_size)

162
src/core/core.cc

@ -0,0 +1,162 @@
#include "bfs.h"
#include "core.h"
#include "raw_code.h"
#define ALLOW_UP (filter != -UP)
#define ALLOW_DOWN (filter != -DOWN)
#define ALLOW_LEFT (filter != -LEFT)
#define ALLOW_RIGHT (filter != -RIGHT)
#define NOT_COLUMN_0 ((addr & 3) != 0)
#define NOT_COLUMN_2 ((addr & 3) != 2)
#define NOT_COLUMN_3 ((addr & 3) != 1)
#define MOVE_UP (next_addr = addr + UP)
#define MOVE_DOWN (next_addr = addr + DOWN)
#define MOVE_LEFT (next_addr = addr + LEFT)
#define MOVE_RIGHT (next_addr = addr + RIGHT)
#define TOP_LIMIT(ADDR) (addr >= ADDR * 3)
#define BOTTOM_LIMIT(ADDR) (addr <= ADDR * 3)
#define RELEASE(NEXT_CODE, FILTER) { \
cache_t next_case = { \
.code = NEXT_CODE, \
.mask = F_1x1 << next_addr, \
.filter = FILTER, \
.addr = next_addr \
}; \
cache_insert(next_case); \
}
#define release_1x1(FILTER) RELEASE(NEXT_CODE_1x1, FILTER)
#define release_1x2(FILTER) RELEASE(NEXT_CODE_1x2, FILTER)
#define release_2x1(FILTER) RELEASE(NEXT_CODE_2x1, FILTER)
#define release_2x2(FILTER) RELEASE(NEXT_CODE_2x2, FILTER)
#define NEXT_CODE_1x1 (code & ~(F_1x1 << addr) | (C_1x1 << next_addr))
#define NEXT_CODE_1x2 (code & ~(F_1x2 << addr) | (C_1x2 << 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))
inline void Core::cache_insert(Core::cache_t &next_case) { // try to insert into cache
auto *p = cache;
for (; p < cache + cache_size; ++p) {
if (p->code == next_case.code) {
return; // already exist -> insert failed
}
}
*p = next_case;
++cache_size;
}
void Core::move_1x1(uint64_t code, int addr) { // try to move target 1x1 block
BFS_INIT
while (!BFS_STOP) { // bfs search process
BFS_LOAD
if (ALLOW_UP && TOP_LIMIT(4) && !(code >> MOVE_UP & F_1x1)) {
release_1x1(UP) // 1x1 block move up
}
if (ALLOW_DOWN && BOTTOM_LIMIT(15) && !(code >> MOVE_DOWN & F_1x1)) {
release_1x1(DOWN) // 1x1 block move down
}
if (ALLOW_LEFT && NOT_COLUMN_0 && !(code >> MOVE_LEFT & F_1x1)) {
release_1x1(LEFT) // 1x1 block move left
}
if (ALLOW_RIGHT && NOT_COLUMN_3 && !(code >> MOVE_RIGHT & F_1x1)) {
release_1x1(RIGHT) // 1x1 block move right
}
}
}
void Core::move_1x2(uint64_t code, int addr) { // try to move target 1x2 block
BFS_INIT
while (!BFS_STOP) { // bfs search process
BFS_LOAD
if (ALLOW_UP && TOP_LIMIT(4) && !(code >> MOVE_UP & F_1x2)) {
release_1x2(UP) // 1x2 block move up
}
if (ALLOW_DOWN && BOTTOM_LIMIT(14) && !(code >> MOVE_DOWN & F_1x2)) {
release_1x2(DOWN) // 1x2 block move down
}
if (ALLOW_LEFT && NOT_COLUMN_0 && !(code >> MOVE_LEFT & F_1x1)) {
release_1x2(LEFT) // 1x2 block move left
}
if (ALLOW_RIGHT && NOT_COLUMN_2 && !(code >> MOVE_RIGHT & F_1x1_R)) {
release_1x2(RIGHT) // 1x2 block move right
}
}
}
void Core::move_2x1(uint64_t code, int addr) { // try to move target 2x1 block
BFS_INIT
while (!BFS_STOP) { // bfs search process
BFS_LOAD
if (ALLOW_UP && TOP_LIMIT(4) && !(code >> MOVE_UP & F_1x1)) {
release_2x1(UP) // 2x1 block move up
}
if (ALLOW_DOWN && BOTTOM_LIMIT(11) && !(code >> MOVE_DOWN & F_1x1_D)) {
release_2x1(DOWN) // 2x1 block move down
}
if (ALLOW_LEFT && NOT_COLUMN_0 && !(code >> MOVE_LEFT & F_2x1)) {
release_2x1(LEFT) // 2x1 block move left
}
if (ALLOW_RIGHT && NOT_COLUMN_3 && !(code >> MOVE_RIGHT & F_2x1)) {
release_2x1(RIGHT) // 2x1 block move right
}
}
}
void Core::move_2x2(uint64_t code, int addr) { // try to move target 2x2 block
BFS_INIT
while (!BFS_STOP) { // bfs search process
BFS_LOAD
if (ALLOW_UP && TOP_LIMIT(4) && !(code >> MOVE_UP & F_1x2)) {
release_2x2(UP) // 2x2 block move up
}
if (ALLOW_DOWN && BOTTOM_LIMIT(10) && !(code >> MOVE_DOWN & F_1x2_D)) {
release_2x2(DOWN) // 2x2 block move down
}
if (ALLOW_LEFT && NOT_COLUMN_0 && !(code >> MOVE_LEFT & F_2x1)) {
release_2x2(LEFT) // 2x2 block move left
}
if (ALLOW_RIGHT && NOT_COLUMN_2 && !(code >> MOVE_RIGHT & F_2x1_R)) {
release_2x2(RIGHT) // 2x2 block move right
}
}
}
#include <iostream>
void Core::next_step(uint64_t raw_code) {
auto temp_code = raw_code;
for (int addr = 0; temp_code; addr += 3, temp_code >>= 3) {
switch (temp_code & 0b111) {
case B_1x1:
move_1x1(raw_code, addr);
break;
case B_1x2:
move_1x2(raw_code, addr);
break;
case B_2x1:
move_2x1(raw_code, addr);
break;
case B_2x2:
move_2x2(raw_code, addr);
break;
default:
continue; // B_space or B_fill
}
if (cache_size != 1) {
for (int i = 1; i < cache_size; ++i) {
std::cout << RawCode(cache[i].code).dump_case();
printf("MASK -> %016lX\n", cache[i].mask);
}
// std::cout << "found: " << cache_size - 1 << std::endl;
}
}
}

43
src/core/core.h

@ -0,0 +1,43 @@
#pragma once
#include <cstdint>
#define UP (-12) // -4 * 3-bits
#define LEFT (-3) // +1 * 3-bits
#define DOWN (+12) // +4 * 3-bits
#define RIGHT (+3) // +1 * 3-bits
#define F_1x1 (uint64_t)0x7 // 111
#define F_1x2 (uint64_t)0x3F // 111 111
#define F_2x1 (uint64_t)0x7007 // 111 000 000 000 111
#define F_2x2 (uint64_t)0x3F03F // 111 111 000 000 111 111
#define F_1x1_R (uint64_t)0x38 // 111 000
#define F_1x1_D (uint64_t)0x7000 // 111 000 000 000 000
#define F_2x1_R (uint64_t)0x38038 // 111 000 000 000 111 000
#define F_1x2_D (uint64_t)0x3F000 // 111 111 000 000 000 000
class Core {
public:
struct cache_t {
uint64_t code; // raw code
uint64_t mask; // only 000 or 111
int filter;
int addr;
};
int cache_size;
cache_t cache[16];
inline void cache_insert(Core::cache_t &next_case);
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);
void next_step(uint64_t raw_code);
};

4
src/core_demo.cc

@ -191,8 +191,8 @@ void next_step(uint64_t raw_code) {
}
if (cache_size != 1) {
for (int i = 1; i < cache_size; ++i) {
std::cout << RawCode(cache[i].code).dump_case();
printf("MASK -> %016lX\n", cache[i].mask);
// std::cout << RawCode(cache[i].code).dump_case();
// printf("MASK -> %016lX\n", cache[i].mask);
}
// std::cout << "found: " << cache_size - 1 << std::endl;
}

8
src/main.cc

@ -1,11 +1,12 @@
#include <iostream>
#include "core.h"
#include "all_cases.h"
#include "basic_ranges.h"
#include "common_code.h"
#include "short_code.h"
#include "raw_code.h"
#include "core_demo.h"
//#include "core_demo.h"
#include <thread>
@ -145,8 +146,9 @@ int main() {
// next_step(CommonCode("4FEA134").to_raw_code().unwrap(), 0); // mask unset
auto raw_code = RawCode(CommonCode("4fea134")).unwrap();
// for (int i = 0; i < 1000000000; ++i) {
next_step(raw_code);
auto c = Core();
// for (int i = 0; i < 100000000; ++i) {
c.next_step(raw_code);
// }
return 0;

10
src/raw_code/raw_code.h

@ -15,16 +15,6 @@
#define C_2x1 (uint64_t)0x7002 // 111 000 000 000 010
#define C_2x2 (uint64_t)0x3F03C // 111 111 000 000 111 100
#define F_1x1 (uint64_t)0x7 // 111
#define F_1x2 (uint64_t)0x3F // 111 111
#define F_2x1 (uint64_t)0x7007 // 111 000 000 000 111
#define F_2x2 (uint64_t)0x3F03F // 111 111 000 000 111 111
#define F_1x1_R (uint64_t)0x38 // 111 000
#define F_1x1_D (uint64_t)0x7000 // 111 000 000 000 000
#define F_2x1_R (uint64_t)0x38038 // 111 000 000 000 111 000
#define F_1x2_D (uint64_t)0x3F000 // 111 111 000 000 000 000
class CommonCode;
class RawCode {

Loading…
Cancel
Save