tsgammon-core
Version:
A Backgammon library for Typescript, formerly developed as a part of tsgammon-ui
131 lines (128 loc) • 5.68 kB
JavaScript
;
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;
}
}