tsgammon-core
Version:
A Backgammon library for Typescript, formerly developed as a part of tsgammon-ui
133 lines (128 loc) • 4.1 kB
text/typescript
import { DiceRoll } from '../Dices'
import { RollListener, rollListener } from './RollDispatcher'
import { singleGameDispatcher } from './SingleGameDispatcher'
import { SingleGameListener } from './SingleGameListener'
import { SGOpening, SGToRoll } from './SingleGameState'
import {
SingleGameEventHandlerExtensible,
SingleGameEventHandler,
} from './SingleGameEventHandler'
import { concat0, concat1 } from './utils/concat'
/**
* チェッカープレイを管理する、SingleGameEventHandler
* (SingleGameEventHandlerExtensible)オブジェクトを生成する
* @param rListener
* @param listeners
* @returns
*/
export function buildSGEventHandler(
rListener: RollListener = rollListener(),
...listeners: Partial<SingleGameListener>[]
): SingleGameEventHandlerExtensible {
return buildSGEventHandler_rec(rListener, {}, ...listeners)
}
function buildSGEventHandler_rec(
rollListener: RollListener,
sgListener: Partial<SingleGameListener>,
...listeners: Partial<SingleGameListener>[]
): SingleGameEventHandlerExtensible {
const listener: SingleGameListener = {
...emptySGListener,
...listeners.reduce(
(prev, cur) => concatSGListeners(prev, cur),
sgListener
),
}
const addListeners = (...toAdd: Partial<SingleGameListener>[]) => {
return buildSGEventHandler_rec(rollListener, listener, ...toAdd)
}
return {
..._buildSGEventHandler(rollListener, listener),
addListeners,
}
}
function _buildSGEventHandler(
rollListener: RollListener,
listeners: SingleGameListener
): SingleGameEventHandler {
return {
onStartGame: () => {
const result = singleGameDispatcher.doStartGame()
result(listeners)
},
onCommit: (state) => {
const result = singleGameDispatcher.doCommitCheckerPlay(state)
result(listeners)
},
onRoll: (sgState: SGToRoll) =>
rollListener.onRollRequest((dices: DiceRoll) => {
const result = singleGameDispatcher.doRoll(sgState, dices)
result(listeners)
}),
onRollOpening: (sgState: SGOpening) =>
rollListener.onRollRequest((dices: DiceRoll) => {
const result = singleGameDispatcher.doOpeningRoll(
sgState,
dices
)
result(listeners)
}),
}
}
const emptySGListener: SingleGameListener = {
onAwaitRoll: () => {
//
},
onCheckerPlayCommitted: () => {
//
},
onCheckerPlayStarted: () => {
//
},
onEndOfGame: () => {
//
},
onGameStarted: () => {
//
},
onOpeningCheckerPlayStarted: () => {
//
},
onRerollOpening: () => {
//
},
}
export function concatSGListeners(
base: Partial<SingleGameListener>,
...listners: Partial<SingleGameListener>[]
): Partial<SingleGameListener> {
return listners.reduce(
(
prev: Partial<SingleGameListener>,
cur: Partial<SingleGameListener>
) => {
return {
onGameStarted: concat0(prev?.onGameStarted, cur?.onGameStarted),
onOpeningCheckerPlayStarted: concat1(
prev?.onOpeningCheckerPlayStarted,
cur?.onOpeningCheckerPlayStarted
),
onCheckerPlayStarted: concat1(
prev?.onCheckerPlayStarted,
cur?.onCheckerPlayStarted
),
onCheckerPlayCommitted: concat1(
prev.onCheckerPlayCommitted,
cur.onCheckerPlayCommitted
),
onRerollOpening: concat1(
prev?.onRerollOpening,
cur?.onRerollOpening
),
onAwaitRoll: concat1(prev?.onAwaitRoll, cur?.onAwaitRoll),
onEndOfGame: concat1(prev?.onEndOfGame, cur?.onEndOfGame),
}
},
base
)
}