Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

特殊ルール

前提知識: 合法手生成

合法手生成は駒の利きだけでなく、玉の安全、成り、駒打ち、打ち歩詰めを扱う。 LegalLegalAll はこれらを満たす手だけを返す。

王手を読むための cache

checkers() は手番側の玉へ利いている相手駒の集合を返す。 check_square(piece_type) は手番側のその駒種が、敵玉へ王手する候補升を返す。 blockers_for_king(color)pinners(color) は遠方駒と玉の利き線を使う処理を助ける。

これらは現在局面の cache から得られる読み取り値である。 手を apply または undo した後は、新しい局面の値を読み直す。

王手と回避

手番側の玉が王手されているかは Position::is_in_check() で判定する。 一重王手では玉の移動、王手駒の捕獲、利き線への合駒が回避候補になる。 二重王手では玉の移動だけが回避できる。

Evasions は回避候補を高速に生成するが、すべての候補が最終的に合法とは限らない。 generate_legal_evasionsEvasions を生成した後で合法性を確認する。 通常の対局手には Legal、任意不成を含む完全な合法手集合には LegalAll を使う。 どちらも王手の有無を内部で処理するため、呼び出し側で回避生成へ分岐する必要はない。

玉の安全とピン

玉は相手の利きがある升へ移動できない。 玉以外の駒は、玉と相手の遠方駒の間にあるとき、利き線を外れる移動ができない。 Position::blockers_for_king(color) はそのような遮蔽駒を含む集合を返し、pinned_pieces(color) は自色のピンされた駒を返す。

LegalLegalAll はこの情報を使って、玉の危険な移動と王手を放置する移動を除外する。

玉で王手駒を取る場合も、取った後の升が別の相手駒に利かれていれば合法ではない。 このため「王手駒を取れる」という候補判定だけで、玉の回避を確定しない。

成りと不成

歩、香、桂、銀、角、飛は出発升または到着升が敵陣三段なら成れる。 歩と香が最終段へ、桂が最終二段へ進むときは成りが必須である。 LegalAll と各 *All mode は任意の不成を追加するが、必須成りの不成は追加しない。

Legal と非 All mode は歩、香、角、飛の成れる不成を通常省略する。 銀と桂の任意成りは両方の選択肢を生成する。

成りの可否は出発升または到着升が敵陣にあるかで決まり、移動前後の盤面の駒種とは別の規則である。 成りの必須性は到着升だけで決まるため、候補を絞る処理でも歩・香・桂の終端段を除外しない。

駒打ち

駒打ちは空き升だけへ指せる。 歩と香は最終段へ、桂は最終二段へ打てない。 同じ筋に自分の未成歩があるとき、その筋へ歩を打てない。

LegalLegalAll は持ち駒の枚数、行き所のない駒、二歩、王手回避の合駒条件を確認する。 王手中の駒打ちは、一重王手の利き線を遮る升に限られ、二重王手には使えない。

打ち歩詰め

歩を打って直ちに相手玉を詰ませる手は反則である。 盤上の歩を進めて詰ませる手は、この規則の対象ではない。 Position::is_legal_moveLegal 系の生成は打ち歩詰めを除外する。

打った歩を取れる、玉が逃げられる、または他の合法な応手がある場合、その歩打ちは合法である。 この判定は相手の応手をルールどおりに確認するため、単なる王手判定で置き換えない。

打ち歩詰めを検査するのは歩を持ち駒から打つ場合だけである。 盤上の歩を前へ進めて詰ませる手と、歩以外の駒打ちで詰ませる手はこの禁手に当たらない。

王手候補

generate_checks は捕獲と非捕獲を含む王手候補を出す。 generate_checks_all_move32 は可能な不成も含む Move32 候補を出す。 generate_checks_drops_part は持ち駒による王手候補だけを出す。

これらは候補生成 API なので、王手中の自玉の安全を含む最終的な合法性が必要なら is_legal_move または LegalAll で確認する。

千日手と入玉

同一局面の反復は repetition_state() で読む。 RepetitionState::Draw は通常の千日手、WinLose は連続王手千日手を手番側から見た結果である。 優等局面と劣等局面もこの enum で表すため、探索側は enum 全体をスコア規約へ写像する。

入玉宣言の条件は evaluate_declaration() が構造化して返す。 DeclarationDetail::PointRule には敵陣の玉、敵陣の駒数、点数、必要点の各条件が入り、TryRule にはトライ先の到達・占有・安全条件が入る。 ポイント制では、実際に宣言できる場合だけ declaration_win_move()MOVE_WIN を返す。 トライルールでは同じ API が、トライ升への玉の移動を表す Move32 を返す。

最大手数による引き分けは Position の生成・合法手判定の責務ではない。 対局規約に依存する打ち切りは、消費者が game_ply() を基に適用する。

ルールを確認する順序

外部から受け取った一手は、次の順で扱うと責務が明確になる。

  1. USI や CSA を Move または Move32 へ解析する。
  2. 現局面へ対応付ける必要があれば move32_from_move を使う。
  3. is_legal_move または is_legal_move32 で最終判定する。
  4. 合法な手だけを apply し、必要なら gives_check_move32 を事前計算する。

生成済みの Legal 系の手には 3 を繰り返す必要はない。 ただし候補 mode、棋譜の復元、ネットワーク入力から得た手は、apply 前にこの境界を通す。

次に読む

詰み判定 で、合法な王手候補から一手詰めを判定する方法を確認する。