Browse Source

feat: add python support of `FastCal`

master
Dnomd343 2 weeks ago
parent
commit
dcbe6c8d3f
  1. 2
      src/core_ffi/py_ffi/CMakeLists.txt
  2. 12
      src/core_ffi/py_ffi/binder/fast_cal.cc
  3. 4
      src/core_ffi/py_ffi/include/binder.h
  4. 2
      src/core_ffi/py_ffi/include/exception.h
  5. 63
      src/core_ffi/py_ffi/include/py_ffi/fast_cal.h
  6. 8
      src/core_ffi/py_ffi/klotski.cc
  7. 1
      src/core_ffi/py_ffi/wrapper/fast_cal.cc

2
src/core_ffi/py_ffi/CMakeLists.txt

@ -11,12 +11,14 @@ pybind11_add_module(klotski_py
binder/short_code.cc binder/short_code.cc
binder/group_union.cc binder/group_union.cc
binder/group.cc binder/group.cc
binder/fast_cal.cc
wrapper/short_code.cc wrapper/short_code.cc
wrapper/common_codec.cc wrapper/common_codec.cc
wrapper/cases.cc wrapper/cases.cc
wrapper/group_union.cc wrapper/group_union.cc
wrapper/group.cc wrapper/group.cc
wrapper/fast_cal.cc
) )
target_include_directories(klotski_py PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include) target_include_directories(klotski_py PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_link_libraries(klotski_py PRIVATE klotski::core) target_link_libraries(klotski_py PRIVATE klotski::core)

12
src/core_ffi/py_ffi/binder/fast_cal.cc

@ -0,0 +1,12 @@
#include <py_ffi/fast_cal.h>
#include "binder.h"
void bind_fast_cal(const py::module_ &m) {
py::class_<PyFastCal>(m, "FastCal")
.def(py::init<PyCommonCode>())
.def("solve", &PyFastCal::solve)
.def("exports", &PyFastCal::exports)
.def("build_all", &PyFastCal::build_all)
.def("backtrack", &PyFastCal::backtrack);
}

4
src/core_ffi/py_ffi/include/binder.h

@ -10,6 +10,7 @@ namespace py = pybind11;
#include "py_ffi/group.h" #include "py_ffi/group.h"
#include "py_ffi/short_code.h" #include "py_ffi/short_code.h"
#include "py_ffi/common_code.h" #include "py_ffi/common_code.h"
#include "py_ffi/fast_cal.h"
using klotski::ffi::PyCases; using klotski::ffi::PyCases;
using klotski::ffi::PyCasesIter; using klotski::ffi::PyCasesIter;
@ -17,6 +18,7 @@ using klotski::ffi::PyShortCode;
using klotski::ffi::PyCommonCode; using klotski::ffi::PyCommonCode;
using klotski::ffi::PyGroupUnion; using klotski::ffi::PyGroupUnion;
using klotski::ffi::PyGroup; using klotski::ffi::PyGroup;
using klotski::ffi::PyFastCal;
void bind_cases(const py::module_ &m); void bind_cases(const py::module_ &m);
void bind_short_code(const py::module_ &m); void bind_short_code(const py::module_ &m);
@ -24,3 +26,5 @@ void bind_common_code(const py::module_ &m);
void bind_group_union(const py::module_ &m); void bind_group_union(const py::module_ &m);
void bind_group(const py::module_ &m); void bind_group(const py::module_ &m);
void bind_fast_cal(const py::module_ &m);

2
src/core_ffi/py_ffi/include/exception.h

@ -1,5 +1,3 @@
/// Klotski Engine Python FFI by Dnomd343 @2024
#pragma once #pragma once
#include <string> #include <string>

63
src/core_ffi/py_ffi/include/py_ffi/fast_cal.h

@ -0,0 +1,63 @@
/// Klotski Engine Python FFI by Dnomd343 @2024
#pragma once
#include <fast_cal/fast_cal.h>
#include "py_ffi/common_code.h"
namespace klotski::ffi {
using fast_cal::FastCal;
class PyFastCal {
public:
explicit PyFastCal(PyCommonCode code)
: fast_cal_(FastCal(std::bit_cast<CommonCode>(code).to_raw_code())) {}
// TODO: export solution path directly
std::optional<PyCommonCode> solve() {
auto tmp = fast_cal_.solve();
if (tmp.has_value()) {
return std::bit_cast<PyCommonCode>(tmp.value().to_common_code());
}
return std::nullopt;
}
// std::vector<PyCommonCode> solve_multi();
void build_all() {
fast_cal_.build_all();
}
[[nodiscard]] std::vector<PyCommonCode> backtrack(PyCommonCode code) const {
std::vector<PyCommonCode> path;
for (auto x : fast_cal_.backtrack(std::bit_cast<CommonCode>(code).to_raw_code())) {
path.emplace_back(std::bit_cast<PyCommonCode>(x.to_common_code()));
}
return path;
}
[[nodiscard]] std::vector<std::vector<PyCommonCode>> exports() const {
std::vector<std::vector<PyCommonCode>> result;
const auto data = fast_cal_.exports();
result.reserve(data.size());
for (const auto &layer_raw : data) {
std::vector<PyCommonCode> layer;
layer.reserve(layer_raw.size());
for (auto x : layer_raw) {
layer.emplace_back(std::bit_cast<PyCommonCode>(x.to_common_code()));
}
result.emplace_back(layer);
}
return result;
}
private:
// TODO: add double call protect
FastCal fast_cal_;
};
} // namespace klotski::ffi

8
src/core_ffi/py_ffi/klotski.cc

@ -12,16 +12,9 @@
namespace py = pybind11; namespace py = pybind11;
// using klotski::ffi::PyCases;
// using klotski::ffi::PyShortCode;
// using klotski::ffi::PyCommonCode;
using klotski::ffi::PyExc_CodecError; using klotski::ffi::PyExc_CodecError;
using klotski::ffi::PyExc_GroupError; using klotski::ffi::PyExc_GroupError;
// using klotski::ffi::PyGroup;
// using klotski::ffi::PyGroupUnion;
#include "group/group.h" #include "group/group.h"
#include "all_cases/all_cases.h" #include "all_cases/all_cases.h"
@ -47,6 +40,7 @@ PYBIND11_MODULE(klotski, m) {
bind_common_code(m); bind_common_code(m);
bind_group(m); bind_group(m);
bind_group_union(m); bind_group_union(m);
bind_fast_cal(m);
m.attr("__version__") = "version field"; m.attr("__version__") = "version field";
} }

1
src/core_ffi/py_ffi/wrapper/fast_cal.cc

@ -0,0 +1 @@
#include "py_ffi/fast_cal.h"
Loading…
Cancel
Save