はじめに
ReversiをRustでビットボードを使って実装することにより、高速な処理を実現しつつ、PyO3でPythonバインディングを提供することで使いやすいインターフェースを実現しました。
機械学習で効率的にReversiを実行することを目標としています。
インストール
pip install rust-reversi
実装のポイント
ビットボード
64マスのボードを64ビットの整数で表現することで、ビット演算による高速な状態管理を実現しています
struct Board {
player_board: u64,
opponent_board: u64,
turn: Turn,
}
合法手生成
ビット演算を活用して効率的に合法手を生成しています
fn get_legal_moves(&self) -> u64 {
let horizontal_watch = 0x7E_7E_7E_7E_7E_7E_7E_7E & self.opponent_board;
let vertical_watch = 0x00_FF_FF_FF_FF_FF_FF_00 & self.opponent_board;
let all_watch = 0x_00_7E_7E_7E_7E_7E_7E_7E_00 & self.opponent_board;
// ...
}
Pythonインターフェース
PyO3により、Pythonから直感的に操作できます:
from rust_reversi import Board, Turn, Color
board = Board()
legal_moves = board.get_legal_moves_vec()
move = board.get_random_move()
board.do_move(move)
機能一覧
- ボード状態の管理
- 合法手の生成と検証
- ゲームの進行管理
- 駒数の計算
- テスト用のランダム手生成
テスト
Perftテストによって実装の正確性を確認しています
def perft(board: Board, depth: int) -> int:
if depth == 0:
return 1
if board.is_game_over():
return 1
if board.is_pass():
new_board = board.clone()
new_board.do_pass()
return perft(new_board, depth - 1)
count = 0
for mv in board.get_legal_moves_vec():
new_board = board.clone()
new_board.do_move(mv)
count += perft(new_board, depth - 1)
return count
あとがき
山岡忠夫先生のcreversiが最適化されすぎている(SIMD命令)、古い(numpyのバージョンが古い)ということがあり、自分でreversiを実装してみました。
個人的にはReversiは単純すぎず、難しすぎず教師あり学習や強化学習の題材としてとても優れていると思っています。
学習や推論はPythonで行いたいけどPythonは速度が遅くてつらい...というときに使ってみてください。
探索、学習もRustで書けばよいのではないですか?
今後は対戦機能や機械学習によるAIの実装をしてみたいです。
謝辞
本記事の執筆にあたり、Anthropic社のAIアシスタントClaudeには記事の構成、内容の整理、および表現の改善において多大なる支援をいただきました。ここに感謝の意を表します。
参考
- rust_reversi: https://github.com/neodymium6/rust_reveri
- PyPI rust-reversi: https://pypi.org/project/rust-reversi/
- Perftの活用: https://www.egaroucid.nyanyan.dev/ja/technology/explanation/
- creversi: https://github.com/TadaoYamaoka/creversi
- ビットボード: https://qiita.com/sensuikan1973/items/459b3e11d91f3cb37e43