diff --git a/CMakeLists.txt b/CMakeLists.txt index 72b2372..ccc5364 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 2.8) include_directories("${PROJECT_SOURCE_DIR}/include/") add_definitions(-std=c++1y) -find_package(Boost REQUIRED COMPONENTS program_options system) +find_package(Boost REQUIRED COMPONENTS program_options serialization system) include_directories(SYSTEM ${Boost_INCLUDE_DIRS}) set(libs ${libs} ${Boost_LIBRARIES}) diff --git a/include/analyzed_grid.hpp b/include/analyzed_grid.hpp new file mode 100644 index 0000000..bcef08c --- /dev/null +++ b/include/analyzed_grid.hpp @@ -0,0 +1,42 @@ +#pragma once + +#include "dynamic_grid.hpp" +#include "solver.hpp" +#include "rules.hpp" + +#include +#include +#include + +#include + +template +struct AnalyzedGrid { + Grid grid; + Solution analysis; + BasicRules rules; + +private: + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int version){ + ar & grid & analysis.solution_traces; + } +}; + +inline auto grid_from_file(std::string file_path){ + std::ifstream file(file_path); + boost::archive::text_iarchive ar(file); + + AnalyzedGrid ret; + ar >> ret; + return ret; +} + +inline auto grid_to_file(AnalyzedGrid const & grid, std::string file_path){ + std::ofstream file(file_path); + boost::archive::text_oarchive ar(file); + + ar << grid; +} + diff --git a/include/dynamic_grid.hpp b/include/dynamic_grid.hpp index 6452e40..5c7eb20 100644 --- a/include/dynamic_grid.hpp +++ b/include/dynamic_grid.hpp @@ -2,6 +2,10 @@ #include "utilities.hpp" +#include +#include +#include + #include #include #include @@ -17,6 +21,8 @@ struct DynamicGrid{ DynamicGrid(int width, int height, std::vector && data); + DynamicGrid() = default; + //! \brief Returns an array of all valid positions (may be empty) auto const & all_positions() const{ return positions; @@ -64,6 +70,9 @@ struct DynamicGrid{ //! \brief Pretty prints grid to out void print(std::ostream& out) const; + //! \brief Return a hash of the grid (hopefully unique) + size_t hash() const; + private: int W; int H; @@ -78,6 +87,16 @@ private: //! \brief Returns true if the whole column at x is empty auto empty_column(int x); + + friend class boost::serialization::access; + + //! \brief Serializes the grid + template + void serialize(Archive & ar, const unsigned int version){ + ar & W & H & grid & positions; + // archiving positions is redundant (I'm being lazy here) + // consider make_nvp for readable json + } }; template diff --git a/include/rules.hpp b/include/rules.hpp index b46797d..2eea107 100644 --- a/include/rules.hpp +++ b/include/rules.hpp @@ -1,6 +1,7 @@ #pragma once struct BasicRules { + BasicRules() = default; BasicRules(unsigned int minimal_cluster_size) : min_size(minimal_cluster_size) {} @@ -15,4 +16,10 @@ struct BasicRules { private: unsigned int min_size; + + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int version){ + ar & min_size; + } }; diff --git a/lib/dynamic_grid.cpp b/lib/dynamic_grid.cpp index 900f68a..55b4283 100644 --- a/lib/dynamic_grid.cpp +++ b/lib/dynamic_grid.cpp @@ -1,6 +1,7 @@ #include "dynamic_grid.hpp" #include "colored_output.hpp" +#include #include //! \brief Helper function for all_positions() @@ -95,3 +96,13 @@ void DynamicGrid::print(std::ostream& out) const { } } } + +size_t DynamicGrid::hash() const { + std::string hs(W*H, '\0'); + auto it = hs.begin(); + for(auto&&p : all_positions()){ + *it++ = static_cast(get(p)); + } + + return std::hash()(hs); +} diff --git a/src/PuzzleWuzzleGenerator.cpp b/src/PuzzleWuzzleGenerator.cpp index cb41113..d2ebdd7 100644 --- a/src/PuzzleWuzzleGenerator.cpp +++ b/src/PuzzleWuzzleGenerator.cpp @@ -2,6 +2,7 @@ #include "clusters.hpp" #include "solver.hpp" #include "rules.hpp" +#include "analyzed_grid.hpp" #include @@ -68,6 +69,13 @@ int main(int argc, char** argv){ std::cout << "no solutions\n"; } } + + std::string s = solution.solution_traces.empty() ? "u" : "s"; + std::string filename = "levels/" + std::to_string(w) + "_" + std::to_string(h) + "_" + std::to_string(c) + "_" + s + "_" + std::to_string(field.hash()) + ".lvl"; + grid_to_file({std::move(field), std::move(solution), rules}, filename); + if(verbose){ + std::cout << filename << "\n\n"; + } } std::cout << solvable << " solvable\n";