UNPKG

tsgammon-core

Version:

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

220 lines (210 loc) 6.63 kB
import { nodeWithEmptyDice } from '../../BoardStateNode' import { boardState as _boardState } from '../../BoardState' import { cube, CubeState } from '../../CubeState' import { DicePip } from '../../Dices' import { eog } from '../../EOGStatus' import { GameConf, standardConf } from '../../GameConf' import { Ply } from '../../Ply' import { SGResult } from '../../records/SGResult' import { Score } from '../../Score' import { cbActionRed, cbActionWhite, cbInPlayRed, cbInPlayWhite, cbOpening, cbResponseRed, cbResponseWhite, CBState, cbToRollRed, cbToRollWhite, resultToCBEoG, } from '../CubeGameState' import { eogStateRed, eogStateWhite, inPlayStateRed, inPlayStateWhite, openingState, SGState, toRollStateRed, toRollStateWhite, } from '../SingleGameState' import { redViewAbsoluteBoard, whiteViewAbsoluteBoard, } from '../../AbsoluteBoardState' export enum GameStatus { OPENING, INPLAY_RED, INPLAY_WHITE, CUBEACTION_RED, CUBEACTION_WHITE, CUBERESP_RED, CUBERESP_WHITE, TOROLL_RED, TOROLL_WHITE, EOG_REDWON, EOG_WHITEWON, } /** * ゲーム中の一局面を表すオブジェクトを構成するためのパラメーターの定義:局面に応じて、必要な項目は変化する */ export type GameSetup = // 開始局面では、駒の配置とキューブだけ決まっていれば良い | { gameStatus?: GameStatus.OPENING absPos?: number[] cubeState?: CubeState } // ロール前の局面 | { gameStatus: | GameStatus.TOROLL_RED | GameStatus.TOROLL_WHITE | GameStatus.CUBEACTION_RED | GameStatus.CUBEACTION_WHITE | GameStatus.CUBERESP_RED | GameStatus.CUBERESP_WHITE absPos: number[] cubeState?: CubeState lastPly?: Ply } // 終局後の局面 | { gameStatus: GameStatus.EOG_REDWON | GameStatus.EOG_WHITEWON absPos: number[] stake: Score cubeState?: CubeState lastPly?: Ply } //ロール後の局面 | { gameStatus: GameStatus.INPLAY_RED | GameStatus.INPLAY_WHITE dice1: DicePip dice2: DicePip absPos: number[] cubeState?: CubeState lastPly?: Ply } export function toCBState(gameState: GameSetup = {}): CBState { const { gameStatus, cubeState = cube(1) } = gameState if (gameStatus === undefined) { return cbOpening(cubeState) } switch (gameStatus) { case GameStatus.OPENING: return cbOpening(cubeState) case GameStatus.INPLAY_RED: return cbInPlayRed(cubeState) case GameStatus.INPLAY_WHITE: return cbInPlayWhite(cubeState) case GameStatus.CUBEACTION_RED: return cbActionRed(cubeState) case GameStatus.CUBEACTION_WHITE: return cbActionWhite(cubeState) case GameStatus.CUBERESP_RED: return cbResponseRed(cubeState) case GameStatus.CUBERESP_WHITE: return cbResponseWhite(cubeState) case GameStatus.TOROLL_RED: return cbToRollRed(cubeState, 'Skip') case GameStatus.TOROLL_WHITE: return cbToRollWhite(cubeState, 'Skip') case GameStatus.EOG_REDWON: return resultToCBEoG(cubeState, SGResult.REDWON, eog()) case GameStatus.EOG_WHITEWON: return resultToCBEoG(cubeState, SGResult.WHITEWON, eog()) } } export function toSGState( gameState: GameSetup = {}, gameConf: GameConf = standardConf ): SGState { const { movesForDoublet = 4 } = gameConf if (gameState.gameStatus === undefined) { return openingState( boardState(gameState.absPos ?? standardConf.initialPos), undefined, movesForDoublet ) } switch (gameState.gameStatus) { case GameStatus.OPENING: return openingState( boardState(gameState.absPos ?? standardConf.initialPos), undefined, movesForDoublet ) case GameStatus.CUBEACTION_RED: case GameStatus.TOROLL_RED: case GameStatus.CUBERESP_WHITE: { const board = boardState(gameState.absPos) const lastStateNode = nodeWithEmptyDice(board) return toRollStateRed( lastStateNode.board.revert(), gameState.lastPly, movesForDoublet ) } case GameStatus.CUBEACTION_WHITE: case GameStatus.TOROLL_WHITE: case GameStatus.CUBERESP_RED: { const lastBoardState = boardState(gameState.absPos).revert() const lastStateNode = nodeWithEmptyDice(lastBoardState) return toRollStateWhite( lastStateNode.board.revert(), gameState.lastPly, movesForDoublet ) } case GameStatus.INPLAY_RED: return inPlayStateRed( boardState(gameState.absPos).revert(), gameState, movesForDoublet ) case GameStatus.INPLAY_WHITE: return inPlayStateWhite( boardState(gameState.absPos), gameState, movesForDoublet ) case GameStatus.EOG_REDWON: { const lastBoardState = boardState(gameState.absPos).revert() return eogStateRed( 1, eog(), redViewAbsoluteBoard(lastBoardState), lastBoardState ) } case GameStatus.EOG_WHITEWON: { const lastBoardState = boardState(gameState.absPos).revert() return eogStateWhite( 1, eog(), whiteViewAbsoluteBoard(lastBoardState), lastBoardState ) } } function boardState(pos: number[]) { const pieces = pos.reduce( (prev: { me: number; opp: number }, cur: number) => { return cur > 0 ? { me: prev.me + cur, opp: prev.opp } : cur < 0 ? { me: prev.me, opp: prev.opp - cur } : prev }, { me: 0, opp: 0 } ) return _boardState( pos, [15 - pieces.me, 15 - pieces.opp], gameConf.innerPos, gameConf.isEoGFunc ) } }