Working line iterator, and mostly working flood iterator that should be good enough for world gen.
This commit is contained in:
parent
1295e9631d
commit
d4b6c35120
5 changed files with 91 additions and 39 deletions
|
@ -20,7 +20,7 @@ namespace lighting {
|
||||||
|
|
||||||
const int wall_light = source.strength + WALL_LIGHT_LEVEL;
|
const int wall_light = source.strength + WALL_LIGHT_LEVEL;
|
||||||
for(auto point : has_light) {
|
for(auto point : has_light) {
|
||||||
for(matrix::in_box it{$lightmap, point.x, point.y, 1}; it.next();) {
|
for(matrix::compass it{$lightmap, point.x, point.y}; it.next();) {
|
||||||
if($paths.$paths[it.y][it.x] == WALL_PATH_LIMIT) {
|
if($paths.$paths[it.y][it.x] == WALL_PATH_LIMIT) {
|
||||||
$lightmap[it.y][it.x] = light_level(wall_light, point.x, point.y);
|
$lightmap[it.y][it.x] = light_level(wall_light, point.x, point.y);
|
||||||
}
|
}
|
||||||
|
|
41
matrix.cpp
41
matrix.cpp
|
@ -2,6 +2,8 @@
|
||||||
#include "constants.hpp"
|
#include "constants.hpp"
|
||||||
#include "dbc.hpp"
|
#include "dbc.hpp"
|
||||||
#include <fmt/core.h>
|
#include <fmt/core.h>
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
using namespace fmt;
|
using namespace fmt;
|
||||||
using std::min, std::max;
|
using std::min, std::max;
|
||||||
|
@ -114,7 +116,7 @@ namespace matrix {
|
||||||
|
|
||||||
flood::flood(Matrix &mat, Point start, int old_val, int new_val) :
|
flood::flood(Matrix &mat, Point start, int old_val, int new_val) :
|
||||||
mat(mat), start(start), old_val(old_val), new_val(new_val),
|
mat(mat), start(start), old_val(old_val), new_val(new_val),
|
||||||
dirs{mat, start.x, start.y}
|
x(start.x), y(start.y), dirs{mat, start.x, start.y}
|
||||||
{
|
{
|
||||||
dbc::check(old_val != new_val, "what you doing?");
|
dbc::check(old_val != new_val, "what you doing?");
|
||||||
current_loc = start;
|
current_loc = start;
|
||||||
|
@ -133,8 +135,8 @@ namespace matrix {
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the next thing
|
// get the next thing
|
||||||
if(mat[dirs.y][dirs.x] == old_val) {
|
if(mat[dirs.y][dirs.x] <= old_val) {
|
||||||
mat[dirs.y][dirs.x] += new_val;
|
mat[dirs.y][dirs.x] = new_val;
|
||||||
x = dirs.x;
|
x = dirs.x;
|
||||||
y = dirs.y;
|
y = dirs.y;
|
||||||
|
|
||||||
|
@ -147,20 +149,30 @@ namespace matrix {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool flood::next_working() {
|
line::line(Point start, Point end) :
|
||||||
if(!q.empty()) {
|
x(start.x), y(start.y),
|
||||||
auto current_loc = q.front();
|
x1(end.x), y1(end.y)
|
||||||
q.pop();
|
{
|
||||||
|
dx = std::abs(x1 - x);
|
||||||
|
sx = x < x1 ? 1 : -1;
|
||||||
|
dy = std::abs(y1 - y) * -1;
|
||||||
|
sy = y < y1 ? 1 : -1;
|
||||||
|
error = dx + dy;
|
||||||
|
}
|
||||||
|
|
||||||
for(matrix::in_box box{mat, current_loc.x, current_loc.y, 1};
|
bool line::next() {
|
||||||
box.next();)
|
if(x != x1 || y != y1) {
|
||||||
{
|
int e2 = 2 * error;
|
||||||
if(mat[box.y][box.x] == old_val) {
|
|
||||||
mat[box.y][box.x] += new_val;
|
if(e2 >= dy) {
|
||||||
q.push({.x=box.x, .y=box.y});
|
error = error + dy;
|
||||||
}
|
x = x + sx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(e2 <= dx) {
|
||||||
|
error = error + dx;
|
||||||
|
y = y + sy;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -186,5 +198,4 @@ namespace matrix {
|
||||||
if(it.row) print("\n");
|
if(it.row) print("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
14
matrix.hpp
14
matrix.hpp
|
@ -94,4 +94,18 @@ namespace matrix {
|
||||||
bool next_working();
|
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();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,10 @@ TEST_CASE("lighting a map works", "[lighting]") {
|
||||||
lr.clear_light_target(light1);
|
lr.clear_light_target(light1);
|
||||||
lr.clear_light_target(light2);
|
lr.clear_light_target(light2);
|
||||||
|
|
||||||
const auto &lighting = lr.lighting();
|
Matrix &lighting = lr.lighting();
|
||||||
|
|
||||||
|
matrix::dump("WALLS=====", map.walls());
|
||||||
|
matrix::dump("LIGHT PATHS======", lr.$paths.$paths);
|
||||||
|
|
||||||
// confirm light is set at least at and around the two points
|
// confirm light is set at least at and around the two points
|
||||||
REQUIRE(lighting[light1.y][light1.x] == lighting::LEVELS[source1.strength]);
|
REQUIRE(lighting[light1.y][light1.x] == lighting::LEVELS[source1.strength]);
|
||||||
|
|
|
@ -163,7 +163,7 @@ TEST_CASE("thrash compass iterators", "[matrix:compass]") {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("prototype flood algorithm", "[matrix:flood]") {
|
TEST_CASE("prototype flood algorithm", "[matrix:flood]") {
|
||||||
for(int count = 0; count < 1; count++) {
|
for(int count = 0; count < 1000; count++) {
|
||||||
size_t width = Random::uniform<size_t>(10, 25);
|
size_t width = Random::uniform<size_t>(10, 25);
|
||||||
size_t height = Random::uniform<size_t>(10, 33);
|
size_t height = Random::uniform<size_t>(10, 33);
|
||||||
|
|
||||||
|
@ -171,32 +171,56 @@ TEST_CASE("prototype flood algorithm", "[matrix:flood]") {
|
||||||
WorldBuilder builder(map);
|
WorldBuilder builder(map);
|
||||||
builder.generate();
|
builder.generate();
|
||||||
|
|
||||||
REQUIRE(map.room_count() > 0);
|
if(map.room_count() < 2) continue;
|
||||||
|
|
||||||
Point start = map.place_entity(map.room_count() / 2);
|
Point start = map.place_entity(map.room_count() / 2);
|
||||||
|
map.set_target(start);
|
||||||
|
map.make_paths();
|
||||||
|
Matrix result = map.paths();
|
||||||
|
|
||||||
// BUG: place_entity should not put things in walls
|
// matrix::dump("WALLS BEFORE FLOOD", result, start.x, start.y);
|
||||||
map.$walls[start.y][start.x] = 0;
|
|
||||||
|
|
||||||
matrix::dump("WALLS BEFORE FLOOD", map.walls(), start.x, start.y);
|
for(matrix::flood it{result, start, 3, 15}; it.next();) {
|
||||||
|
REQUIRE(matrix::inbounds(result, it.x, it.y));
|
||||||
/*
|
result[it.y][it.x] = 15;
|
||||||
for(matrix::flood it{map.$walls, start, 0, 10}; it.next_working(); tick++) {
|
|
||||||
println("TEST WORKING");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
for(matrix::flood it{map.$walls, start, 0, 15}; it.next();) {
|
|
||||||
REQUIRE(matrix::inbounds(map.$walls, it.x, it.y));
|
|
||||||
map.$walls[it.y][it.x] = 15;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
matrix::dump("WALLS AFTER FLOOD", map.walls(), start.x, start.y);
|
// matrix::dump("WALLS AFTER FLOOD", result, start.x, start.y);
|
||||||
|
}
|
||||||
// confirm that everything is 1 or 2 which confirms
|
}
|
||||||
// every cell possible is visited and nothing is visited twice
|
|
||||||
for(matrix::each_cell it{map.$walls}; it.next();) {
|
TEST_CASE("prototype line algorithm", "[matrix:line]") {
|
||||||
REQUIRE(map.$walls[it.y][it.x] <= 15);
|
size_t width = Random::uniform<size_t>(10, 12);
|
||||||
}
|
size_t height = Random::uniform<size_t>(10, 15);
|
||||||
|
Map map(width,height);
|
||||||
|
// create a target for the paths
|
||||||
|
Point start{.x=map.width() / 2, .y=map.height()/2};
|
||||||
|
|
||||||
|
for(matrix::in_box box{map.walls(), start.x, start.y, 3};
|
||||||
|
box.next();)
|
||||||
|
{
|
||||||
|
Matrix result = map.walls();
|
||||||
|
result[start.y][start.x] = 1;
|
||||||
|
Point end{.x=box.x, .y=box.y};
|
||||||
|
|
||||||
|
for(matrix::line it{start, end}; it.next();)
|
||||||
|
{
|
||||||
|
REQUIRE(map.inmap(it.x, it.y));
|
||||||
|
result[it.y][it.x] = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
result[start.y][start.x] = 15;
|
||||||
|
|
||||||
|
// matrix::dump("RESULT AFTER LINE", result, end.x, end.y);
|
||||||
|
|
||||||
|
bool f_found = false;
|
||||||
|
for(matrix::each_cell it{result}; it.next();) {
|
||||||
|
if(result[it.y][it.x] == 15) {
|
||||||
|
f_found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
REQUIRE(f_found);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue