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