board-game-engine 2.0.0 → 2.1.0

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/.github/workflows/ci.yml +33 -0
  2. package/README.md +2 -2
  3. package/dist/board-game-engine.cjs +463 -349
  4. package/dist/board-game-engine.js +463 -349
  5. package/dist/board-game-engine.min.js +22 -22
  6. package/dist/board-game-engine.mjs +461 -348
  7. package/dist/client/client.d.ts +76 -0
  8. package/dist/client/client.d.ts.map +1 -0
  9. package/dist/game-factory/bank/bank-slot.d.ts +30 -0
  10. package/dist/game-factory/bank/bank-slot.d.ts.map +1 -0
  11. package/dist/game-factory/bank/bank.d.ts +34 -0
  12. package/dist/game-factory/bank/bank.d.ts.map +1 -0
  13. package/dist/game-factory/board.d.ts +4 -0
  14. package/dist/game-factory/board.d.ts.map +1 -0
  15. package/dist/game-factory/condition/condition-factory.d.ts +4 -0
  16. package/dist/game-factory/condition/condition-factory.d.ts.map +1 -0
  17. package/dist/game-factory/condition/condition.d.ts +13 -0
  18. package/dist/game-factory/condition/condition.d.ts.map +1 -0
  19. package/dist/game-factory/condition/contains-condition.d.ts +8 -0
  20. package/dist/game-factory/condition/contains-condition.d.ts.map +1 -0
  21. package/dist/game-factory/condition/contains-same-condition.d.ts +7 -0
  22. package/dist/game-factory/condition/contains-same-condition.d.ts.map +1 -0
  23. package/dist/game-factory/condition/evaluate-condition.d.ts +8 -0
  24. package/dist/game-factory/condition/evaluate-condition.d.ts.map +1 -0
  25. package/dist/game-factory/condition/every-condition.d.ts +12 -0
  26. package/dist/game-factory/condition/every-condition.d.ts.map +1 -0
  27. package/dist/game-factory/condition/has-line-condition.d.ts +8 -0
  28. package/dist/game-factory/condition/has-line-condition.d.ts.map +1 -0
  29. package/dist/game-factory/condition/in-line-condition.d.ts +8 -0
  30. package/dist/game-factory/condition/in-line-condition.d.ts.map +1 -0
  31. package/dist/game-factory/condition/is-condition.d.ts +8 -0
  32. package/dist/game-factory/condition/is-condition.d.ts.map +1 -0
  33. package/dist/game-factory/condition/is-full-condition.d.ts +7 -0
  34. package/dist/game-factory/condition/is-full-condition.d.ts.map +1 -0
  35. package/dist/game-factory/condition/no-possible-moves-condition.d.ts +7 -0
  36. package/dist/game-factory/condition/no-possible-moves-condition.d.ts.map +1 -0
  37. package/dist/game-factory/condition/not-condition.d.ts +7 -0
  38. package/dist/game-factory/condition/not-condition.d.ts.map +1 -0
  39. package/dist/game-factory/condition/or-condition.d.ts +7 -0
  40. package/dist/game-factory/condition/or-condition.d.ts.map +1 -0
  41. package/dist/game-factory/condition/position-condition.d.ts +7 -0
  42. package/dist/game-factory/condition/position-condition.d.ts.map +1 -0
  43. package/dist/game-factory/condition/some-condition.d.ts +8 -0
  44. package/dist/game-factory/condition/some-condition.d.ts.map +1 -0
  45. package/dist/game-factory/condition/would-condition.d.ts +8 -0
  46. package/dist/game-factory/condition/would-condition.d.ts.map +1 -0
  47. package/dist/game-factory/entity.d.ts +13 -0
  48. package/dist/game-factory/entity.d.ts.map +1 -0
  49. package/dist/game-factory/expand-game-rules.d.ts +3 -0
  50. package/dist/game-factory/expand-game-rules.d.ts.map +1 -0
  51. package/dist/game-factory/game-factory.d.ts +10 -0
  52. package/dist/game-factory/game-factory.d.ts.map +1 -0
  53. package/{src/game-factory/move/end-turn.js → dist/game-factory/move/end-turn.d.ts} +2 -4
  54. package/dist/game-factory/move/end-turn.d.ts.map +1 -0
  55. package/dist/game-factory/move/for-each.d.ts +5 -0
  56. package/dist/game-factory/move/for-each.d.ts.map +1 -0
  57. package/dist/game-factory/move/index.d.ts +6 -0
  58. package/dist/game-factory/move/index.d.ts.map +1 -0
  59. package/dist/game-factory/move/move-entity.d.ts +7 -0
  60. package/dist/game-factory/move/move-entity.d.ts.map +1 -0
  61. package/dist/game-factory/move/move-factory.d.ts +18 -0
  62. package/dist/game-factory/move/move-factory.d.ts.map +1 -0
  63. package/dist/game-factory/move/move.d.ts +54 -0
  64. package/dist/game-factory/move/move.d.ts.map +1 -0
  65. package/dist/game-factory/move/pass-turn.d.ts +5 -0
  66. package/dist/game-factory/move/pass-turn.d.ts.map +1 -0
  67. package/{src/game-factory/move/pass.js → dist/game-factory/move/pass.d.ts} +2 -4
  68. package/dist/game-factory/move/pass.d.ts.map +1 -0
  69. package/dist/game-factory/move/place-new.d.ts +5 -0
  70. package/dist/game-factory/move/place-new.d.ts.map +1 -0
  71. package/dist/game-factory/move/remove-entity.d.ts +5 -0
  72. package/dist/game-factory/move/remove-entity.d.ts.map +1 -0
  73. package/dist/game-factory/move/set-active-players.d.ts +5 -0
  74. package/dist/game-factory/move/set-active-players.d.ts.map +1 -0
  75. package/dist/game-factory/move/set-state.d.ts +5 -0
  76. package/dist/game-factory/move/set-state.d.ts.map +1 -0
  77. package/dist/game-factory/move/shuffle.d.ts +5 -0
  78. package/dist/game-factory/move/shuffle.d.ts.map +1 -0
  79. package/dist/game-factory/move/take-from.d.ts +11 -0
  80. package/dist/game-factory/move/take-from.d.ts.map +1 -0
  81. package/dist/game-factory/space/space.d.ts +10 -0
  82. package/dist/game-factory/space/space.d.ts.map +1 -0
  83. package/dist/game-factory/space-group/grid.d.ts +15 -0
  84. package/dist/game-factory/space-group/grid.d.ts.map +1 -0
  85. package/dist/game-factory/space-group/space-group.d.ts +20 -0
  86. package/dist/game-factory/space-group/space-group.d.ts.map +1 -0
  87. package/dist/index.d.ts +6 -0
  88. package/dist/index.d.ts.map +1 -0
  89. package/dist/registry.d.ts +17 -0
  90. package/dist/registry.d.ts.map +1 -0
  91. package/dist/types/bagel-types.d.ts +339 -0
  92. package/dist/types/bagel-types.d.ts.map +1 -0
  93. package/dist/types/index.d.ts +3 -0
  94. package/dist/types/index.d.ts.map +1 -0
  95. package/dist/types/rule-with-conditions.d.ts +9 -0
  96. package/dist/types/rule-with-conditions.d.ts.map +1 -0
  97. package/dist/utils/any-valid-moves.d.ts +2 -0
  98. package/dist/utils/any-valid-moves.d.ts.map +1 -0
  99. package/dist/utils/bgio-resolve-types.d.ts +25 -0
  100. package/dist/utils/bgio-resolve-types.d.ts.map +1 -0
  101. package/dist/utils/check-conditions.d.ts +7 -0
  102. package/dist/utils/check-conditions.d.ts.map +1 -0
  103. package/dist/utils/create-payload.d.ts +5 -0
  104. package/dist/utils/create-payload.d.ts.map +1 -0
  105. package/dist/utils/deserialize-bgio-arguments.d.ts +3 -0
  106. package/dist/utils/deserialize-bgio-arguments.d.ts.map +1 -0
  107. package/dist/utils/do-moves.d.ts +8 -0
  108. package/dist/utils/do-moves.d.ts.map +1 -0
  109. package/dist/utils/entity-matches.d.ts +6 -0
  110. package/dist/utils/entity-matches.d.ts.map +1 -0
  111. package/dist/utils/find-met-condition.d.ts +6 -0
  112. package/dist/utils/find-met-condition.d.ts.map +1 -0
  113. package/dist/utils/get-current-moves.d.ts +24 -0
  114. package/dist/utils/get-current-moves.d.ts.map +1 -0
  115. package/dist/utils/get-scenario-results.d.ts +3 -0
  116. package/dist/utils/get-scenario-results.d.ts.map +1 -0
  117. package/dist/utils/get-steps.d.ts +13 -0
  118. package/dist/utils/get-steps.d.ts.map +1 -0
  119. package/dist/utils/get.d.ts +7 -0
  120. package/dist/utils/get.d.ts.map +1 -0
  121. package/dist/utils/grid-contains-sequence.d.ts +27 -0
  122. package/dist/utils/grid-contains-sequence.d.ts.map +1 -0
  123. package/dist/utils/json-transformer.d.ts +8 -0
  124. package/dist/utils/json-transformer.d.ts.map +1 -0
  125. package/dist/utils/prepare-payload.d.ts +2 -0
  126. package/dist/utils/prepare-payload.d.ts.map +1 -0
  127. package/dist/utils/resolve-entity.d.ts +3 -0
  128. package/dist/utils/resolve-entity.d.ts.map +1 -0
  129. package/dist/utils/resolve-expression.d.ts +6 -0
  130. package/dist/utils/resolve-expression.d.ts.map +1 -0
  131. package/dist/utils/resolve-properties.d.ts +4 -0
  132. package/dist/utils/resolve-properties.d.ts.map +1 -0
  133. package/dist/utils/simulate-move.d.ts +16 -0
  134. package/dist/utils/simulate-move.d.ts.map +1 -0
  135. package/e2e/fixtures/bge-checkers.html +1 -2
  136. package/e2e/fixtures/bge-minimal.html +1 -2
  137. package/e2e/fixtures/bge-ttt.html +1 -2
  138. package/examples/index.html +1 -1
  139. package/package.json +9 -3
  140. package/playwright-report/index.html +1 -1
  141. package/scripts/build.mjs +2 -2
  142. package/src/client/client.ts +305 -0
  143. package/src/game-factory/bank/bank-slot.ts +81 -0
  144. package/src/game-factory/bank/bank.ts +125 -0
  145. package/src/game-factory/{board.js → board.ts} +1 -1
  146. package/src/game-factory/condition/condition-factory.ts +59 -0
  147. package/src/game-factory/condition/condition.ts +50 -0
  148. package/src/game-factory/condition/{contains-condition.js → contains-condition.ts} +5 -4
  149. package/src/game-factory/condition/{contains-same-condition.js → contains-same-condition.ts} +8 -5
  150. package/src/game-factory/condition/{evaluate-condition.js → evaluate-condition.ts} +4 -3
  151. package/src/game-factory/condition/every-condition.ts +27 -0
  152. package/src/game-factory/condition/has-line-condition.ts +15 -0
  153. package/src/game-factory/condition/in-line-condition.ts +25 -0
  154. package/src/game-factory/condition/is-condition.ts +24 -0
  155. package/src/game-factory/condition/is-full-condition.ts +10 -0
  156. package/src/game-factory/condition/{no-possible-moves-condition.js → no-possible-moves-condition.ts} +3 -2
  157. package/src/game-factory/condition/{not-condition.js → not-condition.ts} +3 -2
  158. package/src/game-factory/condition/{or-condition.js → or-condition.ts} +3 -2
  159. package/src/game-factory/condition/position-condition.ts +13 -0
  160. package/src/game-factory/condition/{some-condition.js → some-condition.ts} +5 -3
  161. package/src/game-factory/condition/would-condition.ts +104 -0
  162. package/src/game-factory/entity.ts +37 -0
  163. package/src/game-factory/expand-game-rules.ts +263 -0
  164. package/src/game-factory/game-factory.ts +263 -0
  165. package/src/game-factory/move/end-turn.ts +7 -0
  166. package/src/game-factory/move/for-each.ts +20 -0
  167. package/src/game-factory/move/move-entity.ts +18 -0
  168. package/src/game-factory/move/move-factory.ts +107 -0
  169. package/src/game-factory/move/move.ts +147 -0
  170. package/src/game-factory/move/pass-turn.ts +15 -0
  171. package/src/game-factory/move/pass.ts +7 -0
  172. package/src/game-factory/move/place-new.ts +42 -0
  173. package/src/game-factory/move/remove-entity.ts +11 -0
  174. package/src/game-factory/move/set-active-players.ts +26 -0
  175. package/src/game-factory/move/set-state.ts +14 -0
  176. package/src/game-factory/move/shuffle.ts +9 -0
  177. package/src/game-factory/move/take-from.ts +12 -0
  178. package/src/game-factory/space/space.ts +36 -0
  179. package/src/game-factory/space-group/grid.ts +48 -0
  180. package/src/game-factory/space-group/space-group.ts +44 -0
  181. package/src/index.ts +5 -0
  182. package/src/types/bagel-types.ts +449 -0
  183. package/src/types/boardgame-io-core.d.ts +7 -0
  184. package/src/types/index.ts +70 -0
  185. package/src/types/rule-with-conditions.ts +9 -0
  186. package/src/utils/{any-valid-moves.js → any-valid-moves.ts} +54 -49
  187. package/src/utils/bgio-resolve-types.ts +27 -0
  188. package/src/utils/check-conditions.ts +28 -0
  189. package/src/utils/create-payload.ts +19 -0
  190. package/src/utils/deserialize-bgio-arguments.ts +10 -0
  191. package/src/utils/do-moves.ts +22 -0
  192. package/src/utils/entity-matches.ts +30 -0
  193. package/src/utils/expr-eval.d.ts +6 -0
  194. package/src/utils/find-met-condition.ts +23 -0
  195. package/src/utils/get-current-moves.ts +39 -0
  196. package/src/utils/get-scenario-results.ts +30 -0
  197. package/src/utils/get-steps.ts +38 -0
  198. package/src/utils/get.ts +28 -0
  199. package/src/utils/{grid-contains-sequence.js → grid-contains-sequence.ts} +71 -33
  200. package/src/utils/json-transformer.ts +17 -0
  201. package/src/utils/prepare-payload.ts +20 -0
  202. package/src/utils/resolve-entity.ts +15 -0
  203. package/src/utils/resolve-expression.ts +16 -0
  204. package/src/utils/resolve-properties.ts +172 -0
  205. package/src/utils/simulate-move.ts +32 -0
  206. package/src/wackson.d.ts +4 -0
  207. package/tsconfig.build.json +14 -0
  208. package/tsconfig.json +21 -0
  209. package/src/client/client.js +0 -224
  210. package/src/game-factory/bank/bank-slot.js +0 -69
  211. package/src/game-factory/bank/bank.js +0 -114
  212. package/src/game-factory/condition/condition-factory.js +0 -52
  213. package/src/game-factory/condition/condition.js +0 -39
  214. package/src/game-factory/condition/every-condition.js +0 -25
  215. package/src/game-factory/condition/has-line-condition.js +0 -14
  216. package/src/game-factory/condition/in-line-condition.js +0 -19
  217. package/src/game-factory/condition/is-condition.js +0 -23
  218. package/src/game-factory/condition/is-full-condition.js +0 -9
  219. package/src/game-factory/condition/position-condition.js +0 -12
  220. package/src/game-factory/condition/would-condition.js +0 -94
  221. package/src/game-factory/entity.js +0 -29
  222. package/src/game-factory/expand-game-rules.js +0 -271
  223. package/src/game-factory/game-factory.js +0 -239
  224. package/src/game-factory/move/for-each.js +0 -18
  225. package/src/game-factory/move/move-entity.js +0 -16
  226. package/src/game-factory/move/move-factory.js +0 -89
  227. package/src/game-factory/move/move.js +0 -131
  228. package/src/game-factory/move/pass-turn.js +0 -10
  229. package/src/game-factory/move/place-new.js +0 -33
  230. package/src/game-factory/move/remove-entity.js +0 -7
  231. package/src/game-factory/move/set-active-players.js +0 -23
  232. package/src/game-factory/move/set-state.js +0 -11
  233. package/src/game-factory/move/shuffle.js +0 -7
  234. package/src/game-factory/move/take-from.js +0 -7
  235. package/src/game-factory/space/space.js +0 -30
  236. package/src/game-factory/space-group/grid.js +0 -43
  237. package/src/game-factory/space-group/space-group.js +0 -29
  238. package/src/index.js +0 -2
  239. package/src/utils/check-conditions.js +0 -28
  240. package/src/utils/create-payload.js +0 -16
  241. package/src/utils/deserialize-bgio-arguments.js +0 -8
  242. package/src/utils/do-moves.js +0 -18
  243. package/src/utils/entity-matches.js +0 -20
  244. package/src/utils/find-met-condition.js +0 -22
  245. package/src/utils/get-current-moves.js +0 -12
  246. package/src/utils/get-scenario-results.js +0 -23
  247. package/src/utils/get-steps.js +0 -29
  248. package/src/utils/get.js +0 -25
  249. package/src/utils/json-transformer.js +0 -12
  250. package/src/utils/prepare-payload.js +0 -16
  251. package/src/utils/resolve-entity.js +0 -9
  252. package/src/utils/resolve-expression.js +0 -10
  253. package/src/utils/resolve-properties.js +0 -149
  254. package/src/utils/simulate-move.js +0 -25
  255. /package/src/game-factory/move/{index.js → index.ts} +0 -0
  256. /package/src/{registry.js → registry.ts} +0 -0
@@ -1,224 +0,0 @@
1
- import { Client as BoardgameIOClient } from '@mnbroatch/boardgame.io/client'
2
- import { Debug } from '@mnbroatch/boardgame.io/debug';
3
- import { SocketIO } from '@mnbroatch/boardgame.io/multiplayer'
4
- import { serialize, deserialize } from 'wackson';
5
- import gameFactory from '../game-factory/game-factory.js'
6
- import { registry } from '../registry.js';
7
- import simulateMove from '../utils/simulate-move.js';
8
- import getCurrentMoves from '../utils/get-current-moves.js';
9
- import resolveProperties from '../utils/resolve-properties.js';
10
- import checkConditions from '../utils/check-conditions.js';
11
- import preparePayload from '../utils/prepare-payload.js';
12
- import getSteps from '../utils/get-steps.js';
13
- import createPayload from '../utils/create-payload.js';
14
-
15
- export class Client {
16
- constructor (options) {
17
- this.options = options
18
- this.game = options.boardgameIOGame
19
- || gameFactory(JSON.parse(options.gameRules), options.gameName)
20
-
21
- if (!options.boardgameIOGame) {
22
- this.moveBuilder = { targets: [], stepIndex: 0, eliminatedMoves: [] }
23
- this.optimisticWinner = null
24
- }
25
- }
26
-
27
- connect () {
28
- const {
29
- server,
30
- numPlayers,
31
- debug = {
32
- collapseOnLoad: true,
33
- impl: Debug,
34
- },
35
- matchID,
36
- playerID,
37
- credentials,
38
- multiplayer = SocketIO({ server, socketOpts: { transports: ['websocket', 'polling'] } }),
39
- } = this.options
40
-
41
- try {
42
- const clientOptions = !credentials
43
- ? { game: this.game, numPlayers, debug }
44
- : {
45
- game: this.game,
46
- multiplayer,
47
- matchID,
48
- playerID,
49
- credentials,
50
- numPlayers,
51
- debug,
52
- }
53
-
54
- this.client = BoardgameIOClient(clientOptions)
55
- this.client.subscribe(() => this.update())
56
- this.client.start()
57
- return this
58
- } catch (error) {
59
- console.error('Failed to join game:', error?.message ?? error)
60
- if (error?.stack) console.error(error.stack)
61
- }
62
- }
63
-
64
- update () {
65
- this.options.onClientUpdate?.()
66
- }
67
-
68
- getState () {
69
- const bgioState = this.client?.getState()
70
- if (!bgioState) return {}
71
-
72
- const state = this.options.boardgameIOGame
73
- ? bgioState
74
- : {
75
- ...bgioState,
76
- G: deserialize(JSON.stringify(bgioState.G), registry),
77
- }
78
-
79
- const gameover = this.optimisticWinner ?? state?.ctx?.gameover
80
-
81
- const currentMoves = gameover
82
- ? []
83
- : getCurrentMoves(state, this.client)
84
-
85
- if (this.options.boardgameIOGame) {
86
- return {
87
- state,
88
- gameover,
89
- moves: this.client.moves,
90
- currentMoves
91
- }
92
- }
93
-
94
- const _wrappedMoves = Object.entries(currentMoves)
95
- .reduce((acc, [moveName, rawMove]) => {
96
- const move = (payload) => {
97
- this.client.moves[moveName](preparePayload(payload))
98
- }
99
- move.moveInstance = rawMove.moveInstance
100
- return { ...acc, [moveName]: move }
101
- }, {})
102
-
103
- const { allClickable, _possibleMoveMeta } = getPossibleMoves(state, _wrappedMoves, this.moveBuilder)
104
-
105
- return { state, gameover, allClickable, _wrappedMoves, _possibleMoveMeta }
106
- }
107
-
108
- doStep (_target) {
109
- if (this.options.boardgameIOGame) return
110
-
111
- const { state, _wrappedMoves, _possibleMoveMeta } = this.getState()
112
-
113
- const target = _target.abstract
114
- ? _target
115
- : state.G.bank.locate(_target.entityId)
116
-
117
- const newEliminated = Object.entries(_possibleMoveMeta)
118
- .filter(([_, meta]) => !hasTarget(meta.clickableForMove, target))
119
- .map(([name]) => name)
120
- .concat(this.moveBuilder.eliminatedMoves);
121
-
122
- if (newEliminated.length === Object.keys(_wrappedMoves).length) {
123
- console.error('invalid move with target:', target?.rule);
124
- return;
125
- }
126
-
127
- const remainingMoveEntries = Object.entries(_possibleMoveMeta)
128
- .filter(([name]) => !newEliminated.includes(name))
129
-
130
- if (isMoveCompleted(state, _wrappedMoves, remainingMoveEntries, this.moveBuilder.stepIndex)) {
131
- const [moveName] = remainingMoveEntries[0]
132
- const move = _wrappedMoves[moveName]
133
- const payload = createPayload(
134
- state,
135
- move.moveInstance.rule,
136
- [...this.moveBuilder.targets, target],
137
- { moveInstance: move.moveInstance }
138
- );
139
-
140
- this.optimisticWinner = getWinnerAfterMove(state, this.game, move.moveInstance, payload);
141
- move(payload);
142
- this.moveBuilder = { targets: [], stepIndex: 0, eliminatedMoves: [] };
143
- } else {
144
- this.moveBuilder = {
145
- eliminatedMoves: newEliminated,
146
- stepIndex: this.moveBuilder.stepIndex + 1,
147
- targets: [...this.moveBuilder.targets, target]
148
- }
149
- }
150
-
151
- this.update()
152
- }
153
-
154
- reset () {
155
- if (this.options.boardgameIOGame) return
156
- this.moveBuilder = { targets: [], stepIndex: 0, eliminatedMoves: [] };
157
- this.optimisticWinner = null
158
- this.update()
159
- }
160
-
161
- undoStep () {
162
- if (this.options.boardgameIOGame) return
163
- if (this.moveBuilder.targets.length) {
164
- this.moveBuilder = {
165
- targets: this.moveBuilder.targets.slice(0, -1),
166
- stepIndex: Math.max(0, this.moveBuilder.stepIndex - 1),
167
- eliminatedMoves: []
168
- }
169
- }
170
- this.update()
171
- }
172
- }
173
-
174
- function hasTarget(clickableSet, target) {
175
- if (!target.abstract) return clickableSet.has(target);
176
- return [...clickableSet].some(item => item.abstract && item.value === target.value);
177
- }
178
-
179
- function getPossibleMoves(bgioState, moves, moveBuilder) {
180
- const { eliminatedMoves, stepIndex } = moveBuilder;
181
- const _possibleMoveMeta = {};
182
- const allClickable = new Set();
183
-
184
- Object.entries(moves)
185
- .filter(([moveName]) => !eliminatedMoves.includes(moveName))
186
- .forEach(([moveName, move]) => {
187
- const moveRule = resolveProperties(bgioState, { ...move.moveInstance.rule, moveName })
188
-
189
- const context = {
190
- moveInstance: move.moveInstance,
191
- moveArguments: moveRule.arguments
192
- }
193
-
194
- const targets = moveBuilder.targets.map(t =>
195
- t.abstract ? t : bgioState.G.bank.locate(t.entityId)
196
- )
197
-
198
- const payload = createPayload(bgioState, moveRule, targets, context);
199
-
200
- context.moveArguments = { ...context.moveArguments, ...payload.arguments }
201
-
202
- const moveIsAllowed = checkConditions(bgioState, moveRule, {}, context).conditionsAreMet;
203
- const moveSteps = getSteps(bgioState, moveRule);
204
-
205
- const clickableForMove = new Set(
206
- (moveIsAllowed && moveSteps?.[stepIndex]?.getClickable(context)) || []
207
- );
208
-
209
- _possibleMoveMeta[moveName] = { clickableForMove };
210
- clickableForMove.forEach(entity => allClickable.add(entity));
211
- });
212
-
213
- return { _possibleMoveMeta, allClickable };
214
- }
215
-
216
- function isMoveCompleted(state, moves, remainingMoveEntries, stepIndex) {
217
- return remainingMoveEntries.length === 1 &&
218
- getSteps(state, moves[remainingMoveEntries[0][0]].moveInstance.rule).length === stepIndex + 1;
219
- }
220
-
221
- function getWinnerAfterMove (state, game, moveInstance, movePayload) {
222
- const simulatedG = simulateMove(state, preparePayload(movePayload), { moveInstance })
223
- return game.endIf?.({ ...state, G: JSON.parse(serialize(simulatedG)) })
224
- }
@@ -1,69 +0,0 @@
1
- import resolveProperties from '../../utils/resolve-properties.js'
2
-
3
- // lazily create entities as needed, and also function as an index of entities created
4
- class BankSlot {
5
- constructor (rule, bank) {
6
- this.bank = bank
7
- this.rule = rule
8
- this.pool = []
9
- this.remaining = +rule.count || 1
10
- }
11
-
12
- getOne (bgioArguments, options, context) {
13
- return this.getMultiple(bgioArguments, 1, options, context)[0]
14
- }
15
-
16
- getMultiple (bgioArguments, count = Infinity, options = {}, context) {
17
- const toReturn = []
18
-
19
- if (this.remaining === Infinity && count === Infinity) {
20
- throw new Error(`Cannot get infinite pieces from slot with infinite remaining: ${this.rule.name}`)
21
- }
22
-
23
- if (count !== Infinity && count > this.remaining) {
24
- throw new Error(`Requested ${count} pieces but only ${this.remaining} available in slot: ${this.rule.name}`)
25
- }
26
-
27
- // Determine actual count to fetch
28
- const actualCount = count === Infinity ? this.remaining : count
29
-
30
- if (this.remaining !== Infinity) {
31
- this.remaining -= actualCount
32
- }
33
-
34
- const fromPool = Math.min(actualCount, this.pool.length)
35
- toReturn.push(...this.pool.splice(0, fromPool))
36
-
37
- const remainder = actualCount - fromPool
38
- if (remainder > 0) {
39
- toReturn.push(
40
- ...Array.from(new Array(remainder)).map(() =>
41
- this.bank.createEntity(this.rule)
42
- )
43
- )
44
- }
45
-
46
- if (options.state) {
47
- const newState = resolveProperties(bgioArguments, options.state, context)
48
- toReturn.forEach(entity => {
49
- entity.state = { ...entity.state, ...newState }
50
- })
51
- }
52
-
53
- return toReturn
54
- }
55
-
56
- returnToBank (entity) {
57
- if (entity.rule.state) {
58
- entity.state = entity.rule.state
59
- } else {
60
- delete entity.state
61
- }
62
- if (this.remaining !== undefined) {
63
- this.remaining += 1
64
- }
65
- this.pool.push(entity)
66
- }
67
- }
68
-
69
- export default BankSlot
@@ -1,114 +0,0 @@
1
- import find from 'lodash/find.js'
2
- import filter from 'lodash/filter.js'
3
- import checkConditions from '../../utils/check-conditions.js'
4
- import { registry } from '../../registry.js'
5
- import BankSlot from './bank-slot.js'
6
-
7
- class Bank {
8
- constructor (entityRules) {
9
- this.currentEntityId = 0
10
- this.tracker = {}
11
- this.slots = entityRules.map(rule => new BankSlot(rule, this))
12
- }
13
-
14
- createEntity (definition = {}, options) {
15
- const entity = new (registry[definition.entityType || 'Entity'])(
16
- {
17
- bank: this,
18
- fromBank: true,
19
- ...options
20
- },
21
- definition,
22
- this.currentEntityId++
23
- )
24
- this.track(entity)
25
- return entity
26
- }
27
-
28
- track (entity) {
29
- this.tracker[entity.entityId] = entity
30
- }
31
-
32
- locate (entityId) {
33
- return this.tracker[entityId]
34
- }
35
-
36
- findAll (bgioArguments, rule, context) {
37
- if (!rule.conditions) {
38
- throw new Error (`Cannot find entity with no conditions. Rule: ${JSON.stringify(rule)}`)
39
- }
40
- return filter(
41
- Object.values(this.tracker),
42
- entity => checkConditions(
43
- bgioArguments,
44
- rule,
45
- { target: entity },
46
- context
47
- ).conditionsAreMet
48
- )
49
- }
50
-
51
- findOne (bgioArguments, rule, context) {
52
- return this.findAll(bgioArguments, rule, context)[0]
53
- }
54
-
55
- find (bgioArguments, rule, context) {
56
- return rule.matchMultiple
57
- ? this.findAll(bgioArguments, rule, context)
58
- : this.findOne(bgioArguments, rule, context)
59
- }
60
-
61
- findParent (entity) {
62
- return find(this.tracker, ent =>
63
- ent.entities?.includes(entity)
64
- || ent.spaces?.includes(entity)
65
- )
66
- }
67
-
68
- getOne (bgioArguments, rule, context) {
69
- const slot = this.getSlot(bgioArguments, rule, context)
70
- if (!slot) {
71
- console.error(`No matching slot for ${JSON.stringify(rule)}`)
72
- }
73
- return slot.getOne(bgioArguments, { state: rule.state }, context)
74
- }
75
-
76
- getMultiple (bgioArguments, rule, count, context) {
77
- const slots = this.getSlots(bgioArguments, rule, context)
78
- if (!slots.length) {
79
- console.error(`No matching slots for ${JSON.stringify(rule)}`)
80
- }
81
- return slots.reduce((acc, slot) => [
82
- ...acc,
83
- ...slot.getMultiple(bgioArguments, count, { state: rule.state })
84
- ], [])
85
- }
86
-
87
- getSlot (bgioArguments, rule, context) {
88
- return this.slots.find(slot => checkConditions(
89
- bgioArguments,
90
- rule,
91
- { target: slot },
92
- context
93
- ).conditionsAreMet
94
- )
95
- }
96
-
97
- getSlots (bgioArguments, rule, context) {
98
- return this.slots.filter(slot => checkConditions(
99
- bgioArguments,
100
- rule,
101
- { target: slot },
102
- context
103
- ).conditionsAreMet
104
- )
105
- }
106
-
107
- returnToBank (bgioArguments, entity) {
108
- this.findParent(entity).remove(entity)
109
- this.getSlot(bgioArguments, entity.rule).returnToBank(entity)
110
- delete this.tracker[entity.entityId]
111
- }
112
- }
113
-
114
- export default Bank
@@ -1,52 +0,0 @@
1
- import Is from "./is-condition.js";
2
- import Not from "./not-condition.js";
3
- import Or from "./or-condition.js";
4
- import Some from "./some-condition.js";
5
- import Every from "./every-condition.js";
6
- import ContainsCondition from "./contains-condition.js";
7
- import ContainsSameCondition from "./contains-same-condition.js";
8
- import InLine from "./in-line-condition.js";
9
- import HasLine from "./has-line-condition.js";
10
- import IsFull from "./is-full-condition.js";
11
- import Would from "./would-condition.js";
12
- import NoPossibleMoves from "./no-possible-moves-condition.js";
13
- import Evaluate from "./evaluate-condition.js";
14
- import Position from "./position-condition.js";
15
- // import BingoCondition from "./bingo-condition.js";
16
- // import RelativeMoveCondition from "./relative-move-condition.js";
17
-
18
- export default function conditionFactory(rule) {
19
- if (rule.conditionType === "Is") {
20
- return new Is(rule);
21
- } else if (rule.conditionType === "Not") {
22
- return new Not(rule);
23
- } else if (rule.conditionType === "Or") {
24
- return new Or(rule);
25
- } else if (rule.conditionType === "Some") {
26
- return new Some(rule);
27
- } else if (rule.conditionType === "Contains") {
28
- return new ContainsCondition(rule);
29
- } else if (rule.conditionType === "ContainsSame") {
30
- return new ContainsSameCondition(rule);
31
- } else if (rule.conditionType === "Every") {
32
- return new Every(rule);
33
- } else if (rule.conditionType === "InLine") {
34
- return new InLine(rule);
35
- } else if (rule.conditionType === "HasLine") {
36
- return new HasLine(rule);
37
- } else if (rule.conditionType === "IsFull") {
38
- return new IsFull(rule);
39
- } else if (rule.conditionType === "Would") {
40
- return new Would(rule);
41
- } else if (rule.conditionType === "NoPossibleMoves") {
42
- return new NoPossibleMoves(rule);
43
- } else if (rule.conditionType === "Evaluate") {
44
- return new Evaluate(rule);
45
- } else if (rule.conditionType === "Position") {
46
- return new Position(rule);
47
- // } else if (rule.conditionType === "bingo") {
48
- // return new BingoCondition(rule);
49
- // } else if (rule.conditionType === "relativeMove") {
50
- // return new RelativeMoveCondition(rule);
51
- }
52
- }
@@ -1,39 +0,0 @@
1
- import resolveProperties from "../../utils/resolve-properties.js";
2
-
3
- export default class Condition {
4
- constructor (rule) {
5
- this.rule = rule
6
- }
7
-
8
- check (bgioArguments, payload, context) {
9
- const conditionPayload = { ...payload }
10
- const newContext = { ...context }
11
-
12
- if (conditionPayload.target) {
13
- newContext.originalTarget = conditionPayload.target
14
- }
15
-
16
- const rule = resolveProperties(
17
- bgioArguments,
18
- this.rule,
19
- newContext
20
- )
21
-
22
- // We don't simply defer to payload target because of parent and relativePath
23
- // target types, for instance, which retarget to another entity
24
- if (rule.target !== undefined) {
25
- conditionPayload.target = rule.target
26
- }
27
-
28
- // Nonexistent entities never fulfill conditions (including "Not" conditions!)
29
- if (this.rule.target !== undefined && !conditionPayload.target) {
30
- return { conditionIsMet: false }
31
- }
32
-
33
- return this.checkCondition(bgioArguments, rule, conditionPayload, newContext)
34
- }
35
-
36
- isMet(...args) {
37
- return this.check(...args).conditionIsMet
38
- }
39
- }
@@ -1,25 +0,0 @@
1
- import Condition from "./condition.js";
2
- import checkConditions from "../../utils/check-conditions.js";
3
-
4
- export default class EveryCondition extends Condition {
5
- checkCondition(bgioArguments, rule, { target: targets }, context) {
6
- const results = targets.map((target) => {
7
- const loopContext = {
8
- ...context,
9
- loopTarget: target
10
- }
11
-
12
- return checkConditions(
13
- bgioArguments,
14
- rule,
15
- undefined,
16
- loopContext
17
- )
18
- })
19
-
20
- return {
21
- conditionIsMet: results.every(r => r.conditionsAreMet),
22
- results
23
- }
24
- }
25
- }
@@ -1,14 +0,0 @@
1
- import Condition from "./condition.js";
2
- import gridContainsSequence from "../../utils/grid-contains-sequence.js";
3
-
4
- export default class HasLineCondition extends Condition {
5
- checkCondition(bgioArguments, rule, payload, context) {
6
- const { matches } = gridContainsSequence(
7
- bgioArguments,
8
- payload.target,
9
- rule.sequence,
10
- context
11
- );
12
- return { matches, conditionIsMet: !!matches.length };
13
- }
14
- }
@@ -1,19 +0,0 @@
1
- import Condition from "./condition.js";
2
- import gridContainsSequence from "../../utils/grid-contains-sequence.js";
3
-
4
-
5
- export default class InLineCondition extends Condition {
6
- checkCondition(bgioArguments, rule, payload, context) {
7
- const { G } = bgioArguments;
8
- const { target } = payload;
9
- const parent = G.bank.findParent(payload.target);
10
-
11
- const { matches: allMatches } = gridContainsSequence(bgioArguments, parent, rule.sequence, context);
12
-
13
- const matches = allMatches.filter(sequence =>
14
- sequence.some(space => space === target)
15
- );
16
-
17
- return { matches, conditionIsMet: !!matches.length };
18
- }
19
- }
@@ -1,23 +0,0 @@
1
- import Condition from "./condition.js";
2
- import entityMatches from '../../utils/entity-matches.js'
3
-
4
- export default class Is extends Condition {
5
- checkCondition(bgioArguments, rule, { target }, context) {
6
- if (this.rule.entity && target !== rule.entity) {
7
- return {
8
- target,
9
- conditionIsMet: false,
10
- }
11
- }
12
-
13
- return {
14
- target,
15
- conditionIsMet: entityMatches(
16
- bgioArguments,
17
- rule.matcher,
18
- target,
19
- context
20
- )
21
- }
22
- }
23
- }
@@ -1,9 +0,0 @@
1
- import Condition from "./condition.js";
2
-
3
- export default class IsFull extends Condition {
4
- checkCondition(bgioArguments, rule, payload, context) {
5
- return {
6
- conditionIsMet: payload.target.spaces.every(space => space?.entities.length)
7
- };
8
- }
9
- }
@@ -1,12 +0,0 @@
1
- import Condition from "./condition.js";
2
-
3
- export default class Position extends Condition {
4
- checkCondition(bgioArguments, rule, { target }) {
5
- const parent = bgioArguments.G.bank.findParent(target)
6
- let conditionIsMet
7
- if (rule.position === 'First') {
8
- conditionIsMet = parent.entities.indexOf(target) === 0
9
- }
10
- return { conditionIsMet }
11
- }
12
- }