Browse Source

refactor: project structure of raw code

master
Dnomd343 2 months ago
parent
commit
4cf888741a
  1. 8
      src/core/CMakeLists.txt
  2. 70
      src/core/raw_code/inline_impl.h
  3. 18
      src/core/raw_code/internal/convert.cc
  4. 18
      src/core/raw_code/internal/mirror.cc
  5. 22
      src/core/raw_code/internal/raw_code.cc
  6. 76
      src/core/raw_code/internal/raw_code.inl
  7. 40
      src/core/raw_code/internal/sundry.cc
  8. 130
      src/core/raw_code/raw_code.h
  9. 46
      src/core/raw_code/sundry.cc

8
src/core/CMakeLists.txt

@ -11,10 +11,10 @@ set(KLOTSKI_CORE_SRC
common_code/internal/serialize.cc
common_code/internal/sundry.cc
raw_code/raw_code.cc
raw_code/convert.cc
raw_code/sundry.cc
raw_code/mirror.cc
raw_code/internal/raw_code.cc
raw_code/internal/convert.cc
raw_code/internal/sundry.cc
raw_code/internal/mirror.cc
short_code/convert.cc
short_code/serialize.cc

70
src/core/raw_code/inline_impl.h

@ -1,70 +0,0 @@
#pragma once
namespace klotski {
namespace codec {
/// Get the original 64-bit code.
inline uint64_t RawCode::unwrap() const noexcept {
return code_;
}
/// Implicit conversion to 64-bit code.
inline RawCode::operator uint64_t() const noexcept {
return code_;
}
/// Equality comparison between RawCode and numbers.
inline bool operator==(RawCode r1, uint64_t r2) noexcept {
return r1.unwrap() == r2;
}
/// RawCode equal comparison implement.
inline bool operator==(RawCode r1, RawCode r2) noexcept {
return r1.unwrap() == r2.unwrap();
}
/// RawCode create without any check.
inline RawCode RawCode::unsafe_create(uint64_t raw_code) noexcept {
return *reinterpret_cast<RawCode*>(&raw_code); // init directly
}
/// RawCode create with valid check.
inline std::optional<RawCode> RawCode::create(uint64_t raw_code) noexcept {
if (!RawCode::check(raw_code)) {
return std::nullopt; // invalid raw code
}
return RawCode::unsafe_create(raw_code);
}
/// Calculate vertically symmetrical case.
inline RawCode RawCode::to_vertical_mirror() const noexcept {
return RawCode::unsafe_create(get_vertical_mirror(code_));
}
/// Calculate horizontally symmetrical case.
inline RawCode RawCode::to_horizontal_mirror() const noexcept {
return RawCode::unsafe_create(get_horizontal_mirror(code_));
}
/// Determine whether the case is vertically symmetrical.
inline bool RawCode::is_vertical_mirror() const noexcept {
return check_vertical_mirror(code_);
}
/// Determine whether the case is horizontally symmetrical.
inline bool RawCode::is_horizontal_mirror() const noexcept {
return check_horizontal_mirror(code_);
}
/// Determine whether two cases are vertically symmetrical to each other.
inline bool RawCode::is_vertical_mirror(RawCode raw_code) const noexcept {
return raw_code.code_ == get_vertical_mirror(code_);
}
/// Determine whether two cases are horizontally symmetrical to each other.
inline bool RawCode::is_horizontal_mirror(RawCode raw_code) const noexcept {
return raw_code.code_ == get_horizontal_mirror(code_);
}
} // namespace codec
} // namespace klotski

18
src/core/raw_code/convert.cc → src/core/raw_code/internal/convert.cc

@ -1,12 +1,10 @@
#include "common.h"
#include "utility.h"
#include "raw_code.h"
#include "utils/common.h"
#include "utils/utility.h"
#include "raw_code/raw_code.h"
namespace klotski {
namespace codec {
namespace klotski::codec {
/// Convert RawCode to CommonCode.
uint64_t RawCode::compact(uint64_t raw_code) noexcept {
uint64_t RawCode::compact(uint64_t raw_code) {
int unfilled = 16;
uint64_t head = 0; // 2x2 block address
uint32_t range = 0;
@ -34,8 +32,7 @@ uint64_t RawCode::compact(uint64_t raw_code) noexcept {
return head | (range << (unfilled << 1)); // fill low bits as zero
}
/// Convert CommonCode to RawCode.
uint64_t RawCode::extract(uint64_t common_code) noexcept {
uint64_t RawCode::extract(uint64_t common_code) {
auto code = K_MASK_2x2 << (common_code >> 32) * 3; // flag for 2x2 block
auto range = range_reverse((uint32_t)common_code); // reversed range
@ -61,5 +58,4 @@ uint64_t RawCode::extract(uint64_t common_code) noexcept {
return code;
}
} // namespace codec
} // namespace klotski
} // namespace klotski::codec

18
src/core/raw_code/mirror.cc → src/core/raw_code/internal/mirror.cc

@ -1,8 +1,7 @@
#include "common.h"
#include "raw_code.h"
#include "utils/common.h"
#include "raw_code/raw_code.h"
namespace klotski {
namespace codec {
namespace klotski::codec {
// ----------------------------------------------------------------------------------------- //
@ -87,7 +86,7 @@ inline static void horizontal_clear(uint64_t &raw_code) {
// ----------------------------------------------------------------------------------------- //
uint64_t RawCode::get_vertical_mirror(uint64_t raw_code) noexcept {
uint64_t RawCode::get_vertical_mirror(uint64_t raw_code) {
vertical_fill(raw_code);
raw_code = (raw_code & MASK_MIRROR_V3)
| ((raw_code >> 48) & MASK_MIRROR_V1) | ((raw_code >> 24) & MASK_MIRROR_V2)
@ -96,7 +95,7 @@ uint64_t RawCode::get_vertical_mirror(uint64_t raw_code) noexcept {
return raw_code;
}
uint64_t RawCode::get_horizontal_mirror(uint64_t raw_code) noexcept {
uint64_t RawCode::get_horizontal_mirror(uint64_t raw_code) {
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
@ -104,13 +103,13 @@ uint64_t RawCode::get_horizontal_mirror(uint64_t raw_code) noexcept {
return raw_code;
}
bool RawCode::check_vertical_mirror(uint64_t raw_code) noexcept {
bool RawCode::check_vertical_mirror(uint64_t raw_code) {
vertical_fill(raw_code);
return !(MASK_MIRROR_V1 & ((raw_code >> 48) ^ raw_code))
&& !(MASK_MIRROR_V2 & ((raw_code >> 24) ^ raw_code));
}
bool RawCode::check_horizontal_mirror(uint64_t raw_code) noexcept {
bool RawCode::check_horizontal_mirror(uint64_t raw_code) {
horizontal_fill(raw_code);
return !(MASK_MIRROR_H1 & ((raw_code >> 9) ^ raw_code))
&& !(MASK_MIRROR_H2 & ((raw_code >> 3) ^ raw_code));
@ -118,5 +117,4 @@ bool RawCode::check_horizontal_mirror(uint64_t raw_code) noexcept {
// ----------------------------------------------------------------------------------------- //
} // namespace codec
} // namespace klotski
} // namespace klotski::codec

22
src/core/raw_code/raw_code.cc → src/core/raw_code/internal/raw_code.cc

@ -1,18 +1,18 @@
#include "common.h"
#include "raw_code.h"
#include "utils/common.h"
#include "raw_code/raw_code.h"
namespace klotski {
namespace codec {
namespace klotski::codec {
// TODO: only for debug usage.
std::ostream& operator<<(std::ostream &out, RawCode self) {
std::ostream& operator<<(std::ostream &out, const RawCode self) {
char *code;
asprintf(&code, "%015llX\n", self.code_); // code length -> 15
out << code;
free(code);
/// 0x0 1x2 2x1 1x1 2x2 b101 b110 fill
char map[] = {'.', '~', '|', '*', '@', '?', '?', '+'};
constexpr char map[] = {
// 0x0 1x2 2x1 1x1 2x2 b101 b110 fill
'.', '~', '|', '*', '@', '?', '?', '+'
};
for (int addr = 0; addr < 60; addr += 3) {
out << map[(self.code_ >> addr) & 0b111];
out << " " << &"\n"[(addr & 0b11) != 0b01];
@ -20,8 +20,7 @@ std::ostream& operator<<(std::ostream &out, RawCode self) {
return out;
}
/// Check the validity of the original RawCode.
bool RawCode::check(uint64_t raw_code) noexcept {
bool RawCode::check(uint64_t raw_code) {
/// 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
@ -70,5 +69,4 @@ bool RawCode::check(uint64_t raw_code) noexcept {
return head_num == 1 && space_num >= 2; // one head and at least 2 space
}
} // namespace codec
} // namespace klotski
} // namespace klotski::codec

76
src/core/raw_code/internal/raw_code.inl

@ -0,0 +1,76 @@
#pragma once
#include <bit>
namespace klotski::codec {
// ------------------------------------------------------------------------------------- //
inline uint64_t RawCode::unwrap() const {
return code_;
}
inline RawCode::operator uint64_t() const {
return code_;
}
// ------------------------------------------------------------------------------------- //
constexpr auto operator==(const RawCode &lhs, const uint64_t rhs) {
return lhs.code_ == rhs;
}
constexpr auto operator<=>(const RawCode &lhs, const uint64_t rhs) {
return lhs.code_ <=> rhs;
}
constexpr auto operator==(const RawCode &lhs, const RawCode &rhs) {
return lhs.code_ == rhs.code_;
}
constexpr auto operator<=>(const RawCode &lhs, const RawCode &rhs) {
return lhs.code_ <=> rhs.code_;
}
// ------------------------------------------------------------------------------------- //
inline RawCode RawCode::unsafe_create(const uint64_t raw_code) {
return std::bit_cast<RawCode>(raw_code); // init directly
}
inline std::optional<RawCode> RawCode::create(const uint64_t raw_code) {
if (!check(raw_code)) {
return std::nullopt; // invalid raw code
}
return unsafe_create(raw_code);
}
// ------------------------------------------------------------------------------------- //
inline bool RawCode::is_vertical_mirror() const {
return check_vertical_mirror(code_);
}
inline bool RawCode::is_horizontal_mirror() const {
return check_horizontal_mirror(code_);
}
inline RawCode RawCode::to_vertical_mirror() const {
return unsafe_create(get_vertical_mirror(code_));
}
inline RawCode RawCode::to_horizontal_mirror() const {
return unsafe_create(get_horizontal_mirror(code_));
}
inline bool RawCode::is_vertical_mirror(const RawCode raw_code) const {
return raw_code.code_ == get_vertical_mirror(code_);
}
inline bool RawCode::is_horizontal_mirror(const RawCode raw_code) const {
return raw_code.code_ == get_horizontal_mirror(code_);
}
// ------------------------------------------------------------------------------------- //
} // namespace klotski::codec

40
src/core/raw_code/internal/sundry.cc

@ -0,0 +1,40 @@
#include "raw_code.h"
#include "common_code.h"
namespace klotski::codec {
// ----------------------------------------------------------------------------------------- //
RawCode::RawCode(const CommonCode common_code) {
code_ = extract(common_code.unwrap());
}
// ----------------------------------------------------------------------------------------- //
CommonCode RawCode::to_common_code() const {
return CommonCode::unsafe_create(compact(code_));
}
// ----------------------------------------------------------------------------------------- //
RawCode RawCode::from_common_code(const CommonCode common_code) {
return common_code.to_raw_code();
}
std::optional<RawCode> RawCode::from_common_code(const uint64_t common_code) {
auto convert = [](const CommonCode code) {
return code.to_raw_code();
};
return CommonCode::create(common_code).transform(convert);
}
std::optional<RawCode> RawCode::from_common_code(const std::string &common_code) {
auto convert = [](const CommonCode code) {
return code.to_raw_code();
};
return CommonCode::from_string(common_code).transform(convert);
}
// ----------------------------------------------------------------------------------------- //
} // namespace klotski::codec

130
src/core/raw_code/raw_code.h

@ -1,4 +1,4 @@
#pragma once
/// Klotski Engine by Dnomd343 @2024
/// RawCode is an uncompressed klotski coding scheme, which is used for program
/// calculation. It encodes the `5x4` chessboard as 0 ~ 19, and using 3-bit to
@ -59,59 +59,125 @@
/// RawCode => 0x0E58'FC85'FFEB'C4DB ///
/// -------------------------------------------------------------------------------------------------- ///
#pragma once
#include <string>
#include <ostream>
#include <cstdint>
#include <optional>
namespace klotski {
namespace codec {
namespace klotski::codec {
class CommonCode;
class RawCode {
public:
explicit operator uint64_t() const noexcept;
static bool check(uint64_t raw_code) noexcept;
// ------------------------------------------------------------------------------------- //
/// Explicit conversion to u64 code.
explicit operator uint64_t() const;
/// Check the validity of the original RawCode.
static bool check(uint64_t raw_code);
// TODO: add macro check here
/// Output string encoding of RawCode only for debug.
friend std::ostream& operator<<(std::ostream &out, RawCode self);
[[nodiscard]] uint64_t unwrap() const noexcept;
[[nodiscard]] CommonCode to_common_code() const noexcept;
// ------------------------------------------------------------------------------------- //
/// Get the original u64 code.
[[nodiscard]] uint64_t unwrap() const;
/// Convert RawCode to CommonCode.
[[nodiscard]] CommonCode to_common_code() const;
// ------------------------------------------------------------------------------------- //
public:
RawCode() = delete;
explicit RawCode(CommonCode common_code) noexcept;
static RawCode unsafe_create(uint64_t raw_code) noexcept;
static std::optional<RawCode> create(uint64_t raw_code) noexcept;
/// Construct RawCode from CommonCode.
explicit RawCode(CommonCode common_code);
/// Create RawCode without any check.
static RawCode unsafe_create(uint64_t raw_code);
/// Create RawCode with validity check.
static std::optional<RawCode> create(uint64_t raw_code);
// ------------------------------------------------------------------------------------- //
/// Create RawCode from CommonCode.
static RawCode from_common_code(CommonCode common_code);
/// Create RawCode from CommonCode in u64.
static std::optional<RawCode> from_common_code(uint64_t common_code);
/// Create RawCode from CommonCode in string form.
static std::optional<RawCode> from_common_code(const std::string &common_code);
// ------------------------------------------------------------------------------------- //
static RawCode from_common_code(CommonCode common_code) noexcept;
static std::optional<RawCode> from_common_code(uint64_t common_code) noexcept;
static std::optional<RawCode> from_common_code(std::string &&common_code) noexcept;
static std::optional<RawCode> from_common_code(const std::string &common_code) noexcept;
/// Compare RawCode with u64 values.
friend constexpr auto operator==(const RawCode &lhs, uint64_t rhs);
friend constexpr auto operator<=>(const RawCode &lhs, uint64_t rhs);
/// Compare the original values of two RawCodes.
friend constexpr auto operator==(const RawCode &lhs, const RawCode &rhs);
friend constexpr auto operator<=>(const RawCode &lhs, const RawCode &rhs);
// ------------------------------------------------------------------------------------- //
/// Calculate vertically symmetrical layout.
[[nodiscard]] RawCode to_vertical_mirror() const;
/// Calculate horizontally symmetrical layout.
[[nodiscard]] RawCode to_horizontal_mirror() const;
// ------------------------------------------------------------------------------------- //
/// Determine whether the layout is vertically symmetrical.
[[nodiscard]] bool is_vertical_mirror() const;
/// Determine whether the layout is horizontally symmetrical.
[[nodiscard]] bool is_horizontal_mirror() const;
/// Determine whether two layouts are vertically symmetrical to each other.
[[nodiscard]] bool is_vertical_mirror(RawCode raw_code) const;
/// Determine whether two layouts are horizontally symmetrical to each other.
[[nodiscard]] bool is_horizontal_mirror(RawCode raw_code) const;
// ------------------------------------------------------------------------------------- //
private:
uint64_t code_;
static uint64_t compact(uint64_t raw_code) noexcept;
static uint64_t extract(uint64_t common_code) noexcept;
public:
[[nodiscard]] RawCode to_vertical_mirror() const noexcept;
[[nodiscard]] RawCode to_horizontal_mirror() const noexcept;
// ------------------------------------------------------------------------------------- //
[[nodiscard]] bool is_vertical_mirror() const noexcept;
[[nodiscard]] bool is_horizontal_mirror() const noexcept;
[[nodiscard]] bool is_vertical_mirror(RawCode raw_code) const noexcept;
[[nodiscard]] bool is_horizontal_mirror(RawCode raw_code) const noexcept;
/// Compact RawCode as CommonCode.
static uint64_t compact(uint64_t raw_code);
private:
static bool check_vertical_mirror(uint64_t raw_code) noexcept;
static bool check_horizontal_mirror(uint64_t raw_code) noexcept;
/// Extract CommonCode as RawCode.
static uint64_t extract(uint64_t common_code);
// ------------------------------------------------------------------------------------- //
/// Check whether the layout is vertically symmetrical.
static bool check_vertical_mirror(uint64_t raw_code);
/// Check whether the layout is horizontally symmetrical.
static bool check_horizontal_mirror(uint64_t raw_code);
/// Get the vertically symmetrical layout.
static uint64_t get_vertical_mirror(uint64_t raw_code);
/// Get the horizontally symmetrical layout.
static uint64_t get_horizontal_mirror(uint64_t raw_code);
static uint64_t get_vertical_mirror(uint64_t raw_code) noexcept;
static uint64_t get_horizontal_mirror(uint64_t raw_code) noexcept;
// ------------------------------------------------------------------------------------- //
};
} // namespace codec
} // namespace klotski
} // namespace klotski::codec
#include "inline_impl.h"
#include "internal/raw_code.inl"

46
src/core/raw_code/sundry.cc

@ -1,46 +0,0 @@
#include "raw_code.h"
#include "common_code.h"
namespace klotski {
namespace codec {
// ----------------------------------------------------------------------------------------- //
RawCode::RawCode(CommonCode common_code) noexcept {
code_ = RawCode::extract(common_code.unwrap());
}
// ----------------------------------------------------------------------------------------- //
CommonCode RawCode::to_common_code() const noexcept {
return CommonCode::unsafe_create(RawCode::compact(code_));
}
// ----------------------------------------------------------------------------------------- //
RawCode RawCode::from_common_code(CommonCode common_code) noexcept {
return common_code.to_raw_code();
}
std::optional<RawCode> RawCode::from_common_code(uint64_t common_code) noexcept {
return CommonCode::create(common_code).transform([](auto common_code) {
return common_code.to_raw_code();
});
}
std::optional<RawCode> RawCode::from_common_code(std::string &&common_code) noexcept {
return CommonCode::from_string(std::move(common_code)).transform([](auto common_code) {
return common_code.to_raw_code();
});
}
std::optional<RawCode> RawCode::from_common_code(const std::string &common_code) noexcept {
return CommonCode::from_string(common_code).transform([](auto common_code) {
return common_code.to_raw_code();
});
}
// ----------------------------------------------------------------------------------------- //
} // namespace codec
} // namespace klotski
Loading…
Cancel
Save