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

内部技術ドキュメント

rsshogi の内部実装を解説する技術ドキュメントです。 「将棋というゲームの要素をコンピュータ上でどう表現し、どう高速に操作するか」を軸に、 小さい概念から積み上げる構成になっています。

なぜ内部実装を理解するべきか

将棋ライブラリの API を使うだけなら、内部実装を知る必要はありません。 しかし、以下のようなケースでは、盤面表現やビット演算のレベルまで理解していることが大きな武器になります。

  • パフォーマンスのボトルネックを診断したい: なぜある局面で合法手生成が遅いのかを調べるには、Bitboard 操作と指し手生成パイプラインの仕組みが必要です
  • エンジンの探索部を書きたい: Position の差分更新、Zobrist ハッシュ、StateInfo の生存期間は探索の正しさと速度の両方に影響します
  • ライブラリに貢献したい: 駒のインデックス設計や 128bit Bitboard のレイアウトには歴史的な理由と技術的なトレードオフがあり、それを理解していないと既存設計と矛盾する変更をしてしまいます
  • 将棋プログラミング全般を学びたい: 本ドキュメントは rsshogi 固有の話に閉じず、主要な将棋エンジンやチェスエンジン(Stockfish)の知見も交えた教科書的な記述を目指しています

想定読者

  • 情報学を学んだ大卒程度
  • ビット演算、メモリ階層、キャッシュの仕組みは理解している
  • 将棋のルールは知っている
  • 将棋プログラミングの内部実装に興味がある

全体の流れ

rsshogi の内部構造は、いきなり Position や合法手生成から読むよりも、 「1 マスをどう番号にするか」から順に積み上げると理解しやすくなります。 この章では次のストーリーで読み進めます。

  1. まず SquarePieceMove で、将棋の語彙を Rust の値に落とし込む。
  2. 次に Bitboard で、81 マスの集合を 128bit のビット列として扱う。
  3. その上に Position を作り、盤・持ち駒・手番・履歴を差分更新する。
  4. Position と Bitboard の情報から、王手回避や二歩を含む合法手を生成する。
  5. 最後に、棋譜・SFEN・PackedSfen などの外部表現へ戻す。

各章は独立した小技の集まりではありません。 たとえば「先手歩を 1 マス前へ進める」が >> 1 で済むのは、座標系が筋優先で並んでいるからです。 合法手生成が速いのは、駒の集合を Bitboard として持ち、Position が差分更新でその集合を保っているからです。 この依存関係を意識すると、後続の最適化や特殊ルールの説明も追いやすくなります。

types → bitboard → position → movegen → serialization → optimization
語彙定義   データ構造   局面管理    合法手生成    永続化         高速化
                                    → mate
                                     詰み判定
  1. 基本型: 座標・駒・指し手の数値表現
  2. ビットボード: 集合演算による盤面の高速操作
  3. 局面管理: Position 構造体と差分更新
  4. 合法手生成: ビットボードを使った手の列挙
  5. 詰み判定: テーブル駆動の 1 手詰め判定
  6. シリアライゼーション: SFEN・棋譜フォーマット・圧縮
  7. パフォーマンス最適化: SIMD による高速化

盤面図の読み方

この章の盤面図は、原則として将棋の通常表示に合わせています。

  • 上端の筋番号は左から 9, 8, ..., 1
  • 右端の段は上から 一, 二, ..., 九
  • 先手の駒は読者側、後手の駒は 180 度回転して表示
  • SFEN は 1 段目から 9 段目へ、各段を / で区切る
  • highlightSquares([n])n は rsshogi の Square と同じ file_idx * 9 + rank_idx(どちらも 0-indexed)

したがって Square(0)1a(1一)、Square(40)5e(5五)、 Square(80)9i(9九)です。盤面上では 1 筋が右、9 筋が左に見えるため、 内部インデックスの増え方と画面上の左右方向を混同しないでください。

依存関係

types ──────────────────────────────┐
  座標 → 駒 → 指し手               │
                                    ▼
bitboard ──────────────────────────┐
  コンセプト → レイアウト → 操作 → 利き│
                                    ▼
position ──────────────────────────┐
  Position → StateInfo → Zobrist   │
                                    ▼
movegen ───────────────────────────┐
  パイプライン → 特殊ルール          │
                                    ▼
mate ◄── (movegen)
  1手詰め solver(rsshogi の範囲)
  ※ 3手詰め以上は探索エンジン側で実装

serialization ◄── (types, position)
  SFEN → 圧縮 → 棋譜フォーマット

optimization ◄── (bitboard)
  SIMD

serialization と optimization は movegen を読む前でも、 position まで読んでいれば独立に読めます。 mate は movegen の知識を前提とします。

推奨読了パス

読者の目的に応じて、以下のパスを推奨します。

将棋プログラミング入門(初学者): types → bitboard/index → bitboard/layout → position/index → movegen/index まず全体像を掴むことを優先し、各章の導入ページだけを読み進めます。

ライブラリ利用者(API の裏側を知りたい): types(全ページ)→ serialization → bitboard/index API に現れる型(Square, Piece, Move)の設計意図と、棋譜フォーマットの仕組みを理解します。

エンジン開発者(探索部・評価関数を書きたい): position(全ページ)→ position/search-integration → movegen → mate rsshogi をラップして探索エンジンを構築する方法を学び、詰み判定を組み込みます。

コントリビュータ(rsshogi に変更を加えたい): 全章を依存関係の順に通読してください。特に position/state-management と movegen/special-rules は、 変更時に壊しやすい不変条件(invariant)が多いため重点的に読むことを推奨します。

次に読む

基本型: まずは座標・駒・指し手の数値表現から始めましょう。