A bit of cleanup and refinement before refactoring.
This commit is contained in:
parent
e86d474c7c
commit
10c152a1c2
5 changed files with 63 additions and 37 deletions
7
Makefile
7
Makefile
|
@ -26,8 +26,11 @@ run: build test
|
||||||
clean:
|
clean:
|
||||||
meson compile --clean -C builddir
|
meson compile --clean -C builddir
|
||||||
|
|
||||||
debug:
|
debug_test: build
|
||||||
gdb --nx -x .gdbinit builddir/roguish.exe
|
gdb --nx -x .gdbinit --ex run --args builddir/runtests.exe
|
||||||
|
|
||||||
|
debug_run: build
|
||||||
|
gdb --nx -x .gdbinit --batch --ex run --ex bt --ex q --args builddir/roguish.exe
|
||||||
|
|
||||||
cover:
|
cover:
|
||||||
gcovr --html coverage/index.html --gcov-ignore-errors=no_working_dir_found --exclude "scratchpad.*" --exclude "subprojects.*" --html-nested coverage/
|
gcovr --html coverage/index.html --gcov-ignore-errors=no_working_dir_found --exclude "scratchpad.*" --exclude "subprojects.*" --html-nested coverage/
|
||||||
|
|
87
map.cpp
87
map.cpp
|
@ -64,26 +64,36 @@ Map::Map(Matrix input_map, Matrix walls_map, int limit) :
|
||||||
{
|
{
|
||||||
$width = $walls[0].size();
|
$width = $walls[0].size();
|
||||||
$height = $walls.size();
|
$height = $walls.size();
|
||||||
|
$paths = Matrix($height, MatrixRow($width, 1));
|
||||||
|
$lightmap = Matrix($height, MatrixRow($width, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::make_paths() {
|
inline void matrix_assign(Matrix &out, int new_value) {
|
||||||
size_t h = $input_map.size();
|
for(auto &row : out) {
|
||||||
size_t w = $input_map[0].size();
|
row.assign(row.size(), new_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Used https://github.com/HenrYxZ/dijkstra-map as a reference.
|
||||||
|
*/
|
||||||
|
void Map::make_paths() {
|
||||||
|
INVARIANT();
|
||||||
// Initialize the new array with every pixel at limit distance
|
// Initialize the new array with every pixel at limit distance
|
||||||
// NOTE: this is normally ones() * limit
|
// NOTE: this is normally ones() * limit
|
||||||
int limit = $limit == 0 ? h * w : $limit;
|
int limit = $limit == 0 ? $height * $width : $limit;
|
||||||
Matrix new_arr = Matrix(h, MatrixRow(w, limit));
|
matrix_assign($paths, limit);
|
||||||
|
|
||||||
Matrix closed = $walls;
|
Matrix closed = $walls;
|
||||||
PointList starting_pixels;
|
PointList starting_pixels;
|
||||||
PointList open_pixels;
|
PointList open_pixels;
|
||||||
|
|
||||||
// First pass: Add starting pixels and put them in closed
|
// First pass: Add starting pixels and put them in closed
|
||||||
for(size_t counter = 0; counter < h * w; counter++) {
|
for(size_t counter = 0; counter < $height * $width; counter++) {
|
||||||
size_t x = counter % w;
|
size_t x = counter % $width; // BUG: is this right?
|
||||||
size_t y = counter / w;
|
size_t y = counter / $width;
|
||||||
if($input_map[y][x] == 0) {
|
if($input_map[y][x] == 0) {
|
||||||
new_arr[y][x] = 0;
|
$paths[y][x] = 0;
|
||||||
closed[y][x] = 1;
|
closed[y][x] = 1;
|
||||||
starting_pixels.push_back({.x=x,.y=y});
|
starting_pixels.push_back({.x=x,.y=y});
|
||||||
}
|
}
|
||||||
|
@ -99,7 +109,7 @@ void Map::make_paths() {
|
||||||
for(; counter < limit && !open_pixels.empty(); ++counter) {
|
for(; counter < limit && !open_pixels.empty(); ++counter) {
|
||||||
PointList next_open;
|
PointList next_open;
|
||||||
for(auto sp : open_pixels) {
|
for(auto sp : open_pixels) {
|
||||||
new_arr[sp.y][sp.x] = counter;
|
$paths[sp.y][sp.x] = counter;
|
||||||
add_neighbors(next_open, closed, sp.y, sp.x);
|
add_neighbors(next_open, closed, sp.y, sp.x);
|
||||||
}
|
}
|
||||||
open_pixels = next_open;
|
open_pixels = next_open;
|
||||||
|
@ -107,22 +117,17 @@ void Map::make_paths() {
|
||||||
|
|
||||||
// Last pass: flood last pixels
|
// Last pass: flood last pixels
|
||||||
for(auto sp : open_pixels) {
|
for(auto sp : open_pixels) {
|
||||||
new_arr[sp.y][sp.x] = counter;
|
$paths[sp.y][sp.x] = counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
$paths = new_arr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::make_room(size_t origin_x, size_t origin_y, size_t w, size_t h) {
|
void Map::make_room(size_t origin_x, size_t origin_y, size_t w, size_t h) {
|
||||||
dbc::pre("x out of bounds", origin_x < $width);
|
INVARIANT();
|
||||||
dbc::pre("y out of bounds", origin_y < $height);
|
dbc::pre("y out of bounds", origin_y + h < $height);
|
||||||
dbc::pre("w out of bounds", w <= $width);
|
dbc::pre("x out of bounds", origin_x + w < $width);
|
||||||
dbc::pre("h out of bounds", h <= $height);
|
|
||||||
|
|
||||||
for(size_t y = origin_y; y < origin_y + h; ++y) {
|
for(size_t y = origin_y; y < origin_y + h; ++y) {
|
||||||
dbc::check(y < $walls.size(), "y is out of bounds");
|
|
||||||
for(size_t x = origin_x; x < origin_x + w; ++x) {
|
for(size_t x = origin_x; x < origin_x + w; ++x) {
|
||||||
dbc::check(x < $walls[y].size(), "x is out of bounds");
|
|
||||||
$walls[y][x] = INV_SPACE;
|
$walls[y][x] = INV_SPACE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -375,11 +380,7 @@ Point Map::center_camera(const Point &around, size_t view_x, size_t view_y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::reset_light() {
|
void Map::reset_light() {
|
||||||
for(auto &row : $lightmap) {
|
matrix_assign($lightmap, lighting::MIN);
|
||||||
for(size_t i = 0; i < row.size(); i++) {
|
|
||||||
row[i] = lighting::MIN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::clear_light_target(const Point &at) {
|
void Map::clear_light_target(const Point &at) {
|
||||||
|
@ -390,7 +391,6 @@ void Map::set_light_target(const Point &at, int value) {
|
||||||
set_target(at, value);
|
set_target(at, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Map::path_light() {
|
void Map::path_light() {
|
||||||
make_paths();
|
make_paths();
|
||||||
}
|
}
|
||||||
|
@ -417,10 +417,13 @@ void Map::render_light(LightSource source, Point at) {
|
||||||
clear_light_target(at);
|
clear_light_target(at);
|
||||||
vector<Point> has_light;
|
vector<Point> has_light;
|
||||||
|
|
||||||
for(size_t x = min.x; x <= max.x; ++x) {
|
for(size_t y = min.y; y <= max.y; ++y) {
|
||||||
for(size_t y = min.y; y <= max.y; ++y) {
|
auto &light_row = $lightmap[y];
|
||||||
if($paths[y][x] != UNPATH) {
|
auto &path_row = $paths[y];
|
||||||
$lightmap[y][x] = light_level(source.strength, x, y);
|
|
||||||
|
for(size_t x = min.x; x <= max.x; ++x) {
|
||||||
|
if(path_row[x] != UNPATH) {
|
||||||
|
light_row[x] = light_level(source.strength, x, y);
|
||||||
has_light.push_back({x,y});
|
has_light.push_back({x,y});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -428,14 +431,30 @@ void Map::render_light(LightSource source, Point at) {
|
||||||
|
|
||||||
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(int i = -1; i <= 1; i++) {
|
for(int j = -1;point.y+j >= 0 && j <= 1 && point.y+j < $height; j++) {
|
||||||
for(int j = -1; j <= 1; j++) {
|
auto &path_row = $paths[point.y+j];
|
||||||
if(!inmap(point.x+i, point.y+j)) continue;
|
auto &light_row = $lightmap[point.y+j];
|
||||||
|
|
||||||
if($paths[point.y+j][point.x+i] == UNPATH) {
|
for(int i = -1; point.x+i >= 0 && i <= 1 && point.x+i < $width; i++) {
|
||||||
$lightmap[point.y+j][point.x+i] = light_level(wall_light, point.x, point.y);
|
if(path_row[point.x+i] == UNPATH) {
|
||||||
|
light_row[point.x+i] = light_level(wall_light, point.x, point.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Map::INVARIANT() {
|
||||||
|
using dbc::check;
|
||||||
|
|
||||||
|
check($paths.size() == height(), "paths wrong height");
|
||||||
|
check($paths[0].size() == width(), "paths wrong width");
|
||||||
|
check($input_map.size() == height(), "input_map wrong height");
|
||||||
|
check($input_map[0].size() == width(), "input_map wrong width");
|
||||||
|
check($walls.size() == height(), "walls wrong height");
|
||||||
|
check($walls[0].size() == width(), "walls wrong width");
|
||||||
|
check($lightmap.size() == height(), "lightmap wrong height");
|
||||||
|
check($lightmap[0].size() == width(), "lightmap wrong width");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
1
map.hpp
1
map.hpp
|
@ -92,4 +92,5 @@ public:
|
||||||
void render_light(LightSource source, Point at);
|
void render_light(LightSource source, Point at);
|
||||||
|
|
||||||
void dump();
|
void dump();
|
||||||
|
bool INVARIANT();
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,13 +35,13 @@ runtests = executable('runtests', [
|
||||||
'tests/map.cpp',
|
'tests/map.cpp',
|
||||||
'tests/collider.cpp',
|
'tests/collider.cpp',
|
||||||
'tests/components.cpp',
|
'tests/components.cpp',
|
||||||
'tests/sound.cpp',
|
|
||||||
'tests/dinkyecs.cpp',
|
'tests/dinkyecs.cpp',
|
||||||
'tests/ansi_parser.cpp',
|
'tests/ansi_parser.cpp',
|
||||||
'tests/config.cpp',
|
'tests/config.cpp',
|
||||||
'tests/save.cpp',
|
'tests/save.cpp',
|
||||||
'tests/render.cpp',
|
'tests/render.cpp',
|
||||||
'tests/panel.cpp',
|
'tests/panel.cpp',
|
||||||
|
'tests/sound.cpp',
|
||||||
],
|
],
|
||||||
dependencies: dependencies)
|
dependencies: dependencies)
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@ TEST_CASE("dijkstra algo test", "[map]") {
|
||||||
test["walls"],
|
test["walls"],
|
||||||
test["limit"]);
|
test["limit"]);
|
||||||
|
|
||||||
|
REQUIRE(map.INVARIANT());
|
||||||
|
|
||||||
map.make_paths();
|
map.make_paths();
|
||||||
Matrix &paths = map.paths();
|
Matrix &paths = map.paths();
|
||||||
|
|
||||||
|
@ -31,6 +33,7 @@ TEST_CASE("dijkstra algo test", "[map]") {
|
||||||
dump_map("RESULT", paths);
|
dump_map("RESULT", paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
REQUIRE(map.INVARIANT());
|
||||||
REQUIRE(paths == expected);
|
REQUIRE(paths == expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue