powergrid-engine 1.11.0 → 1.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/available-moves.d.ts +1 -0
- package/dist/src/available-moves.js +66 -0
- package/dist/src/engine.js +77 -10
- package/dist/src/gamestate.d.ts +2 -1
- package/dist/src/maps/europe.d.ts +62 -0
- package/dist/src/maps/europe.js +356 -0
- package/dist/src/maps/northamerica.d.ts +62 -0
- package/dist/src/maps/northamerica.js +330 -0
- package/dist/src/maps/southafrica.d.ts +26 -26
- package/dist/src/maps/southafrica.js +239 -116
- package/dist/src/maps/ukireland.js +163 -40
- package/dist/src/maps.d.ts +10 -0
- package/dist/src/maps.js +12 -4
- package/dist/src/move.d.ts +1 -0
- package/package.json +1 -1
- package/src/available-moves.ts +88 -1
- package/src/engine.spec.ts +17 -0
- package/src/engine.ts +76 -15
- package/src/gamestate.ts +10 -3
- package/src/maps/europe.ts +391 -0
- package/src/maps/northamerica.ts +360 -0
- package/src/maps/southafrica.ts +247 -116
- package/src/maps/ukireland.ts +170 -40
- package/src/maps.ts +37 -6
- package/src/move.ts +4 -0
package/src/maps/southafrica.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
+
// by John and Cici
|
|
2
|
+
import { cloneDeep } from 'lodash';
|
|
3
|
+
import seedrandom from 'seedrandom';
|
|
4
|
+
import { getPowerPlant } from '../engine';
|
|
5
|
+
import { PowerPlant } from '../gamestate';
|
|
6
|
+
import { shuffle } from '../utils';
|
|
1
7
|
import { GameMap } from './../maps';
|
|
8
|
+
import { powerPlants } from './../powerPlants';
|
|
2
9
|
|
|
3
10
|
export enum Regions {
|
|
4
11
|
Orange = 'orange',
|
|
@@ -9,143 +16,267 @@ export enum Regions {
|
|
|
9
16
|
}
|
|
10
17
|
|
|
11
18
|
export enum Cities {
|
|
12
|
-
|
|
19
|
+
Zimbabwe = 'Zimbabwe',
|
|
13
20
|
Musina = 'Musina',
|
|
14
21
|
Botswana = 'Botswana',
|
|
15
22
|
Polokwane = 'Polokwane',
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
23
|
+
PretoriaN = 'Pretoria N',
|
|
24
|
+
PretoriaS = 'Pretoria S',
|
|
25
|
+
Rustenburg = 'Rustenburg',
|
|
19
26
|
Mozambique = 'Mozambique',
|
|
20
27
|
Mbombela = 'Mbombela',
|
|
21
|
-
|
|
28
|
+
Eswatini = 'Eswatini',
|
|
22
29
|
Germiston = 'Germiston',
|
|
23
|
-
|
|
24
|
-
|
|
30
|
+
JohannesburgN = 'Johannesburg N',
|
|
31
|
+
JohannesburgS = 'Johannesburg S',
|
|
25
32
|
Ladysmith = 'Ladysmith',
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
Newcastle = 'Newcastle',
|
|
34
|
+
Pietermaritzburg = 'Pietermaritzburg',
|
|
35
|
+
DurbanN = 'Durban N',
|
|
36
|
+
DurbanS = 'Durban S',
|
|
37
|
+
Mthatha = 'Mthatha',
|
|
38
|
+
Lesotho = 'Lesotho',
|
|
39
|
+
Bloemfontein = 'Bloemfontein',
|
|
40
|
+
Klerksdorp = 'Klerksdorp',
|
|
41
|
+
Welkom = 'Welkom',
|
|
42
|
+
Kuruman = 'Kuruman',
|
|
36
43
|
Kimberly = 'Kimberly',
|
|
37
|
-
|
|
38
|
-
|
|
44
|
+
Upington = 'Upington',
|
|
45
|
+
Springbok = 'Springbok',
|
|
39
46
|
Namibia = 'Namibia',
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
DeAar = 'De Aar',
|
|
48
|
+
BeaufortWest = 'Beaufort West',
|
|
49
|
+
EastLondon = 'East London',
|
|
50
|
+
PortElizabeth = 'Port Elizabeth',
|
|
51
|
+
George = 'George',
|
|
52
|
+
CapeTownN = 'Cape Town N',
|
|
53
|
+
CapeTownS = 'Cape Town S',
|
|
47
54
|
}
|
|
48
55
|
|
|
49
56
|
export const map: GameMap = {
|
|
50
57
|
name: 'South Africa',
|
|
51
58
|
cities: [
|
|
52
|
-
{ name: Cities.
|
|
53
|
-
{ name: Cities.Musina, region: Regions.Orange, x:
|
|
54
|
-
{ name: Cities.Botswana, region: Regions.Orange, x:
|
|
55
|
-
{ name: Cities.Polokwane, region: Regions.Orange, x:
|
|
56
|
-
{ name: Cities.
|
|
57
|
-
{ name: Cities.
|
|
58
|
-
{ name: Cities.
|
|
59
|
-
{ name: Cities.Mozambique, region: Regions.Green, x:
|
|
60
|
-
{ name: Cities.Mbombela, region: Regions.Green, x:
|
|
61
|
-
{ name: Cities.
|
|
62
|
-
{ name: Cities.Germiston, region: Regions.Green, x:
|
|
63
|
-
{ name: Cities.
|
|
64
|
-
{ name: Cities.
|
|
65
|
-
{ name: Cities.Ladysmith, region: Regions.Green, x:
|
|
66
|
-
{ name: Cities.
|
|
67
|
-
{ name: Cities.
|
|
68
|
-
{ name: Cities.
|
|
69
|
-
{ name: Cities.
|
|
70
|
-
{ name: Cities.
|
|
71
|
-
{ name: Cities.
|
|
72
|
-
{ name: Cities.
|
|
73
|
-
{ name: Cities.
|
|
74
|
-
{ name: Cities.
|
|
75
|
-
{ name: Cities.
|
|
76
|
-
{ name: Cities.Kimberly, region: Regions.Brown, x:
|
|
77
|
-
{ name: Cities.
|
|
78
|
-
{ name: Cities.
|
|
79
|
-
{ name: Cities.Namibia, region: Regions.Brown, x:
|
|
80
|
-
{ name: Cities.
|
|
81
|
-
{ name: Cities.
|
|
82
|
-
{ name: Cities.
|
|
83
|
-
{ name: Cities.
|
|
84
|
-
{ name: Cities.
|
|
85
|
-
{ name: Cities.
|
|
86
|
-
{ name: Cities.
|
|
59
|
+
{ name: Cities.Zimbabwe, region: Regions.Orange, x: 903, y: 50, singleOccupancy: true },
|
|
60
|
+
{ name: Cities.Musina, region: Regions.Orange, x: 874, y: 134 },
|
|
61
|
+
{ name: Cities.Botswana, region: Regions.Orange, x: 560, y: 187, singleOccupancy: true },
|
|
62
|
+
{ name: Cities.Polokwane, region: Regions.Orange, x: 802, y: 189 },
|
|
63
|
+
{ name: Cities.PretoriaN, region: Regions.Orange, x: 759, y: 261 },
|
|
64
|
+
{ name: Cities.PretoriaS, region: Regions.Orange, x: 759, y: 291 },
|
|
65
|
+
{ name: Cities.Rustenburg, region: Regions.Orange, x: 666, y: 310 },
|
|
66
|
+
{ name: Cities.Mozambique, region: Regions.Green, x: 1011, y: 170, singleOccupancy: true },
|
|
67
|
+
{ name: Cities.Mbombela, region: Regions.Green, x: 891, y: 275 },
|
|
68
|
+
{ name: Cities.Eswatini, region: Regions.Green, x: 926, y: 351, singleOccupancy: true },
|
|
69
|
+
{ name: Cities.Germiston, region: Regions.Green, x: 836, y: 351 },
|
|
70
|
+
{ name: Cities.JohannesburgN, region: Regions.Green, x: 753, y: 343 },
|
|
71
|
+
{ name: Cities.JohannesburgS, region: Regions.Green, x: 754, y: 371 },
|
|
72
|
+
{ name: Cities.Ladysmith, region: Regions.Green, x: 823, y: 456 },
|
|
73
|
+
{ name: Cities.Newcastle, region: Regions.Yellow, x: 957, y: 478 },
|
|
74
|
+
{ name: Cities.Pietermaritzburg, region: Regions.Yellow, x: 851, y: 511 },
|
|
75
|
+
{ name: Cities.DurbanN, region: Regions.Yellow, x: 894, y: 563 },
|
|
76
|
+
{ name: Cities.DurbanS, region: Regions.Yellow, x: 893, y: 592 },
|
|
77
|
+
{ name: Cities.Mthatha, region: Regions.Yellow, x: 791, y: 663 },
|
|
78
|
+
{ name: Cities.Lesotho, region: Regions.Yellow, x: 759, y: 523, singleOccupancy: true },
|
|
79
|
+
{ name: Cities.Bloemfontein, region: Regions.Yellow, x: 656, y: 509 },
|
|
80
|
+
{ name: Cities.Klerksdorp, region: Regions.Brown, x: 660, y: 362 },
|
|
81
|
+
{ name: Cities.Welkom, region: Regions.Brown, x: 652, y: 431 },
|
|
82
|
+
{ name: Cities.Kuruman, region: Regions.Brown, x: 499, y: 386 },
|
|
83
|
+
{ name: Cities.Kimberly, region: Regions.Brown, x: 564, y: 496 },
|
|
84
|
+
{ name: Cities.Upington, region: Regions.Brown, x: 378, y: 453 },
|
|
85
|
+
{ name: Cities.Springbok, region: Regions.Brown, x: 211, y: 530 },
|
|
86
|
+
{ name: Cities.Namibia, region: Regions.Brown, x: 189, y: 311, singleOccupancy: true },
|
|
87
|
+
{ name: Cities.DeAar, region: Regions.Red, x: 539, y: 665 },
|
|
88
|
+
{ name: Cities.BeaufortWest, region: Regions.Red, x: 427, y: 705 },
|
|
89
|
+
{ name: Cities.EastLondon, region: Regions.Red, x: 722, y: 750 },
|
|
90
|
+
{ name: Cities.PortElizabeth, region: Regions.Red, x: 600, y: 811 },
|
|
91
|
+
{ name: Cities.George, region: Regions.Red, x: 439, y: 811 },
|
|
92
|
+
{ name: Cities.CapeTownN, region: Regions.Red, x: 233, y: 783 },
|
|
93
|
+
{ name: Cities.CapeTownS, region: Regions.Red, x: 231, y: 812 },
|
|
87
94
|
],
|
|
88
95
|
connections: [
|
|
89
|
-
{ nodes: [Cities.
|
|
90
|
-
{ nodes: [Cities.
|
|
91
|
-
{ nodes: [Cities.Germiston, Cities.
|
|
96
|
+
{ nodes: [Cities.Springbok, Cities.Namibia], cost: 30 },
|
|
97
|
+
{ nodes: [Cities.Bloemfontein, Cities.Lesotho], cost: 30 },
|
|
98
|
+
{ nodes: [Cities.Germiston, Cities.Eswatini], cost: 30 },
|
|
92
99
|
{ nodes: [Cities.Mbombela, Cities.Mozambique], cost: 30 },
|
|
93
|
-
{ nodes: [Cities.Botswana, Cities.
|
|
94
|
-
{ nodes: [Cities.
|
|
95
|
-
{ nodes: [Cities.
|
|
96
|
-
{ nodes: [Cities.
|
|
97
|
-
{ nodes: [Cities.
|
|
98
|
-
{ nodes: [Cities.
|
|
99
|
-
{ nodes: [Cities.
|
|
100
|
-
{ nodes: [Cities.
|
|
101
|
-
{ nodes: [Cities.
|
|
102
|
-
{ nodes: [Cities.
|
|
103
|
-
{ nodes: [Cities.
|
|
104
|
-
{ nodes: [Cities.
|
|
105
|
-
{ nodes: [Cities.
|
|
106
|
-
{ nodes: [Cities.Ladysmith, Cities.
|
|
107
|
-
{ nodes: [Cities.
|
|
108
|
-
{ nodes: [Cities.
|
|
109
|
-
{ nodes: [Cities.
|
|
110
|
-
{ nodes: [Cities.
|
|
111
|
-
{ nodes: [Cities.
|
|
112
|
-
{ nodes: [Cities.
|
|
113
|
-
{ nodes: [Cities.
|
|
114
|
-
{ nodes: [Cities.
|
|
115
|
-
{ nodes: [Cities.
|
|
116
|
-
{ nodes: [Cities.
|
|
117
|
-
{ nodes: [Cities.
|
|
118
|
-
{ nodes: [Cities.
|
|
119
|
-
{ nodes: [Cities.
|
|
120
|
-
{ nodes: [Cities.
|
|
121
|
-
{ nodes: [Cities.
|
|
122
|
-
{ nodes: [Cities.Kimberly, Cities.
|
|
123
|
-
{ nodes: [Cities.Kimberly, Cities.
|
|
124
|
-
{ nodes: [Cities.Kimberly, Cities.
|
|
125
|
-
{ nodes: [Cities.
|
|
126
|
-
{ nodes: [Cities.
|
|
127
|
-
{ nodes: [Cities.
|
|
128
|
-
{ nodes: [Cities.
|
|
100
|
+
{ nodes: [Cities.Botswana, Cities.Rustenburg], cost: 30 },
|
|
101
|
+
{ nodes: [Cities.Zimbabwe, Cities.Musina], cost: 30 },
|
|
102
|
+
{ nodes: [Cities.CapeTownS, Cities.CapeTownN], cost: 0 },
|
|
103
|
+
{ nodes: [Cities.CapeTownS, Cities.George], cost: 16 },
|
|
104
|
+
{ nodes: [Cities.George, Cities.PortElizabeth], cost: 12 },
|
|
105
|
+
{ nodes: [Cities.PortElizabeth, Cities.EastLondon], cost: 13 },
|
|
106
|
+
{ nodes: [Cities.EastLondon, Cities.Mthatha], cost: 8 },
|
|
107
|
+
{ nodes: [Cities.Mthatha, Cities.DurbanS], cost: 13 },
|
|
108
|
+
{ nodes: [Cities.DurbanS, Cities.DurbanN], cost: 0 },
|
|
109
|
+
{ nodes: [Cities.DurbanN, Cities.Pietermaritzburg], cost: 3 },
|
|
110
|
+
{ nodes: [Cities.DurbanN, Cities.Newcastle], cost: 9 },
|
|
111
|
+
{ nodes: [Cities.Newcastle, Cities.Pietermaritzburg], cost: 9 },
|
|
112
|
+
{ nodes: [Cities.Pietermaritzburg, Cities.Ladysmith], cost: 5 },
|
|
113
|
+
{ nodes: [Cities.Ladysmith, Cities.Newcastle], cost: 10 },
|
|
114
|
+
{ nodes: [Cities.Bloemfontein, Cities.Mthatha], cost: 18 },
|
|
115
|
+
{ nodes: [Cities.Bloemfontein, Cities.EastLondon], cost: 22 },
|
|
116
|
+
{ nodes: [Cities.EastLondon, Cities.DeAar], cost: 22 },
|
|
117
|
+
{ nodes: [Cities.DeAar, Cities.PortElizabeth], cost: 18 },
|
|
118
|
+
{ nodes: [Cities.George, Cities.DeAar], cost: 17 },
|
|
119
|
+
{ nodes: [Cities.DeAar, Cities.BeaufortWest], cost: 10 },
|
|
120
|
+
{ nodes: [Cities.BeaufortWest, Cities.George], cost: 8 },
|
|
121
|
+
{ nodes: [Cities.BeaufortWest, Cities.CapeTownN], cost: 22 },
|
|
122
|
+
{ nodes: [Cities.CapeTownN, Cities.Springbok], cost: 22 },
|
|
123
|
+
{ nodes: [Cities.Springbok, Cities.BeaufortWest], cost: 24 },
|
|
124
|
+
{ nodes: [Cities.DeAar, Cities.Springbok], cost: 26 },
|
|
125
|
+
{ nodes: [Cities.Springbok, Cities.Upington], cost: 16 },
|
|
126
|
+
{ nodes: [Cities.Upington, Cities.DeAar], cost: 16 },
|
|
127
|
+
{ nodes: [Cities.DeAar, Cities.Bloemfontein], cost: 13 },
|
|
128
|
+
{ nodes: [Cities.Bloemfontein, Cities.Kimberly], cost: 6 },
|
|
129
|
+
{ nodes: [Cities.Kimberly, Cities.DeAar], cost: 10 },
|
|
130
|
+
{ nodes: [Cities.Kimberly, Cities.Upington], cost: 14 },
|
|
131
|
+
{ nodes: [Cities.Kimberly, Cities.Welkom], cost: 9 },
|
|
132
|
+
{ nodes: [Cities.Welkom, Cities.Bloemfontein], cost: 6 },
|
|
133
|
+
{ nodes: [Cities.Bloemfontein, Cities.Ladysmith], cost: 19 },
|
|
134
|
+
{ nodes: [Cities.Mthatha, Cities.Pietermaritzburg], cost: 12 },
|
|
135
|
+
{ nodes: [Cities.Upington, Cities.Kuruman], cost: 11 },
|
|
129
136
|
{ nodes: [Cities.Musina, Cities.Polokwane], cost: 8 },
|
|
130
|
-
{ nodes: [Cities.Polokwane, Cities.
|
|
131
|
-
{ nodes: [Cities.
|
|
132
|
-
{ nodes: [Cities.
|
|
133
|
-
{ nodes: [Cities.
|
|
134
|
-
{ nodes: [Cities.
|
|
135
|
-
{ nodes: [Cities.
|
|
137
|
+
{ nodes: [Cities.Polokwane, Cities.PretoriaN], cost: 11 },
|
|
138
|
+
{ nodes: [Cities.PretoriaN, Cities.PretoriaS], cost: 0 },
|
|
139
|
+
{ nodes: [Cities.PretoriaS, Cities.JohannesburgN], cost: 2 },
|
|
140
|
+
{ nodes: [Cities.JohannesburgN, Cities.JohannesburgS], cost: 0 },
|
|
141
|
+
{ nodes: [Cities.JohannesburgS, Cities.Germiston], cost: 1 },
|
|
142
|
+
{ nodes: [Cities.JohannesburgN, Cities.Mbombela], cost: 13 },
|
|
136
143
|
{ nodes: [Cities.Mbombela, Cities.Germiston], cost: 13 },
|
|
137
|
-
{ nodes: [Cities.
|
|
144
|
+
{ nodes: [Cities.PretoriaN, Cities.Mbombela], cost: 13 },
|
|
138
145
|
{ nodes: [Cities.Mbombela, Cities.Polokwane], cost: 10 },
|
|
139
146
|
{ nodes: [Cities.Musina, Cities.Mbombela], cost: 15 },
|
|
140
|
-
{ nodes: [Cities.
|
|
141
|
-
{ nodes: [Cities.
|
|
142
|
-
{ nodes: [Cities.
|
|
143
|
-
{ nodes: [Cities.
|
|
144
|
-
{ nodes: [Cities.
|
|
145
|
-
{ nodes: [Cities.
|
|
146
|
-
{ nodes: [Cities.
|
|
147
|
-
{ nodes: [Cities.
|
|
148
|
-
{ nodes: [Cities.
|
|
147
|
+
{ nodes: [Cities.PretoriaN, Cities.Rustenburg], cost: 4 },
|
|
148
|
+
{ nodes: [Cities.Rustenburg, Cities.JohannesburgN], cost: 4 },
|
|
149
|
+
{ nodes: [Cities.JohannesburgN, Cities.Klerksdorp], cost: 7 },
|
|
150
|
+
{ nodes: [Cities.Klerksdorp, Cities.Welkom], cost: 5 },
|
|
151
|
+
{ nodes: [Cities.Bloemfontein, Cities.JohannesburgS], cost: 16 },
|
|
152
|
+
{ nodes: [Cities.Kuruman, Cities.Rustenburg], cost: 18 },
|
|
153
|
+
{ nodes: [Cities.Klerksdorp, Cities.Kuruman], cost: 12 },
|
|
154
|
+
{ nodes: [Cities.Kuruman, Cities.Kimberly], cost: 8 },
|
|
155
|
+
{ nodes: [Cities.JohannesburgS, Cities.Ladysmith], cost: 13 },
|
|
149
156
|
{ nodes: [Cities.Ladysmith, Cities.Germiston], cost: 13 },
|
|
150
157
|
],
|
|
158
|
+
|
|
159
|
+
// Resupply per South Africa refill summary cards. Indexed as
|
|
160
|
+
// [resource][playerCount-2][step-1]. Note: 2P and 3P rows are intentionally
|
|
161
|
+
// identical on the printed cards (same pattern as North America).
|
|
162
|
+
resupply: [
|
|
163
|
+
// Coal
|
|
164
|
+
[
|
|
165
|
+
[4, 7, 5], // 2P
|
|
166
|
+
[4, 7, 5], // 3P
|
|
167
|
+
[5, 8, 6], // 4P
|
|
168
|
+
[6, 9, 7], // 5P
|
|
169
|
+
[7, 10, 8], // 6P
|
|
170
|
+
],
|
|
171
|
+
// Oil
|
|
172
|
+
[
|
|
173
|
+
[1, 2, 1], // 2P
|
|
174
|
+
[1, 2, 1], // 3P
|
|
175
|
+
[2, 3, 2], // 4P
|
|
176
|
+
[2, 4, 3], // 5P
|
|
177
|
+
[4, 5, 4], // 6P
|
|
178
|
+
],
|
|
179
|
+
// Garbage
|
|
180
|
+
[
|
|
181
|
+
[1, 3, 3], // 2P
|
|
182
|
+
[1, 3, 3], // 3P
|
|
183
|
+
[2, 4, 4], // 4P
|
|
184
|
+
[3, 4, 5], // 5P
|
|
185
|
+
[3, 6, 6], // 6P
|
|
186
|
+
],
|
|
187
|
+
// Uranium
|
|
188
|
+
[
|
|
189
|
+
[1, 1, 2], // 2P
|
|
190
|
+
[1, 1, 2], // 3P
|
|
191
|
+
[2, 2, 3], // 4P
|
|
192
|
+
[2, 3, 3], // 5P
|
|
193
|
+
[2, 3, 4], // 6P
|
|
194
|
+
],
|
|
195
|
+
],
|
|
196
|
+
layout: 'Landscape',
|
|
197
|
+
// Cities authored at photo-coord scale (~1200x863). First-pass fit into the
|
|
198
|
+
// standard 1500x800 landscape viewBox — tune after first render.
|
|
199
|
+
adjustRatio: [0.9, 0.75],
|
|
200
|
+
mapPosition: [70, 50],
|
|
201
|
+
mapRotation: 0,
|
|
202
|
+
// SA uses the engine default 8-price market (24 coal / 24 oil / 24 garbage
|
|
203
|
+
// slots + 12 uranium 1–8 + 10/12/14/16), so we don't override coal/oil/
|
|
204
|
+
// garbage/uranium Prices. Only the starting fill differs:
|
|
205
|
+
// coal 1–8 full = 24
|
|
206
|
+
// oil 4–8 = 15
|
|
207
|
+
// garbage 5–8 = 12
|
|
208
|
+
// uranium 12–16 only = 3
|
|
209
|
+
startingResources: [24, 15, 12, 3],
|
|
210
|
+
// Total cubes in the game (used cubes return here; refill draws from here).
|
|
211
|
+
// For SA, USED coal goes to the separate coalStorage pool instead — see
|
|
212
|
+
// GameState.coalStorage and the UsePowerPlant/resupply branches in engine.ts.
|
|
213
|
+
startingSupply: [24, 24, 24, 12],
|
|
214
|
+
// SA removes oil power plant 07 from the deck; the rest follows the standard
|
|
215
|
+
// recharged/original deck setup. With 07 gone the "starter pool" is one
|
|
216
|
+
// plant shorter (12 instead of 13 for recharged; future market shifts to
|
|
217
|
+
// 8/9/10/11 instead of 7/8/9/10 for original).
|
|
218
|
+
setupDeck(numPlayers: number, variant: string, rng: seedrandom.prng) {
|
|
219
|
+
let powerPlantsDeck = cloneDeep(powerPlants).filter((pp) => pp.number !== 7);
|
|
220
|
+
let actualMarket: PowerPlant[];
|
|
221
|
+
let futureMarket: PowerPlant[];
|
|
222
|
+
|
|
223
|
+
if (variant == 'original') {
|
|
224
|
+
powerPlantsDeck = powerPlantsDeck.slice(8);
|
|
225
|
+
const powerPlant13Idx = powerPlantsDeck.findIndex((pp) => pp.number == 13);
|
|
226
|
+
const powerPlant13 = powerPlantsDeck.splice(powerPlant13Idx, 1)[0];
|
|
227
|
+
const step3 = powerPlantsDeck.pop()!;
|
|
228
|
+
|
|
229
|
+
powerPlantsDeck = shuffle(powerPlantsDeck, rng() + '');
|
|
230
|
+
if (numPlayers == 2 || numPlayers == 3) {
|
|
231
|
+
powerPlantsDeck = powerPlantsDeck.slice(8);
|
|
232
|
+
} else if (numPlayers == 4) {
|
|
233
|
+
powerPlantsDeck = powerPlantsDeck.slice(4);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
powerPlantsDeck.unshift(powerPlant13);
|
|
237
|
+
powerPlantsDeck.push(step3);
|
|
238
|
+
|
|
239
|
+
actualMarket = [getPowerPlant(3), getPowerPlant(4), getPowerPlant(5), getPowerPlant(6)];
|
|
240
|
+
futureMarket = [getPowerPlant(8), getPowerPlant(9), getPowerPlant(10), getPowerPlant(11)];
|
|
241
|
+
} else {
|
|
242
|
+
let initialPowerPlants = shuffle(powerPlantsDeck.splice(0, 12), rng() + '');
|
|
243
|
+
let initialPlantMarket = initialPowerPlants.splice(0, 8);
|
|
244
|
+
initialPlantMarket = initialPlantMarket.sort((a, b) => a.number - b.number);
|
|
245
|
+
actualMarket = initialPlantMarket.slice(0, 4);
|
|
246
|
+
futureMarket = initialPlantMarket.slice(4);
|
|
247
|
+
|
|
248
|
+
const first = initialPowerPlants.shift()!;
|
|
249
|
+
const step3 = powerPlantsDeck.pop()!;
|
|
250
|
+
|
|
251
|
+
powerPlantsDeck = shuffle(powerPlantsDeck, rng() + '');
|
|
252
|
+
if (numPlayers == 2 || numPlayers == 3) {
|
|
253
|
+
initialPowerPlants = initialPowerPlants.slice(2);
|
|
254
|
+
powerPlantsDeck = shuffle(powerPlantsDeck.slice(6).concat(initialPowerPlants), rng() + '');
|
|
255
|
+
} else if (numPlayers == 4) {
|
|
256
|
+
initialPowerPlants = initialPowerPlants.slice(1);
|
|
257
|
+
powerPlantsDeck = shuffle(powerPlantsDeck.slice(3).concat(initialPowerPlants), rng() + '');
|
|
258
|
+
} else {
|
|
259
|
+
powerPlantsDeck = shuffle(powerPlantsDeck.concat(initialPowerPlants), rng() + '');
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
powerPlantsDeck.unshift(first);
|
|
263
|
+
powerPlantsDeck.push(step3);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
return { actualMarket, futureMarket, powerPlantsDeck };
|
|
267
|
+
},
|
|
268
|
+
mapSpecificRules:
|
|
269
|
+
'Coal storage: there is a separate storage space below the resource market, ' +
|
|
270
|
+
'empty at game start. Coal used to power plants returns to this storage space ' +
|
|
271
|
+
'(not the main supply). The resource-market refill draws coal from storage ' +
|
|
272
|
+
'first, then from the main supply. Players can always buy coal for $8 from ' +
|
|
273
|
+
'the storage space (in addition to the standard market price). ' +
|
|
274
|
+
'Metropolises: Cape Town, Durban, Johannesburg and Pretoria each consist of ' +
|
|
275
|
+
'two cities (N and S) connected by a 0-cost edge. ' +
|
|
276
|
+
'Cross-border connections: the six 30-Elektro connections to neighboring ' +
|
|
277
|
+
'countries (Namibia, Botswana, Zimbabwe, Mozambique, Eswatini, Lesotho) are ' +
|
|
278
|
+
'available from the start of the game. The 30 Elektro is the complete cost ' +
|
|
279
|
+
'— no house-base cost is added on top. Only a single player can build on ' +
|
|
280
|
+
'each cross-border space (cap of 1 instead of the standard 3). ' +
|
|
281
|
+
'Power plant 07 is removed from the deck.',
|
|
151
282
|
};
|
package/src/maps/ukireland.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
+
// by John and Cici
|
|
2
|
+
import { cloneDeep } from 'lodash';
|
|
3
|
+
import seedrandom from 'seedrandom';
|
|
4
|
+
import { getPowerPlant } from '../engine';
|
|
5
|
+
import { PowerPlant } from '../gamestate';
|
|
6
|
+
import { shuffle } from '../utils';
|
|
1
7
|
import { GameMap } from './../maps';
|
|
8
|
+
import { powerPlants } from './../powerPlants';
|
|
2
9
|
|
|
3
10
|
export enum Regions {
|
|
4
11
|
Red = 'red',
|
|
@@ -55,46 +62,46 @@ export enum Cities {
|
|
|
55
62
|
export const map: GameMap = {
|
|
56
63
|
name: 'UK & Ireland',
|
|
57
64
|
cities: [
|
|
58
|
-
{ name: Cities.Norwich, region: Regions.Red, x: 646, y: 702 },
|
|
59
|
-
{ name: Cities.London1, region: Regions.Red, x: 554, y: 756 },
|
|
60
|
-
{ name: Cities.London2, region: Regions.Red, x: 550, y: 780 },
|
|
61
|
-
{ name: Cities.Brighton, region: Regions.Red, x: 537, y: 837 },
|
|
62
|
-
{ name: Cities.Southampton, region: Regions.Red, x: 451, y: 805 },
|
|
63
|
-
{ name: Cities.Plymouth, region: Regions.Red, x: 312, y: 814 },
|
|
64
|
-
{ name: Cities.Leicester, region: Regions.Red, x: 540, y: 680 },
|
|
65
|
-
{ name: Cities.Bristol, region: Regions.Red, x: 425, y: 762 },
|
|
66
|
-
{ name: Cities.Newcastleupontyne, region: Regions.Pink, x: 550, y: 414 },
|
|
67
|
-
{ name: Cities.Leeds, region: Regions.Pink, x: 559, y: 541 },
|
|
68
|
-
{ name: Cities.Sheffield, region: Regions.Pink, x: 530, y: 590 },
|
|
69
|
-
{ name: Cities.Nottingham, region: Regions.Pink, x: 531, y: 632 },
|
|
70
|
-
{ name: Cities.Birmingham, region: Regions.Pink, x: 465, y: 663 },
|
|
71
|
-
{ name: Cities.Manchester, region: Regions.Pink, x: 479, y: 543 },
|
|
72
|
-
{ name: Cities.Liverpool, region: Regions.Pink, x: 433, y: 576 },
|
|
73
|
-
{ name: Cities.Newportcasnewydd, region: Regions.Yellow, x: 425, y: 722 },
|
|
74
|
-
{ name: Cities.Bangor, region: Regions.Yellow, x: 348, y: 574 },
|
|
75
|
-
{ name: Cities.Aberystwyth, region: Regions.Yellow, x: 357, y: 639 },
|
|
76
|
-
{ name: Cities.Swanseaabertawe, region: Regions.Yellow, x: 346, y: 706 },
|
|
77
|
-
{ name: Cities.Cardiffcaerdydd, region: Regions.Yellow, x: 357, y: 741 },
|
|
78
|
-
{ name: Cities.Haverfordwesthwlffordd, region: Regions.Yellow, x: 303, y: 673 },
|
|
79
|
-
{ name: Cities.Invernessinbhirnis, region: Regions.Brown, x: 479, y: 208 },
|
|
80
|
-
{ name: Cities.Aberdeenobardheathain, region: Regions.Brown, x: 588, y: 245 },
|
|
81
|
-
{ name: Cities.Dundeedundeach, region: Regions.Brown, x: 552, y: 286 },
|
|
82
|
-
{ name: Cities.Perthpeairt, region: Regions.Brown, x: 489, y: 307 },
|
|
83
|
-
{ name: Cities.Edinburgh, region: Regions.Brown, x: 494, y: 350 },
|
|
84
|
-
{ name: Cities.Dumfries, region: Regions.Brown, x: 441, y: 417 },
|
|
85
|
-
{ name: Cities.Glasgow, region: Regions.Brown, x: 422, y: 335 },
|
|
86
|
-
{ name: Cities.Coleraine, region: Regions.Orange, x: 330, y: 367 },
|
|
87
|
-
{ name: Cities.Derry, region: Regions.Orange, x: 256, y: 362 },
|
|
88
|
-
{ name: Cities.Belfast, region: Regions.Orange, x: 342, y: 421 },
|
|
89
|
-
{ name: Cities.Newry, region: Regions.Orange, x: 298, y: 462 },
|
|
90
|
-
{ name: Cities.Omagh, region: Regions.Orange, x: 260, y: 403 },
|
|
91
|
-
{ name: Cities.Sligo, region: Regions.Green, x: 181, y: 411 },
|
|
92
|
-
{ name: Cities.Dublin, region: Regions.Green, x: 274, y: 530 },
|
|
93
|
-
{ name: Cities.Waterford, region: Regions.Green, x: 210, y: 611 },
|
|
94
|
-
{ name: Cities.Cork, region: Regions.Green, x: 114, y: 626 },
|
|
95
|
-
{ name: Cities.Athlone, region: Regions.Green, x: 200, y: 489 },
|
|
96
|
-
{ name: Cities.Galway, region: Regions.Green, x: 112, y: 486 },
|
|
97
|
-
{ name: Cities.Limerick, region: Regions.Green, x: 122, y: 546 },
|
|
65
|
+
{ name: Cities.Norwich, region: Regions.Red, island: 'gb', x: 646, y: 702 },
|
|
66
|
+
{ name: Cities.London1, region: Regions.Red, island: 'gb', x: 554, y: 756 },
|
|
67
|
+
{ name: Cities.London2, region: Regions.Red, island: 'gb', x: 550, y: 780 },
|
|
68
|
+
{ name: Cities.Brighton, region: Regions.Red, island: 'gb', x: 537, y: 837 },
|
|
69
|
+
{ name: Cities.Southampton, region: Regions.Red, island: 'gb', x: 451, y: 805 },
|
|
70
|
+
{ name: Cities.Plymouth, region: Regions.Red, island: 'gb', x: 312, y: 814 },
|
|
71
|
+
{ name: Cities.Leicester, region: Regions.Red, island: 'gb', x: 540, y: 680 },
|
|
72
|
+
{ name: Cities.Bristol, region: Regions.Red, island: 'gb', x: 425, y: 762 },
|
|
73
|
+
{ name: Cities.Newcastleupontyne, region: Regions.Pink, island: 'gb', x: 550, y: 414 },
|
|
74
|
+
{ name: Cities.Leeds, region: Regions.Pink, island: 'gb', x: 559, y: 541 },
|
|
75
|
+
{ name: Cities.Sheffield, region: Regions.Pink, island: 'gb', x: 530, y: 590 },
|
|
76
|
+
{ name: Cities.Nottingham, region: Regions.Pink, island: 'gb', x: 531, y: 632 },
|
|
77
|
+
{ name: Cities.Birmingham, region: Regions.Pink, island: 'gb', x: 465, y: 663 },
|
|
78
|
+
{ name: Cities.Manchester, region: Regions.Pink, island: 'gb', x: 479, y: 543 },
|
|
79
|
+
{ name: Cities.Liverpool, region: Regions.Pink, island: 'gb', x: 433, y: 576 },
|
|
80
|
+
{ name: Cities.Newportcasnewydd, region: Regions.Yellow, island: 'gb', x: 425, y: 722 },
|
|
81
|
+
{ name: Cities.Bangor, region: Regions.Yellow, island: 'gb', x: 348, y: 574 },
|
|
82
|
+
{ name: Cities.Aberystwyth, region: Regions.Yellow, island: 'gb', x: 357, y: 639 },
|
|
83
|
+
{ name: Cities.Swanseaabertawe, region: Regions.Yellow, island: 'gb', x: 346, y: 706 },
|
|
84
|
+
{ name: Cities.Cardiffcaerdydd, region: Regions.Yellow, island: 'gb', x: 357, y: 741 },
|
|
85
|
+
{ name: Cities.Haverfordwesthwlffordd, region: Regions.Yellow, island: 'gb', x: 303, y: 673 },
|
|
86
|
+
{ name: Cities.Invernessinbhirnis, region: Regions.Brown, island: 'gb', x: 479, y: 208 },
|
|
87
|
+
{ name: Cities.Aberdeenobardheathain, region: Regions.Brown, island: 'gb', x: 588, y: 245 },
|
|
88
|
+
{ name: Cities.Dundeedundeach, region: Regions.Brown, island: 'gb', x: 552, y: 286 },
|
|
89
|
+
{ name: Cities.Perthpeairt, region: Regions.Brown, island: 'gb', x: 489, y: 307 },
|
|
90
|
+
{ name: Cities.Edinburgh, region: Regions.Brown, island: 'gb', x: 494, y: 350 },
|
|
91
|
+
{ name: Cities.Dumfries, region: Regions.Brown, island: 'gb', x: 441, y: 417 },
|
|
92
|
+
{ name: Cities.Glasgow, region: Regions.Brown, island: 'gb', x: 422, y: 335 },
|
|
93
|
+
{ name: Cities.Coleraine, region: Regions.Orange, island: 'ie', x: 330, y: 367 },
|
|
94
|
+
{ name: Cities.Derry, region: Regions.Orange, island: 'ie', x: 256, y: 362 },
|
|
95
|
+
{ name: Cities.Belfast, region: Regions.Orange, island: 'ie', x: 342, y: 421 },
|
|
96
|
+
{ name: Cities.Newry, region: Regions.Orange, island: 'ie', x: 298, y: 462 },
|
|
97
|
+
{ name: Cities.Omagh, region: Regions.Orange, island: 'ie', x: 260, y: 403 },
|
|
98
|
+
{ name: Cities.Sligo, region: Regions.Green, island: 'ie', x: 181, y: 411 },
|
|
99
|
+
{ name: Cities.Dublin, region: Regions.Green, island: 'ie', x: 274, y: 530 },
|
|
100
|
+
{ name: Cities.Waterford, region: Regions.Green, island: 'ie', x: 210, y: 611 },
|
|
101
|
+
{ name: Cities.Cork, region: Regions.Green, island: 'ie', x: 114, y: 626 },
|
|
102
|
+
{ name: Cities.Athlone, region: Regions.Green, island: 'ie', x: 200, y: 489 },
|
|
103
|
+
{ name: Cities.Galway, region: Regions.Green, island: 'ie', x: 112, y: 486 },
|
|
104
|
+
{ name: Cities.Limerick, region: Regions.Green, island: 'ie', x: 122, y: 546 },
|
|
98
105
|
],
|
|
99
106
|
connections: [
|
|
100
107
|
{ nodes: [Cities.Nottingham, Cities.Leicester], cost: 4 },
|
|
@@ -172,4 +179,127 @@ export const map: GameMap = {
|
|
|
172
179
|
{ nodes: [Cities.Omagh, Cities.Derry], cost: 5 },
|
|
173
180
|
{ nodes: [Cities.Omagh, Cities.Sligo], cost: 10 },
|
|
174
181
|
],
|
|
182
|
+
layout: 'Portrait',
|
|
183
|
+
// Stub coords are at photo scale (x range ~110-650, y range ~200-840 — taller
|
|
184
|
+
// than wide). First-pass fit into the default portrait viewBox — tune after
|
|
185
|
+
// first render against the printed board.
|
|
186
|
+
adjustRatio: [1.1, 1.1],
|
|
187
|
+
mapPosition: [10, -75],
|
|
188
|
+
mapRotation: 0,
|
|
189
|
+
// Resupply table read from the printed UK & Ireland refill summary cards.
|
|
190
|
+
// Indexed [resource][playerCount-2][step-1]. Note: 2P and 3P rows are NOT
|
|
191
|
+
// identical on this map (unlike NA / SA), except for the Garbage row.
|
|
192
|
+
resupply: [
|
|
193
|
+
// Coal
|
|
194
|
+
[
|
|
195
|
+
[3, 4, 3], // 2P
|
|
196
|
+
[3, 5, 3], // 3P
|
|
197
|
+
[4, 6, 4], // 4P
|
|
198
|
+
[4, 7, 5], // 5P
|
|
199
|
+
[6, 8, 6], // 6P
|
|
200
|
+
],
|
|
201
|
+
// Oil
|
|
202
|
+
[
|
|
203
|
+
[2, 3, 2], // 2P
|
|
204
|
+
[2, 4, 2], // 3P
|
|
205
|
+
[3, 5, 3], // 4P
|
|
206
|
+
[4, 6, 4], // 5P
|
|
207
|
+
[5, 7, 5], // 6P
|
|
208
|
+
],
|
|
209
|
+
// Garbage
|
|
210
|
+
[
|
|
211
|
+
[1, 2, 2], // 2P
|
|
212
|
+
[1, 2, 2], // 3P
|
|
213
|
+
[2, 3, 3], // 4P
|
|
214
|
+
[3, 3, 5], // 5P
|
|
215
|
+
[3, 5, 5], // 6P
|
|
216
|
+
],
|
|
217
|
+
// Uranium
|
|
218
|
+
[
|
|
219
|
+
[1, 1, 1], // 2P
|
|
220
|
+
[1, 2, 1], // 3P
|
|
221
|
+
[1, 3, 1], // 4P
|
|
222
|
+
[2, 4, 2], // 5P
|
|
223
|
+
[2, 4, 3], // 6P
|
|
224
|
+
],
|
|
225
|
+
],
|
|
226
|
+
// Standard 8-price market (no overrides). Starting fill from the rulebook:
|
|
227
|
+
// coal 1-8 full = 24
|
|
228
|
+
// oil 3-8 = 18
|
|
229
|
+
// garbage 5-8 = 12
|
|
230
|
+
// uranium none = 0
|
|
231
|
+
startingResources: [24, 18, 12, 0],
|
|
232
|
+
startingSupply: [24, 24, 24, 12],
|
|
233
|
+
// Two-network mechanic: 20 Elektro surcharge to start a network on an
|
|
234
|
+
// island where the player has no city. The cross-island build skips the
|
|
235
|
+
// dijkstra path (there is no sea edge) and pays house base + 20.
|
|
236
|
+
crossIslandSurcharge: 20,
|
|
237
|
+
// Step 3 is placed 3rd from last in the deck (two plants below it) so Step
|
|
238
|
+
// 3 starts earlier than on most maps. Otherwise standard recharged/original
|
|
239
|
+
// deck prep.
|
|
240
|
+
setupDeck(numPlayers: number, variant: string, rng: seedrandom.prng) {
|
|
241
|
+
let powerPlantsDeck = cloneDeep(powerPlants);
|
|
242
|
+
let actualMarket: PowerPlant[];
|
|
243
|
+
let futureMarket: PowerPlant[];
|
|
244
|
+
|
|
245
|
+
if (variant == 'original') {
|
|
246
|
+
powerPlantsDeck = powerPlantsDeck.slice(8);
|
|
247
|
+
const powerPlant13Idx = powerPlantsDeck.findIndex((pp) => pp.number == 13);
|
|
248
|
+
const powerPlant13 = powerPlantsDeck.splice(powerPlant13Idx, 1)[0];
|
|
249
|
+
const step3 = powerPlantsDeck.pop()!;
|
|
250
|
+
|
|
251
|
+
powerPlantsDeck = shuffle(powerPlantsDeck, rng() + '');
|
|
252
|
+
if (numPlayers == 2 || numPlayers == 3) {
|
|
253
|
+
powerPlantsDeck = powerPlantsDeck.slice(8);
|
|
254
|
+
} else if (numPlayers == 4) {
|
|
255
|
+
powerPlantsDeck = powerPlantsDeck.slice(4);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
powerPlantsDeck.unshift(powerPlant13);
|
|
259
|
+
// UK&I: Step 3 sits 3rd from last (two plants below it).
|
|
260
|
+
powerPlantsDeck.splice(powerPlantsDeck.length - 2, 0, step3);
|
|
261
|
+
|
|
262
|
+
actualMarket = [getPowerPlant(3), getPowerPlant(4), getPowerPlant(5), getPowerPlant(6)];
|
|
263
|
+
futureMarket = [getPowerPlant(7), getPowerPlant(8), getPowerPlant(9), getPowerPlant(10)];
|
|
264
|
+
} else {
|
|
265
|
+
let initialPowerPlants = shuffle(powerPlantsDeck.splice(0, 13), rng() + '');
|
|
266
|
+
let initialPlantMarket = initialPowerPlants.splice(0, 8);
|
|
267
|
+
initialPlantMarket = initialPlantMarket.sort((a, b) => a.number - b.number);
|
|
268
|
+
actualMarket = initialPlantMarket.slice(0, 4);
|
|
269
|
+
futureMarket = initialPlantMarket.slice(4);
|
|
270
|
+
|
|
271
|
+
const first = initialPowerPlants.shift()!;
|
|
272
|
+
const step3 = powerPlantsDeck.pop()!;
|
|
273
|
+
|
|
274
|
+
powerPlantsDeck = shuffle(powerPlantsDeck, rng() + '');
|
|
275
|
+
if (numPlayers == 2 || numPlayers == 3) {
|
|
276
|
+
initialPowerPlants = initialPowerPlants.slice(2);
|
|
277
|
+
powerPlantsDeck = shuffle(powerPlantsDeck.slice(6).concat(initialPowerPlants), rng() + '');
|
|
278
|
+
} else if (numPlayers == 4) {
|
|
279
|
+
initialPowerPlants = initialPowerPlants.slice(1);
|
|
280
|
+
powerPlantsDeck = shuffle(powerPlantsDeck.slice(3).concat(initialPowerPlants), rng() + '');
|
|
281
|
+
} else {
|
|
282
|
+
powerPlantsDeck = shuffle(powerPlantsDeck.concat(initialPowerPlants), rng() + '');
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
powerPlantsDeck.unshift(first);
|
|
286
|
+
// UK&I: Step 3 sits 3rd from last (two plants below it). The engine's
|
|
287
|
+
// standard Step 3 trigger already reshuffles plants below + discard
|
|
288
|
+
// into the new face-down deck, so we only need the placement here.
|
|
289
|
+
powerPlantsDeck.splice(powerPlantsDeck.length - 2, 0, step3);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return { actualMarket, futureMarket, powerPlantsDeck };
|
|
293
|
+
},
|
|
294
|
+
mapSpecificRules:
|
|
295
|
+
'Two networks: Ireland (Green and Orange regions) and Great Britain ' +
|
|
296
|
+
'(Red, Pink, Yellow, Brown) have no sea connection. A player may run ' +
|
|
297
|
+
'one network on each island. Starting a second network on the other ' +
|
|
298
|
+
'island costs an extra 20 Elektro on top of the normal first-house cost. ' +
|
|
299
|
+
'Nuclear restriction: a player whose network is entirely in the Republic ' +
|
|
300
|
+
'of Ireland (Green region) cannot bid on or auction a nuclear power plant ' +
|
|
301
|
+
'until they build a city in Scotland, Wales, England, or Northern Ireland. ' +
|
|
302
|
+
'Early Step 3: the Step 3 card is placed 3rd from last in the deck (two ' +
|
|
303
|
+
'plants below it). Step 2 begins when a player connects their 7th city ' +
|
|
304
|
+
'(6th for 6 players).',
|
|
175
305
|
};
|