tsgammon-core
Version:
A Backgammon library for Typescript, formerly developed as a part of tsgammon-ui
155 lines (154 loc) • 5.53 kB
JavaScript
;
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;