tsgammon-core
Version:
A Backgammon library for Typescript, formerly developed as a part of tsgammon-ui
137 lines (130 loc) • 3.69 kB
text/typescript
import { DicePip } from '../Dices'
export enum TURN {
X,
O,
OVER,
}
export enum COLOUR {
X,
O,
}
export enum DIRECTION {
ASC,
DESC,
}
/**
* FIBS形式文字列の各項目を要素とする型
*/
export type FIBSBoard = {
player: string
opponent: string
matchLen: number
playerScore: number
opponentScore: number
pos: number[]
turn: TURN
dice1: DicePip | 0
dice2: DicePip | 0
cubeValue: number
playerMayDouble: boolean
opponentMayDouble: boolean
wasDoubled: boolean
colour: COLOUR
direction: DIRECTION
home: number
bar: number
playerOnHome: number
opponentOnHome: number
canMove: number
_forcedMove: false
_didCrawford: false
redoubles: number
}
/**
* 既定値を補ってFIBSBoardを生成する
*
* @param board
* @returns
*/
export function initBoard(board?: Partial<FIBSBoard>): FIBSBoard {
return {
player: 'You',
opponent: 'opponent',
matchLen: 9999,
playerScore: 0,
opponentScore: 0,
// prettier-ignore
pos: [
0,
-2, 0, 0, 0, 0, 5, 0, 3, 0, 0, 0, -5,
5, 0, 0, 0, -3, 0, -5, 0, 0, 0, 0, 2,
0,
],
turn: TURN.OVER,
dice1: 0,
dice2: 0,
cubeValue: 1,
playerMayDouble: true,
opponentMayDouble: true,
wasDoubled: false,
colour: COLOUR.X,
direction: DIRECTION.DESC,
home: 0,
bar: 25,
playerOnHome: 0,
opponentOnHome: 0,
canMove: 0,
_forcedMove: false,
_didCrawford: false,
redoubles: 0,
...board,
}
}
/**
* FIBS形式の文字列を生成する
*
* http://www.fibs.com/fibs_interface.html#board_state
*
* @param board 局面
* @param player 自分の名前
* @param opponent 対戦相手の名前
* @returns
*/
export function encodeFIBSBoardString(board: FIBSBoard): string {
validate(board)
const score3 = `${board.matchLen}:${board.playerScore}:${board.opponentScore}`
const boardPos26 = `${board.pos.join(':')}`
const turn = board.turn === TURN.OVER ? 0 : board.turn === TURN.O ? 1 : -1
const dice4 =
board.turn === TURN.OVER
? '0:0:0:0'
: board.turn === TURN.O
? board.colour === COLOUR.O
? `${board.dice1}:${board.dice2}:0:0`
: `0:0:${board.dice1}:${board.dice2}`
: board.colour === COLOUR.X
? `${board.dice1}:${board.dice2}:0:0`
: `0:0:${board.dice1}:${board.dice2}`
const cube4 = `${board.cubeValue}:${board.playerMayDouble ? 1 : 0}:${
board.opponentMayDouble ? 1 : 0
}:${board.wasDoubled ? 1 : 0}`
const boardLayout4 = `${board.colour === COLOUR.O ? 1 : -1}:${
board.direction === DIRECTION.ASC ? 1 : -1
}:${board.home}:${board.bar}`
const [playerOnTheBar, opponentOnTheBar] = (
board.direction === DIRECTION.ASC
? [board.pos[0], board.pos[25]]
: [board.pos[25], board.pos[0]]
).map(Math.abs)
const pieces4 = `${board.playerOnHome}:${board.opponentOnHome}:${playerOnTheBar}:${opponentOnTheBar}`
const movable3 = `${board.canMove}:${board._forcedMove ? 0 : 0}:${
board._didCrawford ? 0 : 0
}`
const redoubles1 = board.redoubles
return `board:${board.player}:${board.opponent}:${score3}:${boardPos26}:${turn}:${dice4}:${cube4}:${boardLayout4}:${pieces4}:${movable3}:${redoubles1}`
}
function validate(board: FIBSBoard) {
if (board.pos.length != 26) {
throw new Error('board length != 26, was:' + board.pos.length)
}
}