tsgammon-core
Version:
A Backgammon library for Typescript, formerly developed as a part of tsgammon-ui
46 lines (45 loc) • 2.77 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.applyDicePipToPoints = void 0;
const BoardStateNode_1 = require("../BoardStateNode");
const isLegalMove_1 = require("./isLegalMove");
/**
* 指定された盤面について、指定された目を各ポイントに適用し、それぞれの場合の子局面を生成する。
*
* 生成された子局面は、ポイント位置に対して子局面を返す関数として返される。
*
* @param board 盤面
* @param dicePip 盤面に対して使用したいダイス目
* @param nodeBuilder ダイスが適用可能なポイントについて、適用後の状態を表す子局面ノードを生成する関数
* @param mark この局面での未使用のダイスの数
* @returns 各ポイントへのダイス適用可否(可の場合は{@link BoardStateNode}、否の場合は{@link NoMove})を返す関数と、使用できなかったダイスの数(必ずmark以下の値となる)が返る
*
* 返値の未使用のダイスの数は、この局面で全くダイスが適用できない場合はmarkのままとなり、そうでなければ、
* 子局面全体でできるだけ多くダイスを使った場合の、残りのダイス数となる。
*
*/
function applyDicePipToPoints(board, dicePip, nodeBuilder, mark) {
// すでに終局となっているのならば、子局面は生成しない
if (board.eogStatus().isEndOfGame) {
return [() => BoardStateNode_1.NO_MOVE, mark];
}
// 各ポイントについて、そこの駒を動かす手が有効なら、nodeBuilderを呼んで子局面を生成する
const nodesAndMarksForEachPoint = board.points.map((_, index) => {
// 各ポイントについて、指定のダイス目が使えるかどうか判断する
const move = (0, isLegalMove_1.isLegalMove)(board, index, dicePip);
// 使えるポイントについては子ノードを生成し、そうでなければNO_MOVEを返す
return move.isLegal
? nodeBuilder(board.movePiece(index, dicePip), move.move)
: [BoardStateNode_1.NO_MOVE, mark];
});
// 使用不能なダイスの数については、最小値をとる
const markedMin = nodesAndMarksForEachPoint
.map(([, mark]) => mark)
.reduce((m1, m2) => Math.min(m1, m2));
// 最大限ダイスを使える手に絞り込む
const nodes = nodesAndMarksForEachPoint.map(([node, marked]) => {
return marked === markedMin ? node : BoardStateNode_1.NO_MOVE;
});
return [(pos) => { var _a; return (_a = nodes[pos]) !== null && _a !== void 0 ? _a : BoardStateNode_1.NO_MOVE; }, markedMin];
}
exports.applyDicePipToPoints = applyDicePipToPoints;