UNPKG

tsgammon-core

Version:

A Backgammon library for Typescript, formerly developed as a part of tsgammon-ui

187 lines (186 loc) 9.68 kB
"use strict"; 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; }