tsgammon-core
Version:
A Backgammon library for Typescript, formerly developed as a part of tsgammon-ui
187 lines (186 loc) • 9.68 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildBGEventHandler = void 0;
const BGEventHandler_1 = require("./BGEventHandler");
const CubeGameDispatcher_1 = require("./CubeGameDispatcher");
const EOGEventHandlers_1 = require("./EOGEventHandlers");
const RollDispatcher_1 = require("./RollDispatcher");
const SingleGameDispatcher_1 = require("./SingleGameDispatcher");
/**
* BGEventHandler(BGEventHandlerExtensible)オブジェクトを生成する
* @param skipCubeAction キューブアクション要否の判定関数(不要の場合、trueを返す)
* @param rListener ダイスのロール目を供給するRollListenerオブジェクト
* @param listeners BGEventHandlerに追加するBGListenerの配列
* @returns
*/
function buildBGEventHandler(skipCubeAction, rListener = (0, RollDispatcher_1.rollListener)(), ...listeners) {
return buildBGEventHandler_rec(skipCubeAction, rListener, {}, ...listeners);
}
exports.buildBGEventHandler = buildBGEventHandler;
function buildBGEventHandler_rec(skipCubeAction, rListener = (0, RollDispatcher_1.rollListener)(), _bgListeners, ...listeners) {
const bgListeners = listeners.reduce((prev, cur) => (0, BGEventHandler_1.concatBGListeners)(prev, cur), _bgListeners);
const handlers = _buildBGEventHandler(skipCubeAction, rListener, bgListeners);
function addListeners(...toAdd) {
return buildBGEventHandler_rec(skipCubeAction, rListener, bgListeners, ...toAdd);
}
return Object.assign(Object.assign({}, handlers), { addListener: addListeners });
}
// singleGameDispatcherとcubeGameDispatcherを組み合わせて、BGEventHandlerを実装している
function _buildBGEventHandler(skipCubeAction, rollListener, bgListeners) {
// チェッカープレイでの終局処理の定義
const { onEndOfBGGame: onEndOfCubeGame } = (0, EOGEventHandlers_1.eogEventHandler)(bgListeners);
const sgDispatcher = (0, RollDispatcher_1.withRL)(SingleGameDispatcher_1.singleGameDispatcher, rollListener);
const bgHandler = {
onRollOpening: (bgState) => {
const sgResult = sgDispatcher.doOpeningRoll(bgState.sgState);
sgResult({
// オープニングロールがあった:キューブ側もチェッカープレイに遷移
onOpeningCheckerPlayStarted: (nextSGState) => {
const cbResult = CubeGameDispatcher_1.cubeGameDispatcher.doStartOpeningCheckerPlay(bgState.cbState, nextSGState.isRed);
cbResult({
onAwaitCheckerPlay: (nextCBState) => {
var _a;
(_a = bgListeners.onAwaitCheckerPlay) === null || _a === void 0 ? void 0 : _a.call(bgListeners, {
cbState: nextCBState,
sgState: nextSGState,
});
},
});
},
// オープニングロールのリロール:Cube側には影響がないので、イベント通知のみ
onRerollOpening: (nextSGState) => {
var _a;
(_a = bgListeners.onBGOpeningRerolled) === null || _a === void 0 ? void 0 : _a.call(bgListeners, {
cbState: bgState.cbState,
sgState: nextSGState,
});
},
});
},
onCommit: (bgState) => {
const sgResult = sgDispatcher.doCommitCheckerPlay(bgState.sgState);
sgResult({
// チェッカープレイが終了した:単にイベントを通知するだけにし、
// キューブの状態管理は他のListener(onAwaitRoll, onEndOfCubeGame)に任せる
onCheckerPlayCommitted: (committedState) => {
var _a;
(_a = bgListeners.onCommitted) === null || _a === void 0 ? void 0 : _a.call(bgListeners, {
cbState: bgState.cbState,
sgState: committedState,
});
},
// チェッカープレイが終了し、まだ終局でない:
// キューブアクション状態またはロール待ち状態のいずれかへ遷移し、
// 各Listenerに通知する
onAwaitRoll: (nextSGState) => {
const cbResult = CubeGameDispatcher_1.cubeGameDispatcher.doStartCubeAction(bgState.cbState, skipCubeAction);
cbResult({
onAwaitCubeAction: (nextCBState) => {
var _a;
(_a = bgListeners.onAwaitCubeAction) === null || _a === void 0 ? void 0 : _a.call(bgListeners, {
cbState: nextCBState,
sgState: nextSGState,
});
},
onCubeActionStarted: (nextCBState) => {
var _a;
(_a = bgListeners.onCubeActionStarted) === null || _a === void 0 ? void 0 : _a.call(bgListeners, {
cbState: nextCBState,
sgState: nextSGState,
});
},
onCubeActionSkipped: (nextCBState) => {
var _a;
(_a = bgListeners.onCubeActionSkipped) === null || _a === void 0 ? void 0 : _a.call(bgListeners, {
cbState: nextCBState,
sgState: nextSGState,
});
},
});
},
// ゲームが終了した:EoGを通知する
onEndOfGame: (nextSGState) => {
onEndOfCubeGame({ cbState: bgState.cbState, sgState: nextSGState }, nextSGState.result, nextSGState.eogStatus);
},
});
},
onRoll: (bgState) => {
const sgResult = sgDispatcher.doRoll(bgState.sgState);
sgResult({
// チェッカープレイ状態に遷移した:キューブ側でも状態遷移する
onCheckerPlayStarted: (nextSGState) => {
const cbResult = CubeGameDispatcher_1.cubeGameDispatcher.doStartCheckerPlay(bgState.cbState);
cbResult({
onAwaitCheckerPlay: (nextCBState) => {
var _a;
(_a = bgListeners.onAwaitCheckerPlay) === null || _a === void 0 ? void 0 : _a.call(bgListeners, {
cbState: nextCBState,
sgState: nextSGState,
});
},
});
},
});
},
// ゲームを開始した:キューブ側でもゲーム開始
onStartGame: () => {
const sgResult = sgDispatcher.doStartGame();
sgResult({
onGameStarted: () => {
const cbResult = CubeGameDispatcher_1.cubeGameDispatcher.doStartCubeGame();
cbResult({
onCubeGameStarted: () => {
var _a;
(_a = bgListeners.onBGGameStarted) === null || _a === void 0 ? void 0 : _a.call(bgListeners);
},
});
},
});
},
// ダブルされた:キューブ側でもダブル
onDouble: (bgState) => {
const result = CubeGameDispatcher_1.cubeGameDispatcher.doDouble(bgState.cbState);
result({
onDoubled: (nextState) => {
var _a;
(_a = bgListeners.onDoubled) === null || _a === void 0 ? void 0 : _a.call(bgListeners, {
cbState: nextState,
sgState: bgState.sgState,
}, bgState.cbState);
},
});
},
// テイクされた:キューブ側でもテイク、さらに必要なら自動ロール
onTake: (bgState) => {
const result = CubeGameDispatcher_1.cubeGameDispatcher.doTake(bgState.cbState);
result({
onDoubleAccepted: (nextState) => {
var _a;
(_a = bgListeners.onDoubleAccepted) === null || _a === void 0 ? void 0 : _a.call(bgListeners, {
cbState: nextState,
sgState: bgState.sgState,
}, bgState.cbState);
// Take後は自動ロール
bgHandler.onRoll({
cbState: nextState,
sgState: bgState.sgState,
});
},
});
},
// パスされた:キューブ側でもパス(終局状態となる)
onPass: (bgState) => {
const result = CubeGameDispatcher_1.cubeGameDispatcher.doPass(bgState.cbState);
result({
onEndOfCubeGame: (cbEoG) => {
var _a;
(_a = bgListeners.onEndOfBGGame) === null || _a === void 0 ? void 0 : _a.call(bgListeners, {
cbState: cbEoG,
sgState: bgState.sgState,
});
},
});
},
};
return bgHandler;
}