@thegraid/hexlib 1.0.14 → 1.1.3

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.
Files changed (47) hide show
  1. package/README.md +3 -0
  2. package/dist/game-play.d.ts +8 -15
  3. package/dist/game-play.d.ts.map +1 -1
  4. package/dist/game-play.js +12 -19
  5. package/dist/game-play.js.map +1 -1
  6. package/dist/game-setup.d.ts +44 -19
  7. package/dist/game-setup.d.ts.map +1 -1
  8. package/dist/game-setup.js +71 -35
  9. package/dist/game-setup.js.map +1 -1
  10. package/dist/hex-intfs.d.ts +2 -1
  11. package/dist/hex-intfs.d.ts.map +1 -1
  12. package/dist/hex-intfs.js +14 -13
  13. package/dist/hex-intfs.js.map +1 -1
  14. package/dist/hex.d.ts +209 -97
  15. package/dist/hex.d.ts.map +1 -1
  16. package/dist/hex.js +223 -193
  17. package/dist/hex.js.map +1 -1
  18. package/dist/meeple.d.ts +10 -8
  19. package/dist/meeple.d.ts.map +1 -1
  20. package/dist/meeple.js +12 -20
  21. package/dist/meeple.js.map +1 -1
  22. package/dist/plan-proxy.d.ts.map +1 -1
  23. package/dist/plan-proxy.js +4 -4
  24. package/dist/scenario-parser.d.ts +3 -2
  25. package/dist/scenario-parser.d.ts.map +1 -1
  26. package/dist/scenario-parser.js +2 -2
  27. package/dist/scenario-parser.js.map +1 -1
  28. package/dist/shapes.d.ts +5 -5
  29. package/dist/shapes.d.ts.map +1 -1
  30. package/dist/shapes.js +2 -2
  31. package/dist/shapes.js.map +1 -1
  32. package/dist/stream-writer.js +3 -3
  33. package/dist/table-params.d.ts.map +1 -1
  34. package/dist/table-params.js +1 -1
  35. package/dist/table-params.js.map +1 -1
  36. package/dist/table.d.ts +1109 -21
  37. package/dist/table.d.ts.map +1 -1
  38. package/dist/table.js +72 -38
  39. package/dist/table.js.map +1 -1
  40. package/dist/tile-source.d.ts +3 -3
  41. package/dist/tile-source.d.ts.map +1 -1
  42. package/dist/tile-source.js.map +1 -1
  43. package/dist/tile.d.ts +71 -23
  44. package/dist/tile.d.ts.map +1 -1
  45. package/dist/tile.js +77 -21
  46. package/dist/tile.js.map +1 -1
  47. package/package.json +2 -2
package/dist/hex.js CHANGED
@@ -1,11 +1,12 @@
1
1
  import { C, CenterText, F } from "@thegraid/easeljs-lib";
2
2
  import { Container, Point } from "@thegraid/easeljs-module";
3
+ import { NamedContainer } from "./game-play";
3
4
  import { H } from "./hex-intfs";
4
5
  import { HexShape, LegalMark } from "./shapes";
5
6
  import { TP } from "./table-params";
6
7
  export const S_Resign = 'Hex@Resign';
7
8
  export const S_Skip = 'Hex@skip ';
8
- /** to recognize this class in hexUnderPoint and obtain the associated Hex2. */
9
+ /** to recognize this class in hexUnderPoint and obtain the associated hex2: IHex2 */
9
10
  export class HexCont extends Container {
10
11
  hex2;
11
12
  constructor(hex2) {
@@ -14,10 +15,13 @@ export class HexCont extends Container {
14
15
  }
15
16
  }
16
17
  function nf(n) { return `${n !== undefined ? (n === Math.floor(n)) ? n : n.toFixed(1) : ''}`; }
17
- /** Base Hex, has no connection to graphics.
18
- * topological links to adjacent hex objects.
18
+ /**
19
+ * Minimal Hex, with topological links to adjacent hex objects,
20
+ * has no connection to graphics.
19
21
  */
20
22
  export class Hex {
23
+ /** Identify Hex instance derived from Hex2Mixin; and so implements IHex2. */
24
+ static isIHex2(hex) { return hex.implementsIHex2; }
21
25
  /** return indicated Hex from otherMap */
22
26
  static ofMap(ihex, otherMap) {
23
27
  try {
@@ -39,8 +43,8 @@ export class Hex {
39
43
  this.links = {};
40
44
  }
41
45
  /** (x,y): center of hex; (width,height) of hex; scaled by radius if supplied
42
- * @param radius [1] radius used in drawPolyStar(radius,,, H.dirRot[tiltDir])
43
- * @param ewTopo [TP.useEwTopo] true -> suitable for ewTopo (long axis of hex is N/S)
46
+ * @param radius [TP.hexRad] 'size' of hex; radius used in drawPolyStar(radius,,, H.dirRot[tiltDir])
47
+ * @param ewTopo [TP.useEwTopo] true -> suitable for ewTopo (has E & W [vertical] sides)
44
48
  * @param row [this.row]
45
49
  * @param col [this.col]
46
50
  * @returns \{ x, y, w, h, dxdc, dydr } of cell at [row, col]
@@ -63,7 +67,7 @@ export class Hex {
63
67
  return { x, y, w, h, dxdc, dydr };
64
68
  }
65
69
  }
66
- get xywh0() { return this.xywh(); } // so can see xywh from debugger
70
+ get xywh0() { return this.xywh(TP.hexRad); } // so can see xywh from debugger
67
71
  // _Aname: string;
68
72
  // get Aname() { return this._Aname; }
69
73
  // protected set Aname (name: string) { this._Aname = name; }
@@ -89,6 +93,7 @@ export class Hex {
89
93
  _isLegal;
90
94
  get isLegal() { return this._isLegal; }
91
95
  set isLegal(v) { this._isLegal = v; }
96
+ /** hexlib.Hex uses only the HexM slice of a HexMap. */
92
97
  map; // Note: this.parent == this.map.hexCont [cached] TODO: typify ??
93
98
  row;
94
99
  col;
@@ -151,7 +156,7 @@ export class Hex {
151
156
  }
152
157
  return hex;
153
158
  }
154
- /** distance between Hexes: adjacent = 1, based on row, col, sqrt3 */
159
+ /** distance between Hexes: adjacent = 1, based on row, col, unit = 1 / H.sqrt3 */
155
160
  radialDist(hex) {
156
161
  let unit = 1 / H.sqrt3; // so w = delta(col) = 1
157
162
  let { x: tx, y: ty } = this.xywh(unit), { x: hx, y: hy } = hex.xywh(unit);
@@ -180,169 +185,183 @@ export class Hex1 extends Hex {
180
185
  return `${color}@${this.rcsp}`;
181
186
  }
182
187
  }
183
- /** Mixin Hex2Lib with (Hex1Local extends Hex1Lib) */
184
- export function Hex2LibMixer(Base) {
185
- return class Hex2Code extends Base {
188
+ /**
189
+ * Mixin hexlib/Hex2 with (LocalHex extends Hex1)
190
+ *
191
+ * class LocalHex1 extends Hex1Lib { ... }
192
+ *
193
+ * class LibHex2extendsLocalHex1 extends Hex2Mixin(LocalHex1) { }
194
+ *
195
+ * class LocalHex2 extends LibHex2extendsLocalHex1 { ... }
196
+ *
197
+ * https://www.typescriptlang.org/docs/handbook/mixins.html
198
+ */
199
+ export function Hex2Mixin(Base) {
200
+ return class Hex2Impl extends Base {
201
+ /**
202
+ * add Hex2 to map?.mapCont.hexCont; not in map.hexAry!
203
+ *
204
+ * Hex2.cont contains:
205
+ * - hexShape: polyStar Shape of radius @ (XY=0,0)
206
+ * - rcText: '(r,c)' slightly above center, WHITE
207
+ * - distText: initially distText.text = `${district}` slightly below center, BLACK
208
+ */
186
209
  constructor(...args) {
187
- super(...args); // invoke the given Base constructor: Hex2Lib
210
+ const [map, row, col, name] = args;
211
+ super(map, row, col, name); // invoke the given Base constructor: LocalHex1
212
+ this.constructorCode(map, row, col, name);
188
213
  return; // breakpoint able
189
214
  }
190
- };
191
- }
192
- /** One Hex cell in the game, shown as a polyStar Shape */
193
- export class Hex2 extends Hex1 {
194
- /** Child of mapCont.hexCont: HexCont holds hexShape(color), rcText, distText, capMark */
195
- cont = new HexCont(this); // Hex IS-A Hex0, HAS-A HexCont Container
196
- radius = TP.hexRad; // determines width & height
197
- hexShape = this.makeHexShape(); // shown on this.cont: colored hexagon
198
- get mapCont() { return this.map.mapCont; }
199
- get markCont() { return this.mapCont.markCont; }
200
- get x() { return this.cont.x; }
201
- set x(v) { this.cont.x = v; }
202
- get y() { return this.cont.y; }
203
- set y(v) { this.cont.y = v; }
204
- get scaleX() { return this.cont.scaleX; }
205
- get scaleY() { return this.cont.scaleY; }
206
- // if override set, then must override get!
207
- get district() { return this._district; }
208
- set district(d) {
209
- this._district = d; // cannot use super.district = d [causes recursion, IIRC]
210
- this.distText.text = `${d}`;
211
- }
212
- distColor; // district color of hexShape (paintHexShape)
213
- distText; // shown on this.cont
214
- rcText; // shown on this.cont
215
- setUnit(unit, meep = false) {
216
- const cont = this.mapCont.tileCont, x = this.x, y = this.y;
217
- let k = true; // debug double tile
218
- const this_unit = (meep ? this.meep : this.tile);
219
- if (unit !== undefined && this_unit !== undefined && !(meep && this_unit.recycleVerb === 'demolished')) {
220
- if (this === this_unit.source?.hex && this === unit.source?.hex) {
221
- // Table.dragStart does moveTo(undefined); which triggers source.nextUnit()
222
- // so if we drop to the startHex, we have a collision.
223
- // Resolve by putting this_unit (the 'nextUnit') back in the source.
224
- // (availUnit will recurse to set this.unit = undefined)
225
- this_unit.source.availUnit(this_unit); // Meeple extends Tile, but TS seems confused.
215
+ implementsIHex2 = true;
216
+ /** Child of mapCont.hexCont: HexCont holds hexShape(color), rcText, distText, capMark */
217
+ cont = new HexCont(this); // Hex IS-A Hex0, HAS-A HexCont Container
218
+ radius = TP.hexRad; // determines width & height
219
+ hexShape = this.makeHexShape(); // shown on this.cont: colored hexagon
220
+ get mapCont() { return this.map.mapCont; }
221
+ get markCont() { return this.mapCont.markCont; }
222
+ get x() { return this.cont.x; }
223
+ set x(v) { this.cont.x = v; }
224
+ get y() { return this.cont.y; }
225
+ set y(v) { this.cont.y = v; }
226
+ get scaleX() { return this.cont.scaleX; }
227
+ get scaleY() { return this.cont.scaleY; }
228
+ // if override set, then must override get!
229
+ get district() { return this._district; }
230
+ set district(d) {
231
+ this._district = d; // cannot use super.district = d [causes recursion, IIRC]
232
+ this.distText.text = `${d}`;
233
+ }
234
+ distColor; // district color of hexShape (paintHexShape)
235
+ distText; // shown on this.cont
236
+ rcText; // shown on this.cont
237
+ setUnit(unit, meep = false) {
238
+ const cont = this.mapCont.tileCont, x = this.x, y = this.y;
239
+ let k = true; // debug double tile
240
+ const this_unit = (meep ? this.meep : this.tile);
241
+ if (unit !== undefined && this_unit !== undefined && !(meep && this_unit.recycleVerb === 'demolished')) {
242
+ if (this === this_unit.source?.hex && this === unit.source?.hex) {
243
+ // Table.dragStart does moveTo(undefined); which triggers source.nextUnit()
244
+ // so if we drop to the startHex, we have a collision.
245
+ // Resolve by putting this_unit (the 'nextUnit') back in the source.
246
+ // (availUnit will recurse to set this.unit = undefined)
247
+ this_unit.source.availUnit(this_unit); // Meeple extends Tile, but TS seems confused.
248
+ }
249
+ else if (k)
250
+ debugger;
251
+ }
252
+ meep ? (super.meep = unit) : (super.tile = unit); // set _meep or _tile;
253
+ if (unit !== undefined) {
254
+ unit.x = x;
255
+ unit.y = y;
256
+ cont.addChild(unit); // meep will go under tile
257
+ // after source.hex is set, updateCounter:
258
+ if (this === unit.source?.hex)
259
+ unit.source.updateCounter();
226
260
  }
227
- else if (k)
228
- debugger;
229
261
  }
230
- meep ? (super.meep = unit) : (super.tile = unit); // set _meep or _tile;
231
- if (unit !== undefined) {
232
- unit.x = x;
233
- unit.y = y;
234
- cont.addChild(unit); // meep will go under tile
235
- // after source.hex is set, updateCounter:
236
- if (this === unit.source?.hex)
237
- unit.source.updateCounter();
262
+ get tile() { return super.tile; }
263
+ set tile(tile) { this.setUnit(tile, false); }
264
+ get meep() { return super.meep; }
265
+ set meep(meep) { this.setUnit(meep, true); }
266
+ constructorCode(map, row, col, name) {
267
+ this.initCont(row, col);
268
+ map?.mapCont.hexCont.addChild(this.cont);
269
+ this.hexShape.name = this.Aname;
270
+ const nf = (n) => `${n !== undefined ? (n === Math.floor(n)) ? n : n.toFixed(1) : ''}`;
271
+ const rc = `${nf(row)},${nf(col)}`, rcf = 26 * TP.hexRad / 60;
272
+ const rct = this.rcText = new CenterText(rc, F.fontSpec(rcf), 'white');
273
+ rct.y -= rcf / 2; // raise it up
274
+ this.cont.addChild(rct);
275
+ const dtf = 20 * TP.hexRad / 60;
276
+ this.distText = new CenterText(``, F.fontSpec(dtf));
277
+ this.distText.y += dtf; // push it down
278
+ this.cont.addChild(this.distText);
279
+ this.legalMark.setOnHex(this);
280
+ this.showText(true); // & this.cache()
238
281
  }
239
- }
240
- get tile() { return super.tile; }
241
- set tile(tile) { this.setUnit(tile, false); }
242
- get meep() { return super.meep; }
243
- set meep(meep) { this.setUnit(meep, true); }
244
- /**
245
- * add Hex2 to map?.mapCont.hexCont; not in map.hexAry!
246
- * Hex2.cont contains:
247
- * - hexShape: polyStar Shape of radius @ (XY=0,0)
248
- * - rcText: '(r,c)' slightly above center, WHITE
249
- * - distText: initially distText.text = `${district}` slightly below center, BLACK
250
- */
251
- constructor(map, row, col, name) {
252
- super(map, row, col, name);
253
- this.constructorCode(map, row, col, name);
254
- }
255
- constructorCode(map, row, col, name) {
256
- this.initCont(row, col);
257
- map?.mapCont.hexCont.addChild(this.cont);
258
- this.hexShape.name = this.Aname;
259
- const nf = (n) => `${n !== undefined ? (n === Math.floor(n)) ? n : n.toFixed(1) : ''}`;
260
- const rc = `${nf(row)},${nf(col)}`, rcf = 26 * TP.hexRad / 60;
261
- const rct = this.rcText = new CenterText(rc, F.fontSpec(rcf), 'white');
262
- rct.y -= rcf / 2; // raise it up
263
- this.cont.addChild(rct);
264
- const dtf = 20 * TP.hexRad / 60;
265
- this.distText = new CenterText(``, F.fontSpec(dtf));
266
- this.distText.y += dtf; // push it down
267
- this.cont.addChild(this.distText);
268
- this.legalMark.setOnHex(this);
269
- this.showText(true); // & this.cache()
270
- }
271
- /** set visibility of rcText & distText */
272
- showText(vis = !this.rcText.visible) {
273
- this.rcText.visible = this.distText.visible = vis;
274
- this.cont.updateCache();
275
- }
276
- legalMark = new LegalMark();
277
- get isLegal() { return this._isLegal; }
278
- set isLegal(v) {
279
- super.isLegal = v;
280
- this.legalMark.visible = v;
281
- }
282
- /** place this.cont; setBounds(); cont.cache() */
283
- initCont(row, col) {
284
- const cont = this.cont;
285
- const { x, y, w, h } = this.xywh(this.radius, TP.useEwTopo, row, col); // include margin space between hexes
286
- cont.x = x;
287
- cont.y = y;
288
- // initialize cache bounds:
289
- cont.setBounds(-w / 2, -h / 2, w, h);
290
- const b = cont.getBounds();
291
- cont.cache(b.x, b.y, b.width, b.height);
292
- // cont.rotation = this.map.topoRot;
293
- }
294
- makeHexShape(shape = HexShape) {
295
- const hs = new shape(this.radius);
296
- this.cont.addChildAt(hs, 0);
297
- this.cont.hitArea = hs;
298
- hs.paint('grey');
299
- return hs;
300
- }
301
- /** set hexShape using color: draw border and fill
302
- * @param color
303
- * @param district if supplied, set this.district
304
- */
305
- setHexColor(color, district) {
306
- if (district !== undefined)
307
- this.district = district; // hex.setHexColor update district
308
- this.distColor = color;
309
- this.hexShape.paint(color);
310
- this.cont.updateCache();
311
- }
312
- // The following were created for the map in hexmarket:
313
- /** unit distance between Hexes: adjacent = 1; see also: radialDist */
314
- metricDist(hex) {
315
- let { x: tx, y: ty } = this.xywh(1), { x: hx, y: hy } = hex.xywh(1);
316
- let dx = tx - hx, dy = ty - hy;
317
- return Math.sqrt(dx * dx + dy * dy); // tw == H.sqrt3
318
- }
319
- /** location of corner between dir0 and dir1; in parent coordinates.
320
- * @param dir0 an EwDir
321
- * @param dir1 an EwDir
322
- */
323
- // hexmarket uses to find ewDir corner between two nsDir edges.
324
- cornerPoint(dir0, dir1) {
325
- const d0 = H.ewDirRot[dir0], d1 = H.ewDirRot[dir1];
326
- let a2 = (d0 + d1) / 2, h = this.radius;
327
- if (Math.abs(d0 - d1) > 180)
328
- a2 += 180;
329
- let a = a2 * H.degToRadians;
330
- return new Point(this.x + Math.sin(a) * h, this.y - Math.cos(a) * h);
331
- }
332
- /** Location of edge point in dir; in parent coordinates.
333
- * @param dir indicates direction to edge
334
- * @param rad [1] per-unit distance from center: 0 --> center, 1 --> exactly on edge, 1+ --> outside hex
335
- * @param point [new Point()] set location-x,y in point and return it.
336
- */
337
- edgePoint(dir, rad = 1, point = new Point()) {
338
- const a = H.nsDirRot[dir] * H.degToRadians, h = rad * this.radius * H.sqrt3_2;
339
- point.x = this.hexShape.x + Math.sin(a) * h;
340
- point.y = this.hexShape.y - Math.cos(a) * h;
341
- return point;
342
- }
282
+ /** set visibility of rcText & distText */
283
+ showText(vis = !this.rcText.visible) {
284
+ this.rcText.visible = this.distText.visible = vis;
285
+ this.cont.updateCache();
286
+ }
287
+ legalMark = new LegalMark();
288
+ get isLegal() { return this._isLegal; }
289
+ set isLegal(v) {
290
+ super.isLegal = v;
291
+ this.legalMark.visible = v;
292
+ }
293
+ /** place this.cont; setBounds(); cont.cache() */
294
+ initCont(row, col) {
295
+ const cont = this.cont;
296
+ const { x, y, w, h } = this.xywh(this.radius, TP.useEwTopo, row, col); // include margin space between hexes
297
+ cont.x = x;
298
+ cont.y = y;
299
+ // initialize cache bounds:
300
+ cont.setBounds(-w / 2, -h / 2, w, h);
301
+ const b = cont.getBounds();
302
+ cont.cache(b.x, b.y, b.width, b.height);
303
+ // cont.rotation = this.map.topoRot;
304
+ }
305
+ makeHexShape(shape = HexShape) {
306
+ const hs = new shape(this.radius);
307
+ this.cont.addChildAt(hs, 0);
308
+ this.cont.hitArea = hs;
309
+ hs.paint('grey');
310
+ return hs;
311
+ }
312
+ /** set hexShape using color: draw border and fill
313
+ * @param color
314
+ * @param district if supplied, set this.district
315
+ */
316
+ setHexColor(color, district) {
317
+ if (district !== undefined)
318
+ this.district = district; // hex.setHexColor update district
319
+ this.distColor = color;
320
+ this.hexShape.paint(color);
321
+ this.cont.updateCache();
322
+ }
323
+ // The following were created for the map in hexmarket:
324
+ /** unit distance between Hexes: adjacent = 1; see also: radialDist */
325
+ metricDist(hex) {
326
+ let { x: tx, y: ty } = this.xywh(1), { x: hx, y: hy } = hex.xywh(1);
327
+ let dx = tx - hx, dy = ty - hy;
328
+ return Math.sqrt(dx * dx + dy * dy); // tw == H.sqrt3
329
+ }
330
+ /** Location of corner between dir0 and dir1; in parent coordinates.
331
+ * @param dir0 a HexDir
332
+ * @param dir1 a HexDir
333
+ * @param point [new Point()] set location-x,y in point and return it.
334
+ * @param rad [this.radius]
335
+ */
336
+ cornerPoint(dir0, dir1, point = new Point(), rad = this.radius) {
337
+ const d0 = H.dirRot[dir0], d1 = H.dirRot[dir1];
338
+ let a2 = (d0 + d1) / 2;
339
+ if (Math.abs(d0 - d1) > 180)
340
+ a2 += 180;
341
+ const a = a2 * H.degToRadians;
342
+ point.x = this.x + Math.sin(a) * rad;
343
+ point.y = this.y - Math.cos(a) * rad;
344
+ return point;
345
+ }
346
+ /** Location of edge point in dir; in parent coordinates.
347
+ * @param dir indicates direction to edge
348
+ * @param rad [1] per-unit distance from center: 0 --> center, 1 --> exactly on edge, 1+ --> outside hex
349
+ * @param point [new Point()] set location-x,y in point and return it.
350
+ */
351
+ edgePoint(dir, rad = 1, point = new Point()) {
352
+ const a = H.dirRot[dir] * H.degToRadians, h = rad * this.radius * H.sqrt3_2;
353
+ point.x = this.x + Math.sin(a) * h;
354
+ point.y = this.y - Math.cos(a) * h;
355
+ return point;
356
+ }
357
+ };
343
358
  }
344
- export class RecycleHex extends Hex2 {
359
+ /** a default Constructor and implementation of IHex2 */
360
+ export class Hex2 extends Hex2Mixin(Hex1) {
345
361
  }
362
+ /** a default Constructor and impl for RecycleHex. */
363
+ export class RecycleHex extends Hex2 {
364
+ } // RecycleHex
346
365
  /**
347
366
  * A HexShape/PaintableShape to indicate selected hex of HexMap.
348
367
  *
@@ -359,15 +378,10 @@ export class HexMark extends HexShape {
359
378
  this.graphics.f(cm).dp(0, 0, this.radius, 6, 0, this.tilt);
360
379
  this.cache(-radius, -radius, 2 * radius, 2 * radius);
361
380
  this.graphics.c().f(C.BLACK).dc(0, 0, radius0);
362
- this.updateCache("destination-out");
381
+ this.updateCache('destination-out');
363
382
  this.setHexBounds(); // bounds are based on readonly, should be const
364
383
  this.mouseEnabled = false;
365
384
  }
366
- // don't invoke Mark.paint(new_color); TODO: remove this override.
367
- // override paint(color: string): Graphics {
368
- // this.setHexBounds(); // <--- likely redundant, see HexSHape
369
- // return this.graphics; // do not repaint.
370
- // }
371
385
  // Fail: markCont to be 'above' tileCont...
372
386
  /**
373
387
  * Show or hide mark on given hex; and hex.updateCache.
@@ -423,8 +437,7 @@ export class MapCont extends Container {
423
437
  this._cNames = cNames.concat();
424
438
  this.removeAllChildren();
425
439
  this.cNames.forEach(cname => {
426
- const cont = new Container();
427
- cont.Aname = cont.name = cname;
440
+ const cont = new NamedContainer(cname);
428
441
  this[cname] = cont;
429
442
  this.addChild(cont);
430
443
  });
@@ -449,28 +462,34 @@ export class MapCont extends Container {
449
462
  }
450
463
  }
451
464
  /**
452
- * Collection of Hex *and* Graphics-Containers for Hex2
453
- * districts: Hex[]
465
+ * 2-D Array[row][col]: Hex; plus a mapCont of Graphics-Containers for IHex2.
466
+ *
467
+ * hexAry[n]: all the Hex (or IHex2) elements.
454
468
  *
455
- * HexMap[row][col]: Hex or Hex2 elements.
456
- * If mapCont is set, then populate with Hex2
469
+ * district[i]: Hex[]; all the Hex in a given district.
457
470
  *
458
471
  * (TP.mh X TP.nh) hexes in districts;
459
472
  *
460
- * With a Mark and off-map: skipHex & resignHex
473
+ * Use addToMapCont(hexC), to populate with new hexC()
474
+ *
475
+ * mark: a HexMark to visually indicate a selected IHex2.
461
476
  *
462
477
  */
463
478
  export class HexMap extends Array {
464
479
  hexC;
465
480
  Aname;
466
- // A color for each District: 'rgb(198,198,198)'
467
- static distColor = ['lightgrey', "limegreen", "deepskyblue", "rgb(255,165,0)", "violet", "rgb(250,80,80)", "yellow"];
481
+ /** A color for each District: 'rgb(198,198,198)' */
482
+ static distColor = ['lightgrey', 'limegreen', 'deepskyblue', 'rgb(255,165,0)', 'violet', 'rgb(250,80,80)', 'yellow'];
468
483
  /**
469
- * HexMap: TP.nRows X TP.nCols hexes.
484
+ * HexMap: TP.nRows X TP.nCols of Hex [new hexC()]
470
485
  *
471
- * Basic map is non-GUI, addToMapCont uses Hex2 elements to enable GUI interaction.
472
- * @param addToMapCont use Hex2 for Hex, make Containers: hexCont, infCont, markCont, stoneCont
473
- * @param hexC Constructor<T> for the Hex elements (typed as HexConstructor<Hex> for Typescript...)
486
+ * Basic map is non-GUI, addToMapCont(hexC) makes IHex2 elements to enable GUI interaction.
487
+ * Use hexC() to make Hex; mapCont has layers of Containers per HexMap.cNames;
488
+ *
489
+ * @param radius [TP.hexRad] typically 60
490
+ * @param addToMapCont [false] set true to include addToMapCont(hexC)
491
+ * @param hexC [Hex] HexConstructor\<Hex\> for each element
492
+ * @param Aname ['mainMap'] a name for debugger
474
493
  */
475
494
  constructor(radius = TP.hexRad, addToMapCont = false, hexC = Hex, Aname = 'mainMap') {
476
495
  super(); // Array<Array<Hex>>()
@@ -480,8 +499,9 @@ export class HexMap extends Array {
480
499
  if (addToMapCont)
481
500
  this.addToMapCont(this.hexC);
482
501
  }
483
- get asHex2Map() { return this; }
484
- /** Each occupied Hex, with the occupying PlayerColor */
502
+ /** may be obsolete when using IHex2 */
503
+ get asIHex2Map() { return this; }
504
+ /** Each occupied Hex, with the associated district color */
485
505
  district = [];
486
506
  hexAry; // set by makeAllDistricts()
487
507
  mapCont = new MapCont(); // if/when using Hex2
@@ -495,7 +515,7 @@ export class HexMap extends Array {
495
515
  //
496
516
  radius = TP.hexRad;
497
517
  /** return this.centerHex.xywh() for this.topo */
498
- get xywh() { return this.centerHex.xywh(); }
518
+ get xywh() { return this.centerHex.xywh(this.radius); }
499
519
  minCol = undefined; // Array.forEach does not look at negative indices!
500
520
  maxCol = undefined; // used by rcLinear
501
521
  minRow = undefined; // to find centerHex
@@ -599,7 +619,7 @@ export class HexMap extends Array {
599
619
  if (!hex) { // || hex.Aname === S_Skip || hex.Aname === S_Resign) {
600
620
  mark.visible = false;
601
621
  }
602
- else if (hex instanceof Hex2) {
622
+ else if (Hex.isIHex2(hex)) {
603
623
  mark.scaleX = hex.scaleX;
604
624
  mark.scaleY = hex.scaleY;
605
625
  mark.visible = true;
@@ -655,16 +675,19 @@ export class HexMap extends Array {
655
675
  });
656
676
  }
657
677
  /**
658
- * The [Legal] Hex (LegalMark.hex2) under the given x,y coordinates.
659
- * If on the line, then the top (last drawn) Hex.
678
+ * Return the Hex under the given x,y coordinates.
679
+ *
680
+ * Conceptually: (legal ? LegalMark : HexCont)?.hex2 as \<T extends IHex2\>;
681
+ *
682
+ * If multiple HexCont at x,y, return the top (last drawn) HexCont.
660
683
  * @param x in local coordinates of this HexMap.mapCont
661
684
  * @param y
662
- * @param legal - returnn ONLY hex with LegalMark visible & mouseenabled.
663
- * @returns the Hex2 under mouse or undefined, if not a Hex (background)
685
+ * @param legal - return ONLY a Hex with LegalMark visible & mouseenabled.
686
+ * @returns the IHex2 of the LegalMark or HexCont at the given point (or undefined if no such HexCont)
664
687
  */
665
688
  hexUnderPoint(x, y, legal = true) {
666
689
  const mark = this.mapCont.markCont.getObjectUnderPoint(x, y, 1);
667
- // Note: in theory, mark could be on a Hex2 that is NOT in hexCont!
690
+ // Note: in theory, mark could be on a IHex2 that is NOT in hexCont!
668
691
  if (mark instanceof LegalMark)
669
692
  return mark.hex2;
670
693
  if (legal)
@@ -703,13 +726,15 @@ export class HexMap extends Array {
703
726
  this.setSize(nh, mh);
704
727
  const rc0 = this.calculateRC0();
705
728
  const hexAry = this.hexAry = this.makeAllHexes(nh, mh, rc0); // nh hexes on outer ring; single meta-hex
706
- this.mapCont.hexCont && this.mapCont.centerContainers();
707
729
  return hexAry;
708
730
  }
709
731
  /**
710
732
  * overridable action for makeAllDistricts;
711
733
  *
712
- * Base implementation invokes makeMetaDistrict(nh, mh, rc0)
734
+ * Base implementation invokes makeMetaHexRings(nh, mh, rc0)
735
+ *
736
+ * Alterative: makeRect(nrow, ncol, ...)
737
+ *
713
738
  * @param nh
714
739
  * @param mh
715
740
  * @param rc0
@@ -720,6 +745,11 @@ export class HexMap extends Array {
720
745
  }
721
746
  /**
722
747
  * Make the center district, then make (mh-1) rings other meta-hex districts.
748
+ *
749
+ * Spiral clockwise from center, placing a line of meta-hex [using makeMetaHex()].
750
+ *
751
+ * MakeMetaHex likewise spirals from center, placing a line of Hex.
752
+ *
723
753
  * @param nh order [number of 'rings'] of meta-hexes (2 or 3 for this game) [TP.mHexes]
724
754
  * @param mh size ['rings' in each meta-hex] of meta-hex (1..6) [TP.nHexes]
725
755
  * @param rc0 location of initial, central Hex
@@ -810,7 +840,7 @@ export class HexMap extends Array {
810
840
  */
811
841
  setDistrictAndPaint(hexAry, district = 0) {
812
842
  this.district[district] = hexAry;
813
- if (hexAry[0] instanceof Hex2) {
843
+ if (Hex.isIHex2(hexAry[0])) {
814
844
  this.paintDistrict(hexAry, district);
815
845
  }
816
846
  }