board-game-engine 2.0.1 → 2.1.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.
Files changed (251) hide show
  1. package/dist/board-game-engine.cjs +5509 -5613
  2. package/dist/board-game-engine.js +5509 -5613
  3. package/dist/board-game-engine.min.js +22 -22
  4. package/dist/board-game-engine.mjs +5508 -5611
  5. package/package.json +4 -10
  6. package/playwright-report/index.html +1 -1
  7. package/scripts/build.mjs +2 -2
  8. package/src/client/client.js +224 -0
  9. package/src/game-factory/bank/bank-slot.js +69 -0
  10. package/src/game-factory/bank/bank.js +114 -0
  11. package/src/game-factory/{board.ts → board.js} +1 -1
  12. package/src/game-factory/condition/condition-factory.js +52 -0
  13. package/src/game-factory/condition/condition.js +39 -0
  14. package/src/game-factory/condition/{contains-condition.ts → contains-condition.js} +4 -5
  15. package/src/game-factory/condition/{contains-same-condition.ts → contains-same-condition.js} +5 -8
  16. package/src/game-factory/condition/{evaluate-condition.ts → evaluate-condition.js} +3 -4
  17. package/src/game-factory/condition/every-condition.js +25 -0
  18. package/src/game-factory/condition/has-line-condition.js +14 -0
  19. package/src/game-factory/condition/in-line-condition.js +19 -0
  20. package/src/game-factory/condition/is-condition.js +23 -0
  21. package/src/game-factory/condition/is-full-condition.js +9 -0
  22. package/src/game-factory/condition/{no-possible-moves-condition.ts → no-possible-moves-condition.js} +2 -3
  23. package/src/game-factory/condition/{not-condition.ts → not-condition.js} +2 -3
  24. package/src/game-factory/condition/{or-condition.ts → or-condition.js} +2 -3
  25. package/src/game-factory/condition/position-condition.js +12 -0
  26. package/src/game-factory/condition/{some-condition.ts → some-condition.js} +3 -5
  27. package/src/game-factory/condition/would-condition.js +94 -0
  28. package/src/game-factory/entity.js +29 -0
  29. package/src/game-factory/expand-game-rules.js +271 -0
  30. package/src/game-factory/game-factory.js +240 -0
  31. package/{dist/game-factory/move/end-turn.d.ts → src/game-factory/move/end-turn.js} +4 -2
  32. package/src/game-factory/move/for-each.js +18 -0
  33. package/src/game-factory/move/move-entity.js +16 -0
  34. package/src/game-factory/move/move-factory.js +89 -0
  35. package/src/game-factory/move/move.js +131 -0
  36. package/src/game-factory/move/pass-turn.js +10 -0
  37. package/{dist/game-factory/move/pass.d.ts → src/game-factory/move/pass.js} +4 -2
  38. package/src/game-factory/move/place-new.js +33 -0
  39. package/src/game-factory/move/remove-entity.js +7 -0
  40. package/src/game-factory/move/set-active-players.js +23 -0
  41. package/src/game-factory/move/set-state.js +11 -0
  42. package/src/game-factory/move/shuffle.js +7 -0
  43. package/src/game-factory/move/take-from.js +7 -0
  44. package/src/game-factory/space/space.js +30 -0
  45. package/src/game-factory/space-group/grid.js +43 -0
  46. package/src/game-factory/space-group/space-group.js +29 -0
  47. package/src/index.js +2 -0
  48. package/src/utils/{any-valid-moves.ts → any-valid-moves.js} +49 -54
  49. package/src/utils/check-conditions.js +28 -0
  50. package/src/utils/create-payload.js +16 -0
  51. package/src/utils/deserialize-bgio-arguments.js +8 -0
  52. package/src/utils/do-moves.js +18 -0
  53. package/src/utils/entity-matches.js +20 -0
  54. package/src/utils/find-met-condition.js +22 -0
  55. package/src/utils/get-current-moves.js +12 -0
  56. package/src/utils/get-scenario-results.js +23 -0
  57. package/src/utils/get-steps.js +29 -0
  58. package/src/utils/get.js +25 -0
  59. package/src/utils/{grid-contains-sequence.ts → grid-contains-sequence.js} +33 -71
  60. package/src/utils/json-transformer.js +12 -0
  61. package/src/utils/prepare-payload.js +17 -0
  62. package/src/utils/resolve-entity.js +9 -0
  63. package/src/utils/resolve-expression.js +10 -0
  64. package/src/utils/resolve-properties.js +149 -0
  65. package/src/utils/simulate-move.js +25 -0
  66. package/.github/workflows/ci.yml +0 -33
  67. package/dist/client/client.d.ts +0 -76
  68. package/dist/client/client.d.ts.map +0 -1
  69. package/dist/game-factory/bank/bank-slot.d.ts +0 -30
  70. package/dist/game-factory/bank/bank-slot.d.ts.map +0 -1
  71. package/dist/game-factory/bank/bank.d.ts +0 -34
  72. package/dist/game-factory/bank/bank.d.ts.map +0 -1
  73. package/dist/game-factory/board.d.ts +0 -4
  74. package/dist/game-factory/board.d.ts.map +0 -1
  75. package/dist/game-factory/condition/condition-factory.d.ts +0 -4
  76. package/dist/game-factory/condition/condition-factory.d.ts.map +0 -1
  77. package/dist/game-factory/condition/condition.d.ts +0 -13
  78. package/dist/game-factory/condition/condition.d.ts.map +0 -1
  79. package/dist/game-factory/condition/contains-condition.d.ts +0 -8
  80. package/dist/game-factory/condition/contains-condition.d.ts.map +0 -1
  81. package/dist/game-factory/condition/contains-same-condition.d.ts +0 -7
  82. package/dist/game-factory/condition/contains-same-condition.d.ts.map +0 -1
  83. package/dist/game-factory/condition/evaluate-condition.d.ts +0 -8
  84. package/dist/game-factory/condition/evaluate-condition.d.ts.map +0 -1
  85. package/dist/game-factory/condition/every-condition.d.ts +0 -12
  86. package/dist/game-factory/condition/every-condition.d.ts.map +0 -1
  87. package/dist/game-factory/condition/has-line-condition.d.ts +0 -8
  88. package/dist/game-factory/condition/has-line-condition.d.ts.map +0 -1
  89. package/dist/game-factory/condition/in-line-condition.d.ts +0 -8
  90. package/dist/game-factory/condition/in-line-condition.d.ts.map +0 -1
  91. package/dist/game-factory/condition/is-condition.d.ts +0 -8
  92. package/dist/game-factory/condition/is-condition.d.ts.map +0 -1
  93. package/dist/game-factory/condition/is-full-condition.d.ts +0 -7
  94. package/dist/game-factory/condition/is-full-condition.d.ts.map +0 -1
  95. package/dist/game-factory/condition/no-possible-moves-condition.d.ts +0 -7
  96. package/dist/game-factory/condition/no-possible-moves-condition.d.ts.map +0 -1
  97. package/dist/game-factory/condition/not-condition.d.ts +0 -7
  98. package/dist/game-factory/condition/not-condition.d.ts.map +0 -1
  99. package/dist/game-factory/condition/or-condition.d.ts +0 -7
  100. package/dist/game-factory/condition/or-condition.d.ts.map +0 -1
  101. package/dist/game-factory/condition/position-condition.d.ts +0 -7
  102. package/dist/game-factory/condition/position-condition.d.ts.map +0 -1
  103. package/dist/game-factory/condition/some-condition.d.ts +0 -8
  104. package/dist/game-factory/condition/some-condition.d.ts.map +0 -1
  105. package/dist/game-factory/condition/would-condition.d.ts +0 -8
  106. package/dist/game-factory/condition/would-condition.d.ts.map +0 -1
  107. package/dist/game-factory/entity.d.ts +0 -13
  108. package/dist/game-factory/entity.d.ts.map +0 -1
  109. package/dist/game-factory/expand-game-rules.d.ts +0 -3
  110. package/dist/game-factory/expand-game-rules.d.ts.map +0 -1
  111. package/dist/game-factory/game-factory.d.ts +0 -10
  112. package/dist/game-factory/game-factory.d.ts.map +0 -1
  113. package/dist/game-factory/move/end-turn.d.ts.map +0 -1
  114. package/dist/game-factory/move/for-each.d.ts +0 -5
  115. package/dist/game-factory/move/for-each.d.ts.map +0 -1
  116. package/dist/game-factory/move/index.d.ts +0 -6
  117. package/dist/game-factory/move/index.d.ts.map +0 -1
  118. package/dist/game-factory/move/move-entity.d.ts +0 -7
  119. package/dist/game-factory/move/move-entity.d.ts.map +0 -1
  120. package/dist/game-factory/move/move-factory.d.ts +0 -18
  121. package/dist/game-factory/move/move-factory.d.ts.map +0 -1
  122. package/dist/game-factory/move/move.d.ts +0 -54
  123. package/dist/game-factory/move/move.d.ts.map +0 -1
  124. package/dist/game-factory/move/pass-turn.d.ts +0 -5
  125. package/dist/game-factory/move/pass-turn.d.ts.map +0 -1
  126. package/dist/game-factory/move/pass.d.ts.map +0 -1
  127. package/dist/game-factory/move/place-new.d.ts +0 -5
  128. package/dist/game-factory/move/place-new.d.ts.map +0 -1
  129. package/dist/game-factory/move/remove-entity.d.ts +0 -5
  130. package/dist/game-factory/move/remove-entity.d.ts.map +0 -1
  131. package/dist/game-factory/move/set-active-players.d.ts +0 -5
  132. package/dist/game-factory/move/set-active-players.d.ts.map +0 -1
  133. package/dist/game-factory/move/set-state.d.ts +0 -5
  134. package/dist/game-factory/move/set-state.d.ts.map +0 -1
  135. package/dist/game-factory/move/shuffle.d.ts +0 -5
  136. package/dist/game-factory/move/shuffle.d.ts.map +0 -1
  137. package/dist/game-factory/move/take-from.d.ts +0 -11
  138. package/dist/game-factory/move/take-from.d.ts.map +0 -1
  139. package/dist/game-factory/space/space.d.ts +0 -10
  140. package/dist/game-factory/space/space.d.ts.map +0 -1
  141. package/dist/game-factory/space-group/grid.d.ts +0 -15
  142. package/dist/game-factory/space-group/grid.d.ts.map +0 -1
  143. package/dist/game-factory/space-group/space-group.d.ts +0 -20
  144. package/dist/game-factory/space-group/space-group.d.ts.map +0 -1
  145. package/dist/index.d.ts +0 -6
  146. package/dist/index.d.ts.map +0 -1
  147. package/dist/registry.d.ts +0 -17
  148. package/dist/registry.d.ts.map +0 -1
  149. package/dist/types/bagel-types.d.ts +0 -339
  150. package/dist/types/bagel-types.d.ts.map +0 -1
  151. package/dist/types/index.d.ts +0 -3
  152. package/dist/types/index.d.ts.map +0 -1
  153. package/dist/types/rule-with-conditions.d.ts +0 -9
  154. package/dist/types/rule-with-conditions.d.ts.map +0 -1
  155. package/dist/utils/any-valid-moves.d.ts +0 -2
  156. package/dist/utils/any-valid-moves.d.ts.map +0 -1
  157. package/dist/utils/bgio-resolve-types.d.ts +0 -25
  158. package/dist/utils/bgio-resolve-types.d.ts.map +0 -1
  159. package/dist/utils/check-conditions.d.ts +0 -7
  160. package/dist/utils/check-conditions.d.ts.map +0 -1
  161. package/dist/utils/create-payload.d.ts +0 -5
  162. package/dist/utils/create-payload.d.ts.map +0 -1
  163. package/dist/utils/deserialize-bgio-arguments.d.ts +0 -3
  164. package/dist/utils/deserialize-bgio-arguments.d.ts.map +0 -1
  165. package/dist/utils/do-moves.d.ts +0 -8
  166. package/dist/utils/do-moves.d.ts.map +0 -1
  167. package/dist/utils/entity-matches.d.ts +0 -6
  168. package/dist/utils/entity-matches.d.ts.map +0 -1
  169. package/dist/utils/find-met-condition.d.ts +0 -6
  170. package/dist/utils/find-met-condition.d.ts.map +0 -1
  171. package/dist/utils/get-current-moves.d.ts +0 -24
  172. package/dist/utils/get-current-moves.d.ts.map +0 -1
  173. package/dist/utils/get-scenario-results.d.ts +0 -3
  174. package/dist/utils/get-scenario-results.d.ts.map +0 -1
  175. package/dist/utils/get-steps.d.ts +0 -13
  176. package/dist/utils/get-steps.d.ts.map +0 -1
  177. package/dist/utils/get.d.ts +0 -7
  178. package/dist/utils/get.d.ts.map +0 -1
  179. package/dist/utils/grid-contains-sequence.d.ts +0 -27
  180. package/dist/utils/grid-contains-sequence.d.ts.map +0 -1
  181. package/dist/utils/json-transformer.d.ts +0 -8
  182. package/dist/utils/json-transformer.d.ts.map +0 -1
  183. package/dist/utils/prepare-payload.d.ts +0 -2
  184. package/dist/utils/prepare-payload.d.ts.map +0 -1
  185. package/dist/utils/resolve-entity.d.ts +0 -3
  186. package/dist/utils/resolve-entity.d.ts.map +0 -1
  187. package/dist/utils/resolve-expression.d.ts +0 -6
  188. package/dist/utils/resolve-expression.d.ts.map +0 -1
  189. package/dist/utils/resolve-properties.d.ts +0 -4
  190. package/dist/utils/resolve-properties.d.ts.map +0 -1
  191. package/dist/utils/simulate-move.d.ts +0 -16
  192. package/dist/utils/simulate-move.d.ts.map +0 -1
  193. package/src/client/client.ts +0 -306
  194. package/src/game-factory/bank/bank-slot.ts +0 -81
  195. package/src/game-factory/bank/bank.ts +0 -125
  196. package/src/game-factory/condition/condition-factory.ts +0 -59
  197. package/src/game-factory/condition/condition.ts +0 -50
  198. package/src/game-factory/condition/every-condition.ts +0 -27
  199. package/src/game-factory/condition/has-line-condition.ts +0 -15
  200. package/src/game-factory/condition/in-line-condition.ts +0 -25
  201. package/src/game-factory/condition/is-condition.ts +0 -24
  202. package/src/game-factory/condition/is-full-condition.ts +0 -10
  203. package/src/game-factory/condition/position-condition.ts +0 -13
  204. package/src/game-factory/condition/would-condition.ts +0 -104
  205. package/src/game-factory/entity.ts +0 -37
  206. package/src/game-factory/expand-game-rules.ts +0 -263
  207. package/src/game-factory/game-factory.ts +0 -263
  208. package/src/game-factory/move/end-turn.ts +0 -7
  209. package/src/game-factory/move/for-each.ts +0 -20
  210. package/src/game-factory/move/move-entity.ts +0 -18
  211. package/src/game-factory/move/move-factory.ts +0 -107
  212. package/src/game-factory/move/move.ts +0 -147
  213. package/src/game-factory/move/pass-turn.ts +0 -15
  214. package/src/game-factory/move/pass.ts +0 -7
  215. package/src/game-factory/move/place-new.ts +0 -42
  216. package/src/game-factory/move/remove-entity.ts +0 -11
  217. package/src/game-factory/move/set-active-players.ts +0 -26
  218. package/src/game-factory/move/set-state.ts +0 -14
  219. package/src/game-factory/move/shuffle.ts +0 -9
  220. package/src/game-factory/move/take-from.ts +0 -12
  221. package/src/game-factory/space/space.ts +0 -36
  222. package/src/game-factory/space-group/grid.ts +0 -48
  223. package/src/game-factory/space-group/space-group.ts +0 -44
  224. package/src/index.ts +0 -5
  225. package/src/types/bagel-types.ts +0 -449
  226. package/src/types/boardgame-io-core.d.ts +0 -7
  227. package/src/types/index.ts +0 -70
  228. package/src/types/rule-with-conditions.ts +0 -9
  229. package/src/utils/bgio-resolve-types.ts +0 -27
  230. package/src/utils/check-conditions.ts +0 -28
  231. package/src/utils/create-payload.ts +0 -19
  232. package/src/utils/deserialize-bgio-arguments.ts +0 -10
  233. package/src/utils/do-moves.ts +0 -22
  234. package/src/utils/entity-matches.ts +0 -30
  235. package/src/utils/expr-eval.d.ts +0 -6
  236. package/src/utils/find-met-condition.ts +0 -23
  237. package/src/utils/get-current-moves.ts +0 -39
  238. package/src/utils/get-scenario-results.ts +0 -30
  239. package/src/utils/get-steps.ts +0 -38
  240. package/src/utils/get.ts +0 -28
  241. package/src/utils/json-transformer.ts +0 -17
  242. package/src/utils/prepare-payload.ts +0 -20
  243. package/src/utils/resolve-entity.ts +0 -15
  244. package/src/utils/resolve-expression.ts +0 -16
  245. package/src/utils/resolve-properties.ts +0 -172
  246. package/src/utils/simulate-move.ts +0 -32
  247. package/src/wackson.d.ts +0 -4
  248. package/tsconfig.build.json +0 -14
  249. package/tsconfig.json +0 -21
  250. /package/src/game-factory/move/{index.ts → index.js} +0 -0
  251. /package/src/{registry.ts → registry.js} +0 -0
@@ -1,15 +0,0 @@
1
- import Condition from "./condition.js";
2
- import gridContainsSequence from "../../utils/grid-contains-sequence.js";
3
- import type { GridLike, SequenceChunk } from "../../utils/grid-contains-sequence.js";
4
-
5
- export default class HasLineCondition extends Condition {
6
- checkCondition (bgioArguments: unknown, rule: unknown, payload: Record<string, unknown>, context: Record<string, unknown>) {
7
- const { matches } = gridContainsSequence(
8
- bgioArguments,
9
- payload.target as GridLike,
10
- (rule as { sequence: SequenceChunk[] }).sequence,
11
- context
12
- ) as { matches: unknown[] };
13
- return { matches, conditionIsMet: !!matches.length };
14
- }
15
- }
@@ -1,25 +0,0 @@
1
- import Condition from "./condition.js";
2
- import gridContainsSequence from "../../utils/grid-contains-sequence.js";
3
- import type { GridLike, SequenceChunk } from "../../utils/grid-contains-sequence.js";
4
-
5
-
6
- export default class InLineCondition extends Condition {
7
- checkCondition (bgioArguments: unknown, rule: unknown, payload: Record<string, unknown>, context: Record<string, unknown>) {
8
- const { G } = bgioArguments as { G: { bank: { findParent: (t: unknown) => unknown } } };
9
- const { target } = payload;
10
- const parent = G.bank.findParent(payload.target);
11
-
12
- const { matches: allMatches } = gridContainsSequence(
13
- bgioArguments,
14
- parent as GridLike,
15
- (rule as { sequence: SequenceChunk[] }).sequence,
16
- context
17
- ) as { matches: unknown[][] };
18
-
19
- const matches = allMatches.filter((sequence: unknown[]) =>
20
- sequence.some((space: unknown) => space === target)
21
- );
22
-
23
- return { matches, conditionIsMet: !!matches.length };
24
- }
25
- }
@@ -1,24 +0,0 @@
1
- import Condition from "./condition.js";
2
- import entityMatches from '../../utils/entity-matches.js'
3
- import type { BgioResolveState } from "../../utils/bgio-resolve-types.js";
4
-
5
- export default class Is extends Condition {
6
- checkCondition (bgioArguments: unknown, rule: unknown, { target }: Record<string, unknown>, context: Record<string, unknown>) {
7
- if ((this.rule as { entity?: unknown }).entity && target !== (rule as { entity?: unknown }).entity) {
8
- return {
9
- target,
10
- conditionIsMet: false,
11
- }
12
- }
13
-
14
- return {
15
- target,
16
- conditionIsMet: entityMatches(
17
- bgioArguments as BgioResolveState,
18
- (rule as { matcher: Record<string, unknown> }).matcher,
19
- target as { rule: Record<string, unknown>; state?: Record<string, unknown> },
20
- context
21
- )
22
- }
23
- }
24
- }
@@ -1,10 +0,0 @@
1
- import Condition from "./condition.js";
2
-
3
- export default class IsFull extends Condition {
4
- checkCondition (_bgioArguments: unknown, _rule: unknown, payload: Record<string, unknown>, _context: Record<string, unknown>) {
5
- const t = payload.target as { spaces: { entities?: unknown[] }[] };
6
- return {
7
- conditionIsMet: t.spaces.every((space: { entities?: unknown[] }) => space?.entities?.length)
8
- };
9
- }
10
- }
@@ -1,13 +0,0 @@
1
- import Condition from "./condition.js";
2
-
3
- export default class Position extends Condition {
4
- checkCondition (bgioArguments: unknown, rule: unknown, conditionPayload: Record<string, unknown>, _newContext: Record<string, unknown>) {
5
- const target = conditionPayload.target;
6
- const parent = (bgioArguments as { G: { bank: { findParent: (t: unknown) => { entities: unknown[] } } } }).G.bank.findParent(target);
7
- let conditionIsMet = false;
8
- if ((rule as { position?: string }).position === "First") {
9
- conditionIsMet = parent.entities.indexOf(target) === 0;
10
- }
11
- return { conditionIsMet };
12
- }
13
- }
@@ -1,104 +0,0 @@
1
- import type { Condition as ConditionRule } from "../../types/bagel-types.js";
2
- import Condition from "./condition.js";
3
- import checkConditions from "../../utils/check-conditions.js";
4
- import simulateMove from "../../utils/simulate-move.js";
5
- import type { BgioResolveState } from "../../utils/bgio-resolve-types.js";
6
-
7
- const argNameMap: Record<string, string[]> = {
8
- PlaceNew: ["destination"],
9
- RemoveEntity: ["entity"],
10
- MoveEntity: ["entity", "destination"],
11
- TakeFrom: ["source", "destination"],
12
- SetState: ["entity", "state"],
13
- };
14
-
15
- export default class WouldCondition extends Condition {
16
- checkCondition (
17
- bgioArguments: unknown,
18
- rule: unknown,
19
- conditionPayload: Record<string, unknown>,
20
- context: Record<string, unknown>
21
- ) {
22
- const target = conditionPayload.target;
23
- const targets = (conditionPayload.targets as unknown[] | undefined) ?? [target];
24
-
25
- const moveType = (context.moveInstance as { rule: { moveType: string } } | undefined)?.rule?.moveType;
26
- const argNames = moveType ? argNameMap[moveType] : undefined;
27
- const payload = {
28
- arguments: targets.reduce<Record<string, unknown>>((acc, t, i) => {
29
- const key = argNames?.[i] ?? `arg${i}`;
30
- return { ...acc, [key]: t };
31
- }, {}),
32
- };
33
-
34
- const simulatedG = simulateMove(
35
- bgioArguments as BgioResolveState,
36
- payload as Parameters<typeof simulateMove>[1],
37
- context as Parameters<typeof simulateMove>[2]
38
- ) as { bank: { locate: (id: unknown) => unknown } };
39
-
40
- let simulatedConditionsPayload: Record<string, unknown> = {};
41
- if (target) {
42
- simulatedConditionsPayload = {
43
- target: simulatedG.bank.locate((target as { entityId: unknown }).entityId),
44
- };
45
- } else if (targets) {
46
- simulatedConditionsPayload = {
47
- targets: targets.map((t) => simulatedG.bank.locate((t as { entityId: unknown }).entityId)),
48
- };
49
- }
50
-
51
- const conditionResults = checkConditions(
52
- { ...(bgioArguments as BgioResolveState), G: simulatedG } as BgioResolveState,
53
- (rule as { conditions?: ConditionRule[] }).conditions,
54
- simulatedConditionsPayload,
55
- context
56
- );
57
-
58
- const conditionIsMet = conditionResults.conditionsAreMet;
59
-
60
- const results = conditionIsMet
61
- ? restoreReferences(
62
- conditionResults.results,
63
- (entityId: unknown) =>
64
- (bgioArguments as { G: { bank: { locate: (id: unknown) => unknown } } }).G.bank.locate(entityId)
65
- )
66
- : conditionResults.results;
67
-
68
- return {
69
- results,
70
- conditionIsMet,
71
- };
72
- }
73
- }
74
-
75
- function restoreReferences (
76
- obj: unknown,
77
- getOriginalEntity: (id: unknown) => unknown,
78
- seen = new WeakSet<object>()
79
- ): unknown {
80
- if (typeof obj !== "object" || obj === null) {
81
- return obj;
82
- }
83
-
84
- if (seen.has(obj)) {
85
- return obj;
86
- }
87
- seen.add(obj);
88
-
89
- if ((obj as { entityId?: unknown }).entityId !== undefined) {
90
- return getOriginalEntity((obj as { entityId: unknown }).entityId);
91
- }
92
-
93
- if (Array.isArray(obj)) {
94
- return obj.map((item) => restoreReferences(item, getOriginalEntity, seen));
95
- }
96
-
97
- const restored: Record<string, unknown> = {};
98
- for (const key in obj) {
99
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
100
- restored[key] = restoreReferences((obj as Record<string, unknown>)[key], getOriginalEntity, seen);
101
- }
102
- }
103
- return restored;
104
- }
@@ -1,37 +0,0 @@
1
- export default class Entity {
2
- rule: Record<string, unknown>;
3
- entityId: number;
4
- state: Record<string, unknown>;
5
-
6
- constructor (
7
- options: { fromBank?: boolean; initialStateGroups?: Record<string, string> } | undefined,
8
- rule: Record<string, unknown>,
9
- id: number
10
- ) {
11
- if (!options?.fromBank) {
12
- throw new Error(`Do not create entities directly. Go through the Bank. rule: ${JSON.stringify(rule)}`);
13
- }
14
- this.rule = rule;
15
- this.entityId = id;
16
- this.state = {};
17
- if (this.rule.stateGroups) {
18
- Object.entries(this.rule.stateGroups as Record<string, Record<string, Record<string, unknown>>>)
19
- .forEach(([stateGroupName, stateGroupValues]) => {
20
- const stateGroupValueName = options?.initialStateGroups?.[stateGroupName]
21
- ?? Object.keys(stateGroupValues)[0];
22
- Object.assign(this.state, stateGroupValues[stateGroupValueName]);
23
- });
24
- }
25
- if (this.rule.state) {
26
- Object.assign(this.state, this.rule.state as Record<string, unknown>);
27
- }
28
- }
29
-
30
- get attributes () {
31
- return {
32
- ...this.rule,
33
- ...this,
34
- ...this.state,
35
- };
36
- }
37
- }
@@ -1,263 +0,0 @@
1
- import find from "lodash/find.js";
2
- import type { Entity, EntityMatcher, EntityAttributes, GameFactoryInput, ExpandedGameRules, MoveDefinition } from "../types/bagel-types.js";
3
- import transformJSON from "../utils/json-transformer.js";
4
-
5
- type TransformRule = {
6
- test: (val: unknown) => boolean;
7
- replace: (val: unknown) => unknown;
8
- };
9
-
10
- const invariantEntities = [
11
- {
12
- entityType: "Space",
13
- count: "Infinity",
14
- },
15
- {
16
- entityType: "Board",
17
- name: "sharedBoard",
18
- },
19
- {
20
- name: "playerMarker",
21
- perPlayer: true,
22
- count: "Infinity",
23
- },
24
- ] as Entity[];
25
-
26
- function expandEntities (rules: { entities: Entity[] }) {
27
- rules.entities = [
28
- ...invariantEntities,
29
- ...(rules.entities || []),
30
- ];
31
- }
32
-
33
- function expandInitialPlacements (rules: Record<string, unknown>, entities: Entity[]) {
34
- if (rules.sharedBoard) {
35
- const sharedBoard = rules.sharedBoard as EntityMatcher<EntityAttributes<Entity>>[];
36
- const sharedBoardPlacements = sharedBoard.map((matcher) => ({ entity: matcher, destination: { name: "sharedBoard" } }));
37
- if (!rules.initialPlacements) rules.initialPlacements = [];
38
- (rules.initialPlacements as unknown[]).unshift(...sharedBoardPlacements);
39
- }
40
-
41
- if (rules.personalBoard) {
42
- entities.push({
43
- entityType: "Board",
44
- name: "personalBoard",
45
- perPlayer: true,
46
- });
47
- const personalBoard = rules.personalBoard as EntityMatcher<EntityAttributes<Entity>>[];
48
- const personalBoardPlacements = personalBoard.map((matcher) => ({
49
- entity: matcher,
50
- destination: {
51
- name: "personalBoard",
52
- },
53
- }));
54
- if (!rules.initialPlacements) rules.initialPlacements = [];
55
- (rules.initialPlacements as unknown[]).unshift(...personalBoardPlacements);
56
- }
57
-
58
- if (rules.initialPlacements) {
59
- const initialPlacementMoves = (rules.initialPlacements as Array<{ entity: Record<string, unknown>; destination: { index?: number; name?: string } }>).map((placement) => {
60
- const { state, ...matcher } = placement.entity;
61
- const entityDefinition = find(entities, matcher) as Entity | undefined;
62
-
63
- if (placement.destination.name === "personalBoard") {
64
- return {
65
- moveType: "ForEach",
66
- arguments: {
67
- targets: {
68
- type: "ctxPath",
69
- path: ["playOrder"],
70
- },
71
- },
72
- move: {
73
- moveType: "PlaceNew",
74
- entity: {
75
- state,
76
- conditions: [{
77
- conditionType: "Is",
78
- matcher: {
79
- ...matcher,
80
- ...(entityDefinition?.perPlayer
81
- ? {
82
- player: {
83
- type: "contextPath",
84
- path: ["loopTarget"],
85
- },
86
- }
87
- : {}
88
- ),
89
- },
90
- }],
91
- },
92
- arguments: {
93
- destination: {
94
- conditions: [{
95
- conditionType: "Is",
96
- matcher: {
97
- ...placement.destination,
98
- player: {
99
- type: "contextPath",
100
- path: ["loopTarget"],
101
- },
102
- },
103
- }],
104
- },
105
- },
106
- },
107
- } as MoveDefinition;
108
- } else {
109
- return {
110
- moveType: "PlaceNew",
111
- entity: {
112
- state,
113
- conditions: [{
114
- conditionType: "Is",
115
- matcher,
116
- }],
117
- },
118
- arguments: {
119
- destination: {
120
- conditions: [{
121
- conditionType: "Is",
122
- matcher: placement.destination,
123
- }],
124
- },
125
- },
126
- } as MoveDefinition;
127
- }
128
- });
129
- if (!rules.initialMoves) rules.initialMoves = [];
130
- (rules.initialMoves as MoveDefinition[]).unshift(...initialPlacementMoves);
131
- delete rules.initialPlacements;
132
- }
133
- }
134
-
135
- const keyMappings: [string, string][] = [];
136
-
137
- const simpleReplacements: [string, unknown][] = [
138
- [
139
- "isCurrentPlayer",
140
- {
141
- conditionType: "Is",
142
- matcher: {
143
- player: {
144
- type: "ctxPath",
145
- path: ["currentPlayer"],
146
- },
147
- },
148
- },
149
- ],
150
- [
151
- "isEmpty",
152
- {
153
- conditionType: "Not",
154
- conditions: [{ conditionType: "Contains" }],
155
- },
156
- ],
157
- [
158
- "ownerOfFirstResultEntity",
159
- {
160
- type: "contextPath",
161
- path: ["results", 0, "matches", 0, 0, "entities", 0, "attributes", "player"],
162
- },
163
- ],
164
- ];
165
-
166
- const transformationRules: TransformRule[] = [
167
- {
168
- test: (val) => Boolean(val && typeof val === "object"),
169
- replace: (val) => {
170
- const obj = val as Record<string, unknown>;
171
- keyMappings.forEach(([oldKey, newKey]) => {
172
- if (Object.prototype.hasOwnProperty.call(obj, oldKey)) {
173
- obj[newKey] = obj[oldKey];
174
- delete obj[oldKey];
175
- }
176
- });
177
- return val;
178
- },
179
- },
180
- {
181
- test: (val) => typeof val === "string",
182
- replace: (val) => {
183
- for (let i = 0, len = simpleReplacements.length; i < len; i++) {
184
- if (val === simpleReplacements[i][0]) {
185
- return simpleReplacements[i][1];
186
- }
187
- }
188
- return val;
189
- },
190
- },
191
- {
192
- test: (val) => Boolean(val && typeof val === "object" && (val as { conditions?: unknown }).conditions),
193
- replace: (val) => {
194
- const v = val as { conditions: unknown };
195
- if (!Array.isArray(v.conditions)) {
196
- v.conditions = [v.conditions];
197
- }
198
- return val;
199
- },
200
- },
201
- {
202
- test: (val) => Boolean(val && typeof val === "object" && (val as { conditions?: unknown }).conditions),
203
- replace: (val) => {
204
- const v = val as { conditions: Array<Record<string, unknown>> };
205
- for (let i = 0, len = v.conditions.length; i < len; i++) {
206
- if (!v.conditions[i].conditionType) {
207
- v.conditions[i] = {
208
- conditionType: "Is",
209
- matcher: v.conditions[i],
210
- };
211
- }
212
- }
213
- return val;
214
- },
215
- },
216
- {
217
- test: (val) => Boolean(val && typeof val === "object" && typeof (val as { target?: unknown }).target === "string"),
218
- replace: (val) => {
219
- const v = val as { target: string };
220
- return {
221
- ...v,
222
- target: {
223
- conditions: [{
224
- conditionType: "Is",
225
- matcher: {
226
- name: v.target,
227
- },
228
- }],
229
- },
230
- };
231
- },
232
- },
233
- ];
234
-
235
- export default function expandGameRules (gameRules: GameFactoryInput): ExpandedGameRules {
236
- const rules = transformJSON(gameRules, transformationRules) as GameFactoryInput;
237
-
238
- if (!rules.sharedBoard) {
239
- rules.sharedBoard = rules.entities as unknown as GameFactoryInput["sharedBoard"];
240
- }
241
-
242
- if (!rules.turn) {
243
- rules.turn = {
244
- minMoves: 1,
245
- maxMoves: 1,
246
- };
247
- }
248
-
249
- expandEntities(rules);
250
- expandInitialPlacements(rules as unknown as Record<string, unknown>, rules.entities);
251
-
252
- if (rules.phases) {
253
- Object.entries(rules.phases).forEach((phaseRule) => {
254
- expandInitialPlacements(phaseRule as unknown as Record<string, unknown>, rules.entities);
255
- });
256
- }
257
-
258
- if (gameRules.numPlayers) {
259
- gameRules.minPlayers = gameRules.maxPlayers = gameRules.numPlayers;
260
- }
261
-
262
- return rules as ExpandedGameRules;
263
- }