Browse Source

build: file structure of cmake project

legacy
Dnomd343 2 years ago
parent
commit
84c2a783af
  1. 3
      CMakeLists.txt
  2. 5
      all_cases/CMakeLists.txt
  3. 74
      all_cases/main.cc
  4. 7
      src-legacy/CMakeLists.txt
  5. 0
      src-legacy/case.cc
  6. 0
      src-legacy/common.cc
  7. 0
      src-legacy/klotski.cc
  8. 315
      src-legacy/main.cc
  9. 11
      src/CMakeLists.txt
  10. 4
      src/all_cases/CMakeLists.txt
  11. 22
      src/all_cases/all_cases.cc
  12. 0
      src/all_cases/all_cases.h
  13. 0
      src/all_cases/basic_ranges.cc
  14. 0
      src/all_cases/basic_ranges.h
  15. 3
      src/common/CMakeLists.txt
  16. 0
      src/common/common.cc
  17. 0
      src/common/common.h
  18. 342
      src/main.cc

3
CMakeLists.txt

@ -2,6 +2,5 @@ cmake_minimum_required(VERSION 3.0)
set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD 14)
project(klotski) project(klotski)
#add_subdirectory(src) add_subdirectory(src)
add_subdirectory(all_cases)
#add_subdirectory(klotski) #add_subdirectory(klotski)

5
all_cases/CMakeLists.txt

@ -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)

74
all_cases/main.cc

@ -1,74 +0,0 @@
#include <iostream>
#include "all_cases.h"
#include "basic_ranges.h"
#include <thread>
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;
}

7
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})

0
src/case.cc → src-legacy/case.cc

0
src/common.cc → src-legacy/common.cc

0
src/klotski.cc → src-legacy/klotski.cc

315
src-legacy/main.cc

@ -0,0 +1,315 @@
#include "case.h"
#include "klotski.h"
#include <cstdio>
#include <cstdint>
#include <list>
#include <unordered_map>
#include <queue>
#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<klotski_info*> src;
};
std::queue<klotski_info*> cal_cache;
std::unordered_map<uint64_t, klotski_info*> 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<uint64_t> 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<uint64_t> 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;
}

11
src/CMakeLists.txt

@ -1,7 +1,10 @@
cmake_minimum_required(VERSION 3.0) 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_subdirectory(common)
add_executable(klotski ${SRC}) add_subdirectory(all_cases)
add_executable(klotski main.cc)
target_link_libraries(klotski common all_cases)

4
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)

22
all_cases/all_cases.cc → src/all_cases/all_cases.cc

@ -5,6 +5,17 @@ std::mutex AllCases::all_cases_building;
bool AllCases::all_cases_available = false; bool AllCases::all_cases_available = false;
std::vector<uint32_t> AllCases::all_cases[]; std::vector<uint32_t> 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<uint32_t> (*AllCases::get_all_cases())[16] { // get const ptr of all cases const std::vector<uint32_t> (*AllCases::get_all_cases())[16] { // get const ptr of all cases
if (all_cases->empty()) { if (all_cases->empty()) {
build_all_cases(); // all cases initialize build_all_cases(); // all cases initialize
@ -34,14 +45,3 @@ void AllCases::build_all_cases() { // build all cases
} }
AllCases::all_cases_building.unlock(); 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;
}

0
all_cases/all_cases.h → src/all_cases/all_cases.h

0
all_cases/basic_ranges.cc → src/all_cases/basic_ranges.cc

0
all_cases/basic_ranges.h → src/all_cases/basic_ranges.h

3
src/common/CMakeLists.txt

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

0
all_cases/common.cc → src/common/common.cc

0
all_cases/common.h → src/common/common.h

342
src/main.cc

@ -1,315 +1,47 @@
#include "case.h" #include <iostream>
#include "klotski.h" #include "all_cases.h"
#include <cstdio> #include "basic_ranges.h"
#include <cstdint>
#include <list> void get_status() {
#include <unordered_map> switch (BasicRanges::basic_ranges_status()) {
#include <queue> case BasicRanges::NO_INIT:
std::cout << "basic ranges no init" << std::endl;
#define UP (-12) break;
#define LEFT (-3) case BasicRanges::BUILDING:
#define DOWN 12 std::cout << "basic ranges building" << std::endl;
#define DOWN_2 24 break;
#define RIGHT 3 case BasicRanges::AVAILABLE:
#define RIGHT_2 6 std::cout << "basic ranges available" << std::endl;
break;
struct cache { }
uint64_t code;
uint64_t filter; switch (AllCases::all_cases_status()) {
}; case AllCases::NO_INIT:
struct cache move_cache[16]; std::cout << "all cases no init" << std::endl;
int move_cache_num; break;
case AllCases::BUILDING:
struct klotski_info { std::cout << "all cases building" << std::endl;
int step; break;
uint64_t code; case AllCases::AVAILABLE:
uint64_t filter; std::cout << "all cases available" << std::endl;
std::list<klotski_info*> src; break;
};
std::queue<klotski_info*> cal_cache;
std::unordered_map<uint64_t, klotski_info*> 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() { int main() {
printf("Klotski engine\n");
std::vector<uint64_t> 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)); get_status();
// printf("%lx\n", compact_code(0x0603EDF5CAFFF5E2)); BasicRanges::build_basic_ranges();
get_status();
AllCases::build_all_cases();
get_status();
// graph_output(extract_code(0x4FEA13400)); for (auto const &all_case : *AllCases::get_all_cases()) {
// printf("\n"); std::cout << " " << all_case.size() << std::endl;
// graph_output(extract_code(0x1A9BF0C00));
// printf("\n");
// std::vector<uint64_t> 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);
} }
std::cout << BasicRanges::get_basic_ranges() << std::endl;
std::cout << AllCases::get_basic_ranges() << std::endl;
return 0; return 0;
} }

Loading…
Cancel
Save