UNPKG

tsgammon-core

Version:

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

77 lines (72 loc) 2.72 kB
import { BoardStateNode, NoMove, NO_MOVE, wrap } from '../BoardStateNode' import { findMove } from './findMove' /** * 与えられたBoardStateNodeについて、指定された位置へ駒を動かすムーブがあれば、それを返す * @param node * @param pos * @param useMinorFirst * @returns */ export function makeLeap( node: BoardStateNode, pos: number, useMinorFirst: boolean ): BoardStateNode | NoMove { const dices = node.dices.filter((d) => !d.used) if (dices.length == 0) { return NO_MOVE } // まず、一つだけですむケースを探す const { major, minor } = dices.length >= 2 ? dices[0].pip > dices[1].pip ? { major: dices[0].pip, minor: dices[1].pip } : { major: dices[1].pip, minor: dices[0].pip } : { major: dices[0].pip, minor: undefined } const withMajor = pos - major >= 0 ? findMove(node, pos - major, false) : NO_MOVE // 本来はここでもuseMinorFirstを意識しないといけないが、この関数はmakePointの後で // 使用する想定なので、major/minorの両方で駒が動かせる時は、そちらで拾われることになり // 意識する意味がない if ( withMajor.hasValue && withMajor.lastMoves()[withMajor.lastMoves().length - 1].to === pos ) { return withMajor } if (minor === undefined) { return NO_MOVE } const withMinor = pos - minor >= 0 ? findMove(node, pos - minor, true) : NO_MOVE if ( withMinor.hasValue && withMinor.lastMoves()[withMinor.lastMoves().length - 1].to === pos ) { return withMinor } // 二つ使う場合は、useMinorFirstを反映させる const from = pos - (major + minor) const leap = wrap(node) .apply((node) => findMove(node, from, useMinorFirst)) .apply((node) => makeLeap(node, pos, useMinorFirst)).unwrap if (leap.hasValue) { return leap } // ゾロ目でないなら、これ以上のサーチは不要 if (dices.length < 3) { return NO_MOVE } // 残りのダイス(全て同じ目とする)が使えるかどうかは再帰して判定する return ( wrap(node) // 一つ前のポイントをクリックした状態を生成 .apply((node) => pos - major >= 0 ? makeLeap(node, pos - major, useMinorFirst) : NO_MOVE ) // 一つ前のポイントにきた駒をクリックして進めた状態を生成 .apply((node) => findMove(node, pos - major, useMinorFirst)).unwrap ) }