Skip to content

Repository files navigation

三人麻雀AI学習アプリ

tests License: MIT Python

三人麻雀(萬子なし・北なし)の牌効率を学ぶためのプロジェクトです。計算部分は外部依存なしのPythonライブラリ sanma として切り出してあり、それを使うWebアプリ(FastAPI + React)が同梱されています。

構成

ディレクトリ 内容
sanma/ 牌効率計算ライブラリ。シャンテン数・受け入れ枚数・打牌評価。外部依存なし
backend/ FastAPIのゲームAPI。sanma を呼ぶだけの薄い層
frontend/ React UI
tests/ 60件のテスト

ライブラリとして使う

pip install sanma
import sanma

hand = sanma.parse("123456789p123s5s")

sanma.shanten(hand)     # 0(和了形は -1)
sanma.ukeire(hand)      # {'5s': 3} シャンテンを進める牌と残り枚数

sanma.best_discard(sanma.parse("123456789p123s5s7z"))   # '7z'

詳しくは sanma/README.md を参照してください。

なぜ三人麻雀専用のライブラリが要るか

三人麻雀は萬子と北を使わないため、牌種は24種・96枚です(4人麻雀は34種・136枚)。ここから2つの違いが出ます。

受け入れ枚数は山の構成に依存するので、4人麻雀向けの数字はそのまま使えません。また么九牌が10種しかないため、13種必要な国士無双は成立しません。

一方でシャンテン数そのものは、どちらの麻雀でも手牌だけで決まる同じ関数です。このライブラリは MahjongRepository/mahjong(天鳳の牌譜2,600万手で検証されている)との差分テストで検証しています。国士を無効にした条件で、ランダム手牌8,000件に対し不一致0件でした。

つまり、既存ライブラリで足りない部分は受け入れ計算と打牌評価であり、そこがこのライブラリの担当範囲です。

実測値

Python 3.13 / M1 Mac での計測です。

項目
テスト 60件パス
既存ライブラリとの差分照合 8,000手牌で不一致0件(国士無効時)
分析APIのレイテンシ 中央値 2.9ms / p95 24.9ms
100局の自動プレイ エラー0件・和了35局・流局65局(うちテンパイ36局)

シャンテン計算は筒子・索子・字牌をスート単位で分解してメモ化しています。手牌全体をキーにするよりキャッシュ命中率が高く、同一局面を繰り返し評価する受け入れ計算で効きます。

アプリを動かす

# バックエンド
cd backend
pip install -r requirements.txt
uvicorn server:app --reload --port 8001

# フロントエンド(別ターミナル)
cd frontend
yarn install
yarn start

フロントエンドは http://localhost:3000 、APIは http://localhost:8001 で起動します。詳細は SETUP_GUIDE.md を参照してください。

テスト

pip install pytest mahjong
python -m pytest tests/ -v

mahjong は差分テスト専用の依存です。入っていない場合、差分テストだけスキップされます。ライブラリ本体は外部依存なしで動きます。

API

メソッド パス 内容
GET /api/health ヘルスチェック
POST /api/game/start 新規対局を開始(自分は14枚配牌)
GET /api/game/{game_id}/state 対局状態を取得
POST /api/game/{game_id}/analyze 手牌を分析
POST /api/game/{game_id}/discard 打牌する
GET /api/learning/tips 学習用のヒントを取得

山が尽きると phasefinished になり、以降の打牌は 400 を返します。

分析レスポンスの例:

{
  "shanten": 3,
  "recommended_discard": "2z",
  "efficiency_tiles": {"1p": 4, "4p": 4, "3s": 4},
  "tile_analysis": {
    "2z": {"shanten_after": 3, "ukeire_count": 43, "efficiency": 0.921, "safety": 0.85, "score": 0.899}
  }
}

実装範囲

実装済み: シャンテン計算(通常手・七対子)、受け入れ枚数、打牌評価、筋による安全度。

未実装: 鳴き(ポン・カン)、役と点数の計算、フリテン判定。安全度は牌の危険度を学ぶための目安であり、放銃率の推定ではありません。

ライセンス

MIT License

About

三人麻雀(サンマ)の牌効率トレーナー。シャンテン数・受け入れ枚数・打牌の安全度を計算する外部依存なしのPythonエンジン + React UI

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages