diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b8eac1..b779232 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,5 @@ cmake_minimum_required(VERSION 3.0) set(CMAKE_CXX_STANDARD 14) project(klotski) -#add_subdirectory(src) -add_subdirectory(all_cases) +add_subdirectory(src) #add_subdirectory(klotski) diff --git a/all_cases/CMakeLists.txt b/all_cases/CMakeLists.txt deleted file mode 100644 index 2cda079..0000000 --- a/all_cases/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -cmake_minimum_required(VERSION 3.0) -set(CMAKE_CXX_STANDARD 14) - -add_executable(klotski main.cc common.cc basic_ranges.cc all_cases.cc) -target_link_libraries(klotski pthread) diff --git a/all_cases/main.cc b/all_cases/main.cc deleted file mode 100644 index 1277476..0000000 --- a/all_cases/main.cc +++ /dev/null @@ -1,74 +0,0 @@ -#include -#include "all_cases.h" -#include "basic_ranges.h" - -#include - -void get_status() { - switch (BasicRanges::basic_ranges_status()) { - case BasicRanges::NO_INIT: - std::cout << "basic ranges no init" << std::endl; - break; - case BasicRanges::BUILDING: - std::cout << "basic ranges building" << std::endl; - break; - case BasicRanges::AVAILABLE: - std::cout << "basic ranges available" << std::endl; - break; - } - - switch (AllCases::all_cases_status()) { - case AllCases::NO_INIT: - std::cout << "all cases no init" << std::endl; - break; - case AllCases::BUILDING: - std::cout << "all cases building" << std::endl; - break; - case AllCases::AVAILABLE: - std::cout << "all cases available" << std::endl; - break; - } -} - -int main() { - -// get_status(); -// -// std::thread t1(BasicRanges::build_basic_ranges); -// std::thread t2(BasicRanges::build_basic_ranges); -// std::thread t3(BasicRanges::build_basic_ranges); -// std::thread t(get_status); -// t1.join(); -// t2.join(); -// t3.join(); -// t.join(); -// -// get_status(); -// -// std::cout << BasicRanges::get_basic_ranges()->size() << std::endl; - - - get_status(); - - std::thread t1(AllCases::build_all_cases); - std::thread t2(AllCases::build_all_cases); - std::thread t3(AllCases::build_all_cases); - std::thread t(get_status); - t1.join(); - t2.join(); - t3.join(); - t.join(); - -// AllCases::build_all_cases(); - - get_status(); - - for (auto const &all_case : *AllCases::get_all_cases()) { - std::cout << " " << all_case.size() << std::endl; - } - - std::cout << BasicRanges::get_basic_ranges() << std::endl; - std::cout << AllCases::get_basic_ranges() << std::endl; - - return 0; -} diff --git a/src-legacy/CMakeLists.txt b/src-legacy/CMakeLists.txt new file mode 100644 index 0000000..0e513aa --- /dev/null +++ b/src-legacy/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.0) +set(CMAKE_CXX_STANDARD 14) + +include_directories(${PROJECT_SOURCE_DIR}/include) + +aux_source_directory(${PROJECT_SOURCE_DIR}/src SRC) +add_executable(klotski ${SRC}) diff --git a/src/case.cc b/src-legacy/case.cc similarity index 100% rename from src/case.cc rename to src-legacy/case.cc diff --git a/src/common.cc b/src-legacy/common.cc similarity index 100% rename from src/common.cc rename to src-legacy/common.cc diff --git a/src/klotski.cc b/src-legacy/klotski.cc similarity index 100% rename from src/klotski.cc rename to src-legacy/klotski.cc diff --git a/src-legacy/main.cc b/src-legacy/main.cc new file mode 100644 index 0000000..d81e1aa --- /dev/null +++ b/src-legacy/main.cc @@ -0,0 +1,315 @@ +#include "case.h" +#include "klotski.h" +#include +#include +#include +#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; + +struct klotski_info { + int step; + uint64_t code; + uint64_t filter; + std::list src; +}; + +std::queue cal_cache; +std::unordered_map klotski_case; + +void graph_output(uint64_t code) { + for (int i = 0; i < 20; ++i) { + switch (code & 0x7) { + case B_1x1: + printf("# "); + break; + case B_1x2: + printf("& "); + break; + case B_2x1: + printf("$ "); + break; + case B_2x2: + printf("@ "); + break; + case B_fill: + printf("* "); + break; + case B_space: + printf(". "); + break; + default: + printf("? "); + } + if ((i & 0x3) == 0x3) { + printf("\n"); + } + code >>= 3; + } +} + + +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); + } + } +} + +void add_new_case(klotski_info *src, uint64_t code, uint64_t filter) { + auto existing_case = klotski_case.find(code); + if (existing_case != klotski_case.end()) { + existing_case->second->filter |= filter; + if (existing_case->second->step != src->step) { + existing_case->second->src.push_back(src); + } + return; + } + + auto info = new struct klotski_info; + info->code = code; + info->filter = filter; + info->step = src->step + 1; + info->src.push_back(src); + cal_cache.emplace(info); + klotski_case.emplace(code, info); +} + +void next_step(klotski_info *klotski) { + move_cache->code = klotski->code; + uint64_t range = move_cache->code & ~klotski->filter; + for (int addr = 0; range; range >>= 3, addr += 3) { + move_cache_num = 1; + switch (range & 0x7) { + case B_2x2: + move_block_2x2(move_cache->code, addr, 0); + break; + case B_2x1: + move_block_2x1(move_cache->code, addr, 0); + break; + case B_1x2: + move_block_1x2(move_cache->code, addr, 0); + break; + case B_1x1: + move_block_1x1(move_cache->code, addr, 0); + break; + default: + continue; + } + for (struct cache *p = move_cache + 1; p < move_cache + move_cache_num; ++p) { + add_new_case(klotski, p->code, p->filter); + } + } +} + +void cal_klotski(uint64_t code) { + + auto setup = new klotski_info; + setup->step = 0; + setup->code = code; + setup->filter = 0x0; + + klotski_case.clear(); + klotski_case.emplace(code, setup); + + cal_cache.push(setup); + while (!cal_cache.empty()) { + next_step(cal_cache.front()); + cal_cache.pop(); + } + +// printf("count -> %zu\n", klotski_case.size()); + +} + +int main() { + printf("Klotski engine\n"); + + std::vector all_cases; + find_all_case(&all_cases); + +// std::cout << "klotski cases -> " << all_cases.size() << std::endl; + + printf("klotski cases -> %zu\n", all_cases.size()); + + return 0; + +// printf("%lx\n", compact_code(0x0E58FC85FFEBC4DB)); +// printf("%lx\n", compact_code(0x0603EDF5CAFFF5E2)); + +// graph_output(extract_code(0x4FEA13400)); +// printf("\n"); +// 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); +// } +// } + + // 0x4FEA13400 + // # # # @ | 011 011 011 010 => 0100 1101 1011 -> 4DB + // * * & @ | 100 111 010 111 => 1110 1011 1100 -> EBC + // * * & $ | 111 111 111 010 => 0101 1111 1111 -> 5FF + // . + + $ | 000 001 111 111 => 1111 1100 1000 -> FC8 + // . # ~ ~ | 000 011 001 111 => 1110 0101 1000 -> E58 + // 0x0E58FC85FFEBC4DB + + // 0x1A9BF0C00 + // @ * * @ | 010 100 111 010 => 0101 1110 0010 -> 5E2 + // @ * * @ | 111 111 111 111 => 1111 1111 1111 -> FFF + // $ ~ ~ $ | 010 001 111 010 => 0101 1100 1010 -> 5CA + // $ # # $ | 111 011 011 111 => 1110 1101 1111 -> EDF + // # . . # | 011 000 000 011 => 0110 0000 0011 -> 603 + // 0x0603EDF5CAFFF5E2 + + +// uint64_t code = 0x0603EDF5CAFFF5E2; + uint64_t code = 0x0E58FC85FFEBC4DB; + + for (int i = 0; i < 100; ++i) { + cal_klotski(code); + } + + return 0; +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0e513aa..afb42c1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,7 +1,10 @@ cmake_minimum_required(VERSION 3.0) -set(CMAKE_CXX_STANDARD 14) -include_directories(${PROJECT_SOURCE_DIR}/include) +include_directories(${PROJECT_SOURCE_DIR}/src/common) +include_directories(${PROJECT_SOURCE_DIR}/src/all_cases) -aux_source_directory(${PROJECT_SOURCE_DIR}/src SRC) -add_executable(klotski ${SRC}) +add_subdirectory(common) +add_subdirectory(all_cases) + +add_executable(klotski main.cc) +target_link_libraries(klotski common all_cases) diff --git a/src/all_cases/CMakeLists.txt b/src/all_cases/CMakeLists.txt new file mode 100644 index 0000000..cfcce31 --- /dev/null +++ b/src/all_cases/CMakeLists.txt @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.0) + +add_library(all_cases basic_ranges.cc all_cases.cc) +target_link_libraries(all_cases common) diff --git a/all_cases/all_cases.cc b/src/all_cases/all_cases.cc similarity index 100% rename from all_cases/all_cases.cc rename to src/all_cases/all_cases.cc index bd33119..143ab16 100644 --- a/all_cases/all_cases.cc +++ b/src/all_cases/all_cases.cc @@ -5,6 +5,17 @@ std::mutex AllCases::all_cases_building; bool AllCases::all_cases_available = false; std::vector AllCases::all_cases[]; +AllCases::Status AllCases::all_cases_status() { // get all cases status + if (all_cases_available) { + return AVAILABLE; // all cases already built + } + if (!all_cases_building.try_lock()) { // fail to lock mutex -> another thread working + return BUILDING; + } + all_cases_building.unlock(); // release mutex + return NO_INIT; +} + const std::vector (*AllCases::get_all_cases())[16] { // get const ptr of all cases if (all_cases->empty()) { build_all_cases(); // all cases initialize @@ -34,14 +45,3 @@ void AllCases::build_all_cases() { // build all cases } AllCases::all_cases_building.unlock(); } - -AllCases::Status AllCases::all_cases_status() { // get all cases status - if (all_cases_available) { - return AVAILABLE; // all cases already built - } - if (!all_cases_building.try_lock()) { // fail to lock mutex -> another thread working - return BUILDING; - } - all_cases_building.unlock(); // release mutex - return NO_INIT; -} diff --git a/all_cases/all_cases.h b/src/all_cases/all_cases.h similarity index 100% rename from all_cases/all_cases.h rename to src/all_cases/all_cases.h diff --git a/all_cases/basic_ranges.cc b/src/all_cases/basic_ranges.cc similarity index 100% rename from all_cases/basic_ranges.cc rename to src/all_cases/basic_ranges.cc diff --git a/all_cases/basic_ranges.h b/src/all_cases/basic_ranges.h similarity index 100% rename from all_cases/basic_ranges.h rename to src/all_cases/basic_ranges.h diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt new file mode 100644 index 0000000..0ab3fea --- /dev/null +++ b/src/common/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.0) + +add_library(common common.cc) diff --git a/all_cases/common.cc b/src/common/common.cc similarity index 100% rename from all_cases/common.cc rename to src/common/common.cc diff --git a/all_cases/common.h b/src/common/common.h similarity index 100% rename from all_cases/common.h rename to src/common/common.h diff --git a/src/main.cc b/src/main.cc index d81e1aa..0cf39c6 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,315 +1,47 @@ -#include "case.h" -#include "klotski.h" -#include -#include -#include -#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; - -struct klotski_info { - int step; - uint64_t code; - uint64_t filter; - std::list src; -}; - -std::queue cal_cache; -std::unordered_map klotski_case; - -void graph_output(uint64_t code) { - for (int i = 0; i < 20; ++i) { - switch (code & 0x7) { - case B_1x1: - printf("# "); - break; - case B_1x2: - printf("& "); - break; - case B_2x1: - printf("$ "); - break; - case B_2x2: - printf("@ "); - break; - case B_fill: - printf("* "); - break; - case B_space: - printf(". "); - break; - default: - printf("? "); - } - if ((i & 0x3) == 0x3) { - printf("\n"); - } - code >>= 3; - } -} - - -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); - } +#include +#include "all_cases.h" +#include "basic_ranges.h" + +void get_status() { + switch (BasicRanges::basic_ranges_status()) { + case BasicRanges::NO_INIT: + std::cout << "basic ranges no init" << std::endl; + break; + case BasicRanges::BUILDING: + std::cout << "basic ranges building" << std::endl; + break; + case BasicRanges::AVAILABLE: + std::cout << "basic ranges available" << std::endl; + break; + } + + switch (AllCases::all_cases_status()) { + case AllCases::NO_INIT: + std::cout << "all cases no init" << std::endl; + break; + case AllCases::BUILDING: + std::cout << "all cases building" << std::endl; + break; + case AllCases::AVAILABLE: + std::cout << "all cases available" << std::endl; + break; } - 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); - } - } -} - -void add_new_case(klotski_info *src, uint64_t code, uint64_t filter) { - auto existing_case = klotski_case.find(code); - if (existing_case != klotski_case.end()) { - existing_case->second->filter |= filter; - if (existing_case->second->step != src->step) { - existing_case->second->src.push_back(src); - } - return; - } - - auto info = new struct klotski_info; - info->code = code; - info->filter = filter; - info->step = src->step + 1; - info->src.push_back(src); - cal_cache.emplace(info); - klotski_case.emplace(code, info); -} - -void next_step(klotski_info *klotski) { - move_cache->code = klotski->code; - uint64_t range = move_cache->code & ~klotski->filter; - for (int addr = 0; range; range >>= 3, addr += 3) { - move_cache_num = 1; - switch (range & 0x7) { - case B_2x2: - move_block_2x2(move_cache->code, addr, 0); - break; - case B_2x1: - move_block_2x1(move_cache->code, addr, 0); - break; - case B_1x2: - move_block_1x2(move_cache->code, addr, 0); - break; - case B_1x1: - move_block_1x1(move_cache->code, addr, 0); - break; - default: - continue; - } - for (struct cache *p = move_cache + 1; p < move_cache + move_cache_num; ++p) { - add_new_case(klotski, p->code, p->filter); - } - } -} - -void cal_klotski(uint64_t code) { - - auto setup = new klotski_info; - setup->step = 0; - setup->code = code; - setup->filter = 0x0; - - klotski_case.clear(); - klotski_case.emplace(code, setup); - - cal_cache.push(setup); - while (!cal_cache.empty()) { - next_step(cal_cache.front()); - cal_cache.pop(); - } - -// printf("count -> %zu\n", klotski_case.size()); - } int main() { - printf("Klotski engine\n"); - - std::vector all_cases; - find_all_case(&all_cases); - -// std::cout << "klotski cases -> " << all_cases.size() << std::endl; - - printf("klotski cases -> %zu\n", all_cases.size()); - - return 0; -// printf("%lx\n", compact_code(0x0E58FC85FFEBC4DB)); -// printf("%lx\n", compact_code(0x0603EDF5CAFFF5E2)); + get_status(); + BasicRanges::build_basic_ranges(); + get_status(); + AllCases::build_all_cases(); + get_status(); -// graph_output(extract_code(0x4FEA13400)); -// printf("\n"); -// 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); -// } -// } - - // 0x4FEA13400 - // # # # @ | 011 011 011 010 => 0100 1101 1011 -> 4DB - // * * & @ | 100 111 010 111 => 1110 1011 1100 -> EBC - // * * & $ | 111 111 111 010 => 0101 1111 1111 -> 5FF - // . + + $ | 000 001 111 111 => 1111 1100 1000 -> FC8 - // . # ~ ~ | 000 011 001 111 => 1110 0101 1000 -> E58 - // 0x0E58FC85FFEBC4DB - - // 0x1A9BF0C00 - // @ * * @ | 010 100 111 010 => 0101 1110 0010 -> 5E2 - // @ * * @ | 111 111 111 111 => 1111 1111 1111 -> FFF - // $ ~ ~ $ | 010 001 111 010 => 0101 1100 1010 -> 5CA - // $ # # $ | 111 011 011 111 => 1110 1101 1111 -> EDF - // # . . # | 011 000 000 011 => 0110 0000 0011 -> 603 - // 0x0603EDF5CAFFF5E2 - - -// uint64_t code = 0x0603EDF5CAFFF5E2; - uint64_t code = 0x0E58FC85FFEBC4DB; - - for (int i = 0; i < 100; ++i) { - cal_klotski(code); + for (auto const &all_case : *AllCases::get_all_cases()) { + std::cout << " " << all_case.size() << std::endl; } + std::cout << BasicRanges::get_basic_ranges() << std::endl; + std::cout << AllCases::get_basic_ranges() << std::endl; + return 0; }