forked from amitp/mapgen2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
RoadsSpanningTree.as
93 lines (82 loc) · 2.92 KB
/
RoadsSpanningTree.as
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// Place roads on the polygonal island map using a minimal spanning tree
// Author: [email protected]
// License: MIT
package {
import graph.*;
public class RoadsSpanningTree {
// The road array marks the edges that are roads.
public var road:Array; // edge index -> boolean
public var roadConnections:Array; // center index -> array of Edges with roads
public function RoadsSpanningTree() {
road = [];
roadConnections = [];
}
public function createRoads(map:Map):void {
var status:Array = []; // index -> status (undefined for unvisited, 'fringe', or 'closed')
var fringe:Array = []; // locations that are still being analyzed
var p:Center, q:Corner, r:Center, edge:Edge, i:int;
// Initialize
for each (edge in map.edges) {
road[edge.index] = 0;
}
// Start with the highest elevation Center -- everything else
// will connect to this location
r = map.centers[0];
for each (p in map.centers) {
if (p.elevation > r.elevation) {
r = p;
}
}
status[r.index] = 'fringe';
fringe = [r];
while (fringe.length > 0) {
// Pick a node randomly. Also interesting is to always pick the first or last node.
i = Math.floor(Math.random() * fringe.length);
// i = 0;
// i = fringe.length - 1;
if (i > 0 && Math.random() < 0.5) i -= 1;
p = fringe[i];
fringe[i] = fringe[0];
fringe.shift();
status[p.index] = 'closed';
for each (edge in p.borders) {
r = (edge.d0 == p)? edge.d1 : edge.d0;
if (r && !r.water) {
if (!status[r.index]) {
// We've never been here, so let's add this to the fringe
status[r.index] = 'fringe';
fringe.push(r);
road[edge.index] = 1;
} else if (status[r.index] == 'fringe') {
// We've been here -- what if the cost is lower? TODO: ignore for now
}
}
}
}
// Build the roadConnections list from roads
for each (edge in map.edges) {
if (road[edge.index] > 0) {
for each (p in [edge.d0, edge.d1]) {
if (p) {
if (!roadConnections[p.index]) {
roadConnections[p.index] = [];
}
roadConnections[p.index].push(edge);
}
}
}
}
// Rebuild roads from roadConnections
for each (edge in map.edges) {
if (road[edge.index] > 0) {
for each (p in [edge.d0, edge.d1]) {
if (p) {
road[edge.index] = Math.max(road[edge.index], roadConnections[p.index].length);
}
}
}
road[edge.index] = Math.min(3, Math.max(0, road[edge.index] - 2));
}
}
}
}