From 99cc98ee00b95fea117f932d3b72685d108c9a4e Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Sun, 20 Oct 2024 10:42:26 +0800 Subject: [PATCH] feat: python wrapper of group module --- src/core_ffi/CMakeLists.txt | 2 + src/core_ffi/py_ffi/binder.cc | 39 ++++++++++++++ src/core_ffi/py_ffi/include/py_exps.h | 14 +++++ src/core_ffi/py_ffi/include/py_group.h | 71 ++++++++++++++++++++++++++ src/core_ffi/py_ffi/py_group.cc | 39 ++++++++++++++ src/core_ffi/py_ffi/py_group_union.cc | 58 +++++++++++++++++++++ 6 files changed, 223 insertions(+) create mode 100644 src/core_ffi/py_ffi/include/py_group.h create mode 100644 src/core_ffi/py_ffi/py_group.cc create mode 100644 src/core_ffi/py_ffi/py_group_union.cc diff --git a/src/core_ffi/CMakeLists.txt b/src/core_ffi/CMakeLists.txt index 424715e..ba48a6c 100644 --- a/src/core_ffi/CMakeLists.txt +++ b/src/core_ffi/CMakeLists.txt @@ -16,6 +16,8 @@ if (KLSK_PYTHON_FFI) py_ffi/codec/short_code.cc py_ffi/codec/common_codec.cc py_ffi/py_cases.cc + py_ffi/py_group_union.cc + py_ffi/py_group.cc ) target_include_directories(klotski_py PRIVATE py_ffi/include) target_link_libraries(klotski_py PRIVATE klotski::core) diff --git a/src/core_ffi/py_ffi/binder.cc b/src/core_ffi/py_ffi/binder.cc index e04bd9f..306a776 100644 --- a/src/core_ffi/py_ffi/binder.cc +++ b/src/core_ffi/py_ffi/binder.cc @@ -1,9 +1,11 @@ #include #include +#include #include "py_exps.h" #include "py_codec.h" #include "py_cases.h" +#include "py_group.h" namespace py = pybind11; @@ -14,6 +16,9 @@ using klotski::ffi::PyCodecExp; using klotski::ffi::PyShortCode; using klotski::ffi::PyCommonCode; +using klotski::ffi::PyGroup; +using klotski::ffi::PyGroupUnion; + void bind_common_code(const py::module_ &m) { py::class_(m, "CommonCode") .def(py::init()) @@ -100,5 +105,39 @@ PYBIND11_MODULE(klotski, m) { bind_short_code(m); bind_common_code(m); + py::class_(m, "GroupUnion") + .def(py::init()) + .def(py::init()) + .def(py::init()) + +// .def(py::hash(py::self)) +// .def(py::self == py::self) +// .def("__str__", &PyShortCode::str) + .def("__int__", &PyGroupUnion::value) +// .def("__repr__", &PyGroupUnion::repr) + + .def("cases", &PyGroupUnion::cases) + .def("groups", &PyGroupUnion::groups) + + .def_property_readonly("size", &PyGroupUnion::size) + .def_property_readonly("value", &PyGroupUnion::value) + .def_property_readonly("group_num", &PyGroupUnion::group_num) + .def_property_readonly("pattern_num", &PyGroupUnion::pattern_num) + .def_property_readonly("max_group_size", &PyGroupUnion::max_group_size); + + py::class_(m, "Group") + .def_property_readonly("type_id", &PyGroup::type_id) + .def_property_readonly("pattern_id", &PyGroup::pattern_id) + + .def("__str__", &PyGroup::to_string) + + .def("cases", &PyGroup::cases) + .def("to_vertical_mirror", &PyGroup::to_vertical_mirror) + .def("to_horizontal_mirror", &PyGroup::to_horizontal_mirror) + + .def_property_readonly("size", &PyGroup::size) + .def_property_readonly("is_vertical_mirror", &PyGroup::is_vertical_mirror) + .def_property_readonly("is_horizontal_mirror", &PyGroup::is_horizontal_mirror); + m.attr("__version__") = "version field"; } diff --git a/src/core_ffi/py_ffi/include/py_exps.h b/src/core_ffi/py_ffi/include/py_exps.h index 0b56ae1..8d13379 100644 --- a/src/core_ffi/py_ffi/include/py_exps.h +++ b/src/core_ffi/py_ffi/include/py_exps.h @@ -18,4 +18,18 @@ private: std::string msg_; }; +class PyGroupExp final : std::exception { +public: + explicit PyGroupExp(const std::string_view &msg) : msg_(msg) {} + + ~PyGroupExp() override = default; + + [[nodiscard]] const char* what() const noexcept override { + return msg_.c_str(); + } + +private: + std::string msg_; +}; + } // namespace klotski::ffi diff --git a/src/core_ffi/py_ffi/include/py_group.h b/src/core_ffi/py_ffi/include/py_group.h new file mode 100644 index 0000000..6c78767 --- /dev/null +++ b/src/core_ffi/py_ffi/include/py_group.h @@ -0,0 +1,71 @@ +/// Klotski Engine Python FFI by Dnomd343 @2024 + +#pragma once + +#include +#include + +#include "group/group.h" + +#include "py_cases.h" + +#include "py_codec.h" + +namespace klotski::ffi { + +using klotski::cases::Group; +using klotski::cases::GroupUnion; + +class PyGroup { +public: +// [[nodiscard]] Toward toward() const; + + [[nodiscard]] uint32_t type_id() const; + + [[nodiscard]] uint32_t pattern_id() const; + + [[nodiscard]] std::string to_string() const; + + [[nodiscard]] PyCases cases() const; + + [[nodiscard]] uint32_t size() const; + +// [[nodiscard]] MirrorType mirror_type() const; + + [[nodiscard]] bool is_vertical_mirror() const; + + [[nodiscard]] bool is_horizontal_mirror() const; + + [[nodiscard]] PyGroup to_vertical_mirror() const; + + [[nodiscard]] PyGroup to_horizontal_mirror() const; + +private: + Group group_; +}; + +class PyGroupUnion { +public: + PyGroupUnion(uint8_t type_id); + PyGroupUnion(PyShortCode short_code); + PyGroupUnion(PyCommonCode common_code); + + [[nodiscard]] uint32_t value() const; + + [[nodiscard]] uint32_t size() const; + + [[nodiscard]] uint32_t group_num() const; + + [[nodiscard]] uint32_t pattern_num() const; + + [[nodiscard]] uint32_t max_group_size() const; + + [[nodiscard]] PyCases cases() const; + + [[nodiscard]] std::vector groups() const; + +private: + GroupUnion group_union_; +}; + +} // namespace klotski diff --git a/src/core_ffi/py_ffi/py_group.cc b/src/core_ffi/py_ffi/py_group.cc new file mode 100644 index 0000000..4e17632 --- /dev/null +++ b/src/core_ffi/py_ffi/py_group.cc @@ -0,0 +1,39 @@ +#include "include/py_group.h" + +using namespace klotski::ffi; + +uint32_t PyGroup::type_id() const { + return group_.type_id(); +} + +uint32_t PyGroup::pattern_id() const { + return group_.pattern_id(); +} + +std::string PyGroup::to_string() const { + return group_.to_string(); +} + +PyCases PyGroup::cases() const { + return PyCases::from(group_.cases()); +} + +uint32_t PyGroup::size() const { + return group_.size(); +} + +bool PyGroup::is_vertical_mirror() const { + return group_.is_vertical_mirror(); +} + +bool PyGroup::is_horizontal_mirror() const { + return group_.is_horizontal_mirror(); +} + +PyGroup PyGroup::to_vertical_mirror() const { + return std::bit_cast(group_.to_vertical_mirror()); +} + +PyGroup PyGroup::to_horizontal_mirror() const { + return std::bit_cast(group_.to_horizontal_mirror()); +} diff --git a/src/core_ffi/py_ffi/py_group_union.cc b/src/core_ffi/py_ffi/py_group_union.cc new file mode 100644 index 0000000..48b4a41 --- /dev/null +++ b/src/core_ffi/py_ffi/py_group_union.cc @@ -0,0 +1,58 @@ +#include "include/py_group.h" + +#include "include/py_exps.h" + +using klotski::ffi::PyGroupExp; + +using klotski::ffi::PyGroupUnion; + +static klotski::cases::GroupUnion convert(uint8_t type_id) { + auto group_union = klotski::cases::GroupUnion::create(type_id); + if (!group_union.has_value()) { + throw PyGroupExp(std::format("invalid type id -> {}", type_id)); + } + return group_union.value(); +} + +PyGroupUnion::PyGroupUnion(uint8_t type_id) : + group_union_(convert(type_id)) {} + +PyGroupUnion::PyGroupUnion(PyShortCode short_code) : + group_union_(GroupUnion::from_short_code(std::bit_cast(short_code))) {} + +PyGroupUnion::PyGroupUnion(PyCommonCode common_code) : + group_union_(GroupUnion::from_common_code(std::bit_cast(common_code))) {} + +uint32_t PyGroupUnion::value() const { + return group_union_.unwrap(); +} + +uint32_t PyGroupUnion::size() const { + return group_union_.size(); +} + +uint32_t PyGroupUnion::group_num() const { + return group_union_.group_num(); +} + +uint32_t PyGroupUnion::pattern_num() const { + return group_union_.pattern_num(); +} + +uint32_t PyGroupUnion::max_group_size() const { + return group_union_.max_group_size(); +} + +klotski::ffi::PyCases PyGroupUnion::cases() const { + auto cases = PyCases::from(group_union_.cases()); + return cases; +} + +std::vector PyGroupUnion::groups() const { + std::vector groups; + groups.reserve(group_num()); + for (auto group : group_union_.groups()) { + groups.emplace_back(std::bit_cast(group)); + } + return groups; +}