board-game-engine 0.0.5 → 0.0.7
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/dist/board-game-engine.js +51 -92
- package/dist/board-game-engine.min.js +1 -1
- package/package.json +1 -1
- package/src/client/client.js +79 -154
- package/src/game-factory/condition/or-condition.js +0 -1
- package/src/game-factory/move/set-state.js +0 -2
- package/src/utils/get-steps.js +1 -0
- package/src/utils/resolve-properties.js +9 -17
|
@@ -16367,20 +16367,17 @@ class Client {
|
|
|
16367
16367
|
eliminatedMoves: []
|
|
16368
16368
|
};
|
|
16369
16369
|
this.optimisticWinner = null;
|
|
16370
|
-
this.
|
|
16371
|
-
this.game = (0, _gameFactory.default)(JSON.parse(options.gameRules), options.gameName);
|
|
16370
|
+
this.game = options.game || (0, _gameFactory.default)(JSON.parse(options.gameRules), options.gameName);
|
|
16372
16371
|
}
|
|
16373
16372
|
connect() {
|
|
16374
16373
|
const {
|
|
16375
16374
|
server,
|
|
16376
16375
|
numPlayers,
|
|
16377
|
-
onClientUpdate,
|
|
16378
16376
|
debug = {
|
|
16379
16377
|
collapseOnLoad: true,
|
|
16380
16378
|
impl: _debug.Debug
|
|
16381
16379
|
},
|
|
16382
16380
|
gameId,
|
|
16383
|
-
gameRules,
|
|
16384
16381
|
boardgamePlayerID,
|
|
16385
16382
|
clientToken,
|
|
16386
16383
|
singlePlayer = !clientToken
|
|
@@ -16392,7 +16389,7 @@ class Client {
|
|
|
16392
16389
|
debug
|
|
16393
16390
|
} : {
|
|
16394
16391
|
game: this.game,
|
|
16395
|
-
multiplayer:
|
|
16392
|
+
multiplayer: (0, _multiplayer.SocketIO)({
|
|
16396
16393
|
server,
|
|
16397
16394
|
socketOpts: {
|
|
16398
16395
|
transports: ['websocket', 'polling']
|
|
@@ -16404,15 +16401,16 @@ class Client {
|
|
|
16404
16401
|
debug
|
|
16405
16402
|
};
|
|
16406
16403
|
this.client = (0, _client.Client)(clientOptions);
|
|
16407
|
-
|
|
16408
|
-
this.client.subscribe(onClientUpdate);
|
|
16409
|
-
}
|
|
16404
|
+
this.client.subscribe(() => this.update());
|
|
16410
16405
|
this.client.start();
|
|
16411
16406
|
return this;
|
|
16412
16407
|
} catch (error) {
|
|
16413
16408
|
console.error('Failed to join game:', error);
|
|
16414
16409
|
}
|
|
16415
16410
|
}
|
|
16411
|
+
update() {
|
|
16412
|
+
this.options.onClientUpdate?.();
|
|
16413
|
+
}
|
|
16416
16414
|
getState() {
|
|
16417
16415
|
let state;
|
|
16418
16416
|
let moves;
|
|
@@ -16425,8 +16423,6 @@ class Client {
|
|
|
16425
16423
|
originalG: clientState.G
|
|
16426
16424
|
};
|
|
16427
16425
|
gameover = state?.ctx?.gameover;
|
|
16428
|
-
|
|
16429
|
-
// Fix: use arrow function so `this` refers to the Client instance
|
|
16430
16426
|
moves = !gameover ? Object.entries((0, _getCurrentMoves.default)(state, this.client)).reduce((acc, _ref) => {
|
|
16431
16427
|
let [moveName, rawMove] = _ref;
|
|
16432
16428
|
const move = payload => {
|
|
@@ -16439,27 +16435,28 @@ class Client {
|
|
|
16439
16435
|
};
|
|
16440
16436
|
}, {}) : [];
|
|
16441
16437
|
}
|
|
16438
|
+
const {
|
|
16439
|
+
allClickable,
|
|
16440
|
+
possibleMoveMeta
|
|
16441
|
+
} = getPossibleMoves(state, moves, this.moveBuilder);
|
|
16442
16442
|
return {
|
|
16443
16443
|
state,
|
|
16444
16444
|
gameover,
|
|
16445
|
-
moves
|
|
16445
|
+
moves,
|
|
16446
|
+
allClickable,
|
|
16447
|
+
possibleMoveMeta
|
|
16446
16448
|
};
|
|
16447
16449
|
}
|
|
16448
|
-
doStep(
|
|
16450
|
+
doStep(_target) {
|
|
16449
16451
|
const {
|
|
16450
16452
|
state,
|
|
16451
|
-
moves
|
|
16453
|
+
moves,
|
|
16454
|
+
possibleMoveMeta
|
|
16452
16455
|
} = this.getState();
|
|
16453
|
-
const
|
|
16454
|
-
possibleMoveMeta,
|
|
16455
|
-
allClickable
|
|
16456
|
-
} = getPossibleMoves(state, moves, this.moveBuilder, isSpectator);
|
|
16457
|
-
this.allClickable = allClickable;
|
|
16458
|
-
|
|
16459
|
-
// Filter out moves that don't accept this target
|
|
16456
|
+
const target = _target.abstract ? _target : state.G.bank.locate(_target.entityId);
|
|
16460
16457
|
const newEliminated = Object.entries(possibleMoveMeta).filter(_ref2 => {
|
|
16461
16458
|
let [_, meta] = _ref2;
|
|
16462
|
-
return !meta.
|
|
16459
|
+
return !hasTarget(meta.clickableForMove, target);
|
|
16463
16460
|
}).map(_ref3 => {
|
|
16464
16461
|
let [name] = _ref3;
|
|
16465
16462
|
return name;
|
|
@@ -16468,30 +16465,31 @@ class Client {
|
|
|
16468
16465
|
console.error('invalid move with target:', target?.rule);
|
|
16469
16466
|
return;
|
|
16470
16467
|
}
|
|
16471
|
-
|
|
16472
|
-
eliminatedMoves: newEliminated,
|
|
16473
|
-
stepIndex: this.moveBuilder.stepIndex + 1,
|
|
16474
|
-
targets: [...this.moveBuilder.targets, target]
|
|
16475
|
-
};
|
|
16476
|
-
|
|
16477
|
-
// Fix: filter possibleMoveMeta to only include moves not in newEliminated,
|
|
16478
|
-
// so findCompletedMove sees the post-elimination state rather than the stale pre-elimination state
|
|
16479
|
-
const filteredMoveMeta = Object.fromEntries(Object.entries(possibleMoveMeta).filter(_ref4 => {
|
|
16468
|
+
const remainingMoveEntries = Object.entries(possibleMoveMeta).filter(_ref4 => {
|
|
16480
16469
|
let [name] = _ref4;
|
|
16481
16470
|
return !newEliminated.includes(name);
|
|
16482
|
-
})
|
|
16483
|
-
|
|
16484
|
-
|
|
16485
|
-
|
|
16486
|
-
|
|
16487
|
-
|
|
16471
|
+
});
|
|
16472
|
+
if (isMoveCompleted(state, moves, remainingMoveEntries, this.moveBuilder.stepIndex)) {
|
|
16473
|
+
const [moveName] = remainingMoveEntries[0];
|
|
16474
|
+
const move = moves[moveName];
|
|
16475
|
+
const payload = (0, _createPayload.default)(state, move.moveInstance.rule, [...this.moveBuilder.targets, target], {
|
|
16476
|
+
moveInstance: move.moveInstance
|
|
16477
|
+
});
|
|
16478
|
+
this.optimisticWinner = getWinnerAfterMove(state, this.game, move.moveInstance, payload);
|
|
16479
|
+
move(payload);
|
|
16488
16480
|
this.moveBuilder = {
|
|
16489
16481
|
targets: [],
|
|
16490
16482
|
stepIndex: 0,
|
|
16491
16483
|
eliminatedMoves: []
|
|
16492
16484
|
};
|
|
16485
|
+
} else {
|
|
16486
|
+
this.moveBuilder = {
|
|
16487
|
+
eliminatedMoves: newEliminated,
|
|
16488
|
+
stepIndex: this.moveBuilder.stepIndex + 1,
|
|
16489
|
+
targets: [...this.moveBuilder.targets, target]
|
|
16490
|
+
};
|
|
16493
16491
|
}
|
|
16494
|
-
this.
|
|
16492
|
+
this.update();
|
|
16495
16493
|
}
|
|
16496
16494
|
reset() {
|
|
16497
16495
|
this.moveBuilder = {
|
|
@@ -16500,7 +16498,7 @@ class Client {
|
|
|
16500
16498
|
eliminatedMoves: []
|
|
16501
16499
|
};
|
|
16502
16500
|
this.optimisticWinner = null;
|
|
16503
|
-
this.
|
|
16501
|
+
this.update();
|
|
16504
16502
|
}
|
|
16505
16503
|
undoStep() {
|
|
16506
16504
|
if (this.moveBuilder.targets.length) {
|
|
@@ -16510,28 +16508,25 @@ class Client {
|
|
|
16510
16508
|
eliminatedMoves: []
|
|
16511
16509
|
};
|
|
16512
16510
|
}
|
|
16513
|
-
this.
|
|
16511
|
+
this.update();
|
|
16514
16512
|
}
|
|
16515
16513
|
}
|
|
16516
16514
|
exports.Client = Client;
|
|
16517
|
-
function
|
|
16518
|
-
if (
|
|
16519
|
-
|
|
16520
|
-
|
|
16521
|
-
|
|
16522
|
-
};
|
|
16523
|
-
}
|
|
16515
|
+
function hasTarget(clickableSet, target) {
|
|
16516
|
+
if (!target.abstract) return clickableSet.has(target);
|
|
16517
|
+
return [...clickableSet].some(item => item.abstract && item.value === target.value);
|
|
16518
|
+
}
|
|
16519
|
+
function getPossibleMoves(bgioState, moves, moveBuilder) {
|
|
16524
16520
|
const {
|
|
16525
16521
|
eliminatedMoves,
|
|
16526
16522
|
stepIndex
|
|
16527
16523
|
} = moveBuilder;
|
|
16528
16524
|
const possibleMoveMeta = {};
|
|
16529
16525
|
const allClickable = new Set();
|
|
16530
|
-
|
|
16526
|
+
Object.entries(moves).filter(_ref5 => {
|
|
16531
16527
|
let [moveName] = _ref5;
|
|
16532
16528
|
return !eliminatedMoves.includes(moveName);
|
|
16533
|
-
})
|
|
16534
|
-
availableMoves.forEach(_ref6 => {
|
|
16529
|
+
}).forEach(_ref6 => {
|
|
16535
16530
|
let [moveName, move] = _ref6;
|
|
16536
16531
|
const moveRule = (0, _resolveProperties.default)(bgioState, {
|
|
16537
16532
|
...move.moveInstance.rule,
|
|
@@ -16541,52 +16536,27 @@ function getPossibleMoves(bgioState, moves, moveBuilder, isSpectator) {
|
|
|
16541
16536
|
moveInstance: move.moveInstance,
|
|
16542
16537
|
moveArguments: moveRule.arguments
|
|
16543
16538
|
};
|
|
16544
|
-
const
|
|
16539
|
+
const targets = moveBuilder.targets.map(t => t.abstract ? t : bgioState.G.bank.locate(t.entityId));
|
|
16540
|
+
const payload = (0, _createPayload.default)(bgioState, moveRule, targets, context);
|
|
16545
16541
|
context.moveArguments = {
|
|
16546
16542
|
...context.moveArguments,
|
|
16547
16543
|
...payload.arguments
|
|
16548
16544
|
};
|
|
16549
16545
|
const moveIsAllowed = (0, _checkConditions.default)(bgioState, moveRule, {}, context).conditionsAreMet;
|
|
16550
16546
|
const moveSteps = (0, _getSteps.default)(bgioState, moveRule);
|
|
16551
|
-
const
|
|
16552
|
-
const currentStep = moveSteps?.[stepIndex];
|
|
16553
|
-
const finishedOnLastStep = moveSteps && !!lastStep && !currentStep;
|
|
16554
|
-
const clickableForMove = new Set(moveIsAllowed && currentStep?.getClickable(context) || []);
|
|
16547
|
+
const clickableForMove = new Set(moveIsAllowed && moveSteps?.[stepIndex]?.getClickable(context) || []);
|
|
16555
16548
|
possibleMoveMeta[moveName] = {
|
|
16556
|
-
finishedOnLastStep,
|
|
16557
16549
|
clickableForMove
|
|
16558
16550
|
};
|
|
16559
|
-
clickableForMove.forEach(entity =>
|
|
16560
|
-
allClickable.add(entity);
|
|
16561
|
-
});
|
|
16551
|
+
clickableForMove.forEach(entity => allClickable.add(entity));
|
|
16562
16552
|
});
|
|
16563
16553
|
return {
|
|
16564
16554
|
possibleMoveMeta,
|
|
16565
16555
|
allClickable
|
|
16566
16556
|
};
|
|
16567
16557
|
}
|
|
16568
|
-
|
|
16569
|
-
|
|
16570
|
-
function findCompletedMove(bgioState, possibleMoveMeta, moveBuilder, moves) {
|
|
16571
|
-
const possibleMoveNames = Object.keys(possibleMoveMeta);
|
|
16572
|
-
|
|
16573
|
-
// Only one possible move left
|
|
16574
|
-
if (possibleMoveNames.length !== 1) return null;
|
|
16575
|
-
const moveName = possibleMoveNames[0];
|
|
16576
|
-
const meta = possibleMoveMeta[moveName];
|
|
16577
|
-
|
|
16578
|
-
// And it's finished
|
|
16579
|
-
if (!meta.finishedOnLastStep) return null;
|
|
16580
|
-
const move = moves[moveName];
|
|
16581
|
-
const moveRule = move.moveInstance.rule;
|
|
16582
|
-
const payload = (0, _createPayload.default)(bgioState, moveRule, moveBuilder.targets, {
|
|
16583
|
-
moveInstance: move.moveInstance
|
|
16584
|
-
});
|
|
16585
|
-
return {
|
|
16586
|
-
moveName,
|
|
16587
|
-
move,
|
|
16588
|
-
payload
|
|
16589
|
-
};
|
|
16558
|
+
function isMoveCompleted(state, moves, remainingMoveEntries, stepIndex) {
|
|
16559
|
+
return remainingMoveEntries.length === 1 && (0, _getSteps.default)(state, moves[remainingMoveEntries[0][0]].moveInstance.rule).length === stepIndex + 1;
|
|
16590
16560
|
}
|
|
16591
16561
|
function getWinnerAfterMove(state, game, moveInstance, movePayload) {
|
|
16592
16562
|
const simulatedG = (0, _simulateMove.default)(state, (0, _preparePayload.default)(movePayload), {
|
|
@@ -17258,7 +17228,6 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
|
|
|
17258
17228
|
class Or extends _condition.default {
|
|
17259
17229
|
checkCondition(bgioArguments, rule, payload, context) {
|
|
17260
17230
|
const result = (0, _findMetCondition.default)(bgioArguments, rule, payload, context);
|
|
17261
|
-
console.log('result', result);
|
|
17262
17231
|
return {
|
|
17263
17232
|
conditionIsMet: !!result
|
|
17264
17233
|
};
|
|
@@ -18447,8 +18416,6 @@ class SetState extends _move.default {
|
|
|
18447
18416
|
state
|
|
18448
18417
|
}
|
|
18449
18418
|
} = _ref;
|
|
18450
|
-
console.log('entity', entity);
|
|
18451
|
-
console.log('state', state);
|
|
18452
18419
|
entity.state = {
|
|
18453
18420
|
...entity.state,
|
|
18454
18421
|
[state.property]: state.value
|
|
@@ -19540,15 +19507,7 @@ function resolveProperty(bgioArguments, value, context) {
|
|
|
19540
19507
|
return maxTargets;
|
|
19541
19508
|
} else if (value?.type === 'Pick') {
|
|
19542
19509
|
const target = resolveProperties(bgioArguments, value.target, context, 'target');
|
|
19543
|
-
|
|
19544
|
-
console.log('target', target);
|
|
19545
|
-
console.log('target.attributes', target.attributes);
|
|
19546
|
-
const x = (0, _pick.default)(resolveProperties(bgioArguments, target.attributes, context, 'attributes'), value.properties);
|
|
19547
|
-
console.log('x', x);
|
|
19548
|
-
return x;
|
|
19549
|
-
} else {
|
|
19550
|
-
console.log('8888target', target);
|
|
19551
|
-
}
|
|
19510
|
+
return (0, _pick.default)(resolveProperties(bgioArguments, target.attributes, context, 'attributes'), value.properties);
|
|
19552
19511
|
} else if (value?.type === 'Coordinates') {
|
|
19553
19512
|
const originalTarget = value.target ? resolveProperties(bgioArguments, value.target, context, 'target') : context.originalTarget;
|
|
19554
19513
|
const parent = bgioArguments.G.bank.findParent(originalTarget);
|