board-game-engine 2.0.0 → 2.0.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.
- package/.github/workflows/ci.yml +33 -0
- package/dist/board-game-engine.cjs +463 -349
- package/dist/board-game-engine.js +463 -349
- package/dist/board-game-engine.min.js +22 -22
- package/dist/board-game-engine.mjs +461 -348
- package/dist/client/client.d.ts +76 -0
- package/dist/client/client.d.ts.map +1 -0
- package/dist/game-factory/bank/bank-slot.d.ts +30 -0
- package/dist/game-factory/bank/bank-slot.d.ts.map +1 -0
- package/dist/game-factory/bank/bank.d.ts +34 -0
- package/dist/game-factory/bank/bank.d.ts.map +1 -0
- package/dist/game-factory/board.d.ts +4 -0
- package/dist/game-factory/board.d.ts.map +1 -0
- package/dist/game-factory/condition/condition-factory.d.ts +4 -0
- package/dist/game-factory/condition/condition-factory.d.ts.map +1 -0
- package/dist/game-factory/condition/condition.d.ts +13 -0
- package/dist/game-factory/condition/condition.d.ts.map +1 -0
- package/dist/game-factory/condition/contains-condition.d.ts +8 -0
- package/dist/game-factory/condition/contains-condition.d.ts.map +1 -0
- package/dist/game-factory/condition/contains-same-condition.d.ts +7 -0
- package/dist/game-factory/condition/contains-same-condition.d.ts.map +1 -0
- package/dist/game-factory/condition/evaluate-condition.d.ts +8 -0
- package/dist/game-factory/condition/evaluate-condition.d.ts.map +1 -0
- package/dist/game-factory/condition/every-condition.d.ts +12 -0
- package/dist/game-factory/condition/every-condition.d.ts.map +1 -0
- package/dist/game-factory/condition/has-line-condition.d.ts +8 -0
- package/dist/game-factory/condition/has-line-condition.d.ts.map +1 -0
- package/dist/game-factory/condition/in-line-condition.d.ts +8 -0
- package/dist/game-factory/condition/in-line-condition.d.ts.map +1 -0
- package/dist/game-factory/condition/is-condition.d.ts +8 -0
- package/dist/game-factory/condition/is-condition.d.ts.map +1 -0
- package/dist/game-factory/condition/is-full-condition.d.ts +7 -0
- package/dist/game-factory/condition/is-full-condition.d.ts.map +1 -0
- package/dist/game-factory/condition/no-possible-moves-condition.d.ts +7 -0
- package/dist/game-factory/condition/no-possible-moves-condition.d.ts.map +1 -0
- package/dist/game-factory/condition/not-condition.d.ts +7 -0
- package/dist/game-factory/condition/not-condition.d.ts.map +1 -0
- package/dist/game-factory/condition/or-condition.d.ts +7 -0
- package/dist/game-factory/condition/or-condition.d.ts.map +1 -0
- package/dist/game-factory/condition/position-condition.d.ts +7 -0
- package/dist/game-factory/condition/position-condition.d.ts.map +1 -0
- package/dist/game-factory/condition/some-condition.d.ts +8 -0
- package/dist/game-factory/condition/some-condition.d.ts.map +1 -0
- package/dist/game-factory/condition/would-condition.d.ts +8 -0
- package/dist/game-factory/condition/would-condition.d.ts.map +1 -0
- package/dist/game-factory/entity.d.ts +13 -0
- package/dist/game-factory/entity.d.ts.map +1 -0
- package/dist/game-factory/expand-game-rules.d.ts +3 -0
- package/dist/game-factory/expand-game-rules.d.ts.map +1 -0
- package/dist/game-factory/game-factory.d.ts +10 -0
- package/dist/game-factory/game-factory.d.ts.map +1 -0
- package/{src/game-factory/move/end-turn.js → dist/game-factory/move/end-turn.d.ts} +2 -4
- package/dist/game-factory/move/end-turn.d.ts.map +1 -0
- package/dist/game-factory/move/for-each.d.ts +5 -0
- package/dist/game-factory/move/for-each.d.ts.map +1 -0
- package/dist/game-factory/move/index.d.ts +6 -0
- package/dist/game-factory/move/index.d.ts.map +1 -0
- package/dist/game-factory/move/move-entity.d.ts +7 -0
- package/dist/game-factory/move/move-entity.d.ts.map +1 -0
- package/dist/game-factory/move/move-factory.d.ts +18 -0
- package/dist/game-factory/move/move-factory.d.ts.map +1 -0
- package/dist/game-factory/move/move.d.ts +54 -0
- package/dist/game-factory/move/move.d.ts.map +1 -0
- package/dist/game-factory/move/pass-turn.d.ts +5 -0
- package/dist/game-factory/move/pass-turn.d.ts.map +1 -0
- package/{src/game-factory/move/pass.js → dist/game-factory/move/pass.d.ts} +2 -4
- package/dist/game-factory/move/pass.d.ts.map +1 -0
- package/dist/game-factory/move/place-new.d.ts +5 -0
- package/dist/game-factory/move/place-new.d.ts.map +1 -0
- package/dist/game-factory/move/remove-entity.d.ts +5 -0
- package/dist/game-factory/move/remove-entity.d.ts.map +1 -0
- package/dist/game-factory/move/set-active-players.d.ts +5 -0
- package/dist/game-factory/move/set-active-players.d.ts.map +1 -0
- package/dist/game-factory/move/set-state.d.ts +5 -0
- package/dist/game-factory/move/set-state.d.ts.map +1 -0
- package/dist/game-factory/move/shuffle.d.ts +5 -0
- package/dist/game-factory/move/shuffle.d.ts.map +1 -0
- package/dist/game-factory/move/take-from.d.ts +11 -0
- package/dist/game-factory/move/take-from.d.ts.map +1 -0
- package/dist/game-factory/space/space.d.ts +10 -0
- package/dist/game-factory/space/space.d.ts.map +1 -0
- package/dist/game-factory/space-group/grid.d.ts +15 -0
- package/dist/game-factory/space-group/grid.d.ts.map +1 -0
- package/dist/game-factory/space-group/space-group.d.ts +20 -0
- package/dist/game-factory/space-group/space-group.d.ts.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/registry.d.ts +17 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/types/bagel-types.d.ts +339 -0
- package/dist/types/bagel-types.d.ts.map +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/rule-with-conditions.d.ts +9 -0
- package/dist/types/rule-with-conditions.d.ts.map +1 -0
- package/dist/utils/any-valid-moves.d.ts +2 -0
- package/dist/utils/any-valid-moves.d.ts.map +1 -0
- package/dist/utils/bgio-resolve-types.d.ts +25 -0
- package/dist/utils/bgio-resolve-types.d.ts.map +1 -0
- package/dist/utils/check-conditions.d.ts +7 -0
- package/dist/utils/check-conditions.d.ts.map +1 -0
- package/dist/utils/create-payload.d.ts +5 -0
- package/dist/utils/create-payload.d.ts.map +1 -0
- package/dist/utils/deserialize-bgio-arguments.d.ts +3 -0
- package/dist/utils/deserialize-bgio-arguments.d.ts.map +1 -0
- package/dist/utils/do-moves.d.ts +8 -0
- package/dist/utils/do-moves.d.ts.map +1 -0
- package/dist/utils/entity-matches.d.ts +6 -0
- package/dist/utils/entity-matches.d.ts.map +1 -0
- package/dist/utils/find-met-condition.d.ts +6 -0
- package/dist/utils/find-met-condition.d.ts.map +1 -0
- package/dist/utils/get-current-moves.d.ts +24 -0
- package/dist/utils/get-current-moves.d.ts.map +1 -0
- package/dist/utils/get-scenario-results.d.ts +3 -0
- package/dist/utils/get-scenario-results.d.ts.map +1 -0
- package/dist/utils/get-steps.d.ts +13 -0
- package/dist/utils/get-steps.d.ts.map +1 -0
- package/dist/utils/get.d.ts +7 -0
- package/dist/utils/get.d.ts.map +1 -0
- package/dist/utils/grid-contains-sequence.d.ts +27 -0
- package/dist/utils/grid-contains-sequence.d.ts.map +1 -0
- package/dist/utils/json-transformer.d.ts +8 -0
- package/dist/utils/json-transformer.d.ts.map +1 -0
- package/dist/utils/prepare-payload.d.ts +2 -0
- package/dist/utils/prepare-payload.d.ts.map +1 -0
- package/dist/utils/resolve-entity.d.ts +3 -0
- package/dist/utils/resolve-entity.d.ts.map +1 -0
- package/dist/utils/resolve-expression.d.ts +6 -0
- package/dist/utils/resolve-expression.d.ts.map +1 -0
- package/dist/utils/resolve-properties.d.ts +4 -0
- package/dist/utils/resolve-properties.d.ts.map +1 -0
- package/dist/utils/simulate-move.d.ts +16 -0
- package/dist/utils/simulate-move.d.ts.map +1 -0
- package/package.json +9 -3
- package/playwright-report/index.html +1 -1
- package/scripts/build.mjs +2 -2
- package/src/client/client.ts +306 -0
- package/src/game-factory/bank/bank-slot.ts +81 -0
- package/src/game-factory/bank/bank.ts +125 -0
- package/src/game-factory/{board.js → board.ts} +1 -1
- package/src/game-factory/condition/condition-factory.ts +59 -0
- package/src/game-factory/condition/condition.ts +50 -0
- package/src/game-factory/condition/{contains-condition.js → contains-condition.ts} +5 -4
- package/src/game-factory/condition/{contains-same-condition.js → contains-same-condition.ts} +8 -5
- package/src/game-factory/condition/{evaluate-condition.js → evaluate-condition.ts} +4 -3
- package/src/game-factory/condition/every-condition.ts +27 -0
- package/src/game-factory/condition/has-line-condition.ts +15 -0
- package/src/game-factory/condition/in-line-condition.ts +25 -0
- package/src/game-factory/condition/is-condition.ts +24 -0
- package/src/game-factory/condition/is-full-condition.ts +10 -0
- package/src/game-factory/condition/{no-possible-moves-condition.js → no-possible-moves-condition.ts} +3 -2
- package/src/game-factory/condition/{not-condition.js → not-condition.ts} +3 -2
- package/src/game-factory/condition/{or-condition.js → or-condition.ts} +3 -2
- package/src/game-factory/condition/position-condition.ts +13 -0
- package/src/game-factory/condition/{some-condition.js → some-condition.ts} +5 -3
- package/src/game-factory/condition/would-condition.ts +104 -0
- package/src/game-factory/entity.ts +37 -0
- package/src/game-factory/expand-game-rules.ts +263 -0
- package/src/game-factory/game-factory.ts +263 -0
- package/src/game-factory/move/end-turn.ts +7 -0
- package/src/game-factory/move/for-each.ts +20 -0
- package/src/game-factory/move/move-entity.ts +18 -0
- package/src/game-factory/move/move-factory.ts +107 -0
- package/src/game-factory/move/move.ts +147 -0
- package/src/game-factory/move/pass-turn.ts +15 -0
- package/src/game-factory/move/pass.ts +7 -0
- package/src/game-factory/move/place-new.ts +42 -0
- package/src/game-factory/move/remove-entity.ts +11 -0
- package/src/game-factory/move/set-active-players.ts +26 -0
- package/src/game-factory/move/set-state.ts +14 -0
- package/src/game-factory/move/shuffle.ts +9 -0
- package/src/game-factory/move/take-from.ts +12 -0
- package/src/game-factory/space/space.ts +36 -0
- package/src/game-factory/space-group/grid.ts +48 -0
- package/src/game-factory/space-group/space-group.ts +44 -0
- package/src/index.ts +5 -0
- package/src/types/bagel-types.ts +449 -0
- package/src/types/boardgame-io-core.d.ts +7 -0
- package/src/types/index.ts +70 -0
- package/src/types/rule-with-conditions.ts +9 -0
- package/src/utils/{any-valid-moves.js → any-valid-moves.ts} +54 -49
- package/src/utils/bgio-resolve-types.ts +27 -0
- package/src/utils/check-conditions.ts +28 -0
- package/src/utils/create-payload.ts +19 -0
- package/src/utils/deserialize-bgio-arguments.ts +10 -0
- package/src/utils/do-moves.ts +22 -0
- package/src/utils/entity-matches.ts +30 -0
- package/src/utils/expr-eval.d.ts +6 -0
- package/src/utils/find-met-condition.ts +23 -0
- package/src/utils/get-current-moves.ts +39 -0
- package/src/utils/get-scenario-results.ts +30 -0
- package/src/utils/get-steps.ts +38 -0
- package/src/utils/get.ts +28 -0
- package/src/utils/{grid-contains-sequence.js → grid-contains-sequence.ts} +71 -33
- package/src/utils/json-transformer.ts +17 -0
- package/src/utils/prepare-payload.ts +20 -0
- package/src/utils/resolve-entity.ts +15 -0
- package/src/utils/resolve-expression.ts +16 -0
- package/src/utils/resolve-properties.ts +172 -0
- package/src/utils/simulate-move.ts +32 -0
- package/src/wackson.d.ts +4 -0
- package/tsconfig.build.json +14 -0
- package/tsconfig.json +21 -0
- package/src/client/client.js +0 -224
- package/src/game-factory/bank/bank-slot.js +0 -69
- package/src/game-factory/bank/bank.js +0 -114
- package/src/game-factory/condition/condition-factory.js +0 -52
- package/src/game-factory/condition/condition.js +0 -39
- package/src/game-factory/condition/every-condition.js +0 -25
- package/src/game-factory/condition/has-line-condition.js +0 -14
- package/src/game-factory/condition/in-line-condition.js +0 -19
- package/src/game-factory/condition/is-condition.js +0 -23
- package/src/game-factory/condition/is-full-condition.js +0 -9
- package/src/game-factory/condition/position-condition.js +0 -12
- package/src/game-factory/condition/would-condition.js +0 -94
- package/src/game-factory/entity.js +0 -29
- package/src/game-factory/expand-game-rules.js +0 -271
- package/src/game-factory/game-factory.js +0 -239
- package/src/game-factory/move/for-each.js +0 -18
- package/src/game-factory/move/move-entity.js +0 -16
- package/src/game-factory/move/move-factory.js +0 -89
- package/src/game-factory/move/move.js +0 -131
- package/src/game-factory/move/pass-turn.js +0 -10
- package/src/game-factory/move/place-new.js +0 -33
- package/src/game-factory/move/remove-entity.js +0 -7
- package/src/game-factory/move/set-active-players.js +0 -23
- package/src/game-factory/move/set-state.js +0 -11
- package/src/game-factory/move/shuffle.js +0 -7
- package/src/game-factory/move/take-from.js +0 -7
- package/src/game-factory/space/space.js +0 -30
- package/src/game-factory/space-group/grid.js +0 -43
- package/src/game-factory/space-group/space-group.js +0 -29
- package/src/index.js +0 -2
- package/src/utils/check-conditions.js +0 -28
- package/src/utils/create-payload.js +0 -16
- package/src/utils/deserialize-bgio-arguments.js +0 -8
- package/src/utils/do-moves.js +0 -18
- package/src/utils/entity-matches.js +0 -20
- package/src/utils/find-met-condition.js +0 -22
- package/src/utils/get-current-moves.js +0 -12
- package/src/utils/get-scenario-results.js +0 -23
- package/src/utils/get-steps.js +0 -29
- package/src/utils/get.js +0 -25
- package/src/utils/json-transformer.js +0 -12
- package/src/utils/prepare-payload.js +0 -16
- package/src/utils/resolve-entity.js +0 -9
- package/src/utils/resolve-expression.js +0 -10
- package/src/utils/resolve-properties.js +0 -149
- package/src/utils/simulate-move.js +0 -25
- /package/src/game-factory/move/{index.js → index.ts} +0 -0
- /package/src/{registry.js → registry.ts} +0 -0
package/src/client/client.js
DELETED
|
@@ -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,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
|
-
}
|