board-game-engine 2.1.0 → 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 (256) hide show
  1. package/README.md +2 -2
  2. package/dist/board-game-engine.cjs +5509 -5613
  3. package/dist/board-game-engine.js +5509 -5613
  4. package/dist/board-game-engine.min.js +22 -22
  5. package/dist/board-game-engine.mjs +5508 -5611
  6. package/e2e/fixtures/bge-checkers.html +2 -1
  7. package/e2e/fixtures/bge-minimal.html +2 -1
  8. package/e2e/fixtures/bge-ttt.html +2 -1
  9. package/examples/index.html +1 -1
  10. package/package.json +4 -10
  11. package/playwright-report/index.html +1 -1
  12. package/scripts/build.mjs +2 -2
  13. package/src/client/client.js +224 -0
  14. package/src/game-factory/bank/bank-slot.js +69 -0
  15. package/src/game-factory/bank/bank.js +114 -0
  16. package/src/game-factory/{board.ts → board.js} +1 -1
  17. package/src/game-factory/condition/condition-factory.js +52 -0
  18. package/src/game-factory/condition/condition.js +39 -0
  19. package/src/game-factory/condition/{contains-condition.ts → contains-condition.js} +4 -5
  20. package/src/game-factory/condition/{contains-same-condition.ts → contains-same-condition.js} +5 -8
  21. package/src/game-factory/condition/{evaluate-condition.ts → evaluate-condition.js} +3 -4
  22. package/src/game-factory/condition/every-condition.js +25 -0
  23. package/src/game-factory/condition/has-line-condition.js +14 -0
  24. package/src/game-factory/condition/in-line-condition.js +19 -0
  25. package/src/game-factory/condition/is-condition.js +23 -0
  26. package/src/game-factory/condition/is-full-condition.js +9 -0
  27. package/src/game-factory/condition/{no-possible-moves-condition.ts → no-possible-moves-condition.js} +2 -3
  28. package/src/game-factory/condition/{not-condition.ts → not-condition.js} +2 -3
  29. package/src/game-factory/condition/{or-condition.ts → or-condition.js} +2 -3
  30. package/src/game-factory/condition/position-condition.js +12 -0
  31. package/src/game-factory/condition/{some-condition.ts → some-condition.js} +3 -5
  32. package/src/game-factory/condition/would-condition.js +94 -0
  33. package/src/game-factory/entity.js +29 -0
  34. package/src/game-factory/expand-game-rules.js +271 -0
  35. package/src/game-factory/game-factory.js +240 -0
  36. package/{dist/game-factory/move/end-turn.d.ts → src/game-factory/move/end-turn.js} +4 -2
  37. package/src/game-factory/move/for-each.js +18 -0
  38. package/src/game-factory/move/move-entity.js +16 -0
  39. package/src/game-factory/move/move-factory.js +89 -0
  40. package/src/game-factory/move/move.js +131 -0
  41. package/src/game-factory/move/pass-turn.js +10 -0
  42. package/{dist/game-factory/move/pass.d.ts → src/game-factory/move/pass.js} +4 -2
  43. package/src/game-factory/move/place-new.js +33 -0
  44. package/src/game-factory/move/remove-entity.js +7 -0
  45. package/src/game-factory/move/set-active-players.js +23 -0
  46. package/src/game-factory/move/set-state.js +11 -0
  47. package/src/game-factory/move/shuffle.js +7 -0
  48. package/src/game-factory/move/take-from.js +7 -0
  49. package/src/game-factory/space/space.js +30 -0
  50. package/src/game-factory/space-group/grid.js +43 -0
  51. package/src/game-factory/space-group/space-group.js +29 -0
  52. package/src/index.js +2 -0
  53. package/src/utils/{any-valid-moves.ts → any-valid-moves.js} +49 -54
  54. package/src/utils/check-conditions.js +28 -0
  55. package/src/utils/create-payload.js +16 -0
  56. package/src/utils/deserialize-bgio-arguments.js +8 -0
  57. package/src/utils/do-moves.js +18 -0
  58. package/src/utils/entity-matches.js +20 -0
  59. package/src/utils/find-met-condition.js +22 -0
  60. package/src/utils/get-current-moves.js +12 -0
  61. package/src/utils/get-scenario-results.js +23 -0
  62. package/src/utils/get-steps.js +29 -0
  63. package/src/utils/get.js +25 -0
  64. package/src/utils/{grid-contains-sequence.ts → grid-contains-sequence.js} +33 -71
  65. package/src/utils/json-transformer.js +12 -0
  66. package/src/utils/prepare-payload.js +17 -0
  67. package/src/utils/resolve-entity.js +9 -0
  68. package/src/utils/resolve-expression.js +10 -0
  69. package/src/utils/resolve-properties.js +149 -0
  70. package/src/utils/simulate-move.js +25 -0
  71. package/.github/workflows/ci.yml +0 -33
  72. package/dist/client/client.d.ts +0 -76
  73. package/dist/client/client.d.ts.map +0 -1
  74. package/dist/game-factory/bank/bank-slot.d.ts +0 -30
  75. package/dist/game-factory/bank/bank-slot.d.ts.map +0 -1
  76. package/dist/game-factory/bank/bank.d.ts +0 -34
  77. package/dist/game-factory/bank/bank.d.ts.map +0 -1
  78. package/dist/game-factory/board.d.ts +0 -4
  79. package/dist/game-factory/board.d.ts.map +0 -1
  80. package/dist/game-factory/condition/condition-factory.d.ts +0 -4
  81. package/dist/game-factory/condition/condition-factory.d.ts.map +0 -1
  82. package/dist/game-factory/condition/condition.d.ts +0 -13
  83. package/dist/game-factory/condition/condition.d.ts.map +0 -1
  84. package/dist/game-factory/condition/contains-condition.d.ts +0 -8
  85. package/dist/game-factory/condition/contains-condition.d.ts.map +0 -1
  86. package/dist/game-factory/condition/contains-same-condition.d.ts +0 -7
  87. package/dist/game-factory/condition/contains-same-condition.d.ts.map +0 -1
  88. package/dist/game-factory/condition/evaluate-condition.d.ts +0 -8
  89. package/dist/game-factory/condition/evaluate-condition.d.ts.map +0 -1
  90. package/dist/game-factory/condition/every-condition.d.ts +0 -12
  91. package/dist/game-factory/condition/every-condition.d.ts.map +0 -1
  92. package/dist/game-factory/condition/has-line-condition.d.ts +0 -8
  93. package/dist/game-factory/condition/has-line-condition.d.ts.map +0 -1
  94. package/dist/game-factory/condition/in-line-condition.d.ts +0 -8
  95. package/dist/game-factory/condition/in-line-condition.d.ts.map +0 -1
  96. package/dist/game-factory/condition/is-condition.d.ts +0 -8
  97. package/dist/game-factory/condition/is-condition.d.ts.map +0 -1
  98. package/dist/game-factory/condition/is-full-condition.d.ts +0 -7
  99. package/dist/game-factory/condition/is-full-condition.d.ts.map +0 -1
  100. package/dist/game-factory/condition/no-possible-moves-condition.d.ts +0 -7
  101. package/dist/game-factory/condition/no-possible-moves-condition.d.ts.map +0 -1
  102. package/dist/game-factory/condition/not-condition.d.ts +0 -7
  103. package/dist/game-factory/condition/not-condition.d.ts.map +0 -1
  104. package/dist/game-factory/condition/or-condition.d.ts +0 -7
  105. package/dist/game-factory/condition/or-condition.d.ts.map +0 -1
  106. package/dist/game-factory/condition/position-condition.d.ts +0 -7
  107. package/dist/game-factory/condition/position-condition.d.ts.map +0 -1
  108. package/dist/game-factory/condition/some-condition.d.ts +0 -8
  109. package/dist/game-factory/condition/some-condition.d.ts.map +0 -1
  110. package/dist/game-factory/condition/would-condition.d.ts +0 -8
  111. package/dist/game-factory/condition/would-condition.d.ts.map +0 -1
  112. package/dist/game-factory/entity.d.ts +0 -13
  113. package/dist/game-factory/entity.d.ts.map +0 -1
  114. package/dist/game-factory/expand-game-rules.d.ts +0 -3
  115. package/dist/game-factory/expand-game-rules.d.ts.map +0 -1
  116. package/dist/game-factory/game-factory.d.ts +0 -10
  117. package/dist/game-factory/game-factory.d.ts.map +0 -1
  118. package/dist/game-factory/move/end-turn.d.ts.map +0 -1
  119. package/dist/game-factory/move/for-each.d.ts +0 -5
  120. package/dist/game-factory/move/for-each.d.ts.map +0 -1
  121. package/dist/game-factory/move/index.d.ts +0 -6
  122. package/dist/game-factory/move/index.d.ts.map +0 -1
  123. package/dist/game-factory/move/move-entity.d.ts +0 -7
  124. package/dist/game-factory/move/move-entity.d.ts.map +0 -1
  125. package/dist/game-factory/move/move-factory.d.ts +0 -18
  126. package/dist/game-factory/move/move-factory.d.ts.map +0 -1
  127. package/dist/game-factory/move/move.d.ts +0 -54
  128. package/dist/game-factory/move/move.d.ts.map +0 -1
  129. package/dist/game-factory/move/pass-turn.d.ts +0 -5
  130. package/dist/game-factory/move/pass-turn.d.ts.map +0 -1
  131. package/dist/game-factory/move/pass.d.ts.map +0 -1
  132. package/dist/game-factory/move/place-new.d.ts +0 -5
  133. package/dist/game-factory/move/place-new.d.ts.map +0 -1
  134. package/dist/game-factory/move/remove-entity.d.ts +0 -5
  135. package/dist/game-factory/move/remove-entity.d.ts.map +0 -1
  136. package/dist/game-factory/move/set-active-players.d.ts +0 -5
  137. package/dist/game-factory/move/set-active-players.d.ts.map +0 -1
  138. package/dist/game-factory/move/set-state.d.ts +0 -5
  139. package/dist/game-factory/move/set-state.d.ts.map +0 -1
  140. package/dist/game-factory/move/shuffle.d.ts +0 -5
  141. package/dist/game-factory/move/shuffle.d.ts.map +0 -1
  142. package/dist/game-factory/move/take-from.d.ts +0 -11
  143. package/dist/game-factory/move/take-from.d.ts.map +0 -1
  144. package/dist/game-factory/space/space.d.ts +0 -10
  145. package/dist/game-factory/space/space.d.ts.map +0 -1
  146. package/dist/game-factory/space-group/grid.d.ts +0 -15
  147. package/dist/game-factory/space-group/grid.d.ts.map +0 -1
  148. package/dist/game-factory/space-group/space-group.d.ts +0 -20
  149. package/dist/game-factory/space-group/space-group.d.ts.map +0 -1
  150. package/dist/index.d.ts +0 -6
  151. package/dist/index.d.ts.map +0 -1
  152. package/dist/registry.d.ts +0 -17
  153. package/dist/registry.d.ts.map +0 -1
  154. package/dist/types/bagel-types.d.ts +0 -339
  155. package/dist/types/bagel-types.d.ts.map +0 -1
  156. package/dist/types/index.d.ts +0 -3
  157. package/dist/types/index.d.ts.map +0 -1
  158. package/dist/types/rule-with-conditions.d.ts +0 -9
  159. package/dist/types/rule-with-conditions.d.ts.map +0 -1
  160. package/dist/utils/any-valid-moves.d.ts +0 -2
  161. package/dist/utils/any-valid-moves.d.ts.map +0 -1
  162. package/dist/utils/bgio-resolve-types.d.ts +0 -25
  163. package/dist/utils/bgio-resolve-types.d.ts.map +0 -1
  164. package/dist/utils/check-conditions.d.ts +0 -7
  165. package/dist/utils/check-conditions.d.ts.map +0 -1
  166. package/dist/utils/create-payload.d.ts +0 -5
  167. package/dist/utils/create-payload.d.ts.map +0 -1
  168. package/dist/utils/deserialize-bgio-arguments.d.ts +0 -3
  169. package/dist/utils/deserialize-bgio-arguments.d.ts.map +0 -1
  170. package/dist/utils/do-moves.d.ts +0 -8
  171. package/dist/utils/do-moves.d.ts.map +0 -1
  172. package/dist/utils/entity-matches.d.ts +0 -6
  173. package/dist/utils/entity-matches.d.ts.map +0 -1
  174. package/dist/utils/find-met-condition.d.ts +0 -6
  175. package/dist/utils/find-met-condition.d.ts.map +0 -1
  176. package/dist/utils/get-current-moves.d.ts +0 -24
  177. package/dist/utils/get-current-moves.d.ts.map +0 -1
  178. package/dist/utils/get-scenario-results.d.ts +0 -3
  179. package/dist/utils/get-scenario-results.d.ts.map +0 -1
  180. package/dist/utils/get-steps.d.ts +0 -13
  181. package/dist/utils/get-steps.d.ts.map +0 -1
  182. package/dist/utils/get.d.ts +0 -7
  183. package/dist/utils/get.d.ts.map +0 -1
  184. package/dist/utils/grid-contains-sequence.d.ts +0 -27
  185. package/dist/utils/grid-contains-sequence.d.ts.map +0 -1
  186. package/dist/utils/json-transformer.d.ts +0 -8
  187. package/dist/utils/json-transformer.d.ts.map +0 -1
  188. package/dist/utils/prepare-payload.d.ts +0 -2
  189. package/dist/utils/prepare-payload.d.ts.map +0 -1
  190. package/dist/utils/resolve-entity.d.ts +0 -3
  191. package/dist/utils/resolve-entity.d.ts.map +0 -1
  192. package/dist/utils/resolve-expression.d.ts +0 -6
  193. package/dist/utils/resolve-expression.d.ts.map +0 -1
  194. package/dist/utils/resolve-properties.d.ts +0 -4
  195. package/dist/utils/resolve-properties.d.ts.map +0 -1
  196. package/dist/utils/simulate-move.d.ts +0 -16
  197. package/dist/utils/simulate-move.d.ts.map +0 -1
  198. package/src/client/client.ts +0 -305
  199. package/src/game-factory/bank/bank-slot.ts +0 -81
  200. package/src/game-factory/bank/bank.ts +0 -125
  201. package/src/game-factory/condition/condition-factory.ts +0 -59
  202. package/src/game-factory/condition/condition.ts +0 -50
  203. package/src/game-factory/condition/every-condition.ts +0 -27
  204. package/src/game-factory/condition/has-line-condition.ts +0 -15
  205. package/src/game-factory/condition/in-line-condition.ts +0 -25
  206. package/src/game-factory/condition/is-condition.ts +0 -24
  207. package/src/game-factory/condition/is-full-condition.ts +0 -10
  208. package/src/game-factory/condition/position-condition.ts +0 -13
  209. package/src/game-factory/condition/would-condition.ts +0 -104
  210. package/src/game-factory/entity.ts +0 -37
  211. package/src/game-factory/expand-game-rules.ts +0 -263
  212. package/src/game-factory/game-factory.ts +0 -263
  213. package/src/game-factory/move/end-turn.ts +0 -7
  214. package/src/game-factory/move/for-each.ts +0 -20
  215. package/src/game-factory/move/move-entity.ts +0 -18
  216. package/src/game-factory/move/move-factory.ts +0 -107
  217. package/src/game-factory/move/move.ts +0 -147
  218. package/src/game-factory/move/pass-turn.ts +0 -15
  219. package/src/game-factory/move/pass.ts +0 -7
  220. package/src/game-factory/move/place-new.ts +0 -42
  221. package/src/game-factory/move/remove-entity.ts +0 -11
  222. package/src/game-factory/move/set-active-players.ts +0 -26
  223. package/src/game-factory/move/set-state.ts +0 -14
  224. package/src/game-factory/move/shuffle.ts +0 -9
  225. package/src/game-factory/move/take-from.ts +0 -12
  226. package/src/game-factory/space/space.ts +0 -36
  227. package/src/game-factory/space-group/grid.ts +0 -48
  228. package/src/game-factory/space-group/space-group.ts +0 -44
  229. package/src/index.ts +0 -5
  230. package/src/types/bagel-types.ts +0 -449
  231. package/src/types/boardgame-io-core.d.ts +0 -7
  232. package/src/types/index.ts +0 -70
  233. package/src/types/rule-with-conditions.ts +0 -9
  234. package/src/utils/bgio-resolve-types.ts +0 -27
  235. package/src/utils/check-conditions.ts +0 -28
  236. package/src/utils/create-payload.ts +0 -19
  237. package/src/utils/deserialize-bgio-arguments.ts +0 -10
  238. package/src/utils/do-moves.ts +0 -22
  239. package/src/utils/entity-matches.ts +0 -30
  240. package/src/utils/expr-eval.d.ts +0 -6
  241. package/src/utils/find-met-condition.ts +0 -23
  242. package/src/utils/get-current-moves.ts +0 -39
  243. package/src/utils/get-scenario-results.ts +0 -30
  244. package/src/utils/get-steps.ts +0 -38
  245. package/src/utils/get.ts +0 -28
  246. package/src/utils/json-transformer.ts +0 -17
  247. package/src/utils/prepare-payload.ts +0 -20
  248. package/src/utils/resolve-entity.ts +0 -15
  249. package/src/utils/resolve-expression.ts +0 -16
  250. package/src/utils/resolve-properties.ts +0 -172
  251. package/src/utils/simulate-move.ts +0 -32
  252. package/src/wackson.d.ts +0 -4
  253. package/tsconfig.build.json +0 -14
  254. package/tsconfig.json +0 -21
  255. /package/src/game-factory/move/{index.ts → index.js} +0 -0
  256. /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
- }