diff --git a/all_cases/CMakeLists.txt b/all_cases/CMakeLists.txt index 649363a..2cda079 100644 --- a/all_cases/CMakeLists.txt +++ b/all_cases/CMakeLists.txt @@ -1,6 +1,5 @@ cmake_minimum_required(VERSION 3.0) set(CMAKE_CXX_STANDARD 14) -#add_executable(klotski main.cc all_cases.cc) -add_executable(klotski main.cc basic_ranges.cc common.cc) +add_executable(klotski main.cc common.cc basic_ranges.cc all_cases.cc) target_link_libraries(klotski pthread) diff --git a/all_cases/all_cases.cc b/all_cases/all_cases.cc index cade9db..cb24166 100644 --- a/all_cases/all_cases.cc +++ b/all_cases/all_cases.cc @@ -1,45 +1,36 @@ +#include "common.h" #include "all_cases.h" -#include -#include -#include +std::mutex AllCases::all_cases_building; +bool AllCases::all_cases_available = false; +std::vector AllCases::all_cases[]; -std::vector AllCases::basic_ranges; - -bool AllCases::basic_ranges_available = false; - -std::mutex AllCases::basic_ranges_building; - -void AllCases::build_basic_ranges() { - - std::cout << std::this_thread::get_id() << " enter build function" << std::endl; - - if (AllCases::basic_ranges_available) { - std::cout << std::this_thread::get_id() << " data already built -> skip" << std::endl; - return; // basic ranges already built +const std::vector (*AllCases::get_all_cases())[16] { // get const ptr of all cases + if (all_cases->empty()) { + build_all_cases(); // all cases initialize } + return &all_cases; // return ptr +} - if (AllCases::basic_ranges_building.try_lock()) { // lock success -> not building - - std::cout << std::this_thread::get_id() << " try lock success -> start build process" << std::endl; - - AllCases::basic_ranges.emplace_back(0); - AllCases::basic_ranges.emplace_back(1); - AllCases::basic_ranges.emplace_back(2); - sleep(2); // assume using a lot of time - - AllCases::basic_ranges_available = true; // enable available flag - - std::cout << std::this_thread::get_id() << " build complete -> continue" << std::endl; - +void AllCases::build_all_cases() { // build all cases + if (AllCases::all_cases_available) { + return; // all cases already built + } + if (AllCases::all_cases_building.try_lock()) { // lock success -> start building + /// head -> 0/1/2 / 4/5/6 / 8/9/10 / 12/13/14 + for (uint32_t head = 0; head < 16; ++head) { // address of 2x2 block + if ((head & 0b11) == 0b11) { + continue; // invalid 2x2 address + } + for (uint32_t const &range : *get_basic_ranges()) { // check base on 2x2 address and range + if (Common::check_case(head, range)) { + all_cases[head].emplace_back(Common::range_reverse(range)); // found valid case + } + } + } + AllCases::all_cases_available = true; // set available flag } else { // another thread building - - std::cout << std::this_thread::get_id() << " another thread building -> wait" << std::endl; - AllCases::basic_ranges_building.lock(); // blocking wait - + AllCases::all_cases_building.lock(); // blocking waiting } - std::cout << std::this_thread::get_id() << " work complete -> unlock" << std::endl; - AllCases::basic_ranges_building.unlock(); - - + AllCases::all_cases_building.unlock(); } diff --git a/all_cases/all_cases.h b/all_cases/all_cases.h index ad127d3..89f9e9f 100644 --- a/all_cases/all_cases.h +++ b/all_cases/all_cases.h @@ -3,22 +3,15 @@ #include #include #include +#include "basic_ranges.h" -//class BasicRanges { -//public: -// -// -// -// static std::vector basic_ranges; -// -// static void build_basic_ranges(); -// -// static bool basic_ranges_available; -// -// static std::mutex basic_ranges_building; -// -//private: -// -// void generate_ranges(int n1, int n2, int n3, int n4); -// -//}; +class AllCases : public BasicRanges { +public: + static void build_all_cases(); + static const std::vector (*get_all_cases())[16]; + +private: + static bool all_cases_available; + static std::mutex all_cases_building; + static std::vector all_cases[16]; +}; diff --git a/all_cases/main.cc b/all_cases/main.cc index 32d8073..f424045 100644 --- a/all_cases/main.cc +++ b/all_cases/main.cc @@ -1,5 +1,5 @@ #include -//#include "all_cases.h" +#include "all_cases.h" #include "basic_ranges.h" #include @@ -20,20 +20,34 @@ void get_status() { 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); +// 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; + + + std::thread t1(AllCases::build_all_cases); + std::thread t2(AllCases::build_all_cases); + std::thread t3(AllCases::build_all_cases); t1.join(); t2.join(); t3.join(); - t.join(); - get_status(); + AllCases::build_all_cases(); - std::cout << BasicRanges::get_basic_ranges()->size() << std::endl; + for (auto const &all_case : *AllCases::get_all_cases()) { + std::cout << all_case.size() << std::endl; + } return 0; }