-
Notifications
You must be signed in to change notification settings - Fork 1
/
civCityType.go
151 lines (140 loc) · 3.97 KB
/
civCityType.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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package genworldvoronoi
import (
"log"
"github.com/Flokey82/genbiome"
)
// getRegCityType returns the optimal type of city for a given region.
func (m *Civ) getRegCityType(r int) TownType {
// TODO: Cache this somehow.
if m.GetFitnessArableLand()(r) > 0.5 {
return TownTypeFarming
}
// If we have a lot of metals, gems, etc. we have a mining town.
if m.Metals[r] > 0 || m.Gems[r] > 0 {
return TownTypeMining
}
// If we have stone, we have a quarry.
if m.Stones[r] > 0 {
return TownTypeQuarry
}
// TODO: Add more types of cities.
return TownTypeDefault
}
// TownType represents the type of a city.
type TownType string
// The different types of cities.
const (
TownTypeDefault TownType = "town"
TownTypeTrading TownType = "trading"
TownTypeMining TownType = "mining"
TownTypeMiningGems TownType = "mining (gems)"
TownTypeQuarry TownType = "quarry"
TownTypeFarming TownType = "agricultural"
TownTypeDesertOasis TownType = "desert oasis"
)
// FoundingPopulation returns the starting population of a city type.
func (t TownType) FoundingPopulation() int {
switch t {
case TownTypeDefault:
return 100
case TownTypeTrading:
return 80
case TownTypeQuarry, TownTypeMining, TownTypeMiningGems:
return 20
case TownTypeFarming:
return 20
case TownTypeDesertOasis:
return 20
default:
log.Fatalf("unknown city type: %s", t)
}
return 0
}
// GetDistanceSeedFunc returns the distance seed function for a city type.
func (t TownType) GetDistanceSeedFunc(m *Civ) func() []int {
// For now we just maximize the distance to cities of the same type.
return func() []int {
var cities []int
for _, c := range m.Cities {
if c.Type == t {
cities = append(cities, c.ID)
}
}
return cities
}
}
// GetFitnessFunction returns the fitness function for a city type.
func (t TownType) GetFitnessFunction(m *Civ) func(int) float64 {
// TODO: Create different fitness functions for different types of settlement.
// - Capital
// - Cities / Settlements
// ) Proximity to capital!
// - Agricultural
// - Mining
// - ...
switch t {
case TownTypeDefault:
fa := m.GetFitnessClimate()
fb := m.getFitnessCityDefault()
return func(r int) float64 {
return fa(r) * fb(r)
}
case TownTypeTrading:
return m.getFitnessTradingTowns()
case TownTypeQuarry:
fa := m.GetFitnessSteepMountains()
fb := m.GetFitnessClimate()
fc := m.GetFitnessProximityToWater()
fd := m.getFitnessProximityToCities(TownTypeMining, TownTypeMiningGems, TownTypeQuarry)
return func(r int) float64 {
if m.Stones[r] == 0 {
return -1.0
}
return fd(r) * (fa(r)*fb(r) + fc(r)) / 2
}
case TownTypeMining:
fa := m.GetFitnessSteepMountains()
fb := m.GetFitnessClimate()
fc := m.GetFitnessProximityToWater()
fd := m.getFitnessProximityToCities(TownTypeMining, TownTypeMiningGems, TownTypeQuarry)
return func(r int) float64 {
if m.Metals[r] == 0 {
return -1.0
}
return fd(r) * (fa(r)*fb(r) + fc(r)) / 2
}
case TownTypeMiningGems:
fa := m.GetFitnessSteepMountains()
fb := m.GetFitnessClimate()
fc := m.GetFitnessProximityToWater()
fd := m.getFitnessProximityToCities(TownTypeMining, TownTypeMiningGems, TownTypeQuarry)
return func(r int) float64 {
if m.Gems[r] == 0 {
return -1.0
}
return fd(r) * (fa(r)*fb(r) + fc(r)) / 2
}
case TownTypeFarming:
return m.GetFitnessArableLand()
case TownTypeDesertOasis:
// TODO: Improve this fitness function.
// Right now the oasis are placed at the very edges of
// deserts, as there is the "best" climate.
// However, we want them to be trade hubs for desert
// crossings... so we'll need to place them in the middle
// of deserts instead.
fa := m.GetFitnessClimate()
bf := m.GetRegWhittakerModBiomeFunc()
return func(r int) float64 {
biome := bf(r)
if biome == genbiome.WhittakerModBiomeColdDesert ||
biome == genbiome.WhittakerModBiomeSubtropicalDesert {
return fa(r)
}
return 0
}
default:
log.Fatalf("unknown city type: %s", t)
}
return nil
}