ハトネコエ Web がくしゅうちょう

プログラミングやサーバー・Web制作、チームマネジメントなど得た技術のまとめ

Windows版 ChatGPT アプリ(Codex)の Computer Use とブラウザ拡張が使えない問題の解消

Windows版の ChatGPT アプリ(Codex)で Computer Use が使えないし、
Edge、Chrome、Brave のブラウザ拡張も使えないしで困っていたけど、直せたのでメモ。

起きていたこと

ウェブブラウザの拡張機能「ChatGPT」が動かない

ChatGPTアプリがすでにインストール済みなのに、
Brave や Chrome の拡張機能パネルでは以下の表示。
「ChatGPTアプリをインストールしてね〜」と言われ続ける。

Edge では以下のように「Native transport disconnected」と表示されているので、
なんかエラーっぽいってことがわかりやすい。

Computer Use が使えない

Computer Use(日本語では「コンピュータの使用」) の設定を見るとこんな感じ。

上手く設定できている人の画面では
以下のように「任意のアプリ」っていう表示が出るはずなんだけど、それがない状態。

バンドルプラグインが配置されていないっぽい

上に関連する話として、設定の「ブラウザ」を見に行くと

marketplace file `C:\Users\xxxx\.codex\.tmp\bundled-marketplaces\openai-bundled\.agents\plugins\marketplace.json` does not exist

というエラーが出ている。

実際、 C:\Users\xxxx\.codex\.tmp\bundled-marketplaces フォルダを見にいくとファイルが何も入っていない。

plugins\marketplace.json がないから Computer Use のプラグインも機能してないのかなぁ……? の気持ち。

解決方法

ChatGPT に聞いてみても、
「うーん、正直わからないですねー。 https://github.com/openai/codex/issues/25220 に同じ報告は上がっているから、
そのうちバージョンアップで修正されるんじゃない?」的な返事だったのだけれど、
「5月からある issue なら、誰かしら解決方法を見つけた人いるんじゃない?」と聞いてみたら見つけてくれました。

issue 内の hongbenji さんのコメントで、
Dドライブへのインストールだと同じエラーが出たけど、
Cドライブへの再インストールによって解消した経緯を書いてくれていました。

そして私のPCも、Microsoft Store アプリ経由のインストール先は
OSの入っているCドライブでなくDドライブだったので、それが怪しそうだなと試してみることに。

解決の手順

  1. Windows の「設定 → システム → ストレージ → ストレージの詳細設定 → 新しいコンテンツの保存先」に進んでいく
  2. 「新しいアプリの保存先」を D: から C: に変更して「適用」ボタンを押す
  3. ChatGPT アプリをアンインストール
  4. C:\Users\<ユーザー名>\.codex のファイルはこのあと消えてしまうので、コピーしてバックアップをとっておくと安心
  5. Microsoft Store から ChatGPT アプリを再インストール

これで解決!!

ChatGPT アプリ以外を D ドライブに保存されるままにしておきたい場合は、
2 の逆の手順、『「新しいアプリの保存先」を C: から D: に変更して「適用」ボタンを押す』をすればOK。

原因についてChatGPTに尋ねたところ、明確な理由はわからないけれど、
Store 版アプリに同梱された保護・暗号化属性のあるファイルのコピー処理の部分で失敗しているっぽいとのことでした。

いや~、直ってよかったです!

OpenCode で、AIコーディングエージェントを無料で試してみる

Codex (コーデックス)や Claude Code (クロードコード)といった、
AIでプログラミングがおこなえるツールを使うには、有料プランの契約が必要です。

「まずは無料でコーディングエージェントを試したい!」
そういった人には OpenCode (オープンコード)という選択肢が考えられます。

ここでは、OpenCode のインストール方法や、どのように使うかの基礎的な部分を解説します。
なお、ハッカソン参加者向けの紹介記事として書いたため、参加者に多かった Windows でのスクリーンショットを中心としています。

0: 注意!

OpenCode の一部のモデルが無料で使えるのは、
そのモデルを作っている人たちが、多くの人から入力データを集めて、モデルのトレーニング(学習)をしたいからです。

OpenCode を無料で使う場合は、
プロジェクトとして指定するフォルダ(あとで説明します)の中に
個人情報や会社のデータなど、大事なものが入っていないか
充分に気を付けてください。

1: ダウンロード&インストール

PowerShell など、ターミナルの中で動かす方法もありますが、
デスクトップ版がプログラミングに慣れていない人にとってもわかりやすいと思うので、そちらを説明します。

OpenCode のダウンロードページから、デスクトップ版をダウンロードしてください。

Windows の人は「Windows 向けダウンロード」、Mac の人は「macOS 向けダウンロード」と表示されていると思います

ダウンロードが終わったら、そのファイルを実行してインストールしてください。

Windows の場合

インストール中は以下のような画面が現れますが、「インストールが終了しました」のような画面は表示されずに終了するので注意してください。

インストールが終わると、OpenCode が自動で立ち上がり、以下のようなウィンドウが表示されます。

もしも自動で起動しない場合は、デスクトップに OpenCode アプリへのショートカットが現れていると思いますので、
アイコンをダブルクリックして OpenCode を開いてください。

Mac の場合

Mac でのインストールに慣れている人であればいつも通りの流れです。
ダウンロードしたファイルを開くと、以下のような画面が現れます。

OpenCode.app を Applications フォルダにドラッグ&ドロップしてください。

しばらく待つとインストールが完了するので、
Applications フォルダをダブルクリックし、
アプリケーション一覧の中から「OpenCode」を選び起動してください。

2: モデルの選択

無料で提供されるモデルは、時期によってたびたび変わります。

「0: 注意!」の項目で書いたように、
モデルを作っている各社は、あくまでモデルのトレーニングのために無料で提供しているからです。
充分なトレーニングが済んだと判断されると、各社は無料提供をやめてしまいます。

では、モデルを選択してみましょう。
メッセージボックスの左下、以下の画像では「Big Pickle」と表示されている箇所をクリックしてください。

2026年9月5日現在、無料で提供されているモデルは以下の通りです。

今回は、上から2番目の「Muse Spark 1.3」を選んでみます。
Meta社の作っているモデルです。

なお、1番上の「Nemotron 3 Ultra」は応答が返ってくるまでの時間が長すぎました。
無料だから、ある程度は時間がかかることも仕方ないのですが、長すぎると作業が進まないので、
スピードとAIの頭の良さを鑑みて、満足いかない場合には違うモデルを選択してみるといいと思います。

「Muse Spark 1.3」が無料公開されている間は、それを使うといいと思います。
応答速度は遅すぎないですし、性能は Claude Opus 5 に匹敵するという情報がありますので。

3: プロジェクトの選択

次に、どこのフォルダのファイルを読んだり編集するかを設定します。

メッセージボックスの下、以下の画像では「Default Project」と表示されている箇所をクリックしてください。

そうすると以下の選択肢が現れますので、「プロジェクトを追加」を選択してください。

「プロジェクトを追加」をクリック

フォルダーを選択する画面が出てきますので、
読んだり編集したいソースコードが入っているフォルダーを選択し、「フォルダーの選択」ボタンをクリックしてください。

最初の「0: 注意!」の項で書いたように、
ここで指定するフォルダーの中に、モデルのトレーニングに使用されては困る情報(特に個人情報や会社の情報)を置かないようにしましょう!

また、上の画像の例における「Programs」フォルダーのような、いろんなプロジェクトが入っている親フォルダーを指定するのではなく、
1つのプロジェクトだけが入ったフォルダーを指定するようにしましょう。

4: AIに質問してみる

これで準備が整いました! AIに質問してみましょう!

試しに「このプロジェクトの中身を説明して!」と質問してみましょう。

以下のように、ファイルの中身を読んで説明してくれました。

ここからさらに質問していってもいいですし、左上のプラスボタンから、新しいタブを開いて質問することができます。

AIは、情報が溜まりすぎると、どうしていいかわからなくなり変な行動をとることがあるので、
キリのいいタイミングで新しいタブを開き、AIにまっさらな気持ちになってもらうことも大切です。

また、少し上級者向けですが、複数のタブを開くことで、
片方のタブで質問をしながら、もう片方のタブでは実装をしてもらう、などの使い分けも可能です。

5: AIに実装してもらうときのポイント!

実装してほしいことはいっぱいあると思います!
でも、適切に指示してくれないとAIにはわからないこともいっぱいあります。

AIでコーディングをするときのポイントについて記します。

5-1: 実装してもらうよりも先に相談をしよう!

キーワードは「~したいんだけど、どうすればいいか教えて」です!

逆に、「~したい」と最初から言わないよう注意してください。
「~したい」と言われるとAIは急に実装を始めちゃうんですけど、
要望を理解しきれずに混乱して、実装に失敗してしまうことがあります。

「~したいんだけど、どうすればいいか教えて」と聞くことで、
何を使えばいいかや、どういう順番で実装すればいいかなどのアドバイスをくれます。

実際にやってみたのが、以下のスクリーンショットです。
やることの全体像を示してくれるので、AIに急に任せるよりも、自分たちの頭も整理されていきます。

最後に『Supabase前提で MainPage.xaml にランキング表示 + 送信コードまで実装しましょうか?』と聞かれているので
「はい、お願いします」と言ってしまいそうになりますが、AIのオススメに対してグッとこらえるのも大事なポイントです!

AIは「選択肢」として Supabase を推奨してきましたが、どうしてその選択なのかをもっと理解する必要があります。

例えば

どうして Supabase が推奨なの? メリット・デメリットを教えて。Supabase, Firebase, PlayFab 以外の選択肢は本当にないの?

などと聞けると、AIを使いこなせている感が出てきます。
AIの推奨する選択肢について、どうしてなのか? 他の選択肢は本当にないのか? を聞く習慣を身につけましょう!

AIはどれだけ質問しても怒らないので、わからない言葉が出てきたら、わかるまでトコトン質問してください!

理解したら、AIの示してくれた全体像を参考に、少しずつ実装していきましょう。

5-2: こまめに git commit をおこなおう!

git は、例えるならゲームのセーブファイルを分けて保存してくれるようなツールです。

git commit -m "データベースにスコアを保存する機能まで実装" のようなコマンドは、
名前をつけてセーブファイルを作っているコマンドと言えます。

どうしてセーブファイルを分けて保存すると便利かというと、
「うわ、やばい、詰んだ!(どうしようもなくなった!)」というときに、そのセーブファイルに戻れるからです。

git も同じことができます。

「AIにコーディングを任せたら変になった! 戻したい!」というときに、
git reset コマンドで、特定のセーブファイル(=コミット)まで戻れるようリセットすることができます。

機能の実装が終わって、動作することが確認できたタイミングで、
必ずコミット(git commit)をする
ようにしましょう。

ターミナルで git commit をしてもいいですし、
OpenCode 内で「git commit して」と言っても代わりにやってくれます。

git は使い方が難しいところもあるので、git のわからないこともぜひAIに聞いてみてください!

5-3: チームメンバーへの指示のつもりでAIに伝えよう

AIへの悪い指示の例は、「データベースに保存して」や「エラーを直して」という短すぎるものです。
AIのほうから「なにを?」と聞いてくれることもありますが、
会話が長くなってくると、AIのほうで推測して間違った解釈で進めてしまうことがあります。

AIにメッセージを送信する前に、
「チームメンバーに実装を頼むとして、この指示で伝わるかな?」と一度文章を読み返してみてください。

「データベースに保存して」ではなく、
「ランキングを表示する画面で使いたいから、スコアをデータベースに保存する実装をしてもらえる?」に改善されるかもしれません。

「エラーを直して」ではなく、
「http://localhost:3000/hello のページを開くと Invalid token ってエラーが出るんだけど、なぜか調べてくれる?」に改善されるかもしれません。
(余談ですが、エラーやバグは、最初から直してとお願いするよりも、一度調査をお願いするほうが解決の可能性が高まる感覚があります)

少し文章を書くことに時間をかけてでも、
「チームメンバーにこの指示で伝わるかな?」の気持ちで読み直してからAIに送信することを大切にしてください。

6: おわりに

OpenCode にコードの内容を説明してもらってプログラミングへの理解を深めることや、
実装やバグ修正をお願いすることで、プロダクトの完成を目指していってください!

OpenCode で物足りなくなったら、
課金プランである OpenCode Go や、Codex、Claude Code などの使用も検討していってください。

それでは、引き続きファイトです!!🔥

Claude Fable 5 を使って麻雀ウェブアプリを作ってみたのでその記録メモ

指示

4人対戦の麻雀ができるWebアプリケーションを作って。東風戦と半荘戦に対応。
プレイヤーは1人で、他の3人はCPU。
CPUのキャラ設定は、「振り込みがちな初心者」「守りが堅い中級者」「打点高めを狙う中級者」「バランスの取れた中級者」「プロレベルの上級者」から選べるようにしたいです。

ユーザーへのヒアリング

Plan mode で指示したので確認があった。

ルールをユーザーが設定画面から選べるようにする方針もアリかなーと思ったけど、
実装難易度上げて完成しないのもちょっとヤダかなー、と思って、素直に全て推奨項目を選択した。

プランエージェントへの指示

プラン作成にあたって Claude Code は以下のような指示をプランエージェントに(?)投げていた

あなたはソフトウェアアーキテクトです。以下の要件で4人対戦リーチ麻雀Webアプリの詳細な実装計画を設計してください。

## 要件
- 場所: ~/Programs/fable-5-try/mahjong-app(空ディレクトリ、グリーンフィールド)
- 技術スタック: Vite + React + TypeScript、全てクライアントサイド完結(サーバー不要)
- 4人対戦: 人間1人 + CPU 3人
- 東風戦と半荘戦を選択可能
- CPUキャラ設定(ゲーム開始時に各CPUへ割当可能):
  1. 振り込みがちな初心者
  2. 守りが堅い中級者
  3. 打点高めを狙う中級者
  4. バランスの取れた中級者
  5. プロレベルの上級者
- ルール: 標準的なリーチ麻雀フル実装
  - 喰いタンあり・後付けあり・赤ドラ3枚(5萬5筒5索 各1枚)・裏ドラ・カン裏あり
  - 鳴き(ポン・チー・カン[暗槓/明槓/加槓])、リーチ、フリテン(同巡フリテン・リーチ後フリテン含む)
  - 流局: 通常流局(ノーテン罰符)、九種九牌、四風連打、四家立直、四槓散了、流し満貫
  - 連荘、本場、供託、トビ終了、オーラス和了止めは任意
  - 役: 全標準役(1翻〜役満、ダブル役満は任意)、符計算、点数計算(切り上げなし標準)

## 設計してほしいこと
1. **ディレクトリ構成とモジュール分割**: ゲームエンジン(純粋ロジック、React非依存)とUI層の分離方針
2. **コアデータ構造**: 牌の表現(数値エンコーディング推奨か)、手牌・河・副露の表現、ゲーム状態マシン(局の進行: 配牌→ツモ→打牌→鳴き判定→...→和了/流局)
3. **アルゴリズム設計**:
   - シャンテン数計算(標準形・七対子・国士無双)の実装方針
   - 和了判定・面子分解・役判定・符計算・点数計算の設計
   - 待ち牌(テンパイ時の和了牌)列挙
4. **CPU AI設計**: 5キャラの性格をどうパラメータ化するか
   - 共通基盤: 牌効率(シャンテン数を下げる打牌選択)、安全牌判定(現物・スジ・壁・ワンチャンス)
   - キャラ差分: 押し引き閾値、ベタオリ判定、鳴き頻度、打点志向(ドラ・役狙い)、リーチ判断などのパラメータ表を具体的に提案
   - 初心者キャラは「危険牌を平気で切る」「テンパイ即リー」など自然な弱さの表現方法
5. **ゲームフロー制御**: 人間の入力待ち(打牌・鳴き選択・リーチ宣言・和了宣言)とCPUの自動行動を統合する設計(async/await ベースか、イベントキューか、ステートマシンか)
6. **UI設計**: 麻雀卓レイアウト(自分の手牌は下、対面・左右のCPU)、牌の描画方法(Unicode麻雀牌文字 vs CSS/SVG自作)、アクションボタン(ポン/チー/カン/ロン/ツモ/リーチ/パス)、点数表示・結果画面
7. **実装フェーズ分割**: 段階的に動くものを作る順序(例: エンジン→AI→UI)とマイルストーン
8. **テスト方針**: シャンテン計算・点数計算など複雑なロジックのユニットテスト(Vitest)

既存ライブラリ(riichi 等の npm パッケージ)を使うか自作するかの判断も含めてください。自作推奨の場合はその理由を。教育目的というよりは「ちゃんと動く完成品」が目標です。

返答は日本語で、具体的なファイルパス・型定義例・パラメータ表を含む詳細な実装計画を返してください。

ライブラリの吟味

プランを作るに当たってライブラリを使用するか吟味する記録が残っていたのがおもしろかった。

ディレクトリは空(完全グリーンフィールド)であることを確認しました。以下、実装計画の全体設計です。

## 4人対戦リーチ麻雀 Webアプリ 実装計画

### 0. ライブラリ自作 vs 既存パッケージの判断 → 全面自作を推奨

| 候補 | 評価 |
|------|------|
| riichi (npm) | 文字列入力から役・点数を計算できるが、シャンテン計算・待ち列挙・フリテン・ゲーム進行は対象外。型定義が貧弱でルールオプションの細かい制御(カン裏・流し満貫・赤の枚数指定)に難あり。メンテも停滞気味 |
| syanten / shanten-number 系 | シャンテン単機能。AI が必要とする「打牌ごとの受け入れ枚数」APIがなく、結局ラップ層を自作することになる |

自作推奨の理由(完成品志向の観点で):

1. AIがエンジン内部表現を直接食う必要がある。CPU の打牌選択は「14枚から1枚切った後のシャンテン数と受け入れ枚数」を毎ターン数十回計算する。外部ライブラリの文字列I/Fを挟むと変換コストとバグ面が増える。34種カウント配列で統一すれば全アルゴリズムが同じ表現を共有できる。
2. 点数計算と面子分解は役判定・符計算と密結合(高点法のため全分解を列挙して最大を取る)。ここを外部に出すと「平和+ツモ20符」「七対子25符」などの境界でルール差異の調停が発生する。
3. アルゴリズム自体は枯れており(シャンテン数のバックトラック法、標準形分解)、テストベクタで品質担保できる。フル実装でもコア部は合計 2,500 行程度。

依存は Vite + React + TypeScript + Vitest + Zustand の最小構成。牌画像も外部アセットに依存せず自前SVGにする(後述)。

riichi って npm が更新されていないのは調べに行ったのかな? と思ったけど、
検索してライブラリのページを見に行ったら最終更新が5年前だったので、検索せずに答え出した気がする。
(仮にここ数日以内に更新されていた場合には、更新履歴を見に行かなかったことで少し誤りに近い判断となっているのかもしれない)

作成されたプラン

# 4人対戦リーチ麻雀 Webアプリ 実装計画

## Context

`~/Programs/fable-5-try/mahjong-app`(空ディレクトリ)に、人間1人 + CPU 3人で遊べるリーチ麻雀Webアプリをゼロから作る。

- **モード**: 東風戦 / 半荘戦を選択可能
- **CPUキャラ**: 「振り込みがちな初心者」「守りが堅い中級者」「打点高めを狙う中級者」「バランスの取れた中級者」「プロレベルの上級者」の5種から各CPUに割当
- **ルール**: 標準ルールフル実装 — 喰いタン・後付けあり、赤ドラ3枚、裏ドラ・カン裏、鳴き(ポン/チー/カン全種)、リーチ、フリテン(同巡・リーチ後含む)、途中流局(九種九牌・四風連打・四家立直・四槓散了)、流し満貫、連荘・本場・供託・トビ終了、全標準役 + 符計算 + 点数計算(切り上げ満貫なし)
- **技術**: Vite + React + TypeScript + Zustand + Vitest。全てクライアントサイド完結。**麻雀ロジックは全面自作**(外部ライブラリはAI用の受け入れ計算APIがなく、点数計算と面子分解が密結合のため)

## アーキテクチャ方針

- `src/core/`(ゲームエンジン)と `src/ai/`(CPU)は **React非依存の純粋TypeScript**
- エンジンは純Reducer: `applyAction(state, action) → {state, events}` + `legalActions(state) → Map<Seat, Action[]>`
- 進行の「待ち」はエンジン外の非同期ドライバ(controller)が担当。人間入力はPromise、CPUは思考遅延つき同期計算(Web Worker不要)
- 依存方向: `ui → app → ai → core`(逆流禁止)
- シード可能PRNGでリプレイ・バグ再現可能に

## ディレクトリ構成

```
src/
├── core/
│   ├── tiles.ts              # 牌エンコーディング
│   ├── wall.ts               # 山・王牌・ドラ表示牌
│   ├── random.ts             # シード可能PRNG
│   ├── shanten/
│   │   ├── standard.ts       # 標準形(バックトラック+色別メモ化)★最難関
│   │   ├── chiitoi.ts / kokushi.ts
│   │   ├── index.ts          # 3形式min + API
│   │   └── ukeire.ts         # 打牌別受け入れ枚数(AI用)
│   ├── agari/
│   │   ├── decompose.ts      # 和了形の全面子分解列挙
│   │   ├── waits.ts          # 待ち牌列挙
│   │   ├── yaku.ts           # 全役判定 ★
│   │   ├── fu.ts / score.ts  # 符・点数計算
│   └── engine/
│       ├── types.ts          # GameState / RoundState / PlayerState / Phase
│       ├── actions.ts        # Action / GameEvent
│       ├── legal.ts          # 合法アクション列挙
│       ├── reducer.ts        # 状態遷移本体(鳴き調停・フリテン・流局)★
│       ├── furiten.ts / draws.ts
│       └── match.ts          # 連荘・本場・供託・トビ・東風/半荘
├── ai/
│   ├── types.ts / personalities.ts   # 5キャラパラメータ表
│   ├── efficiency.ts         # 牌効率
│   ├── danger.ts             # 危険度推定(現物・スジ・壁・ワンチャンス)
│   ├── value.ts              # 打点見積もり
│   └── decide.ts             # 押し引き統合 ★
├── app/
│   ├── store.ts              # Zustand: スナップショット + UIプロンプト
│   ├── controller.ts         # ゲームループ駆動 ★
│   └── settings.ts
├── ui/
│   ├── TableView.tsx
│   ├── components/           # Tile(自前SVG), Hand, River, MeldArea,
│   │                         # ActionBar, CenterInfo, ResultModal,
│   │                         # FinalResultModal, SetupScreen
│   └── tiles/glyphs.ts       # 牌SVGデータ
└── main.tsx
```

## コアデータ構造

**牌は二層エンコーディング**:
- アルゴリズム用: `TileKind` 0..33(34種)+ `Counts = Uint8Array(34)`
- 状態管理用: `TileId` 0..135(物理牌。`kind = id >> 2`、赤5は各色5の0番個体)

**Phase(局の状態マシン)**:
```
dealing → draw(actor) → [九種九牌|ツモ和了|カン→(槍槓窓)→新ドラ→rinshanDraw|打牌/リーチ]
  → discarded(クレーム窓) → [ロン(ダブロン両者成立)|明槓|ポン/チー|全員パス]
  → [四風連打/四家立直/四槓散了チェック] → [山空→荒牌流局(ノーテン罰符/流し満貫)|次家draw]
  → roundEnd → (match.tsで連荘/次局/gameEnd)
```

同時クレームは全席の応答を集めてから ロン > ポン/カン > チー の優先度で調停。

**PlayerState** は手牌(TileId[]ソート保持)・ツモ牌・副露・河(ツモ切り/リーチ/鳴かれフラグ付き)・リーチ状態(一発含む)・フリテン(permanent/temporary)・流し満貫資格を持つ。

## 主要アルゴリズム

- **シャンテン**: min(標準形, 七対子, 国士)。標準形は再帰バックトラック + 色ごと9要素部分問題のメモ化。テーブル事前計算は不要(メモヒット時 <0.05ms)
- **受け入れ**: 「各牌を足す/引いてシャンテン再計算」の素朴実装で十分高速
- **和了パイプライン**: WinContext → 全面子分解列挙 → 分解ごとに役判定 → 符計算 → **高点法で最大採用** → 点数・支払い分配。待ちの取り方(両面/嵌張/単騎...)も分解ごとに列挙(平和・符に影響)
- **符**: 副底20 + 待ち + 雀頭 + 面子符 + 門前ロン10/ツモ2、平和ツモ20符・七対子25符・喰い平和30符の特例。**切り上げ満貫なし**(7700/11600そのまま)
- **ダブル役満**(国士13面・四暗刻単騎・大四喜・純正九蓮): デフォルトON

## CPU AI 設計

全キャラ共通パイプライン: 状況分析 → 押し引き判定(PUSH/FOLD/MIXED)→ 打牌選択(受け入れ最大 or 危険度最小)→ 鳴き/リーチ/和了判断 → ミス注入。**性格はパラメータのみで差別化**。

| パラメータ | 初心者 | 守備型中級 | 打点型中級 | バランス中級 | 上級 |
|---|---|---|---|---|---|
| safetyAwareness | 0.05 | 0.95 | 0.45 | 0.70 | 0.95 |
| foldShanten | 99(降りない) | 1 | 2 | 2 | 動的EV |
| pushDanger | 1.0 | 0.10 | 0.45 | 0.30 | 0.35 |
| callEagerness | 0.8(鳴きすぎ) | 0.25 | 0.55 | 0.45 | 0.50 |
| yakuAwareness | 0.2(役無し鳴き) | 0.9 | 0.85 | 0.9 | 1.0 |
| valueOrientation | 0.1 | 0.3 | 0.85 | 0.5 | 0.6 |
| riichiStyle | always(即リー) | standard | standard | standard | damaten-aware(跳満級ダマ) |
| mistakeRate/depth | 0.25 / 3 | 0.05 / 1 | 0.07 / 1 | 0.05 / 1 | 0 |
| readsWalls | ✗ | ✓ | ✗ | ✓ | ✓ |
| considersFuriten読み | ✗ | ✗ | ✗ | ✗ | ✓ |

- 初心者の弱さは「危険牌を選ぶ」のではなく「安全を**見ない**」結果として自然に振り込む設計
- 上級は閾値でなく簡易EV(和了率×打点 − 放銃率×失点期待)+ オーラス着順条件を考慮
- 危険度: 現物0 / 字牌0.05〜0.3 / スジ0.15〜0.3 / 無スジ中張0.6〜0.8、壁×0.4・ワンチャンス×0.6

## UI 設計

- **牌は自前SVG**(Unicode麻雀牌は品質バラバラ・赤5表現不能のため不採用)。萬子=漢数字テキスト、筒子=円パターン生成、索子=竹形状、字牌=テキスト。裏向き・横向き(リーチ宣言牌・鳴き出所)はtransform
- **卓レイアウト**: 自分=下(手牌大きめ・表)、対面=上、左右CPU=縦(河はrotate(±90deg))。中央に局数/本場/供託/残り山/ドラ表示/4人の点数。固定アスペクト比でスケール
- **ActionBar**: 合法アクション時のみ ロン/ツモ/リーチ/ポン/チー/カン/パス を表示。リーチ宣言時は切れる牌のみハイライト。チー複数候補は組を提示して選択。リーチ後はツモ切り自動
- **ResultModal**: 手牌公開・役一覧・符翻・点数移動・裏ドラめくり。流局時はテンパイ者公開とノーテン罰符
- **SetupScreen**: 東風/半荘トグル、CPU 3枠 × キャラ5種ドロップダウン
- 人間に合法クレームが無い鳴き窓は即パス(プロンプトしない)。CPU思考遅延500〜1200msは演出

## 実装フェーズ

| Phase | 内容 | 検証 |
|---|---|---|
| P1 | 牌・シャンテン・分解・待ち | Vitest: ランダム手 vs 素朴全探索リファレンス照合 10,000ケース |
| P2 | 役・符・点数 | 点数表テーブル駆動テスト(全役成立/不成立 + 代表点数60ケース) |
| P3 | 局エンジン(reducer/legal/furiten/draws) | シード固定シナリオテスト(槍槓・嶺上・海底・ダブロン・各流局・フリテン) |
| P4 | match.ts + **ランダム自走1000半荘** | クラッシュ0・不変条件(牌136枚・点数+供託=100,000)assert |
| P5 | 最小UI(卓・打牌のみ) | ブラウザで1局打てる |
| P6 | フルUI(全アクション・結果画面・セットアップ) | 人間が半荘完走 |
| P7 | AI 5キャラ | キャラ自走対戦で上級>中級>初心者の着順序列を統計確認 |
| P8 | 仕上げ(アニメーション・レスポンシブ) | 完成 |

P4の自走テストが品質の要 — UIとAIより先にエンジンを統計的に叩いて稀パスのバグを潰す。

## 検証方法

1. `npm test`(Vitest): シャンテン照合・点数表・シナリオ・自走不変条件テスト全通過
2. `npm run dev` でブラウザ起動 → セットアップ画面でキャラ割当 → 半荘を人間として完走(鳴き・リーチ・カン・和了を実際に行使)
3. AI自走統計で性格差(初心者の放銃率が最高、上級の平均着順が最良)を確認

稀パスのバグを潰す

という変な日本語が誕生していた。

プラン自体は良さそうなのでそのまま auto mode で実装開始させたけれど、はたして完成するのか・・・!!!

実装を観察

平気で30分はかかっていて、「どうなるかな〜」の気持ち。

コンテキストのリミットを少し超えてもがんばってくれている・・・。

npm install は失敗し続けている……。どこかで私が手動でやらないといけなさそう。

claude-fable-5 is temporarily unavailable, so auto mode cannot determine the safety of Bash right now. Wait briefly and then try this action again. If it keeps failing, continue with other tasks that don't require this action and come back to it later. Note: reading files, searching code, and other read-only operations do not require the classifier and can still be used.

最後の方はずっと npm install を繰り返していたけど、
これは無理だとわかったのか、 ScheduleWakeup で再実行を予約していったん止まってくれた。

実装時間は60分くらい。

いったんこの状態で .gitignore だけ加え、 git init して全ファイルを commit。

Fable は git commit も許可されてないっぽい。

動作テスト

ほぼほぼ動いてた! すごい!

60分かかったとはいえ、この量のコードを記述したのすごい。
特に CPU の挙動を書いたのがすごい。そこまで出来るんだ……。

https://github.com/nekonenene/mahjong-app-with-fable-5/commit/3fb166472a11e4c567a48672102aaa82d5c9e4ef

npm コマンドの実行をおこなえないから、
テストやローカルサーバの起動の試行をできないという、
なかなかハードモードの中の実装だったけど、それなのに動くものが作れていたのがすごい。

テストプレイしてみるといくつか問題があって、最初はこんな指示で直してもらった。

いくつか問題点があります。

* 音が鳴らないため進行が少しわかりにくいです
* チーやポンを選択できるとき、どのプレイヤーの捨て牌に対しての鳴きかがわからないです
* リーチになったとき「リーチ」や「捨てる牌を選んでください」というメッセージウィンドウと手牌が重なってしまっていて、捨てる牌を選びにくいですし、自分の手牌がわからないので、何待ちかがわかりにくいです。現代の麻雀ゲームのように、どの牌を捨てると何待ちになるのか表示されるといいと思います
* ツモなどの演出がないため、CPUの誰が上がったのかがわかりにくかったです

これ含めて、麻雀部分の修正指示に関しては5回くらいで満足いくものが出来上がったから優秀だった。

鳴きのときのメッセージウィンドウと手牌がかぶる問題、
最終的に盤面を少し小さくしてメッセージウィンドウを盤面の下に表示するという解決方法をとっていて、
スマホの麻雀ゲームでは見ないUIながらも「たしかにその方法があったか!」と感心した。

完成物(リポジトリ)

リポジトリはこちら ⬇️

github.com

コミットメッセージに、どういう指示で直したか書いてるときもあるのでご参考に。

git や npm のコマンドが使えなく、Web検索できなく、MCPも使えないという、
Fable 5 はなかなかハードな環境で動作するにも関わらず、
もともとのモデルの優秀さゆえに、早くいいものを作れていた感じがある。
(この問題、Claude Desktop のバージョンアップをしたら解消した気がする)

完成物(ウェブアプリ)

リポジトリの README にも記載しているけれど、麻雀ウェブアプリはこちら ⬇️

nekonenene.github.io

綿密な動作検証をしたわけではないけれど、
東風戦を通して違和感ないくらいにはなってたので大丈夫なはず。