|
|
@ -4,6 +4,33 @@ |
|
|
|
|
|
|
|
namespace klotski::cases { |
|
|
|
|
|
|
|
[[nodiscard]] constexpr uint32_t GroupPro::type_id() const { |
|
|
|
return type_id_; |
|
|
|
} |
|
|
|
|
|
|
|
[[nodiscard]] constexpr uint32_t GroupPro::pattern_id() const { |
|
|
|
return pattern_id_; |
|
|
|
} |
|
|
|
|
|
|
|
[[nodiscard]] constexpr GroupPro::Toward GroupPro::toward() const { |
|
|
|
return toward_; |
|
|
|
} |
|
|
|
|
|
|
|
constexpr GroupPro GroupPro::unsafe_create(uint32_t type_id, uint32_t pattern_id, Toward toward) { |
|
|
|
return {type_id, pattern_id, toward}; |
|
|
|
} |
|
|
|
|
|
|
|
constexpr std::optional<GroupPro> GroupPro::create(uint32_t type_id, uint32_t pattern_id, Toward toward) { |
|
|
|
if (type_id >= TYPE_ID_LIMIT) { |
|
|
|
return std::nullopt; |
|
|
|
} |
|
|
|
if (pattern_id >= GroupUnion::unsafe_create(type_id).pattern_num()) { |
|
|
|
return std::nullopt; |
|
|
|
} |
|
|
|
// TODO: toward check |
|
|
|
return unsafe_create(type_id, pattern_id, toward); |
|
|
|
} |
|
|
|
|
|
|
|
constexpr uint32_t GroupPro::flat_id() const { |
|
|
|
return PATTERN_OFFSET[type_id_] + pattern_id_; |
|
|
|
} |
|
|
@ -12,6 +39,10 @@ constexpr uint32_t GroupPro::size() const { |
|
|
|
return GROUP_PRO_SIZE[flat_id()]; |
|
|
|
} |
|
|
|
|
|
|
|
inline GroupPro GroupPro::from_short_code(codec::ShortCode short_code) { |
|
|
|
return from_common_code(short_code.to_common_code()); |
|
|
|
} |
|
|
|
|
|
|
|
inline GroupPro GroupPro::from_common_code(codec::CommonCode common_code) { |
|
|
|
return from_raw_code(common_code.to_raw_code()); |
|
|
|
} |
|
|
@ -19,96 +50,96 @@ inline GroupPro GroupPro::from_common_code(codec::CommonCode common_code) { |
|
|
|
constexpr GroupPro::MirrorType GroupPro::mirror_type() const { |
|
|
|
switch (GROUP_PRO_TYPE[flat_id()]) { |
|
|
|
case 0: |
|
|
|
return MirrorType::FullMirror; |
|
|
|
return MirrorType::Full; |
|
|
|
case 1: |
|
|
|
return MirrorType::HorizontalMirror; |
|
|
|
return MirrorType::Horizontal; |
|
|
|
case 2: |
|
|
|
return MirrorType::CentroMirror; |
|
|
|
return MirrorType::Centro; |
|
|
|
case 3: |
|
|
|
return MirrorType::VerticalMirror; |
|
|
|
return MirrorType::Vertical; |
|
|
|
case 4: |
|
|
|
return MirrorType::NonMirror; |
|
|
|
return MirrorType::Ordinary; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
constexpr bool GroupPro::is_vertical_mirror() const { |
|
|
|
switch (mirror_type()) { |
|
|
|
case MirrorType::FullMirror: |
|
|
|
case MirrorType::Full: |
|
|
|
return true; |
|
|
|
case MirrorType::HorizontalMirror: |
|
|
|
case MirrorType::Horizontal: |
|
|
|
return false; |
|
|
|
case MirrorType::CentroMirror: |
|
|
|
case MirrorType::Centro: |
|
|
|
return false; |
|
|
|
case MirrorType::VerticalMirror: |
|
|
|
case MirrorType::Vertical: |
|
|
|
return true; |
|
|
|
case MirrorType::NonMirror: |
|
|
|
case MirrorType::Ordinary: |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
constexpr bool GroupPro::is_horizontal_mirror() const { |
|
|
|
switch (mirror_type()) { |
|
|
|
case MirrorType::FullMirror: |
|
|
|
case MirrorType::Full: |
|
|
|
return true; |
|
|
|
case MirrorType::HorizontalMirror: |
|
|
|
case MirrorType::Horizontal: |
|
|
|
return true; |
|
|
|
case MirrorType::CentroMirror: |
|
|
|
case MirrorType::Centro: |
|
|
|
return false; |
|
|
|
case MirrorType::VerticalMirror: |
|
|
|
case MirrorType::Vertical: |
|
|
|
return false; |
|
|
|
case MirrorType::NonMirror: |
|
|
|
case MirrorType::Ordinary: |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
constexpr GroupPro GroupPro::to_vertical_mirror() const { |
|
|
|
switch (mirror_type()) { |
|
|
|
case MirrorType::FullMirror: |
|
|
|
case MirrorType::Full: |
|
|
|
return *this; |
|
|
|
case MirrorType::HorizontalMirror: |
|
|
|
if (mirror_toward_ == 0) { |
|
|
|
return GroupPro::unsafe_create(type_id_, pattern_id_, 2); |
|
|
|
case MirrorType::Horizontal: |
|
|
|
if (toward_ == Toward::A) { |
|
|
|
return GroupPro::unsafe_create(type_id_, pattern_id_, Toward::C); |
|
|
|
} |
|
|
|
return GroupPro::unsafe_create(type_id_, pattern_id_, 0); |
|
|
|
case MirrorType::CentroMirror: |
|
|
|
if (mirror_toward_ == 0) { |
|
|
|
return GroupPro::unsafe_create(type_id_, pattern_id_, 1); |
|
|
|
return GroupPro::unsafe_create(type_id_, pattern_id_, Toward::A); |
|
|
|
case MirrorType::Centro: |
|
|
|
if (toward_ == Toward::A) { |
|
|
|
return GroupPro::unsafe_create(type_id_, pattern_id_, Toward::B); |
|
|
|
} |
|
|
|
return GroupPro::unsafe_create(type_id_, pattern_id_, 0); |
|
|
|
case MirrorType::VerticalMirror: |
|
|
|
return GroupPro::unsafe_create(type_id_, pattern_id_, Toward::A); |
|
|
|
case MirrorType::Vertical: |
|
|
|
return *this; |
|
|
|
case MirrorType::NonMirror: |
|
|
|
if (mirror_toward_ == 0) { |
|
|
|
return GroupPro::unsafe_create(type_id_, pattern_id_, 2); |
|
|
|
} else if (mirror_toward_ == 1) { |
|
|
|
return GroupPro::unsafe_create(type_id_, pattern_id_, 3); |
|
|
|
} else if (mirror_toward_ == 2) { |
|
|
|
return GroupPro::unsafe_create(type_id_, pattern_id_, 0); |
|
|
|
case MirrorType::Ordinary: |
|
|
|
if (toward_ == Toward::A) { |
|
|
|
return GroupPro::unsafe_create(type_id_, pattern_id_, Toward::C); |
|
|
|
} else if (toward_ == Toward::B) { |
|
|
|
return GroupPro::unsafe_create(type_id_, pattern_id_, Toward::D); |
|
|
|
} else if (toward_ == Toward::C) { |
|
|
|
return GroupPro::unsafe_create(type_id_, pattern_id_, Toward::A); |
|
|
|
} |
|
|
|
return GroupPro::unsafe_create(type_id_, pattern_id_, 1); |
|
|
|
return GroupPro::unsafe_create(type_id_, pattern_id_, Toward::B); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
constexpr GroupPro GroupPro::to_horizontal_mirror() const { |
|
|
|
switch (mirror_type()) { |
|
|
|
case MirrorType::FullMirror: |
|
|
|
case MirrorType::HorizontalMirror: |
|
|
|
case MirrorType::Full: |
|
|
|
case MirrorType::Horizontal: |
|
|
|
return *this; |
|
|
|
case MirrorType::CentroMirror: |
|
|
|
case MirrorType::VerticalMirror: |
|
|
|
if (mirror_toward_ == 0) { |
|
|
|
return GroupPro::unsafe_create(type_id_, pattern_id_, 1); |
|
|
|
} |
|
|
|
return GroupPro::unsafe_create(type_id_, pattern_id_, 0); |
|
|
|
case MirrorType::NonMirror: |
|
|
|
if (mirror_toward_ == 0) { |
|
|
|
return GroupPro::unsafe_create(type_id_, pattern_id_, 1); |
|
|
|
} else if (mirror_toward_ == 1) { |
|
|
|
return GroupPro::unsafe_create(type_id_, pattern_id_, 0); |
|
|
|
} else if (mirror_toward_ == 2) { |
|
|
|
return GroupPro::unsafe_create(type_id_, pattern_id_, 3); |
|
|
|
} |
|
|
|
return GroupPro::unsafe_create(type_id_, pattern_id_, 2); |
|
|
|
case MirrorType::Centro: |
|
|
|
case MirrorType::Vertical: |
|
|
|
if (toward_ == Toward::A) { |
|
|
|
return GroupPro::unsafe_create(type_id_, pattern_id_, Toward::B); |
|
|
|
} |
|
|
|
return GroupPro::unsafe_create(type_id_, pattern_id_, Toward::A); |
|
|
|
case MirrorType::Ordinary: |
|
|
|
if (toward_ == Toward::A) { |
|
|
|
return GroupPro::unsafe_create(type_id_, pattern_id_, Toward::B); |
|
|
|
} else if (toward_ == Toward::B) { |
|
|
|
return GroupPro::unsafe_create(type_id_, pattern_id_, Toward::A); |
|
|
|
} else if (toward_ == Toward::C) { |
|
|
|
return GroupPro::unsafe_create(type_id_, pattern_id_, Toward::D); |
|
|
|
} |
|
|
|
return GroupPro::unsafe_create(type_id_, pattern_id_, Toward::C); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|