# rshogi-py

Python bindings for the `rshogi` Rust crate.

This package provides the standard build of the `rshogi` Python module.
If you want an AVX2-optimized build, use
[`rshogi-py-avx2`](https://pypi.org/project/rshogi-py-avx2/).

## Development Install

```bash
python -m pip install maturin
maturin develop -m crates/rshogi-py/pyproject.toml
```

## AVX2 Build

`rshogi-py-avx2` is an AVX2-enabled build of the same Python module.

```bash
python -m pip install rshogi-py-avx2
```

## Notes

- `rshogi-py` and `rshogi-py-avx2` are mutually exclusive; install only one.
- `rshogi-py` is the safest default for broad compatibility.
- policy 学習向けの move label 変換は `rshogi.policy` から利用できます。

## Policy Labels

```python
from rshogi.core import Move
from rshogi.policy import compact_move_label, move_label
from rshogi.types import Color

mv = Move.from_usi("7g7f")

label = move_label(mv, Color.BLACK)
compact = compact_move_label(mv, Color.BLACK)

print(label)    # 2187 クラス
print(compact)  # 1496 クラス or None
```

## Quick Example

```python
from rshogi.core import Board

board = Board()
board.apply_usi("7g7f")
print(board.to_sfen())
```

raw-state を Python から直接編集することもできます。

```python
from rshogi.core import Board
from rshogi.types import Color, Piece, PieceType, Square

board = Board()
state = board.to_position_state()
state.set_piece(Square.from_usi("7g"), Piece(0))
state.set_piece(Square.from_usi("7f"), Piece.from_color_type(Color.BLACK, PieceType.PAWN))
state.ply = 42

board.set_position_state(state)
report = board.validate_all()
print(board.to_sfen())
print(report.is_valid())
```

USI の `position` 文字列を直接扱うこともできます。

```python
from rshogi.core import Board, normalize_usi_position, parse_usi_position

board = Board()
board.set_usi_position("position startpos moves 7g7f 3c3d")

board2 = parse_usi_position("startpos moves 7g7f")
print(board2.to_sfen())

print(normalize_usi_position("position startpos"))  # "startpos"
```

## cshogi / Apery Compatibility

`rshogi` can interoperate with `cshogi` / Apery move and training-data formats.

```python
from rshogi.core import Board, Move

board = Board()
move = Move.from_usi("7g7f")

apery = move.to_apery()
apery32 = board.apery_move32_from_move(move)
hcpe = board.to_hcpe(best_move=apery, score=120, game_result="BLACK_WIN")

print(int(apery))
print(apery32.to_usi())
print(len(hcpe))  # 38
```

## Structured Imports

`rshogi` provides structured imports through submodules for better organization:

```python
# Types and constants
from rshogi.types import Color, PieceType, Square
from rshogi.core import Move, Move32, AperyMove, AperyMove32

# Board
from rshogi.core import Board, PositionState, ValidationIssue, ValidationReport

# Records
from rshogi.record import GameRecord, GameRecordMetadata, GameResult

# Record conversion
record = GameRecord.from_kif_str(kif_text)
kif_text = record.to_kif()

# Record file I/O
record = GameRecord.from_kif_file("example.kif")
record.write_kif("example_out.kif")

# NumPy dtypes
from rshogi.numpy import (
    PackedSfen,
    PackedSfenValue,
    HuffmanCodedPos,
    HuffmanCodedPosAndEval,
)

# Policy labels
from rshogi.policy import move_label, compact_move_label
```

Use submodules for all imports:

```python
from rshogi.core import Board
from rshogi.core import Move
from rshogi.record import GameRecord
```

## Record I/O Notes

`GameRecord` の棋譜 I/O は Rust core と同じ互換方針で動作します。

- KIF/KI2 は ShogiHome/tsshogi 系の実務互換と `shogi-validator` 寄りの整形を意識しています。
- 変化手順と終局要約が同居する場合、`to_kif()` / `to_ki2()` は `変化：...` を先に、
  `まで...` を最後に出力します。
- `from_csa_str()` / `from_csa_file()` は `'*comment` と `'comment` の両方をコメントとして受理します。
- `to_csa()` は move comment を `'*comment` として出力し、
  `write_kif()` / `write_ki2()` / `write_csa()` は末尾改行つきで書き出します。
