UNPKG

tsgammon-core

Version:

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

179 lines (170 loc) 5.29 kB
import { matchStateEoG, MatchStateEoG, MatchStateInPlay, matchStateLastGame, matchStateNewGame, } from '../MatchState' import { GameConf, standardConf } from '../GameConf' import { gameRecordEoG, GameRecordEoG, GameRecordInPlay, gameRecordInPlay, } from './GameRecord' import { PlyRecordEoG, PlyRecordInPlay } from './PlyRecord' /** * マッチ全体の記録 * @template T 手番に紐づけて保持される、局面を表す任意のオブジェクトの型 */ export type MatchRecord<T> = MatchRecordInPlay<T> | MatchRecordEoG<T> type _MatchRecord<T> = { /** ルールなど、ゲームの設定 */ conf: GameConf /** すでに終局したゲームの記録 */ gameRecords: GameRecordEoG<T>[] } export type MatchRecordInPlay<T> = _MatchRecord<T> & { isEoG: false matchState: MatchStateInPlay /** 現ゲームの記録:すなわち、現在進行中、または最後に終局したゲームの記録 */ curGameRecord: GameRecordInPlay<T> } export type MatchRecordEoG<T> = _MatchRecord<T> & { isEoG: true matchState: MatchStateEoG /** 現ゲームの記録:すなわち、現在進行中、または最後に終局したゲームの記録 */ curGameRecord: GameRecordEoG<T> } export function matchRecordInPlay<T>( conf: GameConf = standardConf, matchState: MatchStateInPlay ): MatchRecordInPlay<T> { const curGameRecord = gameRecordInPlay<T>(matchState) return { isEoG: false, conf, matchState, gameRecords: [], curGameRecord, } } /** * 現在の記録について、一手番分の記録を追加して返す * * @param matchRecord 現在の記録 * @param plyRecord 追加される手番の記録 * @param state 手番に紐づけて記録される、局面の状態を示す任意のオブジェクト * @returns 更新後の記録 */ export function addPlyRecord<T>( matchRecord: MatchRecordInPlay<T>, plyRecord: PlyRecordInPlay, state: T ): MatchRecordInPlay<T> { return { ...matchRecord, curGameRecord: { ...matchRecord.curGameRecord, plyRecords: matchRecord.curGameRecord.plyRecords.concat({ plyRecord, state, }), }, } } /** * 現在の記録について、現ゲームの記録をリセットして返す * * 現ゲームが終局していれば、すでに終局したゲームの記録に追加する。そうでなければ破棄する。 * * ※ 現ゲームが終局しても、画面表示上は終局状態として現ゲームの記録が必要なので、 * 終局の記録{@link eogRecord}と現ゲームの記録のリセットとで処理を分けている。 * * @param matchRecord 現在の記録 * @returns 更新後の記録 */ export function recordFinishedGame<T>( matchRecord: MatchRecordEoG<T> ): MatchRecord<T> { const { matchState } = matchRecord if (matchState.isEoM) { return matchRecord } else { const matchStateNext = matchStateNewGame(matchState) return { ...matchRecord, isEoG: false, matchState: matchStateNext, gameRecords: matchRecord.gameRecords.concat( matchRecord.curGameRecord ), curGameRecord: gameRecordInPlay(matchStateNext), } } } export function discardCurrentGame<T>( matchRecord: MatchRecordInPlay<T> ): MatchRecordInPlay<T> { return { ...matchRecord, curGameRecord: gameRecordInPlay(matchRecord.matchState), } } /** * 現在の記録について、任意の手番に復帰し、それ以降の手番の記録を破棄して返す * @param matchRecord 現在の記録 * @param index 復帰先となる手番 * @returns 更新後の記録 */ export function trimPlyRecords<T>( matchRecord: MatchRecord<T>, index: number ): MatchRecordInPlay<T> { const idx = 0 <= index && index < matchRecord.curGameRecord.plyRecords.length ? index : matchRecord.curGameRecord.plyRecords.length - 1 const matchState: MatchStateInPlay = matchRecord.isEoG ? matchStateLastGame(matchRecord.matchState) : matchRecord.matchState return { ...matchRecord, isEoG: false, matchState, curGameRecord: { ...matchRecord.curGameRecord, plyRecords: matchRecord.curGameRecord.plyRecords.slice(0, idx), isEoG: false, }, } } /** * 現在の記録について、現ゲームの記録に終局の記録を追加して返す * * @param matchRecord 現在の記録 * @param eogMatchState 終局時のMatchState * @param eogRecord 終局の記録 * @returns 更新後の記録 */ export function eogRecord<T>( matchRecord: MatchRecordInPlay<T>, eogRecord: PlyRecordEoG ): MatchRecordEoG<T> { const matchState = matchStateEoG( matchRecord.matchState, eogRecord.stake, eogRecord.eogStatus ) const curGameRecord = gameRecordEoG( matchRecord.curGameRecord, eogRecord, matchState.isEoM ) return { ...matchRecord, isEoG: true, curGameRecord, matchState, } }