From f558e18934fb4c859eb677c1620b26434f9de1f6 Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Sun, 26 Feb 2023 17:08:11 +0800 Subject: [PATCH] feat: mirror functions in klotski function --- src/klotski_core/ffi/codec.cc | 78 +++++++++++++++++++++++---- src/klotski_core/klotski.h | 67 +++++++++++++---------- src/klotski_core/raw_code/convert.cc | 14 ++--- src/klotski_core/raw_code/mirror.cc | 24 ++++----- src/klotski_core/raw_code/raw_code.cc | 10 ++-- src/klotski_core/raw_code/raw_code.h | 60 ++++++++++----------- 6 files changed, 162 insertions(+), 91 deletions(-) diff --git a/src/klotski_core/ffi/codec.cc b/src/klotski_core/ffi/codec.cc index 7bc467c..1823b80 100644 --- a/src/klotski_core/ffi/codec.cc +++ b/src/klotski_core/ffi/codec.cc @@ -10,7 +10,7 @@ using klotski::CommonCode; using klotski::AllCases; using klotski::BasicRanges; -//////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// void short_code_enable() { ShortCode::speed_up(ShortCode::NORMAL); @@ -21,14 +21,22 @@ void short_code_enable_fast() { } bool is_short_code_available() { - return BasicRanges::status() == BasicRanges::AVAILABLE; + if (BasicRanges::status() != BasicRanges::AVAILABLE) { + return false; + } + ShortCode::speed_up(ShortCode::NORMAL); + return true; } bool is_short_code_available_fast() { - return AllCases::status() == AllCases::AVAILABLE; + if (AllCases::status() != AllCases::AVAILABLE) { + return false; + } + ShortCode::speed_up(ShortCode::FAST); + return true; } -//////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// bool raw_code_check(uint64_t raw_code) { return RawCode::check(raw_code); @@ -42,7 +50,7 @@ bool common_code_check(uint64_t common_code) { return CommonCode::check(common_code); } -//////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// bool raw_code_to_short_code(uint64_t raw_code, uint32_t *short_code) { if (!RawCode::check(raw_code)) { @@ -104,7 +112,7 @@ bool common_code_to_short_code(uint64_t common_code, uint32_t *short_code) { return true; } -//////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// uint32_t raw_code_to_short_code_unsafe(uint64_t raw_code) { return RawCode::unsafe_create(raw_code) @@ -132,7 +140,59 @@ uint32_t common_code_to_short_code_unsafe(uint64_t common_code) { return CommonCode::unsafe_create(common_code).to_short_code().unwrap(); } -//////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +bool is_vertical_mirror(uint64_t raw_code, bool *result) { + if (!RawCode::check(raw_code)) { + return false; + } + *result = RawCode::unsafe_create(raw_code).is_vertical_mirror(); + return true; +} + +bool is_horizontal_mirror(uint64_t raw_code, bool *result) { + if (!RawCode::check(raw_code)) { + return false; + } + *result = RawCode::unsafe_create(raw_code).is_horizontal_mirror(); + return true; +} + +bool to_vertical_mirror(uint64_t raw_code, uint64_t *result) { + if (!RawCode::check(raw_code)) { + return false; + } + *result = RawCode::unsafe_create(raw_code).to_vertical_mirror().unwrap(); + return true; +} + +bool to_horizontal_mirror(uint64_t raw_code, uint64_t *result) { + if (!RawCode::check(raw_code)) { + return false; + } + *result = RawCode::unsafe_create(raw_code).to_horizontal_mirror().unwrap(); + return true; +} + +/////////////////////////////////////////////////////////////////////////////// + +bool is_vertical_mirror_unsafe(uint64_t raw_code) { + return RawCode::unsafe_create(raw_code).is_vertical_mirror(); +} + +bool is_horizontal_mirror_unsafe(uint64_t raw_code) { + return RawCode::unsafe_create(raw_code).is_horizontal_mirror(); +} + +uint64_t to_vertical_mirror_unsafe(uint64_t raw_code) { + return RawCode::unsafe_create(raw_code).to_vertical_mirror().unwrap(); +} + +uint64_t to_horizontal_mirror_unsafe(uint64_t raw_code) { + return RawCode::unsafe_create(raw_code).to_horizontal_mirror().unwrap(); +} + +/////////////////////////////////////////////////////////////////////////////// const uint32_t SHORT_CODE_STR_SIZE = 6; @@ -154,7 +214,7 @@ bool short_code_from_string(const char short_code_str[], uint32_t *short_code) { return true; } -//////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// const uint32_t COMMON_CODE_STR_SIZE = 10; @@ -185,4 +245,4 @@ bool common_code_from_string(const char common_code_str[], uint64_t *common_code return true; } -//////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// diff --git a/src/klotski_core/klotski.h b/src/klotski_core/klotski.h index 1936e45..a43a1b8 100644 --- a/src/klotski_core/klotski.h +++ b/src/klotski_core/klotski.h @@ -7,6 +7,8 @@ #include #endif +#define EXTERN_FUNC extern + /// klotski test interface #ifdef __cplusplus extern "C" { @@ -64,38 +66,47 @@ extern "C" { #ifdef __cplusplus extern "C" { #endif - // short code index warm up - extern void short_code_enable(); - extern void short_code_enable_fast(); - extern bool is_short_code_available(); - extern bool is_short_code_available_fast(); - - extern bool raw_code_check(uint64_t raw_code); - extern bool short_code_check(uint32_t short_code); - extern bool common_code_check(uint64_t common_code); - - extern bool raw_code_to_short_code(uint64_t raw_code, uint32_t *short_code); - extern bool short_code_to_raw_code(uint32_t short_code, uint64_t *raw_code); - extern bool raw_code_to_common_code(uint64_t raw_code, uint64_t *common_code); - extern bool common_code_to_raw_code(uint64_t common_code, uint64_t *raw_code); - extern bool short_code_to_common_code(uint32_t short_code, uint64_t *common_code); - extern bool common_code_to_short_code(uint64_t common_code, uint32_t *short_code); - - extern uint32_t raw_code_to_short_code_unsafe(uint64_t raw_code); - extern uint64_t short_code_to_raw_code_unsafe(uint32_t short_code); - extern uint64_t raw_code_to_common_code_unsafe(uint64_t raw_code); - extern uint64_t common_code_to_raw_code_unsafe(uint64_t common_code); - extern uint64_t short_code_to_common_code_unsafe(uint32_t short_code); - extern uint32_t common_code_to_short_code_unsafe(uint64_t common_code); + EXTERN_FUNC void short_code_enable(); + EXTERN_FUNC void short_code_enable_fast(); + EXTERN_FUNC bool is_short_code_available(); + EXTERN_FUNC bool is_short_code_available_fast(); + + EXTERN_FUNC bool raw_code_check(uint64_t raw_code); + EXTERN_FUNC bool short_code_check(uint32_t short_code); + EXTERN_FUNC bool common_code_check(uint64_t common_code); + + EXTERN_FUNC bool raw_code_to_short_code(uint64_t raw_code, uint32_t *short_code); + EXTERN_FUNC bool short_code_to_raw_code(uint32_t short_code, uint64_t *raw_code); + EXTERN_FUNC bool raw_code_to_common_code(uint64_t raw_code, uint64_t *common_code); + EXTERN_FUNC bool common_code_to_raw_code(uint64_t common_code, uint64_t *raw_code); + EXTERN_FUNC bool short_code_to_common_code(uint32_t short_code, uint64_t *common_code); + EXTERN_FUNC bool common_code_to_short_code(uint64_t common_code, uint32_t *short_code); + + EXTERN_FUNC uint32_t raw_code_to_short_code_unsafe(uint64_t raw_code); + EXTERN_FUNC uint64_t short_code_to_raw_code_unsafe(uint32_t short_code); + EXTERN_FUNC uint64_t raw_code_to_common_code_unsafe(uint64_t raw_code); + EXTERN_FUNC uint64_t common_code_to_raw_code_unsafe(uint64_t common_code); + EXTERN_FUNC uint64_t short_code_to_common_code_unsafe(uint32_t short_code); + EXTERN_FUNC uint32_t common_code_to_short_code_unsafe(uint64_t common_code); + + EXTERN_FUNC bool is_vertical_mirror(uint64_t raw_code, bool *result); + EXTERN_FUNC bool is_horizontal_mirror(uint64_t raw_code, bool *result); + EXTERN_FUNC bool to_vertical_mirror(uint64_t raw_code, uint64_t *result); + EXTERN_FUNC bool to_horizontal_mirror(uint64_t raw_code, uint64_t *result); + + EXTERN_FUNC bool is_vertical_mirror_unsafe(uint64_t raw_code); + EXTERN_FUNC bool is_horizontal_mirror_unsafe(uint64_t raw_code); + EXTERN_FUNC uint64_t to_vertical_mirror_unsafe(uint64_t raw_code); + EXTERN_FUNC uint64_t to_horizontal_mirror_unsafe(uint64_t raw_code); extern const uint32_t SHORT_CODE_STR_SIZE; - extern bool short_code_to_string(uint32_t short_code, char short_code_str[]); - extern bool short_code_from_string(const char short_code_str[], uint32_t *short_code); + EXTERN_FUNC bool short_code_to_string(uint32_t short_code, char short_code_str[]); + EXTERN_FUNC bool short_code_from_string(const char short_code_str[], uint32_t *short_code); extern const uint32_t COMMON_CODE_STR_SIZE; - extern bool common_code_to_string(uint64_t common_code, char common_code_str[]); - extern bool common_code_to_string_shorten(uint64_t common_code, char common_code_str[]); - extern bool common_code_from_string(const char common_code_str[], uint64_t *common_code); + EXTERN_FUNC bool common_code_to_string(uint64_t common_code, char common_code_str[]); + EXTERN_FUNC bool common_code_to_string_shorten(uint64_t common_code, char common_code_str[]); + EXTERN_FUNC bool common_code_from_string(const char common_code_str[], uint64_t *common_code); #ifdef __cplusplus } #endif diff --git a/src/klotski_core/raw_code/convert.cc b/src/klotski_core/raw_code/convert.cc index dbfbf41..8c26aeb 100644 --- a/src/klotski_core/raw_code/convert.cc +++ b/src/klotski_core/raw_code/convert.cc @@ -7,17 +7,17 @@ using klotski::RawCodeException; /// -------------------------- RawCode to CommonCode -------------------------- -CommonCode RawCode::to_common_code() const { +CommonCode RawCode::to_common_code() const noexcept { return CommonCode::unsafe_create(RawCode::compact(code)); } /// -------------------------- CommonCode to RawCode -------------------------- -RawCode::RawCode(CommonCode &&common_code) { +RawCode::RawCode(CommonCode &&common_code) noexcept { code = RawCode::extract(common_code.unwrap()); // convert from common code } -RawCode::RawCode(const CommonCode &common_code) { +RawCode::RawCode(const CommonCode &common_code) noexcept { code = RawCode::extract(common_code.unwrap()); // convert from common code } @@ -25,7 +25,7 @@ RawCode RawCode::from_common_code(uint64_t common_code) { return RawCode(CommonCode(common_code)); } -RawCode RawCode::from_common_code(CommonCode &&common_code) { +RawCode RawCode::from_common_code(CommonCode &&common_code) noexcept { return RawCode(std::forward(common_code)); } @@ -35,7 +35,7 @@ RawCode RawCode::from_common_code(std::string &&common_code) { )); } -RawCode RawCode::from_common_code(const CommonCode &common_code) { +RawCode RawCode::from_common_code(const CommonCode &common_code) noexcept { return RawCode(common_code); } @@ -46,7 +46,7 @@ RawCode RawCode::from_common_code(const std::string &common_code) { /// ----------------------------- Basic Functions ----------------------------- /// NOTE: ensure that input raw code is valid! -uint64_t RawCode::compact(uint64_t raw_code) { // raw code --> common code +uint64_t RawCode::compact(uint64_t raw_code) noexcept { // raw code --> common code int unfilled = 16; uint64_t head = 0; // 2x2 block address uint32_t range = 0; @@ -75,7 +75,7 @@ uint64_t RawCode::compact(uint64_t raw_code) { // raw code --> common code } /// NOTE: ensure that input common code is valid! -uint64_t RawCode::extract(uint64_t common_code) { // common code --> raw code +uint64_t RawCode::extract(uint64_t common_code) noexcept { // common code --> raw code auto code = C_2x2 << (common_code >> 32) * 3; // flag for 2x2 block auto range = Common::range_reverse((uint32_t)common_code); // reversed range diff --git a/src/klotski_core/raw_code/mirror.cc b/src/klotski_core/raw_code/mirror.cc index f0c3bdd..af42727 100644 --- a/src/klotski_core/raw_code/mirror.cc +++ b/src/klotski_core/raw_code/mirror.cc @@ -5,37 +5,37 @@ using klotski::RawCode; /// ----------------------------- Mirror Convert ------------------------------ -RawCode RawCode::to_vertical_mirror() const { +RawCode RawCode::to_vertical_mirror() const noexcept { return RawCode::unsafe_create(vertical_mirror(code)); } -RawCode RawCode::to_horizontal_mirror() const { +RawCode RawCode::to_horizontal_mirror() const noexcept { return RawCode::unsafe_create(horizontal_mirror(code)); } /// ------------------------------ Mirror Check ------------------------------- -bool RawCode::is_vertical_mirror() const { +bool RawCode::is_vertical_mirror() const noexcept { return vertical_mirror_check(code); } -bool RawCode::is_horizontal_mirror() const { +bool RawCode::is_horizontal_mirror() const noexcept { return horizontal_mirror_check(code); } -bool RawCode::is_vertical_mirror(RawCode &&raw_code) const { +bool RawCode::is_vertical_mirror(RawCode &&raw_code) const noexcept { return raw_code.unwrap() == vertical_mirror(code); } -bool RawCode::is_horizontal_mirror(RawCode &&raw_code) const { +bool RawCode::is_horizontal_mirror(RawCode &&raw_code) const noexcept { return raw_code.unwrap() == horizontal_mirror(code); } -bool RawCode::is_vertical_mirror(const RawCode &raw_code) const { +bool RawCode::is_vertical_mirror(const RawCode &raw_code) const noexcept { return raw_code.unwrap() == vertical_mirror(code); } -bool RawCode::is_horizontal_mirror(const RawCode &raw_code) const { +bool RawCode::is_horizontal_mirror(const RawCode &raw_code) const noexcept { return raw_code.unwrap() == horizontal_mirror(code); } @@ -118,7 +118,7 @@ inline void horizontal_clear(uint64_t &raw_code) { } } -uint64_t RawCode::vertical_mirror(uint64_t raw_code) { +uint64_t RawCode::vertical_mirror(uint64_t raw_code) noexcept { vertical_fill(raw_code); raw_code = (raw_code & MASK_MIRROR_V3) | ((raw_code >> 48) & MASK_MIRROR_V1) | ((raw_code >> 24) & MASK_MIRROR_V2) @@ -127,7 +127,7 @@ uint64_t RawCode::vertical_mirror(uint64_t raw_code) { return raw_code; } -uint64_t RawCode::horizontal_mirror(uint64_t raw_code) { +uint64_t RawCode::horizontal_mirror(uint64_t raw_code) noexcept { horizontal_fill(raw_code); raw_code = ((raw_code >> 9) & MASK_MIRROR_H1) | ((raw_code >> 3) & MASK_MIRROR_H2) | ((raw_code & MASK_MIRROR_H2) << 3) | ((raw_code & MASK_MIRROR_H1) << 9); // flip raw code @@ -135,13 +135,13 @@ uint64_t RawCode::horizontal_mirror(uint64_t raw_code) { return raw_code; } -bool RawCode::vertical_mirror_check(uint64_t raw_code) { +bool RawCode::vertical_mirror_check(uint64_t raw_code) noexcept { vertical_fill(raw_code); return !(MASK_MIRROR_V1 & ((raw_code >> 48) ^ raw_code)) && !(MASK_MIRROR_V2 & ((raw_code >> 24) ^ raw_code)); } -bool RawCode::horizontal_mirror_check(uint64_t raw_code) { +bool RawCode::horizontal_mirror_check(uint64_t raw_code) noexcept { horizontal_fill(raw_code); return !(MASK_MIRROR_H1 & ((raw_code >> 9) ^ raw_code)) && !(MASK_MIRROR_H2 & ((raw_code >> 3) ^ raw_code)); diff --git a/src/klotski_core/raw_code/raw_code.cc b/src/klotski_core/raw_code/raw_code.cc index a9e24e7..58170d9 100644 --- a/src/klotski_core/raw_code/raw_code.cc +++ b/src/klotski_core/raw_code/raw_code.cc @@ -20,11 +20,11 @@ namespace std { } namespace klotski { - bool RawCode::operator==(const RawCode &raw_code) const { + bool RawCode::operator==(const RawCode &raw_code) const noexcept { return this->code == raw_code.code; } - bool RawCode::operator!=(const RawCode &raw_code) const { + bool RawCode::operator!=(const RawCode &raw_code) const noexcept { return this->code != raw_code.code; } @@ -45,7 +45,7 @@ namespace klotski { } namespace klotski { - bool RawCode::valid() const { + bool RawCode::valid() const noexcept { return RawCode::check(code); } @@ -53,7 +53,7 @@ namespace klotski { return RawCode(raw_code); } - RawCode RawCode::unsafe_create(uint64_t raw_code) { // create without check + RawCode RawCode::unsafe_create(uint64_t raw_code) noexcept { // create without check auto tmp = RawCode(); // init directly tmp.code = raw_code; return tmp; @@ -67,7 +67,7 @@ namespace klotski { } } -bool RawCode::check(uint64_t raw_code) { // check whether raw code is valid +bool RawCode::check(uint64_t raw_code) noexcept { // check whether raw code is valid /// MASK_1x1 | MASK_1x2 | MASK_2x1 | MASK_2x2 /// 100 000 000 000 | 000 100 000 000 | 000 000 000 000 | 000 100 000 000 /// 000 000 000 000 | 000 000 000 000 | 100 000 000 000 | 100 100 000 000 diff --git a/src/klotski_core/raw_code/raw_code.h b/src/klotski_core/raw_code/raw_code.h index 0de9378..18bc520 100644 --- a/src/klotski_core/raw_code/raw_code.h +++ b/src/klotski_core/raw_code/raw_code.h @@ -57,60 +57,60 @@ namespace klotski { uint64_t code; RawCode() = default; // unsafe initialize - static inline uint64_t compact(uint64_t raw_code); // raw code -> common code - static inline uint64_t extract(uint64_t common_code); // common code -> raw code + static inline uint64_t compact(uint64_t raw_code) noexcept; // raw code -> common code + static inline uint64_t extract(uint64_t common_code) noexcept; // common code -> raw code - static inline uint64_t vertical_mirror(uint64_t raw_code); // to vertical mirror - static inline uint64_t horizontal_mirror(uint64_t raw_code); // to horizontal mirror + static inline uint64_t vertical_mirror(uint64_t raw_code) noexcept; // to vertical mirror + static inline uint64_t horizontal_mirror(uint64_t raw_code) noexcept; // to horizontal mirror - static inline bool vertical_mirror_check(uint64_t raw_code); // check vertical mirror - static inline bool horizontal_mirror_check(uint64_t raw_code); // check horizontal mirror + static inline bool vertical_mirror_check(uint64_t raw_code) noexcept; // check vertical mirror + static inline bool horizontal_mirror_check(uint64_t raw_code) noexcept; // check horizontal mirror public: /// RawCode validity check - bool valid() const; - static bool check(uint64_t raw_code); + bool valid() const noexcept; + static bool check(uint64_t raw_code) noexcept; /// Operators of RawCode - bool operator==(const RawCode &raw_code) const; - bool operator!=(const RawCode &raw_code) const; - constexpr explicit operator uint64_t() const { return code; } + bool operator==(const RawCode &raw_code) const noexcept; + bool operator!=(const RawCode &raw_code) const noexcept; + constexpr explicit operator uint64_t() const noexcept { return code; } friend std::ostream& operator<<(std::ostream &out, const RawCode &self); /// Export functions - CommonCode to_common_code() const; - constexpr uint64_t unwrap() const { return code; } + CommonCode to_common_code() const noexcept; + constexpr uint64_t unwrap() const noexcept { return code; } /// RawCode constructors explicit RawCode(uint64_t raw_code); - explicit RawCode(CommonCode &&common_code); - explicit RawCode(const CommonCode &common_code); + explicit RawCode(CommonCode &&common_code) noexcept; + explicit RawCode(const CommonCode &common_code) noexcept; /// Static initialization static RawCode create(uint64_t raw_code); - static RawCode unsafe_create(uint64_t raw_code); + static RawCode unsafe_create(uint64_t raw_code) noexcept; static RawCode from_common_code(uint64_t common_code); - static RawCode from_common_code(CommonCode &&common_code); + static RawCode from_common_code(CommonCode &&common_code) noexcept; static RawCode from_common_code(std::string &&common_code); - static RawCode from_common_code(const CommonCode &common_code); + static RawCode from_common_code(const CommonCode &common_code) noexcept; static RawCode from_common_code(const std::string &common_code); /// Mirror functions - RawCode to_vertical_mirror() const; - RawCode to_horizontal_mirror() const; + RawCode to_vertical_mirror() const noexcept; + RawCode to_horizontal_mirror() const noexcept; - bool is_vertical_mirror() const; // whether vertically symmetrical - bool is_horizontal_mirror() const; // whether horizontally symmetrical + bool is_vertical_mirror() const noexcept; // whether vertically symmetrical + bool is_horizontal_mirror() const noexcept; // whether horizontally symmetrical - bool is_vertical_mirror(RawCode &&raw_code) const; // whether vertically symmetric to another - bool is_vertical_mirror(const RawCode &raw_code) const; - bool is_horizontal_mirror(RawCode &&raw_code) const; // whether horizontally symmetric to another - bool is_horizontal_mirror(const RawCode &raw_code) const; + bool is_vertical_mirror(RawCode &&raw_code) const noexcept; // whether vertically symmetric to another + bool is_vertical_mirror(const RawCode &raw_code) const noexcept; + bool is_horizontal_mirror(RawCode &&raw_code) const noexcept; // whether horizontally symmetric to another + bool is_horizontal_mirror(const RawCode &raw_code) const noexcept; }; - inline bool operator==(uint64_t r1, const RawCode &r2) { return r1 == r2.unwrap(); } - inline bool operator!=(uint64_t r1, const RawCode &r2) { return r1 != r2.unwrap(); } - inline bool operator==(const RawCode &r1, uint64_t r2) { return r1.unwrap() == r2; } - inline bool operator!=(const RawCode &r1, uint64_t r2) { return r1.unwrap() != r2; } + inline bool operator==(uint64_t r1, const RawCode &r2) noexcept { return r1 == r2.unwrap(); } + inline bool operator!=(uint64_t r1, const RawCode &r2) noexcept { return r1 != r2.unwrap(); } + inline bool operator==(const RawCode &r1, uint64_t r2) noexcept { return r1.unwrap() == r2; } + inline bool operator!=(const RawCode &r1, uint64_t r2) noexcept { return r1.unwrap() != r2; } }