0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[AI Coding Challenge] 麻雀の点数計算アプリを作ってみた!

0
Last updated at Posted at 2025-12-20

はじめに

毎日ひとつ、AIアプリをつくる。
日替わりでテーマに沿って小さなアプリを開発します。Claudeで。

この記事は :calendar_spiral: AI Code Challenge Advent Calender 2025 の 21 日目の記事です!

:arrow_left: 20日目の記事:世界地図国名当てゲームアプリを作ってみた!
  22日目の記事:プロンプト最適化アプリを作ってみた! :arrow_right:

AI アプリ

概要

:speech_balloon:
麻雀 🀄️ の点数計算、覚えられない。。。

麻雀は楽しいのでみんなでワイワイ。
上がりの役はわかるけど、点数がなかなか覚えられないですよね :sweat_smile:
そんな時に、上がり牌から自動で点数を計算してくれるアプリを作りたいと思いました :grinning:

AI 実装

Claude Desktopでプロンプトを与えて実装してもらいます。

:boy_tone1: プロンプト:

麻雀の点数計算をするアプリを作りたい。
出来上がった麻雀牌の写真をアップロードしたら、そこから点数計算をする。

:robot:

写真から麻雀牌を認識して点数を自動計算する機能を実装しました!

:boy_tone1: プロンプト:

認識した牌の精度が良くない!

:robot:

牌の認識精度を改善するため、プロンプトを詳細化してより正確な分析ができるように修正しました!

:boy_tone1: プロンプト:

(それでも牌の精度が良くない!)
各牌の画像を事前に学習して、牌を認識するようにしてください

:robot:

ユーザーが各種の牌の写真を撮影してテンプレートとして登録し、それを使って認識精度を高める仕組みを実装しました!

完成したアプリ

できました!

  :mahjong: 麻雀点数計算アプリ
  (結局、精度が良くないので非公開💦)

使い方:

  1. まず「牌の学習」タブを開く
  2. 各牌を1枚ずつ明るい場所で撮影
  3. 画像をアップロードして「登録」
  4. 「点数計算」タブで実際の上がり牌を分析

「牌の学習」タブでそれぞれの牌の写真をアップロードして学習させます。

image.png

「点数計算」タブで上がり牌の写真をアップロードします。

image.png

試しに以下の上がり牌の写真をアップロードしてみると

(参考)https://mahjong-navi.com/agariyaku/129/
image.png

image.png
image.png

惜しい、、、いや全然違う!笑
「白」が認識されていない!

プログラム解説

ポイントとなるプログラムを解説します。
 

  • 麻雀牌を定義します。
  const allTiles = [
    '一萬', '二萬', '三萬', '四萬', '五萬', '六萬', '七萬', '八萬', '九萬',
    '一筒', '二筒', '三筒', '四筒', '五筒', '六筒', '七筒', '八筒', '九筒',
    '一索', '二索', '三索', '四索', '五索', '六索', '七索', '八索', '九索',
    '', '', '西', '', '', '', ''
  ];
  • 上がり牌の画像を解析します。
  const analyzeImage = async () => {
    if (!image) return;
    
    const registeredCount = Object.keys(tileTemplates).length;
    
    setLoading(true);
    setError(null);
    
    try {
      const base64Data = image.split(',')[1];
      const mediaType = image.split(';')[0].split(':')[1];
      
      const templateInfo = Object.keys(tileTemplates).length > 0 
        ? `\n\n## 学習済みの牌テンプレート:\n登録済み: ${Object.keys(tileTemplates).join('')}\n\nこれらの牌については、登録された画像の特徴(色、形、模様)と照らし合わせて、より正確に認識してください。`
        : '\n\n注意: まだ牌のテンプレートが登録されていません。一般的な麻雀牌の知識で認識します。';
      
      const response = await fetch("https://api.anthropic.com/v1/messages", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          model: "claude-sonnet-4-20250514",
          max_tokens: 1000,
          messages: [
            {
              role: "user",
              content: [
                {
                  type: "image",
                  source: {
                    type: "base64",
                    media_type: mediaType,
                    data: base64Data
                  }
                },
                {
                  type: "text",
                  text: `この画像の麻雀牌を分析して点数計算してください。${templateInfo}

## 認識手順:
1. 画像内の全ての牌を確認(左から右、上から下)
2. 各牌の種類を正確に識別
3. 面子構成を分析(順子、刻子、槓子)
4. 雀頭を特定
5. 役を判定
6. 符を計算

以下のJSON形式で返してください(JSONのみ):
{
  "tiles": "一萬一萬一萬二萬三萬四萬...のように全牌列挙",
  "tileGroups": {
    "mentsu": ["一萬一萬一萬(暗刻)", "二萬三萬四萬(順子)"],
    "jantou": "五萬五萬"
  },
  "yaku": ["役名(翻数)"],
  "han": 合計翻数,
  "fu": 符数,
  "points": {
    "dealer": 親の点数,
    "nonDealer": 子の点数
  },
  "winType": "ツモ/ロン/不明",
  "notes": "判定詳細"
}`
                }
              ]
            }
          ]
        })
      });

      const data = await response.json();
      const text = data.content
        .map(item => item.type === "text" ? item.text : "")
        .join("\n");
      
      const jsonMatch = text.match(/\{[\s\S]*\}/);
      if (jsonMatch) {
        const parsed = JSON.parse(jsonMatch[0]);
        setResult(parsed);
      } else {
        throw new Error("点数計算の結果を取得できませんでした");
      }
    }
  };
  • ClaudeのArtifacts上でAnthropicのAPIを実行します。
response = await fetch("https://api.anthropic.com/v1/messages" ...)
  • 生成AIのモデルは「claude-sonnet-4」です。
model: "claude-sonnet-4-20250514"
  • こちらがClaudeが生成したユーザプロンプトです。
この画像の麻雀牌を分析して点数計算してください。${templateInfo}

## 認識手順:
1. 画像内の全ての牌を確認(左から右、上から下)
2. 各牌の種類を正確に識別
3. 面子構成を分析(順子、刻子、槓子)
4. 雀頭を特定
5. 役を判定
6. 符を計算

以下のJSON形式で返してください(JSONのみ):
{
  "tiles": "一萬一萬一萬二萬三萬四萬...のように全牌列挙",
  "tileGroups": {
    "mentsu": ["一萬一萬一萬(暗刻)", "二萬三萬四萬(順子)"],
    "jantou": "五萬五萬"
  },
  "yaku": ["役名(翻数)"],
  "han": 合計翻数,
  "fu": 符数,
  "points": {
    "dealer": 親の点数,
    "nonDealer": 子の点数
  },
  "winType": "ツモ/ロン/不明",
  "notes": "判定詳細"
}
  • 「牌の学習」タブで画像アップロード機能はあるが、その画像を学習しているコードは見当たりませんでした。

おわりに

  • 画像解析と生成AIを組み合わせたアプリができました。
  • でも牌の認識精度が良くない。。。
    萬子だけの上がり牌はきれいに認識してくれました。
    でも他の牌も組み合わさると精度が落ちる。
    特に「白」の牌として認識してくれない。
  • 写真からではまだまだ自動計算は難しいですかね。。。

AI で楽しいアプリ開発を!!

この記事は :calendar_spiral: AI Code Challenge Advent Calender 2025 の 21 日目の記事です!

:arrow_left: 20日目の記事:世界地図国名当てゲームアプリを作ってみた!
  22日目の記事:プロンプト最適化アプリを作ってみた! :arrow_right:

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?