UNPKG

tsgammon-core

Version:

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

131 lines (128 loc) 5.68 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.formatMatchRecord = void 0; const formatPlyRecord_1 = require("./formatPlyRecord"); const formatAbsMove_1 = require("../../utils/formatAbsMove"); const defaultNames_1 = require("./defaultNames"); /** * MatchRecordsをテキスト形式に変換する * * @param matchRecord 対象となるマッチ * @param conf オプショナルルールの適否など、ヘッダ情報に出力する設定情報 */ function formatMatchRecord(matchRecord, redPlayer = defaultNames_1.defaultNames.red, whitePlayer = defaultNames_1.defaultNames.white) { const header = formatHeaderPart(matchRecord, redPlayer, whitePlayer); const gameLog = matchRecord.gameRecords .map((gameRecord, index) => formatGameRecord(gameRecord, index, redPlayer, whitePlayer).join('\n')) .join('\n\n\n\n'); const curGameText = (matchRecord.gameRecords.length === 0 ? '' : '\n\n\n\n') + formatGameRecord(matchRecord.curGameRecord, matchRecord.gameRecords.length, redPlayer, whitePlayer).join('\n'); return header + gameLog + curGameText; } exports.formatMatchRecord = formatMatchRecord; // ヘッダ情報の出力:confのルール設定や日時など function formatHeaderPart(matchRecord, redPlayer = defaultNames_1.defaultNames.red, whitePlayer = defaultNames_1.defaultNames.white) { const conf = matchRecord.conf; const date = new Date(); const digit2 = (s) => s.padStart(2, '0'); const eventDate = `${date.getFullYear()}.${digit2('' + (date.getMonth() + 1))}.${digit2('' + date.getDate())}`; const eventTime = `${digit2('' + date.getHours())}.${digit2('' + date.getMinutes())}`; const header = `; [Site "tsgammon-ui"] ; [Player 1 ${whitePlayer}] ; [Player 2 ${redPlayer}] ; [EventDate "${eventDate}"] ; [EventTime "${eventTime}"] ; [Variation "${conf.name}"] ; [Unrated "On"] ; [Jacoby "${conf.jacobyRule ? 'On' : 'Off'}"] ; [Beaver "Off"] ; [CubeLimit "${conf.cubeMax}"] ${matchRecord.matchState.matchLength + ' point match'} `; return header; } // 1ゲーム分の出力 function formatGameRecord(gameRecord, gameNum, redPlayer = defaultNames_1.defaultNames.red, whitePlayer = defaultNames_1.defaultNames.white) { const columnWidth = 34; const numWidth = 3; const { scoreBefore, plyRecords } = gameRecord; const gameDesc = ` Game ${gameNum + 1}`; const scoreDesc = formatScoreDesc(scoreBefore); const turns = buildTurns(plyRecords.map((rec) => rec.plyRecord)).map((turn, index) => formatTurn(turn, index)); const stakes = gameRecord.isEoG ? formatStakeLine(gameRecord.eogRecord.stake, gameRecord.isEoM) : ''; return [gameDesc, scoreDesc].concat(turns, stakes); function formatScoreDesc(scoreBefore) { const whiteCol = (`${whitePlayer} : ` + scoreBefore.whiteScore).padEnd(numWidth + 1 + columnWidth); const redCol = `${redPlayer} : ${scoreBefore.redScore}`; return ` ${whiteCol}${redCol}`; } function formatTurn(turn, index) { const num = ('' + (index + 1)).padStart(numWidth); const whiteCol = (turn.white ? (0, formatPlyRecord_1.formatPlyRecord)(turn.white, formatAbsMove_1.MoveFormatDirection.RELATIVE_DEC, false, 'Cannot Move') : '').padEnd(columnWidth); const redCol = turn.red ? (0, formatPlyRecord_1.formatPlyRecord)(turn.red, formatAbsMove_1.MoveFormatDirection.RELATIVE_DEC, false, 'Cannot Move') : ''; return `${num}) ${whiteCol}${redCol}`; } function formatStakeLine(stake, isEoM) { const whiteStake = formatStake(stake.whiteScore); const redStake = formatStake(stake.redScore); return ` ${(' ' + whiteStake).padEnd(columnWidth)} ${redStake}`; function formatStake(score) { return score === 0 ? '' : isEoM ? `Wins ${score} point and the match` : `Wins ${score} point`; } } } // White=>RedとなるようPlyRecordを2個ずつペアにして、Turnを構成する function buildTurns(recs) { const { turns, lastWhite } = recs.reduce((prev, plyRecord) => { const cur = plyRecord; if (prev.lastWhite === undefined) { // 保留中のWhiteがない if (cur.isRed) { // 先にRedがきたので、whiteなしの記録として格納する return { turns: prev.turns.concat({ red: cur }) }; } else { // Whiteが来たので、一旦保留 const lastWhite = cur; return { turns: prev.turns, lastWhite }; } } else { // 保留中のWhiteがある if (cur.isRed) { // Whiteを保留しているところにRedが来たので、ペアにして格納 return { turns: prev.turns.concat({ white: prev.lastWhite, red: cur, }), }; } else { // さらにWhiteが来てしまったので、保留していた分をredなしの記録として格納、 // 後から来た分は保留する const lastWhite = cur; return { turns: prev.turns.concat({ white: prev.lastWhite }), lastWhite, }; } } }, { turns: [], lastWhite: undefined }); if (lastWhite) { return turns.concat({ white: lastWhite }); } else { return turns; } }