From afe1528c8282a1bc15dbf7b131f0360d7d230579 Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Sun, 26 Feb 2023 16:02:04 +0800 Subject: [PATCH] feat: complete RawCode vertical mirror --- src/klotski_core/ffi/tmain.cc | 5 ++- src/klotski_core/raw_code/mirror.cc | 63 ++++++++++++++++++----------- 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/src/klotski_core/ffi/tmain.cc b/src/klotski_core/ffi/tmain.cc index 2e1d420..180ea9f 100644 --- a/src/klotski_core/ffi/tmain.cc +++ b/src/klotski_core/ffi/tmain.cc @@ -20,7 +20,10 @@ void tmain() { // std::cout << ret.to_common_code() << std::endl << ret << std::endl; - klotski::RawCode::from_common_code(0x1A9BF0C00).is_vertical_mirror(); +// klotski::RawCode::from_common_code(0x1A9BF0C00).is_vertical_mirror(); + auto ret = klotski::RawCode::from_common_code(0x1A9BF0C00).to_vertical_mirror(); + + std::cout << ret.to_common_code() << std::endl << ret << std::endl; return; diff --git a/src/klotski_core/raw_code/mirror.cc b/src/klotski_core/raw_code/mirror.cc index 35621b7..f0c3bdd 100644 --- a/src/klotski_core/raw_code/mirror.cc +++ b/src/klotski_core/raw_code/mirror.cc @@ -41,27 +41,37 @@ bool RawCode::is_horizontal_mirror(const RawCode &raw_code) const { /// ----------------------------- Basic Functions ----------------------------- -#include - -/// MASK_MIRROR_A | MASK_MIRROR_B +/// MASK_MIRROR_H1 | MASK_MIRROR_H2 /// 111 000 000 000 | 000 111 000 000 /// 111 000 000 000 | 000 111 000 000 /// 111 000 000 000 | 000 111 000 000 /// 111 000 000 000 | 000 111 000 000 /// 111 000 000 000 | 000 111 000 000 -constexpr uint64_t MASK_MIRROR_A = 0x0'007'007'007'007'007; -constexpr uint64_t MASK_MIRROR_B = 0x0'038'038'038'038'038; -void vertical_fill(uint64_t &raw_code) { +constexpr uint64_t MASK_MIRROR_H1 = 0x0'007'007'007'007'007; +constexpr uint64_t MASK_MIRROR_H2 = 0x0'038'038'038'038'038; + +/// MASK_MIRROR_V1 | MASK_MIRROR_V2 | MASK_MIRROR_V3 +/// 111 111 111 111 | 000 000 000 000 | 000 000 000 000 +/// 000 000 000 000 | 111 111 111 111 | 000 000 000 000 +/// 000 000 000 000 | 000 000 000 000 | 111 111 111 111 +/// 000 000 000 000 | 000 000 000 000 | 000 000 000 000 +/// 000 000 000 000 | 000 000 000 000 | 000 000 000 000 + +constexpr uint64_t MASK_MIRROR_V1 = 0x0'000'000'000'000'FFF; +constexpr uint64_t MASK_MIRROR_V2 = 0x0'000'000'000'FFF'000; +constexpr uint64_t MASK_MIRROR_V3 = 0x0'000'000'FFF'000'000; + +inline void vertical_fill(uint64_t &raw_code) { uint64_t mask = 0; - for (int addr = 0; addr < 60; addr += 3) { + for (int addr = 0; addr < 60; addr += 3) { // traverse every 3-bits switch ((raw_code >> addr) & 0b111) { case B_2x1: case B_2x2: mask |= (uint64_t)0b111 << (addr + 12); // generate fill mask } } - for (int addr = 0; addr < 60; addr += 3) { + for (int addr = 0; addr < 60; addr += 3) { // traverse every 3-bits switch ((raw_code | mask) >> addr & 0b111) { case B_2x1: raw_code &= ~(uint64_t(~B_2x1 & 0b111) << (addr + 12)); // fill vertical mirror @@ -88,6 +98,16 @@ inline void horizontal_fill(uint64_t &raw_code) { } } +inline void vertical_clear(uint64_t &raw_code) { + for (int addr = 0; addr < 60; addr += 3) { // traverse every 3-bits + switch ((raw_code >> addr) & 0b111) { + case B_2x1: + case B_2x2: + raw_code |= (uint64_t)0b111 << (addr + 12); // reset as original block + } + } +} + inline void horizontal_clear(uint64_t &raw_code) { for (int addr = 0; addr < 60; addr += 3) { // traverse every 3-bits switch ((raw_code >> addr) & 0b111) { @@ -99,33 +119,30 @@ inline void horizontal_clear(uint64_t &raw_code) { } uint64_t RawCode::vertical_mirror(uint64_t raw_code) { - - // TODO: vertical mirror convert - - return 0; + vertical_fill(raw_code); + raw_code = (raw_code & MASK_MIRROR_V3) + | ((raw_code >> 48) & MASK_MIRROR_V1) | ((raw_code >> 24) & MASK_MIRROR_V2) + | ((raw_code & MASK_MIRROR_V2) << 24) | ((raw_code & MASK_MIRROR_V1) << 48); + vertical_clear(raw_code); + return raw_code; } uint64_t RawCode::horizontal_mirror(uint64_t raw_code) { horizontal_fill(raw_code); - raw_code = ((raw_code >> 9) & MASK_MIRROR_A) | ((raw_code >> 3) & MASK_MIRROR_B) - | ((raw_code & MASK_MIRROR_B) << 3) | ((raw_code & MASK_MIRROR_A) << 9); // flip 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 horizontal_clear(raw_code); return raw_code; } bool RawCode::vertical_mirror_check(uint64_t raw_code) { - - // TODO: whether self vertical mirror - vertical_fill(raw_code); - - std::cout << RawCode::unsafe_create(raw_code) << std::endl; - - return false; + 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) { horizontal_fill(raw_code); - return ((MASK_MIRROR_A & ((raw_code >> 9) ^ raw_code)) == 0) - && ((MASK_MIRROR_B & ((raw_code >> 3) ^ raw_code)) == 0); + return !(MASK_MIRROR_H1 & ((raw_code >> 9) ^ raw_code)) + && !(MASK_MIRROR_H2 & ((raw_code >> 3) ^ raw_code)); }