/
landmasses.go
79 lines (72 loc) · 1.96 KB
/
landmasses.go
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
package geo
import (
"container/list"
"log"
)
func (m *Geo) assignLandmasses() {
m.Landmasses = m.IdentifyLandmasses()
lmSize := make(map[int]int)
for _, lm := range m.Landmasses {
if lm >= 0 {
lmSize[lm]++ // Only count regions that are set to a valid ID.
}
}
m.LandmassSize = lmSize
}
// IdentifyLandmasses returns a mapping from region to landmass ID.
// A landmass is a connected number of regions above sealevel.
func (m *Geo) IdentifyLandmasses() []int {
// NOTE: this is still in need of refinement.
landMasses := initRegionSlice(m.SphereMesh.NumRegions)
for r := range landMasses {
// Skip everything that is ocean.
if m.Elevation[r] <= 0 {
landMasses[r] = -2
}
}
var landID int
var landSizes []int
outReg := make([]int, 0, 8)
for r, lmID := range landMasses {
// Skip if the current region has already been allocated
// or is below sealevel.
if lmID != -1 {
continue
}
var currentLandSize int
queue := list.New()
enqueue := func(r int) {
// Skip if the current region has already been allocated
// or is below sealevel.
if landMasses[r] != -1 {
return
}
landMasses[r] = landID // Assign current landID to the region.
currentLandSize++ // Increase size of known landmass.
for _, nb := range m.SphereMesh.R_circulate_r(outReg, r) {
// Skip if the neighbor region has already been allocated
// or is below sealevel.
if landMasses[nb] != -1 {
continue
}
queue.PushBack(nb)
}
}
// Start queue with current region.
queue.PushBack(r)
// Process each queue entry until we run out of
// regions that belong to this landmass.
for queue.Len() > 0 {
e := queue.Front()
enqueue(e.Value.(int))
queue.Remove(e)
}
// Once done, append the current size to the list of landmass-
// sizes and increment the current landID.
landSizes = append(landSizes, currentLandSize)
landID++
}
log.Println("number of landmasses", landID)
// log.Println(landSizes)
return landMasses
}