UNPKG

tsgammon-core

Version:

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

155 lines (154 loc) 5.53 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.setCPStateListener = exports.decorate = exports.fill = exports.applyCheckerPlay = exports.checkerPlayDispatcher = void 0; const BoardStateNode_1 = require("../BoardStateNode"); const findMove_1 = require("../utils/findMove"); const makeLeap_1 = require("../utils/makeLeap"); const makePoint_1 = require("../utils/makePoint"); /** * CheckerPlayDispatcherオブジェクトを生成する * @param listeners * @returns */ function checkerPlayDispatcher(listeners) { return { doCheckerPlay, doRevertDices, doUndo, doCommitCheckerPlay, doRedo, }; function doCheckerPlay(state, absPos, dices) { const ret = applyCheckerPlay(state, absPos, dices); if (ret.isValid) { listeners.onCheckerPlay(ret.state); } } function doRevertDices(state) { const reverted = Object.assign(Object.assign({}, state), { revertDicesFlag: !state.revertDicesFlag }); listeners.onRevertDices(reverted); } function doUndo(state) { const reverted = Object.assign(Object.assign({}, state), { curPly: { moves: [], dices: state.boardStateNodeRevertTo.dices.map((dice) => dice.pip), isRed: state.curPly.isRed, }, curBoardState: state.boardStateNodeRevertTo, absBoard: state.absBoardRevertTo, isUndoable: false }); listeners.onUndo(reverted); } function doCommitCheckerPlay(state) { const committed = { isCommitted: true, boardStateNode: state.curBoardState, }; listeners.onCommitCheckerPlay(committed); } function doRedo(state) { listeners.onRedo(state); } } exports.checkerPlayDispatcher = checkerPlayDispatcher; /** * 任意のポイントがクリックされたとき、それに対応するムーブを決定し、 * そのムーブの適用後の局面を返す * * @param state 現局面(そこから可能な局面のツリーを含む) * @param absPos クリックされたポイントの絶対座標(=White視点の座標) * @param dices ダイス状態の配列:インデックスの小さいものを優先して使用する * @returns */ function applyCheckerPlay(state, absPos, dices) { const pos = state.toPos(absPos); // Board上の実配置に基づき、小さい目を先に使うかどうかを判定する // ゾロ目でなく、両方使える時で、左側が小さい目の時だけ、 // 小さい方が優先 const useMinorFirst = dices.length === 2 && dices[0].pip < dices[1].pip && !dices[0].used && !dices[1].used; const node = (0, BoardStateNode_1.wrap)(state.curBoardState) // クリック位置から動かせる駒がある .apply((node) => (0, findMove_1.findMove)(node, pos, useMinorFirst)) // クリック位置でポイントを作れる .or((node) => (0, makePoint_1.makePoint)(node, pos)) // クリック位置へ動かせる .or((node) => (0, makeLeap_1.makeLeap)(node, pos, useMinorFirst)).unwrap; return node.hasValue ? { isValid: true, state: Object.assign(Object.assign({}, state), { curBoardState: node, absBoard: state.toAbsBoard(node.board), curPly: state.toPly(node), isUndoable: true }), } : { isValid: false }; } exports.applyCheckerPlay = applyCheckerPlay; function fill(listeners) { const doNothing = { onCheckerPlay: () => { // }, onRevertDices: () => { // }, onUndo: () => { // }, onCommitCheckerPlay: () => { // }, onRedo: () => { // }, }; return Object.assign(Object.assign({}, doNothing), listeners); } exports.fill = fill; function decorate(base, ...listeners) { return listeners.reduce((prev, cur) => { const { onCheckerPlay, onRevertDices, onUndo, onCommitCheckerPlay, onRedo, } = cur; return { onCheckerPlay: onCheckerPlay ? (state) => { prev.onCheckerPlay(state); onCheckerPlay(state); } : prev.onCheckerPlay, onRevertDices: onRevertDices ? (state) => { prev.onRevertDices(state); onRevertDices(state); } : prev.onRevertDices, onUndo: onUndo ? (state) => { prev.onUndo(state); onUndo(state); } : prev.onUndo, onCommitCheckerPlay: onCommitCheckerPlay ? (state) => { prev.onCommitCheckerPlay(state); onCommitCheckerPlay(state); } : prev.onCommitCheckerPlay, onRedo: onRedo ? (state) => { prev.onRedo(state); onRedo(state); } : prev.onRedo, }; }, base); } exports.decorate = decorate; function setCPStateListener(setState) { return { onCheckerPlay: setState, onRevertDices: setState, onUndo: setState, onCommitCheckerPlay: () => { setState(undefined); }, onRedo: setState, }; } exports.setCPStateListener = setCPStateListener;