diff --git a/src/algos/maze.cpp b/src/algos/maze.cpp index 48e7337..861a3e0 100644 --- a/src/algos/maze.cpp +++ b/src/algos/maze.cpp @@ -452,4 +452,46 @@ namespace maze { // didn't find a way to make it valid return now_valid; } + + std::pair script(Map& map, nlohmann::json& config) { + maze::Builder maze(map); + + for(auto& action : config) { + std::string aname = action["action"]; + fmt::println("ACTION {}", aname); + + if(aname == "hunt_and_kill") { + maze.hunt_and_kill(); + } else if(aname == "clear") { + maze.clear(); + } else if(aname == "inner_box") { + std::vector data = action["data"]; + maze.inner_box(data[0], data[1]); + } else if(aname == "randomize_rooms") { + std::vector data = action["data"]; + maze.randomize_rooms(data[0]); + } else if(aname == "open_box") { + std::vector data = action["data"]; + maze.open_box(data[0]); + } else if(aname == "make_doors") { + maze.make_doors(); + } else if(aname == "divide") { + std::vector data = action["data"]; + maze.divide({data[0], data[1]}, {data[2], data[3]}); + } else if(aname == "inner_donut") { + std::vector data = action["data"]; + maze.inner_donut(data[0], data[1]); + } else if(aname == "remove_dead_ends") { + maze.remove_dead_ends(); + } else if(aname == "enclose") { + maze.enclose(); + } else { + dbc::sentinel(fmt::format("Invalid maze action {}", aname)); + } + } + + bool valid = maze.repair(); + + return {maze, valid}; + } } diff --git a/src/algos/maze.hpp b/src/algos/maze.hpp index 9d96182..ffb4de3 100644 --- a/src/algos/maze.hpp +++ b/src/algos/maze.hpp @@ -46,4 +46,6 @@ namespace maze { void punch_dead_end(size_t at_x, size_t at_y, size_t x, size_t y); void in_bounds(size_t x, size_t y); }; + + std::pair script(Map& map, nlohmann::json& config); } diff --git a/tests/mazes.cpp b/tests/mazes.cpp index 476f059..cfd3591 100644 --- a/tests/mazes.cpp +++ b/tests/mazes.cpp @@ -7,7 +7,7 @@ #include "algos/maze.hpp" #include "algos/stats.hpp" -#define DUMP 1 +#define DUMP 0 using std::string; using matrix::Matrix; @@ -130,21 +130,46 @@ TEST_CASE("hunt-and-kill validator", "[mazes]") { maze.make_doors(); valid = maze.repair(); - if(i == 9) { - if(valid) { - maze.dump("VALIDATED"); - } else { - matrix::dump("PATHING", maze.$paths.$paths); - } + if(i == 9 && DUMP) { + maze.dump(valid ? "VALIDATED" : "FAILED!"); } door_prob.sample(valid); } while(!valid); - door_prob.dump(); + if(DUMP) door_prob.dump(); mofm.sample(door_prob.mean()); } - fmt::println("FINAL m-of-m"); - mofm.dump(); + if(DUMP) { + fmt::println("FINAL m-of-m"); + mofm.dump(); + } + REQUIRE(mofm.mean() > 0.20); } + + +TEST_CASE("hunt-and-kill scripting", "[mazes]") { + using namespace nlohmann::literals; + + auto script = R"( + [ + {"action": "hunt_and_kill"}, + {"action": "clear"}, + {"action": "inner_box", "data": [6, 4]}, + {"action": "randomize_rooms", "data": [4]}, + {"action": "divide", "data": [3, 3, 10, 10]}, + {"action": "inner_donut", "data": [5.5,4.5]}, + {"action": "hunt_and_kill"}, + {"action": "open_box", "data": [6]}, + {"action": "remove_dead_ends"}, + {"action": "make_doors"} + ] + )"_json; + + + Map map(33, 33); + auto [maze, valid] = maze::script(map, script); + maze.dump("SCRIPTED"); + REQUIRE(valid == true); +}