From ffee5075773311ee41d24ff063bd87d5046c3df4 Mon Sep 17 00:00:00 2001 From: dnomd343 Date: Tue, 30 Aug 2022 22:40:30 +0800 Subject: [PATCH] feat: klotski basic move --- include/klotski.h | 18 ++-- src/main.cc | 237 +++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 231 insertions(+), 24 deletions(-) diff --git a/include/klotski.h b/include/klotski.h index 19c1230..21ea03b 100644 --- a/include/klotski.h +++ b/include/klotski.h @@ -10,15 +10,15 @@ #define B_1x1 0x3 #define B_2x2 0x4 -#define C_1x1 int64_t(0x3) -#define C_1x2 int64_t(0x39) -#define C_2x1 int64_t(0x7002) -#define C_2x2 int64_t(0x3F03C) - -#define F_1x1 int64_t(0x7) -#define F_1x2 int64_t(0x3F) -#define F_2x1 int64_t(0x7007) -#define F_2x2 int64_t(0x3F03F) +#define C_1x1 uint64_t(0x3) +#define C_1x2 uint64_t(0x39) +#define C_2x1 uint64_t(0x7002) +#define C_2x2 uint64_t(0x3F03C) + +#define F_1x1 uint64_t(0x7) +#define F_1x2 uint64_t(0x3F) +#define F_2x1 uint64_t(0x7007) +#define F_2x2 uint64_t(0x3F03F) uint64_t compact_code(uint64_t code); uint64_t extract_code(uint64_t code); diff --git a/src/main.cc b/src/main.cc index 93eaa20..51e321b 100644 --- a/src/main.cc +++ b/src/main.cc @@ -4,6 +4,20 @@ #include #include +#define UP (-12) +#define LEFT (-3) +#define DOWN 12 +#define DOWN_2 24 +#define RIGHT 3 +#define RIGHT_2 6 + +struct cache { + uint64_t code; + uint64_t filter; +}; +struct cache move_cache[16]; +int move_cache_num; + void graph_output(uint64_t code) { for (int i = 0; i < 20; ++i) { switch (code & 0x7) { @@ -35,6 +49,139 @@ void graph_output(uint64_t code) { } } + +inline bool move_block_release(uint64_t code, uint64_t filter) { + struct cache *p = move_cache; + for (; p < move_cache + move_cache_num; ++p) { + if (p->code == code) { + return false; + } + } + p->code = code; + p->filter = filter; + ++move_cache_num; + return true; +} + +void move_block_1x1(uint64_t code, int addr, int filter) { + int target_addr; + uint64_t ret_code; + if (filter != UP && addr >= 4 * 3 && !(code >> (target_addr = addr + UP) & F_1x1)) { + ret_code = code & ~(F_1x1 << addr) | C_1x1 << target_addr; + if (move_block_release(ret_code, uint64_t(0x7) << target_addr)) { + move_block_1x1(ret_code, target_addr, DOWN); + } + } + if (filter != DOWN && addr <= 15 * 3 && !(code >> (target_addr = addr + DOWN) & F_1x1)) { + ret_code = code & ~(F_1x1 << addr) | C_1x1 << target_addr; + if (move_block_release(ret_code, uint64_t(0x7) << target_addr)) { + move_block_1x1(ret_code, target_addr, UP); + } + } + if (filter != LEFT && (addr & 0x3) != 0 && !(code >> (target_addr = addr + LEFT) & F_1x1)) { + ret_code = code & ~(F_1x1 << addr) | C_1x1 << target_addr; + if (move_block_release(ret_code, uint64_t(0x7) << target_addr)) { + move_block_1x1(ret_code, target_addr, RIGHT); + } + } + if (filter != RIGHT && (addr & 0x3) != 1 && !(code >> (target_addr = addr + RIGHT) & F_1x1)) { + ret_code = code & ~(F_1x1 << addr) | C_1x1 << target_addr; + if (move_block_release(ret_code, uint64_t(0x7) << target_addr)) { + move_block_1x1(ret_code, target_addr, LEFT); + } + } +} + +void move_block_1x2(uint64_t code, int addr, int filter) { + int target_addr; + uint64_t ret_code; + if (filter != UP && addr >= 4 * 3 && !(code >> (target_addr = addr + UP) & F_1x2)) { + ret_code = code & ~(F_1x2 << addr) | C_1x2 << target_addr; + if (move_block_release(ret_code, uint64_t(0x7) << target_addr)) { + move_block_1x2(ret_code, target_addr, DOWN); + } + } + if (filter != DOWN && addr <= 14 * 3 && !(code >> (target_addr = addr + DOWN) & F_1x2)) { + ret_code = code & ~(F_1x2 << addr) | C_1x2 << target_addr; + if (move_block_release(ret_code, uint64_t(0x7) << target_addr)) { + move_block_1x2(ret_code, target_addr, UP); + } + } + if (filter != LEFT && (addr & 0x3) != 0 && !(code >> (target_addr = addr + LEFT) & F_1x1)) { + ret_code = code & ~(F_1x2 << addr) | C_1x2 << target_addr; + if (move_block_release(ret_code, uint64_t(0x7) << target_addr)) { + move_block_1x2(ret_code, target_addr, RIGHT); + } + } + if (filter != RIGHT && (addr & 0x3) != 2 && !(code >> (addr + RIGHT_2) & F_1x1)) { + ret_code = code & ~(F_1x2 << addr) | C_1x2 << (target_addr = addr + RIGHT); + if (move_block_release(ret_code, uint64_t(0x7) << target_addr)) { + move_block_1x2(ret_code, target_addr, LEFT); + } + } +} + +void move_block_2x1(uint64_t code, int addr, int filter) { + int target_addr; + uint64_t ret_code; + if (filter != UP && addr >= 4 * 3 && !(code >> (target_addr = addr + UP) & F_1x1)) { + ret_code = code & ~(F_2x1 << addr) | C_2x1 << target_addr; + if (move_block_release(ret_code, uint64_t(0x7) << target_addr)) { + move_block_2x1(ret_code, target_addr, DOWN); + } + } + if (filter != DOWN && addr <= 11 * 3 && !(code >> (addr + DOWN_2) & F_1x1)) { + ret_code = code & ~(F_2x1 << addr) | C_2x1 << (target_addr = addr + DOWN); + if (move_block_release(ret_code, uint64_t(0x7) << target_addr)) { + move_block_2x1(ret_code, target_addr, UP); + } + } + if (filter != LEFT && (addr & 0x3) != 0 && !(code >> (target_addr = addr + LEFT) & F_2x1)) { + ret_code = code & ~(F_2x1 << addr) | C_2x1 << target_addr; + if (move_block_release(ret_code, uint64_t(0x7) << target_addr)) { + move_block_2x1(ret_code, target_addr, RIGHT); + } + } + if (filter != RIGHT && (addr & 0x3) != 1 && !(code >> (target_addr = addr + RIGHT) & F_2x1)) { + ret_code = code & ~(F_2x1 << addr) | C_2x1 << target_addr; + if (move_block_release(ret_code, uint64_t(0x7) << target_addr)) { + move_block_2x1(ret_code, target_addr, LEFT); + } + } +} + +void move_block_2x2(uint64_t code, int addr, int filter) { + int target_addr; + uint64_t ret_code; + if (filter != UP && addr >= 4 * 3 && !(code >> (target_addr = addr + UP) & F_1x2)) { + ret_code = code & ~(F_2x2 << addr) | C_2x2 << target_addr; + if (move_block_release(ret_code, uint64_t(0x7) << target_addr)) { + move_block_2x2(ret_code, target_addr, DOWN); + } + } + if (filter != DOWN && addr <= 10 * 3 && !(code >> (addr + DOWN_2) & F_1x2)) { + ret_code = code & ~(F_2x2 << addr) | C_2x2 << (target_addr = addr + DOWN); + if (move_block_release(ret_code, uint64_t(0x7) << target_addr)) { + move_block_2x2(ret_code, target_addr, UP); + } + } + if (filter != LEFT && (addr & 0x3) != 0 && !(code >> (target_addr = addr + LEFT) & F_2x1)) { + ret_code = code & ~(F_2x2 << addr) | C_2x2 << target_addr; + if (move_block_release(ret_code, uint64_t(0x7) << target_addr)) { + move_block_2x2(ret_code, target_addr, RIGHT); + } + } + if (filter != RIGHT && (addr & 0x3) != 2 && !(code >> (addr + RIGHT_2) & F_2x1)) { + ret_code = code & ~(F_2x2 << addr) | C_2x2 << (target_addr = addr + RIGHT); + if (move_block_release(ret_code, uint64_t(0x7) << target_addr)) { + move_block_2x2(ret_code, target_addr, LEFT); + } + } +} + + + + int main() { printf("Klotski engine\n"); @@ -46,17 +193,15 @@ int main() { // graph_output(extract_code(0x1A9BF0C00)); // printf("\n"); - std::vector all_case; - find_all_case(&all_case); - printf("count -> %lu\n", all_case.size()); - - for (auto code : all_case) { - if (code != compact_code(extract_code(code))) { - printf("error -> %lx\n", code); - } - } - - return 0; +// std::vector all_case; +// find_all_case(&all_case); +// printf("count -> %lu\n", all_case.size()); +// +// for (auto code : all_case) { +// if (code != compact_code(extract_code(code))) { +// printf("error -> %lx\n", code); +// } +// } // 0x4FEA13400 // # # # @ | 011 011 011 010 => 0100 1101 1011 -> 4DB @@ -66,8 +211,8 @@ int main() { // . # ~ ~ | 000 011 001 111 => 1110 0101 1000 -> E58 // 0x0E58FC85FFEBC4DB - graph_output(0x0E58FC85FFEBC4DB); - printf("\n"); +// graph_output(0x0E58FC85FFEBC4DB); +// printf("\n"); // 0x1A9BF0C00 // @ * * @ | 010 100 111 010 => 0101 1110 0010 -> 5E2 @@ -77,8 +222,70 @@ int main() { // # . . # | 011 000 000 011 => 0110 0000 0011 -> 603 // 0x0603EDF5CAFFF5E2 - graph_output(0x0603EDF5CAFFF5E2); - printf("\n"); +// graph_output(0x0603EDF5CAFFF5E2); +// printf("\n"); + + // 0x... + // . . . . 000 000 000 000 0000 0000 0000 000 + // . # . . 000 011 000 000 0000 0001 1000 018 + // . * * . 000 100 111 000 0001 1110 0000 1E0 + // . * * . 000 111 111 000 0001 1111 1000 1F8 + // . . . . 000 000 000 000 0000 0000 0000 000 + // 0x00001F81E0018000 + + // 0x... + // . . . . 000 000 000 000 0000 0000 0000 000 + // . ~ ~ . 000 001 111 000 0001 1100 1000 1C8 + // . * * . 000 100 111 000 0001 1110 0000 1E0 + // . * * . 000 111 111 000 0001 1111 1000 1F8 + // . . . . 000 000 000 000 0000 0000 0000 000 + // 0x00001F81E01C8000 + + // 0x... + // . . . . 000 000 000 000 0000 0000 0000 000 + // . ~ ~ . 000 001 111 000 0001 1100 1000 1C8 + // . . . . 000 000 000 000 0000 0000 0000 000 + // * * . . 100 111 000 000 0000 0011 1100 03C + // * * . . 111 111 000 000 0000 0011 1111 03F + // 0x003F03C0001C8000 + + // 0x... + // . @ . . 000 010 000 000 0000 0001 0000 010 + // . @ . . 000 111 000 000 0000 0011 1000 038 + // . * * . 000 100 111 000 0001 1110 0000 1E0 + // . * * . 000 111 111 000 0001 1111 1000 1F8 + // . . . . 000 000 000 000 0000 0000 0000 000 + // 0x00001F81E0038010 + + // 0x... + // . . . . 000 000 000 000 0000 0000 0000 000 + // . . . . 000 000 000 000 0000 0000 0000 000 + // . * * . 000 100 111 000 0001 1110 0000 1E0 + // . * * . 000 111 111 000 0001 1111 1000 1F8 + // . . . . 000 000 000 000 0000 0000 0000 000 + // 0x00001F81E0000000 + +// uint64_t code = 0x0E58FC85FFEBC4DB; // 17 +// uint64_t code = 0x00001F81E0018000; // 5 +// uint64_t code = 0x00001F81E01C8000; // 5 +// uint64_t code = 0x003F03C0001C8000; // 5 +// uint64_t code = 0x00001F81E0038010; // 1 + uint64_t code = 0x00001F81E0000000; // 9 + + int move_target = 9; + + move_cache_num = 1; + *move_cache = {code,0}; + +// move_block_1x1(code, move_target * 3, 0); +// move_block_1x2(code, move_target * 3, 0); +// move_block_2x1(code, move_target * 3, 0); + move_block_2x2(code, move_target * 3, 0); + + for (int i = 0; i < move_cache_num; ++i) { + graph_output(move_cache[i].code); + printf("\n"); + } return 0; }