UNPKG

tsgammon-core

Version:

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

178 lines (177 loc) 7.45 kB
"use strict"; 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, }; }; }