Initial Dijkstra algorithm for the map, but doesn't quite work right. The walls in the wall_map are not accounted for in the algorithm.
parent
d7b1cf0bf9
commit
4d748d1f48
@ -0,0 +1,84 @@ |
||||
#include "map.hpp" |
||||
#include <vector> |
||||
#include <fmt/core.h> |
||||
|
||||
using std::vector, std::pair; |
||||
using namespace fmt; |
||||
|
||||
void dump_map(Matrix &map) { |
||||
println("-----------------"); |
||||
for(auto row : map) { |
||||
for(auto col : row) { |
||||
print("{} ", col); |
||||
} |
||||
print("\n"); |
||||
} |
||||
} |
||||
|
||||
|
||||
void add_neighbors(PairList &neighbors, Matrix &closed, size_t j, size_t i) { |
||||
size_t h = closed.size(); |
||||
size_t w = closed[0].size(); |
||||
vector<size_t> rows{j - 1, j, j + 1}; |
||||
vector<size_t> cols{i - 1, i, i + 1}; |
||||
|
||||
for(auto row : rows) { |
||||
for(auto col : cols) { |
||||
if((0 <= row && row < h) && |
||||
(0 <= col && col < w) && |
||||
closed[row][col] == 0) |
||||
{ |
||||
closed[row][col] = 1; |
||||
neighbors.push_back({.j=row, .i=col}); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
Matrix dijkstra_map(Matrix &input_map, Matrix &walls_map, int limit) { |
||||
size_t h = input_map.size(); |
||||
size_t w = input_map[0].size(); |
||||
|
||||
// Initialize the new array with every pixel at limit distance
|
||||
Matrix new_arr = Matrix(h, MatrixRow(w, 1)); |
||||
Matrix closed = walls_map; |
||||
PairList starting_pixels; |
||||
PairList open_pixels; |
||||
limit = limit == 0 ? h * w : limit; |
||||
|
||||
|
||||
// First pass: Add starting pixels and put them in closed
|
||||
for(size_t counter = 0; counter < h * w; counter++) { |
||||
size_t i = counter % w; |
||||
size_t j = counter / w; |
||||
if(input_map[j][i] == 0) { |
||||
new_arr[j][i] = 0; |
||||
closed[j][i] = 1; |
||||
starting_pixels.push_back({.j=j,.i=i}); |
||||
} |
||||
} |
||||
|
||||
// Second pass: Add border to open
|
||||
for(auto sp : starting_pixels) { |
||||
add_neighbors(open_pixels, closed, sp.j, sp.i); |
||||
} |
||||
|
||||
// Third pass: Iterate filling in the open list
|
||||
int counter = 1; |
||||
while(counter < limit && !open_pixels.empty()) { |
||||
PairList next_open; |
||||
for(auto sp : open_pixels) { |
||||
new_arr[sp.j][sp.i] = counter; |
||||
add_neighbors(next_open, closed, sp.j, sp.i); |
||||
} |
||||
open_pixels = next_open; |
||||
++counter; |
||||
} |
||||
|
||||
// Last pass: flood last pixels
|
||||
for(auto sp : open_pixels) { |
||||
new_arr[sp.j][sp.i] = counter; |
||||
} |
||||
|
||||
return new_arr; |
||||
} |
@ -0,0 +1,17 @@ |
||||
#pragma once |
||||
#include <vector> |
||||
#include <utility> |
||||
|
||||
struct Pair { |
||||
size_t j = 0; |
||||
size_t i = 0; |
||||
}; |
||||
|
||||
typedef std::vector<Pair> PairList; |
||||
typedef std::vector<int> MatrixRow; |
||||
typedef std::vector<MatrixRow> Matrix; |
||||
|
||||
void dump_map(Matrix &map); |
||||
void add_neighbors(Matrix &closed, size_t j, size_t i); |
||||
|
||||
Matrix dijkstra_map(Matrix &input_map, Matrix &walls_map, int limit=0); |
@ -0,0 +1,35 @@ |
||||
#include <catch2/catch_test_macros.hpp> |
||||
#include "map.hpp" |
||||
#include <fmt/core.h> |
||||
|
||||
using namespace fmt; |
||||
|
||||
TEST_CASE("dijkstra algo test", "[map]") { |
||||
Matrix in_map = { |
||||
{1, 1, 1, 0}, |
||||
{1, 0, 1, 1}, |
||||
{1, 0, 1, 1}, |
||||
{1, 1, 1, 1}, |
||||
}; |
||||
Matrix walls = { |
||||
{0, 0, 0, 0}, |
||||
{0, 0, 0, 0}, |
||||
{0, 0, 1, 0}, |
||||
{0, 0, 1, 0}, |
||||
}; |
||||
Matrix expected = { |
||||
{1, 1, 1, 0}, |
||||
{1, 0, 1, 1}, |
||||
{1, 0, 0, 2}, |
||||
{1, 1, 0, 3}, |
||||
}; |
||||
|
||||
Matrix res = dijkstra_map(in_map, walls); |
||||
|
||||
println("--- EXPECTED:"); |
||||
dump_map(expected); |
||||
println("--- RESULT:"); |
||||
dump_map(res); |
||||
|
||||
REQUIRE(res == expected); |
||||
} |
Loading…
Reference in new issue