-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathboards.ts
265 lines (256 loc) · 8.49 KB
/
boards.ts
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
import {
Hex,
HexTemplate,
MaxPipsOnChit,
ResourceProducingHexType,
} from "./hexes";
/**
* A template to simplify the specification of a `CatanBoard`
*
*/
export type CatanBoardTemplate = {
/**
* Board shape and initial layout. Each hex spans two CSS grid columns. A
* special `HexTemplate` type `"empty"` is provided to specify *single* empty
* columns. Thus, where `s` is sea and `t` is terrain, we can specify a board
* that looks like this:
*
* ```
* s s s s
* s t t t s
* s t t t t s
* s t t t t t s
* s t t t t s
* s t t t s
* s s s s
* ```
*
* as follows, where `e` is `"empty"`:
*
* ```
* e e e s s s s
* e e s t t t s
* e s t t t t s
* s t t t t t s
* e s t t t t s
* e e s t t t s
* e e e s s s s
* ```
*/
board: HexTemplate[][];
/**
* See {@link UseHorizonalLayout}
*/
horizontal?: UseHorizonalLayout;
/**
* See {@link MinPipsOnHexTypes}
*/
minPipsOnHexTypes?: MinPipsOnHexTypes;
/**
* See {@link MaxPipsOnHexTypes}
*/
maxPipsOnHexTypes?: MaxPipsOnHexTypes;
/**
* See {@link FixNumbersInGroup}
*/
fixNumbersInGroups?: FixNumbersInGroup[];
};
/**
* If true, number chits are rotated -90°, then the entire board 90°. As such, a
* horizontal board must be specified top to bottom (cols) right to left (rows)
* instead of the usual left to right (cols) top to bottom (rows). Useful e.g.
* for Seafarers
*/
export type UseHorizonalLayout = boolean;
/**
* The minimum number of pips which must appear on chits assigned to specified
* hex types after shuffling. This is to be used when the instructions specify
* e.g. to "make sure forest terrains and pasture terrains don't get number
* tokens that are too unfavorable".
*/
export type MinPipsOnHexTypes = {
[type in ResourceProducingHexType]?: 2 | 3 | 4 | 5;
};
/**
* The maxiumum number of pips which may appear on chits assigned to specified
* hex types after shuffling. This is to be used when the instructions specify
* e.g. to "not place... 6s & 8s... on gold fields".
*/
export type MaxPipsOnHexTypes = {
[type in ResourceProducingHexType]?: 1 | 2 | 3 | 4;
};
/**
* The number chits assigned to the hexes in the specified group(s) should not
* be shuffled. The The Pirate Islands scenario, for example, specifies that no
* number chits should be shuffled, and The Wonders of Catan scenario only
* allows shuffling on the main island. Several notes:
*
* 1. The default group (see {@link Hex[group]}) when none is specified is
* `undefined`, so in order to indicate the default group specifically, one
* must specify `undefined`. However, when the meaning is "fix all groups",
* the alias `"all"` is also provided.
* 2. Fixing only some numbers within groups is more complicated due to
* the way shuffling proceeds and is not currently supported. In practice,
* numbers can always be fixed by creating a new group, but the case of
* fixing *some* numbers but allowing *all* terrain to be freely shuffled is
* not supported (no known scenario follows this pattern).
* 3. If this is used for a group where any non-resource-producing hexes are
* not fixed, a number may end up on e.g. the desert, which is obviously
* not desirable. Correct board specification is not rigorously checked and
* left instead to the programmer.
*/
export type FixNumbersInGroup = number | undefined | "all";
/**
* The explicit version of {@link FixNumbersInGroup} used on {@link CatanBoard}
*/
export type FixNumbersInGroupStrict = Exclude<FixNumbersInGroup, "all">;
/**
* Container for explicit storage of neighboring hex indices along with their
* spatial relation to the current hex. Directions are w.r.t. the vertical
* specification of a board. See {@link UseHorizonalLayout}
*/
export type Neighbors = Partial<
Record<"nw" | "ne" | "e" | "se" | "sw" | "w", number>
>;
/**
* All of the data about a Catan board, including the hexes and number chits
* used as well as board shape and display styling. Note that by convention,
* hexes are counted off left to right, top to bottom. For example, in the base
* game, the following indices are used:
*
* ```
* 0 1 2
* 3 4 5 6
* 7 8 9 10 11
* 12 13 14 15
* 16 17 18
* ```
*/
export interface CatanBoard {
/**
* An array of `Hex`s corresponding to the recommended board layout per the
* game manual
*/
recommendedLayout: Hex[];
/**
* An array of `Neighbors` for each hex. See {@link Neighbors}
*/
neighbors: Neighbors[];
/** The CSS
* [grid-template-columns](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns)
* that will be used for the board grid
*/
cssGridTemplateColumns: string;
/** The CSS
* [grid-template-rows](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-rows)
* that will be used for the board grid
*/
cssGridTemplateRows: string;
/**
* An array of CSS
* [grid-area](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-area)
* strings
*/
cssGridAreas: string[];
/**
* If this board grid isn't square, a custom width percentage can be used to
* fix the aspect ratio. Defaults to 100%
*/
boardWidthPercentage?: string;
/**
* If this board grid isn't square, a custom height percentage can be used to
* fix the aspect ratio. Defaults to 100%
*/
boardHeightPercentage?: string;
/**
* See {@link UseHorizonalLayout}
*/
horizontal?: UseHorizonalLayout;
/**
* See {@link MinPipsOnHexTypes}
*/
minPipsOnHexTypes?: MinPipsOnHexTypes;
/**
* See {@link MaxPipsOnHexTypes}
*/
maxPipsOnHexTypes?: MaxPipsOnHexTypes;
/**
* See {@link MaxPipsOnChit}
*/
maxPipsOnChits: MaxPipsOnChit[];
/**
* See {@link FixNumbersInGroupStrict}
*/
fixNumbersInGroups?: FixNumbersInGroupStrict[];
}
export type ExpansionName =
| "Catan"
| "Catan: 5-6 Player Extension"
| "Explorers & Pirates"
| "Explorers & Pirates & Fish"
| "Cities & Knights"
| "Explorers & Pirates + Cities & Knights"
| "Explorers & Pirates & Cities & Knights & Fish (Oh My!)"
| "Heading for New Shores 3-Player Set-up"
| "Heading for New Shores 4-Player Set-up"
| "The Four Islands 3-Player Set-up"
| "The Four Islands 4-Player Set-up"
| "The Fog Islands 3-Player Set-up"
| "The Fog Islands 4-Player Set-up"
| "Through the Desert 3-Player Set-up"
| "Through the Desert 4-Player Set-up"
| "The Forgotten Tribe"
| "Cloth for Catan"
| "The Pirate Islands"
| "The Pirate Islands (Shuffled)"
| "The Wonders of Catan"
| "The Wonders of Catan (Straight Constrained)"
| "New World"
| "New World of Fish"
| "New World Expanded"
| "New World of Fish Expanded"
| "New World Islands"
| "New World of Fish & Islands"
| "Everything, Everywhere, All at Once"
| "Everything, Everywhere, All at Once, Variable"
| "Everything, Everywhere, All the Fish"
| "Everything, Everywhere, All the Fish, Variable"
| "Seafarers & Pirates"
| "Seafarers & Pirates, Variable"
| "Seafarers & Piratical Fish"
| "Seafarers & Piratical Fish, Variable"
| "The Fishermen of Catan"
| "The Rivers of Catan"
| "The Rivers & Lakes of Catan"
| "The Caravans"
| "The Fishy Caravans"
| "Barbarian Attack"
| "Barbarians Attack the Fish"
| "Traders & Barbarians"
| "Traders & Barbarians & Fish"
| "Traders & Barbarians Ultimate (green 1)"
| "Traders & Barbarians Ultimate (green 2)"
| "Traders & Barbarians Ultimate (green 3)"
| "Traders & Barbarians Ultimate (green 4)"
| "Traders & Barbarians Ultimate (green 5)"
| "Traders & Barbarians Ultimate (green 6)"
| "Traders & Barbarians Ultimate (purple 1)"
| "Traders & Barbarians Ultimate (purple 2)"
| "Traders & Barbarians Ultimate (purple 3)"
| "Traders & Barbarians Ultimate (purple 4)"
| "Traders & Barbarians Ultimate (purple 5)"
| "Traders & Barbarians Ultimate (purple 6)"
| "Traders & Barbarians Ultimate (orange 1)"
| "Traders & Barbarians Ultimate (orange 2)"
| "Traders & Barbarians Ultimate (orange 3)"
| "Traders & Barbarians Ultimate (orange 4)"
| "Traders & Barbarians Ultimate (orange 5)"
| "Traders & Barbarians Ultimate (orange 6)";
/**
* A map of expansion names to their board data. Meant to be the top-level
* container for board definitions. `Map`s maintain the type of their keys in
* typescript (as oppposed to `Object`s, which coerce property names to `string`
* when asked e.g. for `Object.keys(...)`), so they're just a little nicer to
* use in the particular way we use `Expansions`
*/
export type Expansions = Map<ExpansionName, CatanBoard>;