(committing very old stuff) No clue what I've changed here
This commit is contained in:
parent
30f2101edd
commit
7273471d43
8 changed files with 98 additions and 17 deletions
|
@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 2.8)
|
||||||
include_directories("${PROJECT_SOURCE_DIR}/include/")
|
include_directories("${PROJECT_SOURCE_DIR}/include/")
|
||||||
add_definitions(-std=c++1y)
|
add_definitions(-std=c++1y)
|
||||||
|
|
||||||
find_package(Boost REQUIRED COMPONENTS program_options serialization system)
|
find_package(Boost REQUIRED COMPONENTS filesystem program_options serialization system)
|
||||||
include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
|
include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
|
||||||
set(libs ${libs} ${Boost_LIBRARIES})
|
set(libs ${libs} ${Boost_LIBRARIES})
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
struct BasicRulesBase {
|
struct BasicRulesBase {
|
||||||
unsigned int min_size;
|
unsigned int min_size;
|
||||||
|
@ -51,23 +52,23 @@ struct DynamicGridBase {
|
||||||
int W;
|
int W;
|
||||||
int H;
|
int H;
|
||||||
std::vector<int> grid;
|
std::vector<int> grid;
|
||||||
std::vector<Position> positions;
|
|
||||||
|
|
||||||
DynamicGridBase() = default;
|
DynamicGridBase() = default;
|
||||||
DynamicGridBase(int width, int height, std::vector<int> && data)
|
DynamicGridBase(int width, int height, std::vector<int> && data)
|
||||||
: W(width), H(height), grid(std::move(data))
|
: W(width), H(height), grid(std::move(data))
|
||||||
{}
|
{
|
||||||
|
assert(W*H == grid.size());
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class boost::serialization::access;
|
friend class boost::serialization::access;
|
||||||
template<class Archive>
|
template<class Archive>
|
||||||
void serialize(Archive & ar, const unsigned int /*version*/){
|
void serialize(Archive & ar, const unsigned int /*version*/){
|
||||||
ar & W & H & grid & positions;
|
ar & W & H & grid;
|
||||||
// archiving positions is redundant (I'm being lazy here)
|
assert(W*H == grid.size());
|
||||||
// consider make_nvp for readable json
|
// consider make_nvp for readable json
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DynamicGrid;
|
AnalyzedGrid<DynamicGridBase> grid_from_file(std::string file_path);
|
||||||
AnalyzedGrid<DynamicGrid> grid_from_file(std::string file_path);
|
void grid_to_file(AnalyzedGrid<DynamicGridBase> const & grid, std::string file_path);
|
||||||
void grid_to_file(AnalyzedGrid<DynamicGrid> const & grid, std::string file_path);
|
|
||||||
|
|
|
@ -16,9 +16,9 @@
|
||||||
struct DynamicGrid : public DynamicGridBase {
|
struct DynamicGrid : public DynamicGridBase {
|
||||||
using Position = DynamicGridBase::Position;
|
using Position = DynamicGridBase::Position;
|
||||||
|
|
||||||
DynamicGrid(int width, int height, std::vector<int> && data);
|
|
||||||
|
|
||||||
DynamicGrid() = default;
|
DynamicGrid() = default;
|
||||||
|
DynamicGrid(DynamicGridBase&& b);
|
||||||
|
DynamicGrid(int width, int height, std::vector<int> && data);
|
||||||
|
|
||||||
//! \brief Returns an array of all valid positions (may be empty)
|
//! \brief Returns an array of all valid positions (may be empty)
|
||||||
auto const & all_positions() const{
|
auto const & all_positions() const{
|
||||||
|
@ -71,6 +71,9 @@ struct DynamicGrid : public DynamicGridBase {
|
||||||
size_t hash() const;
|
size_t hash() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Optimization: caching the positions for the functions all_positions.
|
||||||
|
std::vector<Position> positions;
|
||||||
|
|
||||||
//! \brief Single vertical collapsing step
|
//! \brief Single vertical collapsing step
|
||||||
auto vcollapse();
|
auto vcollapse();
|
||||||
|
|
||||||
|
|
|
@ -5,16 +5,16 @@
|
||||||
#include <boost/archive/text_iarchive.hpp>
|
#include <boost/archive/text_iarchive.hpp>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
AnalyzedGrid<DynamicGrid> grid_from_file(std::string file_path){
|
AnalyzedGrid<DynamicGridBase> grid_from_file(std::string file_path){
|
||||||
std::ifstream file(file_path);
|
std::ifstream file(file_path);
|
||||||
boost::archive::text_iarchive ar(file);
|
boost::archive::text_iarchive ar(file);
|
||||||
|
|
||||||
AnalyzedGrid<DynamicGrid> ret;
|
AnalyzedGrid<DynamicGridBase> ret;
|
||||||
ar >> ret;
|
ar >> ret;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void grid_to_file(const AnalyzedGrid<DynamicGrid>& grid, std::string file_path){
|
void grid_to_file(const AnalyzedGrid<DynamicGridBase>& grid, std::string file_path){
|
||||||
std::ofstream file(file_path);
|
std::ofstream file(file_path);
|
||||||
boost::archive::text_oarchive ar(file);
|
boost::archive::text_oarchive ar(file);
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,13 @@ static auto all_positions_impl(int W, int H) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DynamicGrid::DynamicGrid(DynamicGridBase&& b)
|
||||||
|
: DynamicGridBase(std::move(b)){
|
||||||
|
positions = all_positions_impl(W, H);
|
||||||
|
}
|
||||||
|
|
||||||
DynamicGrid::DynamicGrid(int width, int height, std::vector<int> && data)
|
DynamicGrid::DynamicGrid(int width, int height, std::vector<int> && data)
|
||||||
: DynamicGridBase(width, height, std::move(data)) {
|
: DynamicGridBase(width, height, std::move(data)) {
|
||||||
assert(grid.size() == W*H);
|
|
||||||
positions = all_positions_impl(W, H);
|
positions = all_positions_impl(W, H);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,14 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <random>
|
#include <random>
|
||||||
|
|
||||||
|
static Solutions<DynamicGridBase> slice(Solutions<DynamicGrid> && in){
|
||||||
|
return {std::move(in.traces)};
|
||||||
|
}
|
||||||
|
|
||||||
|
static AnalyzedGrid<DynamicGridBase> slice(AnalyzedGrid<DynamicGrid> && in){
|
||||||
|
return {std::move(in.grid), slice(std::move(in.solutions)), std::move(in.rules)};
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv){
|
int main(int argc, char** argv){
|
||||||
namespace po = boost::program_options;
|
namespace po = boost::program_options;
|
||||||
|
|
||||||
|
@ -68,7 +76,7 @@ int main(int argc, char** argv){
|
||||||
std::cout << filename << "\n\n";
|
std::cout << filename << "\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
grid_to_file({std::move(field), std::move(solutions), rules}, filename);
|
grid_to_file(slice({std::move(field), std::move(solutions), rules}), filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << solvable << " solvable (= " << 100 * solvable / double(solvable + unsolvable) << "%)\n";
|
std::cout << solvable << " solvable (= " << 100 * solvable / double(solvable + unsolvable) << "%)\n";
|
||||||
|
|
63
src/pack.cpp
Normal file
63
src/pack.cpp
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
#include "clusters.hpp"
|
||||||
|
#include "rules.hpp"
|
||||||
|
#include "data.hpp"
|
||||||
|
|
||||||
|
#include <boost/archive/text_oarchive.hpp>
|
||||||
|
#include <boost/program_options.hpp>
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
int main(int argc, char** argv){
|
||||||
|
namespace po = boost::program_options;
|
||||||
|
namespace fs = boost::filesystem;
|
||||||
|
|
||||||
|
// Describe program options
|
||||||
|
po::options_description opts;
|
||||||
|
opts.add_options()
|
||||||
|
("input,i", "input directory")
|
||||||
|
("output,o", po::value<std::string>(), "output file")
|
||||||
|
("add-unsolvables,u", po::bool_switch(), "also adds the unsolvable levels to the pack")
|
||||||
|
("help", po::bool_switch(), "show this help");
|
||||||
|
|
||||||
|
po::positional_options_description file_opts;
|
||||||
|
file_opts.add("input", 1);
|
||||||
|
|
||||||
|
// Parse and store them in a vm
|
||||||
|
po::variables_map vm;
|
||||||
|
po::store(po::command_line_parser(argc, argv).options(opts).positional(file_opts).run(), vm);
|
||||||
|
po::notify(vm);
|
||||||
|
|
||||||
|
if(vm["help"].as<bool>()){
|
||||||
|
std::cout << "Puzzle Wuzzle Level Packer, version " << __DATE__ << std::endl;
|
||||||
|
std::cout << "pack [-u] [-o <outputfile>] <directory>\n";
|
||||||
|
std::cout << opts << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs::path directory = vm["input"].as<std::string>();
|
||||||
|
fs::path output_file = directory.parent_path().string() + ".pck";
|
||||||
|
if(vm.count("output")) output_file = vm["output"].as<std::string>();
|
||||||
|
|
||||||
|
std::vector<AnalyzedGrid<DynamicGridBase>> pack;
|
||||||
|
std::cout << "Packing " << directory << " into " << output_file << std::endl;
|
||||||
|
bool unsolvables = vm["add-unsolvables"].as<bool>();
|
||||||
|
|
||||||
|
fs::directory_iterator eod;
|
||||||
|
for(fs::directory_iterator it(directory); it != eod; ++it){
|
||||||
|
auto && path = it->path();
|
||||||
|
if(path.extension() != ".lvl") continue;
|
||||||
|
|
||||||
|
auto level = grid_from_file(path.string());
|
||||||
|
if(!unsolvables && level.solutions.traces.empty()) continue;
|
||||||
|
|
||||||
|
pack.emplace_back(std::move(level));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ofstream file(output_file.string());
|
||||||
|
boost::archive::text_oarchive ar(file);
|
||||||
|
ar << pack;
|
||||||
|
|
||||||
|
std::cout << "Packed " << pack.size() << " levels" << std::endl;
|
||||||
|
}
|
|
@ -26,20 +26,22 @@ int main(int argc, char** argv){
|
||||||
|
|
||||||
if(vm["help"].as<bool>()){
|
if(vm["help"].as<bool>()){
|
||||||
std::cout << "Puzzle Wuzzle Replayer, version " << __DATE__ << std::endl;
|
std::cout << "Puzzle Wuzzle Replayer, version " << __DATE__ << std::endl;
|
||||||
|
std::cout << "replay <file>\n";
|
||||||
std::cout << opts << std::endl;
|
std::cout << opts << std::endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "= The puzzle =\n";
|
std::cout << "= The puzzle =\n";
|
||||||
auto level = grid_from_file(vm["file"].as<std::string>());
|
auto level = grid_from_file(vm["file"].as<std::string>());
|
||||||
level.grid.print(std::cout);
|
auto original_grid = DynamicGrid{std::move(level.grid)};
|
||||||
|
original_grid.print(std::cout);
|
||||||
std::cout << "has " << level.solutions.traces.size() << " solutions\n\n";
|
std::cout << "has " << level.solutions.traces.size() << " solutions\n\n";
|
||||||
|
|
||||||
int count = 1;
|
int count = 1;
|
||||||
for(auto && solution : level.solutions.traces){
|
for(auto && solution : level.solutions.traces){
|
||||||
std::cout << "= Solution " << count++ << " =\n";
|
std::cout << "= Solution " << count++ << " =\n";
|
||||||
|
|
||||||
auto grid = level.grid;
|
auto grid = original_grid;
|
||||||
grid.print(std::cout);
|
grid.print(std::cout);
|
||||||
|
|
||||||
for(auto && tap : solution){
|
for(auto && tap : solution){
|
||||||
|
|
Reference in a new issue