はじめに
前回の記事では、Claude Codeを使って麻雀の「何切るクイズ」を作りました。
なかなか本格的なアプリが一瞬で完成し、改めてClaude Codeってすごいなと思ったところで、今回はもう一歩踏み込んでみます。
「待ち牌クイズ」を作成し、機能追加してみます。
テンパイの手牌を見て「何が来たらアガリ?」を当てるクイズです。
結果から言うと、ロジック自体は想定以上のものが一発で出てきました。ただし、実際に使ってみるとちゃんとバグも潜んでいました。そこの解消も合わせてやっていきます。
前回に引き続き、記事の中で度々麻雀用語が出てきますが、その解説を挟んでいると記事が麻雀解説記事になってしまうので、適宜以下のリンクなどを参考にしていただければ幸いです。
そもそも待ち牌判定はなぜ難しいのか
麻雀記事ではないとはいえ、多少は話しておかないと意味が分からない記事になるので、前提を少しだけ解説します。
麻雀でアガリになるには、特殊な場合を除いて「14枚の手牌が、4つの面子+1つの雀頭」という形になる必要があります。
問題は、待ち牌が1枚とは限らないこと。
例えば2と3という牌を持っているとき、123か234を作る必要があり、この時は1がきても4が来てもOKという状態です(この時待っているのは1と4なので、答えが一つとは限らない、ということになります)
例:🀇🀈🀉🀊🀋🀌🀍🀎🀏🀙🀙🀙🀚🀛(14枚)
→ この手から1枚切ったとき、待ち牌が「🀙」と「🀜」の両方になるケースがある
これが「多面張(タメンチャン)」と呼ばれるパターンで、全パターンを正確に計算するには複雑なアルゴリズムが必要です。さらに特殊な役まで考慮すると……正直、自力でロジックを組む気にはなれません。
こういう複雑なルールこそ、AIにお任せしたい。
前回同様に丸投げしてみます。
プロンプトを投げてみる
今回も最初から要件はやや具体的に書きました。
コードの書き方は分からなくても、やってほしいことを言語化する力がバイブコーディングでは意外と重要です。これは第1回でも触れましたが、要件定義の能力がそのままプロンプトの質に直結するんですよね。
投げたプロンプト:
index.html に「待ち牌クイズ」モードを追加して。
要件:
- テンパイ(13枚)の手牌を表示し、ユーザーが待ち牌を選んで正誤判定する
- 麻雀の面子構成(順子・刻子・雀頭)を再帰的に計算して、
すべての正しい待ち牌を算出するロジックをJavaScriptで実装する- チートイツ(2枚ペアを7組)の特殊ケースにも対応する
再帰的な計算や特殊ケースへの対応など、意図的に具体的な言葉を入れています。
作成されたので開いてみますと……。
【ターミナルの結果】
● index.html を更新しました。
追加内容:
- 「何切るクイズ」「待ち牌クイズ」のタブ切り替えUI
- findWaitingTiles():全34種の牌を1枚ずつ試してアガリ形になるものを列挙
- isAgari():七対子チェック+通常手(雀頭×面子の再帰探索)の両対応
- 正解・不正解・見逃し牌を色分けしてフィードバック表示
✻ Cogitated for 3m 12s
クイズが2パターンで切り替えができるようになりました。
一度の指示でタブ切り替えUIまで実装してくれるの、改めてすごいですね!
コードのことなんて何もわかっていなくても、今回の場合は「こういう内容で作りたい」というおおよその設計と「好きな題材の知識(今回であれば麻雀)」さえあれば、誰でも簡単にアプリが作れることが分かります。
「実際簡単にアプリが作れるっていうけど、本当なの?」と思われている方も、Claude Codeさえ使える環境なら、こんなに短時間でアプリ本体を作ったり機能追加できたりする、という事実を知っておくだけでも、利用のハードルが下がると思っています。
今回の題材は麻雀ですが、お好きなもので簡単なアプリが作れます!
バグを発見!
こんなに簡単にアプリが作れるなんて!と感動しながら、さっそく「新しい手牌」ボタンを連打して試してみると……あれ、同じ手牌がずっと出てくる。
「ボタン壊れてる?」と思いましたが、画面は正常に動いています。どうやらロジック側の問題っぽい。でも何が原因かは全然わからない。
こういうとき、難しいことは分からないけどとりあえずClaude Codeに伝えてみます。
投げたプロンプト:
「新しい手牌」ボタンを押しても毎回同じ手牌が出てくるんだけど…
すると、原因が特定されました。
待ち牌クイズ:手牌生成
テンパイ(shanten===0)の13枚手牌をランダム生成
最大300回試行。失敗時は既知の良形フォールバックを返す
ランダムサンプリングはテンパイ確率が低すぎるため、検証済み手牌プールから選択する
つまり……ランダムに14枚を配ってテンパイになる確率はそもそも低く、300回試行しても成功しないケースが続いていたようです。失敗したときの「保険」として用意していた固定の手牌がずっと表示されていた、というのが原因でした。トランプ52枚をシャッフルして、「ロイヤルストレートフラッシュ(A・K・Q・J・10の同じマーク5枚)」が出るまで引き続ける、みたいな状況です。理論上はいつか出るけど、確率が低すぎて300回やっても出ない。
このバグの根本的な解決として、検証済みのテンパイ手牌をあらかじめプールとして用意しておき、そこからランダムに1つ選ぶ方式に変更してくれるようです。
修正後のコードを見ると、ランダム生成をまるごとやめて、テンパイ形を20種類あらかじめ用意したプールから選ぶ方式に変わっていました。
const TENPAI_POOL = [
[1,2,3,4,5,6,7,8,9,11,11,12,13], // 両面待ち
[1,1,5,5,9,9,11,11,15,15,21,21,25], // 七対子
[1,2,3,4,5,6,7,8,9,11,11,21,21], // 双碰待ち
// ...全20種類
];
「ランダムにテンパイを引こうとしても確率が低すぎる」という根本問題を指摘して、アプローチごと変えてきたということですね。
ちゃんと両面・七対子・双碰・嵌張・辺張と、いろんな待ちパターンが網羅されていて、クイズとしても練習になる内容になっています。
ここで自分がやったことといえば、「同じ手牌が出てくる」と症状を伝えただけです。
原因の特定も、アプローチを変えるという判断も、全部Claude Codeがやってくれました。
「コードのここが問題だからこう直して」という指示を自分で組み立てなくても、症状を伝えるだけで動いてくれる。
プログラミング経験がなくても、「なんかおかしい」を言語化できれば前に進めるというのは、思っていた以上に心強いものです。
ただ、「ランダム生成からプール方式に変えた」というのは分かりましたが、もし次に似た問題が起きたとき、自分で対処できるかは怪しい。
コードが書けなくても使えるのがバイブコーディングの強みですが、「なぜ直ったかを理解しないまま進む」ことへの不安も正直あります。
これはバイブコーディングの快適さと表裏一体のところで、「直してもらえるけど、学習にはなりにくい」という側面があります。第6回の総括でもう少し掘り下げます(予定)
今回の観察まとめ
手牌生成のバグを除けば、待ち牌判定ロジック自体は一発で正確に動きました。
前回(第1回)で作ったロジックを土台にした機能追加しているからこそ、尚安定していたのかもしれませんね。
逆に言うと、ゼロから全部書かせるより、前回の文脈を引き継いだ状態で追加指示を出すほうが精度が上がるということかもしれません。Claude Codeはフォルダ内のコードを読んだ上で作業してくれるので、前回の構造を把握した状態で動いてくれているんですよね。
Claude Code観察メモ②
| 観察 | 内容 |
|---|---|
| タブ切り替えUIの追加 | ◎ 一発で綺麗に実装された |
| 複雑なロジックの実装 | ◎ シンプルかつ正確な実装が出てきた |
| バグの修正 | ◎ 症状を伝えるだけで原因特定〜解決までやってくれた |
| 修正内容の理解 | △ 「直してもらった」だけだと自分のスキルにはならない |
バイブコーディングは「直してもらうのは最適、しかし学ぶのは難しい」という道具だと改めて感じます。
全部やってくれちゃいますからね。
次回予告
2モードが揃い、アプリとして形になってきました。
次はいよいよ見た目を整えていきます。
