# rshogi

Rust で実装された将棋ライブラリです。[YaneuraOu](https://github.com/yaneurao/YaneuraOu) の
Rust 版を目指し、高速かつ安全な将棋プリミティブを提供します。

Python バインディング ([rshogi-py](https://pypi.org/project/rshogi-py/)) は
[cshogi](https://github.com/TadaoYamaoka/cshogi) API にインスパイアされた設計です。

## 設計思想

### 1. 安全性優先

- `#![deny(unsafe_code)]` により unsafe Rust を禁止
- コンパイル時に検出可能なエラーは型システムで表現
- 実行時エラーは `Result` 型で明示的に扱う

### 2. 正確性

- YaneuraOu の合法手生成との互換性テストで正確性を担保
- Perft テストによる手生成の網羅的検証
- 千日手・入玉宣言勝ちなど将棋固有のルールを正しく実装

### 3. パフォーマンス

- ビットボードによる高速な盤面表現
- Magic Bitboard / PEXT による効率的なスライダー攻撃計算
- 差分更新による Zobrist ハッシュ計算
- SIMD 最適化（AVX2 対応）

### 4. 再利用性

- Rust と Python の両方から利用可能
- エンジンや評価関数とは分離し、純粋な局面管理に専念
- 明確な API 境界でダウンストリームプロジェクトに組み込みやすい

## アーキテクチャ

```text
rshogi
├── types     - 基本型（Color, Square, Move, Bitboard, Hand, ...）
├── board     - 盤面管理と合法手生成
│   ├── Position      - 盤面状態の管理
│   ├── movegen       - 合法手生成
│   ├── attack_tables - 利きテーブル
│   └── ...
├── records   - 棋譜フォーマット（KIF, CSA, JKF, SFEN, Pack, ...）
├── book      - 定跡管理（MemoryBook, StaticBook）
└── mate      - 詰み判定（1手詰め、3手詰め）
```

## クイックスタート

### 盤面操作

```rust
use rshogi::board::{self, Position};
use rshogi::types::Move;

// 初期化（プログラム起動時に1回）
board::init();

// 平手初期局面
let mut pos = board::hirate_position();

// SFEN から局面を構築
let pos = board::position_from_sfen(
    "lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL b - 1"
).unwrap();

// 指し手の適用
let m = Move::from_usi("7g7f", &pos).unwrap();
pos.do_move(m);

// 指し手の取り消し
pos.undo_move(m);

// SFEN 出力
println!("{}", pos.sfen(None));
```

### 合法手生成

```rust
use rshogi::board::{self, Position, MoveList};
use rshogi::movegen::{Legal, generate_moves};

board::init();
let pos = board::hirate_position();

// 合法手を生成
let mut moves = MoveList::new();
generate_moves::<Legal>(&pos, &mut moves);

for m in moves.iter() {
    println!("{}", m.to_usi());
}

// 合法手の数
println!("合法手数: {}", moves.len());
```

### 棋譜の読み込み

```rust
use rshogi::records::formats::kif;

let kif_text = r#"
手合割：平手
手数----指手---------消費時間--
   1 ７六歩(77)
   2 ３四歩(33)
"#;

let record = kif::parse_kif_str(kif_text).unwrap();
println!("手数: {}", record.main_line().len());
```

### 定跡の利用

```rust
use rshogi::board::{self, Position};
use rshogi::book::{Book, MemoryBook, BookBuilder, book_key_from_position};

board::init();
let pos = board::hirate_position();

// 定跡を構築（GameRecord から）
let mut builder = BookBuilder::default();
// builder.add_record(&record);
let book = builder.build();

// 定跡を検索
let key = book_key_from_position(&pos);
if let Some(entries) = book.lookup(&key) {
    for entry in entries {
        println!("{}: {}", entry.mov.to_usi(), entry.count);
    }
}
```

## モジュール詳細

### `types` - 基本型

将棋で使用する基本的な型を定義します。

| 型 | 説明 |
|---|---|
| `Color` | 手番（先手 `BLACK` / 後手 `WHITE`） |
| `Square` | マス（0-80、9x9 盤面） |
| `File` | 筋（1-9） |
| `Rank` | 段（一-九） |
| `PieceType` | 駒種（歩、香、桂、銀、金、角、飛、玉、と、... ） |
| `Piece` | 駒（駒種 + 手番） |
| `Hand` | 持ち駒（各駒種の枚数をビットパック） |
| `Move` | 32bit 指し手（移動元・移動先・成り・駒打ちなど） |
| `Move16` | 16bit 指し手（コンパクト版） |
| `Bitboard` | 81bit ビットボード |
| `GameResult` | 対局結果（勝敗、千日手、入玉宣言など） |

### `board` - 盤面管理

`Position` 構造体で盤面状態を管理します。

**主要メソッド:**

| メソッド | 説明 |
|---|---|
| `do_move(m)` | 指し手を適用 |
| `undo_move(m)` | 指し手を取り消し |
| `is_legal(m)` | 合法手か判定 |
| `checkers()` | 王手している駒のビットボード |
| `in_check()` | 王手されているか |
| `is_mated()` | 詰んでいるか |
| `sfen(ply)` | SFEN 文字列を生成 |
| `key()` | Zobrist ハッシュキー |

### `board::movegen` - 合法手生成

ジェネリクスによる型安全な手生成 API を提供します。

```rust
use rshogi::movegen::{generate_moves, Legal, Captures, Evasions};

// 全合法手
generate_moves::<Legal>(&pos, &mut moves);

// 駒を取る手のみ
generate_moves::<Captures>(&pos, &mut moves);

// 王手回避手（王手されている場合）
generate_moves::<Evasions>(&pos, &mut moves);
```

**手生成タイプ:**

| タイプ | 説明 |
|---|---|
| `Legal` | 全合法手 |
| `Captures` | 駒を取る手 |
| `Quiets` | 駒を取らない手 |
| `Evasions` | 王手回避手 |
| `Checks` | 王手をかける手 |
| `Recaptures` | 取り返し手 |

### `records` - 棋譜フォーマット

複数の棋譜フォーマットの読み書きをサポートします。

| フォーマット | パース | 出力 |
|---|:---:|:---:|
| KIF | ✅ | ✅ |
| KI2 | ✅ | ✅ |
| CSA | ✅ | ✅ |
| JKF | ❌ | ✅ |
| SFEN | ✅ | ✅ |
| Pack | ✅ | ✅ |

### `book` - 定跡

Zobrist ハッシュによる高速な定跡検索を提供します。

- `MemoryBook`: メモリ内で定跡を管理
- `StaticBook`: 静的にコンパイルされた定跡
- `BookBuilder`: `GameRecord` から定跡を構築

### `mate` - 詰み判定

高速な詰み判定ルーチンを提供します。

- `solve_mate_in_one()`: 1手詰め判定
- `solve_mate_in_three()`: 3手詰め判定

## 互換性

### YaneuraOu 互換

- 内部のビットボード表現、Zobrist ハッシュ、手のエンコーディングは YaneuraOu と互換
- `Move16` は YaneuraOu の `Move16` と同一のビットレイアウト
- Perft 結果が YaneuraOu と一致することを検証済み

### cshogi 互換

- Python バインディング (`rshogi-py`) は cshogi API を意識した設計
- `Board.push_usi()`, `Board.legal_moves()` などの基本 API は cshogi と類似

## ライセンス

MIT License
