board-game-engine 1.0.5 → 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/examples/checkers.json +2 -2
- package/examples/connect-four.json +1 -1
- package/examples/eights.json +15 -15
- 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
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import _matches from "lodash/matches.js";
|
|
2
2
|
import Condition from "../condition/condition.js";
|
|
3
3
|
import resolveExpression from "../../utils/resolve-expression.js";
|
|
4
|
+
import type { BgioResolveState } from "../../utils/bgio-resolve-types.js";
|
|
4
5
|
|
|
5
6
|
export default class Evaluate extends Condition {
|
|
6
|
-
checkCondition(bgioArguments, rule, payload, context) {
|
|
7
|
+
checkCondition (bgioArguments: unknown, rule: unknown, payload: Record<string, unknown>, context: Record<string, unknown>) {
|
|
7
8
|
const newContext = { ...context }
|
|
8
9
|
if (payload?.target) {
|
|
9
10
|
newContext.target = payload.target
|
|
10
11
|
}
|
|
11
12
|
const result = resolveExpression(
|
|
12
|
-
bgioArguments,
|
|
13
|
-
rule,
|
|
13
|
+
bgioArguments as BgioResolveState,
|
|
14
|
+
rule as { expression: string; arguments?: unknown },
|
|
14
15
|
newContext
|
|
15
16
|
)
|
|
16
17
|
return { result, conditionIsMet: !!result }
|
|
@@ -0,0 +1,27 @@
|
|
|
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
|
+
|
|
5
|
+
export default class EveryCondition extends Condition {
|
|
6
|
+
checkCondition (bgioArguments: unknown, rule: unknown, conditionPayload: Record<string, unknown>, context: Record<string, unknown>) {
|
|
7
|
+
const targets = conditionPayload.target as unknown[];
|
|
8
|
+
const results = targets.map((target: unknown) => {
|
|
9
|
+
const loopContext = {
|
|
10
|
+
...context,
|
|
11
|
+
loopTarget: target
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return checkConditions(
|
|
15
|
+
bgioArguments,
|
|
16
|
+
(rule as { conditions?: ConditionRule[] }).conditions,
|
|
17
|
+
undefined,
|
|
18
|
+
loopContext
|
|
19
|
+
)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
conditionIsMet: results.every((r: { conditionsAreMet: boolean }) => r.conditionsAreMet),
|
|
24
|
+
results
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
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
|
+
}
|
package/src/game-factory/condition/{no-possible-moves-condition.js → no-possible-moves-condition.ts}
RENAMED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import Condition from "./condition.js";
|
|
2
2
|
import areThereValidMoves from "../../utils/any-valid-moves.js";
|
|
3
3
|
import getCurrentMoves from "../../utils/get-current-moves.js";
|
|
4
|
+
import type { GetCurrentMovesClient, GetCurrentMovesState } from "../../utils/get-current-moves.js";
|
|
4
5
|
|
|
5
6
|
export default class NoPossibleMoves extends Condition {
|
|
6
|
-
checkCondition(bgioArguments,
|
|
7
|
+
checkCondition (bgioArguments: unknown, _unused: unknown, _payload: unknown, context: Record<string, unknown>) {
|
|
7
8
|
return {
|
|
8
9
|
conditionIsMet: !areThereValidMoves(
|
|
9
10
|
bgioArguments,
|
|
10
|
-
getCurrentMoves(bgioArguments, context),
|
|
11
|
+
getCurrentMoves(bgioArguments as GetCurrentMovesState, context as unknown as GetCurrentMovesClient),
|
|
11
12
|
)
|
|
12
13
|
}
|
|
13
14
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import type { Condition as ConditionRule } from "../../types/bagel-types.js";
|
|
1
2
|
import Condition from "./condition.js";
|
|
2
3
|
import checkConditions from "../../utils/check-conditions.js";
|
|
3
4
|
|
|
4
5
|
export default class NotCondition extends Condition {
|
|
5
|
-
checkCondition(bgioArguments, rule, payload, context) {
|
|
6
|
+
checkCondition (bgioArguments: unknown, rule: unknown, payload: Record<string, unknown>, context: Record<string, unknown>) {
|
|
6
7
|
const result = checkConditions(
|
|
7
8
|
bgioArguments,
|
|
8
|
-
rule,
|
|
9
|
+
(rule as { conditions?: ConditionRule[] }).conditions,
|
|
9
10
|
payload,
|
|
10
11
|
context
|
|
11
12
|
)
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import type { Condition as ConditionRule } from "../../types/bagel-types.js";
|
|
1
2
|
import Condition from "./condition.js";
|
|
2
3
|
import findMetCondition from "../../utils/find-met-condition.js";
|
|
3
4
|
|
|
4
5
|
export default class Or extends Condition {
|
|
5
|
-
checkCondition(bgioArguments, rule, payload, context) {
|
|
6
|
+
checkCondition (bgioArguments: unknown, rule: unknown, payload: Record<string, unknown>, context: Record<string, unknown>) {
|
|
6
7
|
const result = findMetCondition(
|
|
7
8
|
bgioArguments,
|
|
8
|
-
rule,
|
|
9
|
+
(rule as { conditions?: ConditionRule[] }).conditions,
|
|
9
10
|
payload,
|
|
10
11
|
context
|
|
11
12
|
)
|
|
@@ -0,0 +1,13 @@
|
|
|
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,16 +1,18 @@
|
|
|
1
|
+
import type { Condition as ConditionRule } from "../../types/bagel-types.js";
|
|
1
2
|
import Condition from "./condition.js";
|
|
2
3
|
import checkConditions from "../../utils/check-conditions.js";
|
|
3
4
|
|
|
4
5
|
export default class SomeCondition extends Condition {
|
|
5
|
-
checkCondition(bgioArguments, rule,
|
|
6
|
-
const
|
|
6
|
+
checkCondition (bgioArguments: unknown, rule: unknown, conditionPayload: Record<string, unknown>, context: Record<string, unknown>) {
|
|
7
|
+
const targets = conditionPayload.target as unknown[];
|
|
8
|
+
const result = targets.find((target: unknown) => {
|
|
7
9
|
const loopContext = {
|
|
8
10
|
...context,
|
|
9
11
|
loopTarget: target
|
|
10
12
|
}
|
|
11
13
|
return checkConditions(
|
|
12
14
|
bgioArguments,
|
|
13
|
-
rule,
|
|
15
|
+
(rule as { conditions?: ConditionRule[] }).conditions,
|
|
14
16
|
undefined,
|
|
15
17
|
loopContext
|
|
16
18
|
).conditionsAreMet
|
|
@@ -0,0 +1,104 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,263 @@
|
|
|
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
|
+
}
|