#pragma once #include #include #include #include #include #include "point.hpp" using fmt::println; namespace matrix { using std::vector, std::queue, std::array; typedef vector Row; typedef vector Matrix; struct each_cell { size_t x = ~0; size_t y = ~0; size_t width = 0; size_t height = 0; each_cell(Matrix &mat); bool next(); }; struct each_row { Matrix &$mat; size_t x = ~0; size_t y = ~0; size_t width = 0; size_t height = 0; bool row = false; each_row(Matrix &mat); bool next(); }; struct in_box { size_t x = 0; // these are set in constructor size_t y = 0; // again, no fancy ~ trick needed size_t left = 0; size_t top = 0; size_t right = 0; size_t bottom = 0; in_box(Matrix &mat, size_t x, size_t y, size_t size); bool next(); void dump(); }; struct compass { size_t x = 0; // these are set in constructor size_t y = 0; // again, no fancy ~ trick needed array x_dirs{0, 1, 0, -1}; array y_dirs{-1, 0, 1, 0}; size_t max_dirs=0; size_t dir = ~0; compass(Matrix &mat, size_t x, size_t y); bool next(); }; /* * Just a quick thing to reset a matrix to a value. */ inline void assign(Matrix &out, int new_value) { for(auto &row : out) { row.assign(row.size(), new_value); } } inline bool inbounds(Matrix &mat, size_t x, size_t y) { // since Point.x and Point.y are size_t any negatives are massive bool res = (y < mat.size()) && (x < mat[0].size()); return res; } void dump(const std::string &msg, Matrix &map, int show_x=-1, int show_y=-1); struct flood { Matrix &mat; Point start; int old_val; int new_val; queue q; Point current_loc; int x; int y; matrix::compass dirs; flood(Matrix &mat, Point start, int old_val, int new_val); bool next(); bool next_working(); }; }