forked from CleverRaven/Cataclysm-DDA
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathflood_fill.h
55 lines (47 loc) · 1.75 KB
/
flood_fill.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#pragma once
#ifndef CATA_SRC_FLOOD_FILL_H
#define CATA_SRC_FLOOD_FILL_H
#include <queue>
#include <vector>
#include <unordered_set>
#include "enums.h"
#include "point.h"
namespace ff
{
/**
* Given a starting point, flood fill out to the 4-connected points, applying the provided predicate
* to determine if a given point should be added to the collection of flood-filled points, and then
* return that collection.
* @param starting_point starting point of the flood fill. No assumptions made about if it will satisfy
* the predicate.
* @param visited externally provided set of points that have already been designated as visited which
* will be updated by this call.
* @param predicate UnaryPredicate that will be provided with a point for evaluation as to whether or
* not the point should be filled.
*/
template<typename Point, typename UnaryPredicate>
std::vector<Point> point_flood_fill_4_connected( const Point &starting_point,
std::unordered_set<Point> &visited, UnaryPredicate predicate )
{
std::vector<Point> filled_points;
std::queue<Point> to_check;
to_check.push( starting_point );
while( !to_check.empty() ) {
const Point current_point = to_check.front();
to_check.pop();
if( visited.find( current_point ) != visited.end() ) {
continue;
}
visited.emplace( current_point );
if( predicate( current_point ) ) {
filled_points.emplace_back( current_point );
to_check.push( current_point + point_south );
to_check.push( current_point + point_north );
to_check.push( current_point + point_east );
to_check.push( current_point + point_west );
}
}
return filled_points;
}
} // namespace ff
#endif // CATA_SRC_FLOOD_FILL_H