tsgammon-core
Version:
A Backgammon library for Typescript, formerly developed as a part of tsgammon-ui
178 lines (177 loc) • 7.45 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.eogStateNogame = exports.eogStateWhite = exports.eogStateRed = exports.toRollStateWhite = exports.toRollStateRed = exports.inPlayStateWhite = exports.inPlayStateRedFromNode = exports.inPlayStateRed = exports.openingState = void 0;
const AbsoluteBoardState_1 = require("../AbsoluteBoardState");
const AbsoluteMove_1 = require("../AbsoluteMove");
const BoardStateNode_1 = require("../BoardStateNode");
const SGResult_1 = require("../records/SGResult");
const Score_1 = require("../Score");
function openingState(boardState, dicePip, movesForDouble = 4) {
const absBoard = (0, AbsoluteBoardState_1.whiteViewAbsoluteBoard)(boardState);
return {
tag: 'SGOpening',
dicePip,
absBoard,
boardState,
doOpening: (openingRoll) => {
if (openingRoll.dice1 === openingRoll.dice2) {
return openingState(boardState, openingRoll.dice1, movesForDouble);
}
else {
const isRedPlayerFirst = openingRoll.dice1 > openingRoll.dice2;
const boardToPlay = isRedPlayerFirst
? boardState.revert()
: boardState;
const inPlayState = isRedPlayerFirst
? inPlayStateRed
: inPlayStateWhite;
return inPlayState(boardToPlay, openingRoll, movesForDouble);
}
},
};
}
exports.openingState = openingState;
function inPlayStateRed(boardState, dices, movesForDouble = 4) {
const node = (0, BoardStateNode_1.boardStateNode)(boardState, dices, movesForDouble);
return inPlayStateRedFromNode(node, {
dices: node.dices.map((dice) => dice.pip),
moves: [],
isRed: true,
}, node, movesForDouble);
}
exports.inPlayStateRed = inPlayStateRed;
function inPlayStateRedFromNode(boardStateNode, curPly, revertTo, movesForDouble) {
const dices = boardStateNode.dices;
const absBoard = (0, AbsoluteBoardState_1.redViewAbsoluteBoard)(boardStateNode.board);
const toPly = buildToPly(boardStateNode.dices, AbsoluteMove_1.makeMoveAbsoluteAsRed, true);
const doCheckerPlayCommit = buildDoCheckerCommit(toPly, (boardState, lastPly) => toRollStateWhite(boardState, lastPly, movesForDouble), (stakeValue, eog, committed) => eogStateRed(eog.calcStake(stakeValue), eog, (0, AbsoluteBoardState_1.redViewAbsoluteBoard)(committed.board), committed.board));
return {
curPly,
tag: 'SGInPlay',
boardStateNode,
boardState: boardStateNode.board,
dices,
absBoard,
revertTo,
toPly,
toPos: (n) => boardStateNode.board.invertPos(n),
toAbsBoard: AbsoluteBoardState_1.redViewAbsoluteBoard,
isRed: true,
doCheckerPlayCommit,
withNode: (node) => {
return inPlayStateRedFromNode(node, toPly(node), revertTo, movesForDouble);
},
};
}
exports.inPlayStateRedFromNode = inPlayStateRedFromNode;
function inPlayStateWhite(boardState, dices, movesForDouble = 4) {
const node = (0, BoardStateNode_1.boardStateNode)(boardState, dices, movesForDouble);
return inPlayStateWhiteFromNode(node, {
dices: node.dices.map((dice) => dice.pip),
moves: [],
isRed: false,
}, node, movesForDouble);
}
exports.inPlayStateWhite = inPlayStateWhite;
function inPlayStateWhiteFromNode(boardStateNode, curPly, revertTo, movesForDouble) {
const dices = boardStateNode.dices;
const absBoard = (0, AbsoluteBoardState_1.whiteViewAbsoluteBoard)(boardStateNode.board);
const toPly = buildToPly(boardStateNode.dices, AbsoluteMove_1.makeMoveAbsoluteAsWhite, false);
const doCheckerPlayCommit = buildDoCheckerCommit(toPly, (boardState, lastPly) => toRollStateRed(boardState, lastPly, movesForDouble), (stakeValue, eog, committed) => eogStateWhite(eog.calcStake(stakeValue), eog, (0, AbsoluteBoardState_1.whiteViewAbsoluteBoard)(committed.board), committed.board));
return {
curPly,
tag: 'SGInPlay',
boardStateNode,
boardState: boardStateNode.board,
dices,
absBoard,
revertTo,
toPly,
toPos: (n) => n,
toAbsBoard: AbsoluteBoardState_1.whiteViewAbsoluteBoard,
isRed: false,
doCheckerPlayCommit,
withNode: (node) => {
return inPlayStateWhiteFromNode(node, toPly(node), revertTo, movesForDouble);
},
};
}
function buildDoCheckerCommit(toPly, toRollState, toEoGState) {
return (committed) => {
const ply = toPly(committed);
const boardState = committed.board;
const eogStatus = boardState.eogStatus();
if (eogStatus.isEndOfGame) {
return toEoGState(1, committed.board.eogStatus(), committed);
}
else {
// 手番プレイヤーと相対表記の盤面とをそれぞれ入れ替える
const nextBoardState = boardState.revert();
return toRollState(nextBoardState, ply);
}
};
}
function toRollStateRed(boardState, lastPly = { moves: [], dices: [], isRed: true }, movesForDouble = 4) {
const absBoard = (0, AbsoluteBoardState_1.redViewAbsoluteBoard)(boardState);
return {
tag: 'SGToRoll',
boardState,
absBoard,
isRed: true,
lastPly,
doRoll: (dices) => {
return inPlayStateRed(boardState, dices, movesForDouble);
},
};
}
exports.toRollStateRed = toRollStateRed;
function toRollStateWhite(boardState, lastPly = { moves: [], dices: [], isRed: false }, movesForDouble = 4) {
const absBoard = (0, AbsoluteBoardState_1.whiteViewAbsoluteBoard)(boardState);
return {
tag: 'SGToRoll',
boardState,
absBoard,
isRed: false,
lastPly,
doRoll: (dices) => {
return inPlayStateWhite(boardState, dices, movesForDouble);
},
};
}
exports.toRollStateWhite = toRollStateWhite;
function eogStateRed(stakeValue, eogStatus, absBoard, boardState) {
const stake = (0, Score_1.scoreAsRed)(stakeValue);
return Object.assign(Object.assign({}, eogState(eogStatus, stake, absBoard, boardState)), { result: SGResult_1.SGResult.REDWON, isRed: true });
}
exports.eogStateRed = eogStateRed;
function eogStateWhite(stakeValue, eogStatus, absBoard, boardState) {
const stake = (0, Score_1.scoreAsWhite)(stakeValue);
return Object.assign(Object.assign({}, eogState(eogStatus, stake, absBoard, boardState)), { result: SGResult_1.SGResult.WHITEWON, isRed: false });
}
exports.eogStateWhite = eogStateWhite;
function eogStateNogame(eogStatus, absBoard, boardState) {
return Object.assign(Object.assign({}, eogState(eogStatus, (0, Score_1.score)(), absBoard, boardState)), { result: SGResult_1.SGResult.NOGAME });
}
exports.eogStateNogame = eogStateNogame;
function eogState(eogStatus, stake, absBoard, boardState) {
return {
tag: 'SGEoG',
absBoard,
boardState,
dices: [],
stake,
eogStatus,
};
}
function buildToPly(dices, toAbsMove, isRed) {
return (boardStateNode) => {
return {
moves: boardStateNode
.lastMoves()
.map((m) => toAbsMove(m, boardStateNode.board.invertPos)),
dices: dices.map((dice) => dice.pip),
isRed: isRed,
isWhite: !isRed,
};
};
}