Took the plunge and converted my 'shaperators' into templates so they'll work on any 'matrix-like' thing.
This commit is contained in:
parent
5adeb4e078
commit
4cb41a61db
5 changed files with 182 additions and 192 deletions
139
matrix.cpp
139
matrix.cpp
|
@ -8,122 +8,8 @@
|
|||
using namespace fmt;
|
||||
using std::min, std::max;
|
||||
|
||||
inline size_t next_x(size_t x, size_t width) {
|
||||
return (x + 1) * ((x + 1) < width);
|
||||
}
|
||||
|
||||
inline size_t next_y(size_t x, size_t y) {
|
||||
return y + (x == 0);
|
||||
}
|
||||
|
||||
inline bool at_end(size_t y, size_t height) {
|
||||
return y < height;
|
||||
}
|
||||
|
||||
inline bool end_row(size_t x, size_t width) {
|
||||
return x == width - 1;
|
||||
}
|
||||
|
||||
|
||||
namespace matrix {
|
||||
|
||||
each_cell::each_cell(Matrix &mat)
|
||||
{
|
||||
height = mat.size();
|
||||
width = mat[0].size();
|
||||
}
|
||||
|
||||
bool each_cell::next() {
|
||||
x = next_x(x, width);
|
||||
y = next_y(x, y);
|
||||
return at_end(y, height);
|
||||
}
|
||||
|
||||
each_row::each_row(Matrix &mat) :
|
||||
$mat(mat)
|
||||
{
|
||||
height = $mat.size();
|
||||
width = $mat[0].size();
|
||||
}
|
||||
|
||||
bool each_row::next() {
|
||||
x = next_x(x, width);
|
||||
y = next_y(x, y);
|
||||
row = end_row(x, width);
|
||||
return at_end(y, height);
|
||||
}
|
||||
|
||||
in_box::in_box(Matrix &mat, size_t at_x, size_t at_y, size_t size) :
|
||||
from_x(at_x), from_y(at_y)
|
||||
{
|
||||
size_t h = matrix::height(mat);
|
||||
size_t w = matrix::width(mat);
|
||||
|
||||
// keeps it from going below zero
|
||||
// need extra -1 to compensate for the first next()
|
||||
left = max(from_x, size) - size;
|
||||
x = left - 1; // must be -1 for next()
|
||||
// keeps it from going above width
|
||||
right = min(from_x + size + 1, w);
|
||||
|
||||
// same for these two
|
||||
top = max(from_y, size) - size;
|
||||
y = top - (left == 0);
|
||||
bottom = min(from_y + size + 1, h);
|
||||
}
|
||||
|
||||
bool in_box::next() {
|
||||
// calc next but allow to go to 0 for next
|
||||
x = next_x(x, right);
|
||||
// x will go to 0, which signals new line
|
||||
y = next_y(x, y); // this must go here
|
||||
// if x==0 then this moves it to min_x
|
||||
x = max(x, left);
|
||||
// and done
|
||||
|
||||
return at_end(y, bottom);
|
||||
}
|
||||
|
||||
float in_box::distance() {
|
||||
int dx = from_x - x;
|
||||
int dy = from_y - y;
|
||||
|
||||
return sqrt((dx * dx) + (dy * dy));
|
||||
}
|
||||
|
||||
void in_box::dump() {
|
||||
println("BOX: x={},y={}; left={},right={}; top={},bottom={}",
|
||||
x, y, left, right, top, bottom);
|
||||
}
|
||||
|
||||
compass::compass(Matrix &mat, size_t x, size_t y) :
|
||||
x(x), y(y)
|
||||
{
|
||||
array<int, 4> x_in{0, 1, 0, -1};
|
||||
array<int, 4> y_in{-1, 0, 1, 0};
|
||||
|
||||
for(size_t i = 0; i < 4; i++) {
|
||||
int nx = x + x_in[i];
|
||||
int ny = y + y_in[i];
|
||||
if(matrix::inbounds(mat, nx, ny)) {
|
||||
x_dirs[max_dirs] = nx;
|
||||
y_dirs[max_dirs] = ny;
|
||||
max_dirs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool compass::next() {
|
||||
dir++;
|
||||
if(dir < max_dirs) {
|
||||
x = x_dirs[dir];
|
||||
y = y_dirs[dir];
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
flood::flood(Matrix &mat, Point start, int old_val, int new_val) :
|
||||
mat(mat), start(start), old_val(old_val), new_val(new_val),
|
||||
x(start.x), y(start.y), dirs{mat, start.x, start.y}
|
||||
|
@ -189,31 +75,6 @@ namespace matrix {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
circle::circle(Matrix &mat, Point center, float radius) :
|
||||
center_x(center.x), center_y(center.y), radius(radius)
|
||||
{
|
||||
width = matrix::width(mat);
|
||||
height = matrix::height(mat);
|
||||
top = max(int(floor(center_y - radius)), 0);
|
||||
bottom = min(int(floor(center_y + radius)), height - 1);
|
||||
|
||||
y = top;
|
||||
}
|
||||
|
||||
bool circle::next() {
|
||||
y++;
|
||||
if(y <= bottom) {
|
||||
dy = y - center_y;
|
||||
dx = floor(sqrt(radius * radius - dy * dy));
|
||||
left = max(0, int(center_x) - dx);
|
||||
right = min(width, int(center_x) + dx + 1);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void dump(const std::string &msg, Matrix &map, int show_x, int show_y) {
|
||||
println("----------------- {}", msg);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue