@@ -25,9 +25,7 @@ namespace unnatural
25
25
for (uint32 j = i + 1 ; j < n; j++)
26
26
{
27
27
const Real c = distance (tiles[positions[i]].position , tiles[positions[j]].position );
28
- // score = min(score, c); // this causes a crash when compiled with visual studio 2022 msvc with optimizations
29
- if (c < score)
30
- score = c;
28
+ score = min (score, c);
31
29
}
32
30
}
33
31
return score;
@@ -54,6 +52,69 @@ namespace unnatural
54
52
});
55
53
}
56
54
55
+ void filterPositionsByLargestConnectedWalkableComponent (std::vector<uint32> &positions)
56
+ {
57
+ const auto &walkable = [](uint32 i) -> bool
58
+ {
59
+ switch (tiles[i].type )
60
+ {
61
+ case TerrainTypeEnum::Road:
62
+ case TerrainTypeEnum::Flat:
63
+ case TerrainTypeEnum::Rough:
64
+ return true ;
65
+ default :
66
+ return false ;
67
+ }
68
+ };
69
+
70
+ const uint32 cnt = tiles.size ();
71
+ std::vector<uint32> component;
72
+ component.resize (cnt, m);
73
+
74
+ uint32 largestSize = 0 ;
75
+ uint32 largestIndex = m;
76
+
77
+ const auto &floodfill = [&](const uint32 start)
78
+ {
79
+ const uint32 index = component[start];
80
+ uint32 size = 1 ;
81
+ std::vector<uint32> open ;
82
+ open .reserve (cnt / 10 );
83
+ open .push_back (start);
84
+ while (!open .empty ())
85
+ {
86
+ const uint32 i = open .back ();
87
+ open .pop_back ();
88
+ CAGE_ASSERT (component[i] == index );
89
+ for (uint32 j : tiles[i].neighbors )
90
+ {
91
+ if (component[j] != m || !walkable (j))
92
+ continue ;
93
+ component[j] = index ;
94
+ size++;
95
+ open .push_back (j);
96
+ }
97
+ }
98
+ if (size > largestSize)
99
+ {
100
+ largestSize = size;
101
+ largestIndex = index ;
102
+ }
103
+ };
104
+
105
+ uint32 next = 0 ;
106
+ for (uint32 i = 0 ; i < cnt; i++)
107
+ {
108
+ if (component[i] != m || !walkable (i))
109
+ continue ;
110
+ component[i] = next;
111
+ floodfill (i);
112
+ next++;
113
+ }
114
+
115
+ std::erase_if (positions, [&](uint32 i) { return component[i] != largestIndex; });
116
+ }
117
+
57
118
std::vector<uint32> generateCadidates ()
58
119
{
59
120
std::vector<uint32> candidates;
@@ -62,7 +123,8 @@ namespace unnatural
62
123
if (it->buildable )
63
124
candidates.push_back (it.index );
64
125
filterPositionsByBuildableRadius (candidates);
65
- CAGE_LOG (SeverityEnum::Info, " generator" , Stringizer () + " starting position candidates: " + candidates.size () + " (after eliminating due to insufficient buildable neighbors)" );
126
+ filterPositionsByLargestConnectedWalkableComponent (candidates);
127
+ CAGE_LOG (SeverityEnum::Info, " generator" , Stringizer () + " starting position candidates: " + candidates.size ());
66
128
return candidates;
67
129
}
68
130
0 commit comments