|
|
|
#pragma once
|
|
|
|
#include <vector>
|
|
|
|
#include <queue>
|
|
|
|
#include <string>
|
|
|
|
#include <array>
|
|
|
|
#include <fmt/core.h>
|
|
|
|
#include "point.hpp"
|
|
|
|
|
|
|
|
using fmt::println;
|
|
|
|
|
|
|
|
namespace matrix {
|
|
|
|
using std::vector, std::queue, std::array;
|
|
|
|
|
|
|
|
typedef vector<int> Row;
|
|
|
|
typedef vector<Row> 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 from_x;
|
|
|
|
size_t from_y;
|
|
|
|
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);
|
|
|
|
float distance();
|
|
|
|
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<int, 4> x_dirs{0, 1, 0, -1};
|
|
|
|
array<int, 4> 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline size_t width(Matrix &mat) {
|
|
|
|
return mat[0].size();
|
|
|
|
}
|
|
|
|
|
|
|
|
inline size_t height(Matrix &mat) {
|
|
|
|
return mat.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
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<Point> 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();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct line {
|
|
|
|
int x;
|
|
|
|
int y;
|
|
|
|
int x1;
|
|
|
|
int y1;
|
|
|
|
int sx;
|
|
|
|
int sy;
|
|
|
|
int dx;
|
|
|
|
int dy;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
line(Point start, Point end);
|
|
|
|
bool next();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct circle {
|
|
|
|
float center_x;
|
|
|
|
float center_y;
|
|
|
|
float radius = 0.0f;
|
|
|
|
int y = 0;
|
|
|
|
int dx = 0;
|
|
|
|
int dy = 0;
|
|
|
|
int left = 0;
|
|
|
|
int right = 0;
|
|
|
|
int top = 0;
|
|
|
|
int bottom = 0;
|
|
|
|
int width = 0;
|
|
|
|
int height = 0;
|
|
|
|
|
|
|
|
circle(Matrix &mat, Point center, float radius);
|
|
|
|
void update();
|
|
|
|
bool next();
|
|
|
|
};
|
|
|
|
}
|