ChatGPT vs Claude3:『からあげゲーム』制作対決!どっちが上手く揚げられる?

この記事はからあげ帝国 Advent Calendar 2024の19日目の記事です。


先によくわからない内容になったことをお詫びします🙇🙇🙇

からあげ帝国 Advent Calendar 2024に申し込んだものの、全くアイデアが浮かばず困っていました🥲 そこで、からあげ帝国の聖典である「面倒なことはChatGPTにやらせよう」という教えに従って、アイデアを求めることにしました。

amzn.to

イデアだしのスタート

以下のようにプロンプトで考えてもらったところ

からあげと違う言葉を繋げて新しいアイデアを20考えてください。それがどんなものなのかも考えて教えてください。

ChatGPT 4oからは以下のような提案がきました。

「からあげ」という言葉に違う言葉を繋げて、新しいアイデアを20個考え、その内容も説明します。

1)からあげソーダ
からあげ風味の炭酸飲料。揚げたての香りとシュワシュワの刺激がマニア向け。

2)からあげバーガー
からあげをパティ代わりに使ったバーガー。ジューシーな鶏肉とバンズの相性が抜群。

3)からあげカレー
からあげを具にしたカレー。スパイスと衣の香ばしさが融合したボリューム満点の一皿。

4)からあげタワー
からあげを高く積み上げたメニュー。イベントやパーティで人気のシェアフード。

5)からあげクッション
からあげの形をした大きなクッション。リアルな見た目で癒しとインパクトを提供。

6)からあげチョコレート
衣の塩気とチョコの甘さが意外に合うスイーツ。新感覚の食べ合わせ。

7)からあげフォンデュ
からあげをチーズフォンデュの具材として楽しむメニュー。とろけるチーズと絡めて食べる。

8)からあげアート
からあげを題材にした美術作品。形や色を再現し、揚げ物文化を表現する芸術の一形態。

9)からあげロボット
自動でからあげを揚げ続けるAI搭載ロボット。飲食店の作業を効率化。

10)からあげ香水
からあげの香ばしい香りを再現した香水。食欲をそそる一風変わったフレグランス。

11)からあげガチャ
ガチャガチャで出てくる唐揚げ型フィギュアやアクセサリー。コレクター向け商品。

12)からあげピザ
からあげを具材にしたピザ。ジューシーな肉汁とチーズのハーモニーが楽しめる。

13)からあげカフェ
からあげをテーマにしたカフェ。各国風味の唐揚げやドリンクセットが楽しめる。

14)からあげサラダ
野菜と一緒に食べるヘルシー志向のからあげメニュー。衣のサクサク感がアクセント。

15)からあげクレープ
からあげと甘辛いソースをクレープ生地で巻いた一品。食事系クレープとして話題に。

13)からあげまくら
からあげを模した柔らかい枕。見た目がリアルで楽しいインテリアアイテム。

14)からあげドーナツ
からあげを揚げたドーナツ生地で包んだハイブリッドスナック。甘じょっぱさが魅力。

15)からあげゲーム
からあげを揚げるスピードや温度管理を競うシミュレーションゲーム。料理好き向け。

16)からあげスニーカー
からあげ柄のスニーカー。ファッションと食文化を融合させたユニークなデザイン。

17)からあげ温泉
からあげをイメージした香ばしい出汁の温泉。ユニークな体験型観光地として人気。

18)からあげゲーム
からあげを揚げるスピードや温度管理を競うシミュレーションゲーム。料理好き向け。

19)からあげスニーカー
からあげ柄のスニーカー。ファッションと食文化を融合させたユニークなデザイン。

20)からあげ温泉
からあげをイメージした香ばしい出汁の温泉。ユニークな体験型観光地として人気。

食べ物なので、そのジャンルからは外れたものが少ないですが、奇抜なアイデアはできています。 では、今回は以下のからあげゲームを題材にしてみます。

15)からあげゲーム
からあげを揚げるスピードや温度管理を競うシミュレーションゲーム。料理好き向け。

LLMによるゲーム開発対決🤼

最近のChatGPTに代表される大規模言語モデルであるLLMでは、プログラミングのコードも書いてくれる(実行もしてくれるもの)もあります。

このアイデアを元に、最新の大規模言語モデルLLM)であるChatGPT 4o(以下ChatGPT)とClaude3.5sonet(以下Claude3)に、それぞれの視点でからあげゲームを作ってもらうことにしました。

参考(どちらも有料版を使用しています)

流れとしては、各LLMに対してゲームの仕組みを生成してもらいます。そのプログラムの初期バージョンと、やり取りをする中で出来上がった完成品を比較するというものを書いていきたいと思います。

ChatGPTのアプローチ

からあげゲーム初期バージョン

ChatGPTに頼むとPythonを使用してテキストコンソール版のプログラムを作成してきます🙄これをゲームと呼ぶかについてはいささかの疑問はありますが、プログラミング言語としてはPythonが好きなのだなということはわかります。また、揚げ時間をゲームとして扱うこともわかります。絵文字🍗を使用してゲームらしさを出す努力は認めたいです。

ChatGPTの初期バージョンのプログラム

import time
import random

def fry_game():
    print("🍗 唐揚げゲームへようこそ!🍗")
    print("最適な時間で唐揚げを揚げましょう!\n")
    print("ゲームのルール:")
    print("・10秒がベストな揚げ時間です。")
    print("・スタート後、あなたが揚げると思ったタイミングでEnterキーを押してください。")
    print("・揚げ時間が近いほど高スコアです!\n")
    
    input("準備ができたらEnterキーを押してスタート!")
    
    print("\n唐揚げを揚げ始めます... 🍳")
    start_time = time.time()  # 開始時間
    input("揚がったと思ったらEnterキーを押してください!")
    end_time = time.time()  # 終了時間
    
    fry_time = end_time - start_time
    print(f"\nあなたの揚げ時間: {fry_time:.2f} 秒")
    
    # スコア判定
    perfect_time = 10.0
    difference = abs(perfect_time - fry_time)
    
    if difference < 0.5:
        score = 100
        comment = "完璧!サクサクジューシーな唐揚げが完成しました!✨"
    elif difference < 1.5:
        score = 80
        comment = "ほぼ完璧!少し揚げすぎかも?でもおいしい!"
    elif difference < 3.0:
        score = 50
        comment = "まあまあ...もう少し頑張りましょう!"
    else:
        score = 20
        comment = "残念...揚げすぎか生焼けです。次回に期待!"
    
    print(f"スコア: {score}点")
    print(comment)

# ゲーム実行
fry_game()

からあげゲーム進化版(10分後)

さすがにこれはということで、Webアプリにしてほしいこと、画像ファイルを準備したのでそれを使用してほしいという点のやり取りをして以下の様なゲームになりました。かかった時間は画像の検索も含めて10分です。

画像素材いらすとやさんのものを使用させていただきました。)

からあげゲーム進化版(10分後)

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>🍗 唐揚げゲーム 🍗</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            text-align: center;
            background-color: #fff3e0;
            color: #5c2c06;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
        }
        h1 {
            margin-top: 10px;
        }
        button {
            background-color: #ff9800;
            color: white;
            border: none;
            padding: 15px 30px;
            font-size: 1.2em;
            cursor: pointer;
            margin: 20px;
        }
        button:hover {
            background-color: #f57c00;
        }
        .image-container {
            position: relative;
            width: 300px;
            height: auto;
        }
        img {
            width: 100%;
            height: auto;
            display: block;
        }
        #startImage {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            display: none;
        }
        #friedChicken {
            display: none;
        }
        /* 結果表示のデザイン */
        #result {
            font-size: 2em; /* フォントサイズを大きく */
            font-weight: bold; /* フォントを太字に */
            color: #d84315; /* 色を強調(濃いオレンジ) */
            margin-top: 20px;
            line-height: 1.5;
        }
    </style>
</head>
<body>
    <h1>🍗 唐揚げゲーム 🍗</h1>
    <p>10秒でボタンを押して唐揚げを揚げましょう!</p>
    
    <!-- イラスト -->
    <div class="image-container">
        <img src="frying_pan.png" id="fryingPan" alt="揚げているフライパン">
        <img src="start.png" id="startImage" alt="スタート">
        <img src="fried_chicken.png" id="friedChicken" alt="完成した唐揚げ">
    </div>

    <!-- ボタン -->
    <button id="actionButton">揚げ始める!</button>

    <!-- 結果表示 -->
    <p id="result"></p>

    <script>
        let startTime, endTime;
        let isFrying = false;

        const actionButton = document.getElementById("actionButton");
        const result = document.getElementById("result");

        const startImage = document.getElementById("startImage");
        const fryingPan = document.getElementById("fryingPan");
        const friedChicken = document.getElementById("friedChicken");

        actionButton.addEventListener("click", () => {
            if (!isFrying) {
                result.innerText = "";
                startImage.style.display = "block";
                fryingPan.style.display = "block";
                friedChicken.style.display = "none";

                setTimeout(() => {
                    startImage.style.display = "none";
                }, 1000);

                startTime = new Date();
                actionButton.textContent = "揚がった!";
                isFrying = true;
            } else {
                endTime = new Date();
                const fryTime = (endTime - startTime) / 1000;
                const perfectTime = 10.0;
                const difference = Math.abs(perfectTime - fryTime);

                let score, comment;
                if (difference < 0.5) {
                    score = 100;
                    comment = "✨ 完璧!サクサクジューシーな唐揚げです!✨";
                } else if (difference < 1.5) {
                    score = 80;
                    comment = "ほぼ完璧!少し揚げすぎかも?でもおいしい!";
                } else if (difference < 3.0) {
                    score = 50;
                    comment = "うーん...まあまあです。次は頑張りましょう!";
                } else {
                    score = 20;
                    comment = "😅 残念...揚げすぎか生焼けです。";
                }

                result.innerHTML = `あなたの揚げ時間: <span>${fryTime.toFixed(2)}</span> 秒<br>スコア: <span>${score}</span>点<br>${comment}`;

                fryingPan.style.display = "none";
                friedChicken.style.display = "block";

                actionButton.textContent = "揚げ始める!";
                isFrying = false;
            }
        });
    </script>
</body>
</html>

基本的にはPythonのコードをWeb化して画像の切り替え処理を入れたというものですね。からあげ画像(要素)は人間が画像ファイルを与えたという点ではまだまだかもしれませんが、見違える進化がありました。

実際に動かすには上記のhtmlファイルと画像ファイルを同じフォルダにいれて、htmlファイルをブラウザで開きます。

Claude3のアプローチ

からあげゲーム初期バージョン

Claude3は最初からReactでWebアプリとして作成していきます。Reactにそこまで詳しくない方からするとかなりとばすなという印象。その上エラーっぽい挙動があったりして、やり直しもおこなうなど過程は微妙です。

Claude3の考えたゲーム性は時間と味付けの量という2つの要素を組み合わせた、より複雑なゲーム性にしたようです。ChatGPTとは異なる考えがあることが見えますね。丸いボタンを使っているのでUIにも工夫をしています。

Claude3の考える10分後バージョンのプログラム

先ほどの丸い部分が画像に入れ替わりました。

からあげゲーム進化版(10分後)

claude.site

画像がないのでこちらも絵文字🍗を使用していますが、あまりにも小さい表示なので先ほどと同じ画像素材を加えてもらいます。

Reactでは自分がよくわからないのでWebアプリにしてほしいこと、画像差し替えをしてほしいという点などのやり取りをして以下の様なゲームになりました。今回は画像検索なしで10分程度かかってしまいました。

画像素材

先ほどと同じ素材をいらすとやさんのものを使用させていただきました。

からあげゲーム進化版(10分後)

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>からあげクッキング</title>
    <style>
        body {
            font-family: sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
        }
        .game-container {
            background: white;
            padding: 20px;
            border-radius: 10px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            width: 100%;
            max-width: 500px;
            text-align: center;
        }
        .game-area {
            min-height: 200px;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            margin: 20px 0;
        }
        .start-image {
            width: 300px;
            height: 80px;
            object-fit: contain;
        }
        .game-character {
            width: 150px;
            height: 150px;
            object-fit: contain;
        }
        .progress-bar {
            width: 100%;
            height: 20px;
            background: #eee;
            border-radius: 10px;
            overflow: hidden;
            margin: 10px 0;
        }
        .progress-fill {
            width: 0%;
            height: 100%;
            background: #3b82f6;
            transition: width 0.3s ease;
        }
        button {
            background: #3b82f6;
            color: white;
            border: none;
            padding: 10px 20px;
            border-radius: 5px;
            cursor: pointer;
            margin: 5px;
            font-size: 16px;
            width: 100%;
            max-width: 300px;
        }
        button:hover {
            background: #2563eb;
        }
        button:disabled {
            background: #ccc;
            cursor: not-allowed;
        }
        .temperature {
            font-size: 24px;
            margin: 10px 0;
        }
        .score {
            font-size: 20px;
            font-weight: bold;
            margin: 10px 0;
        }
        .message {
            color: #2563eb;
            margin: 10px 0;
            font-size: 18px;
        }
    </style>
</head>
<body>
    <div class="game-container">
        <h1>からあげクッキング</h1>
        <div class="score">スコア: <span id="score">0</span></div>
        <div class="message" id="message">調理開始を押してください</div>
        
        <div class="game-area" id="gameArea">
            <img src="start.png" alt="スタート" class="start-image" id="gameImage">
        </div>

        <div id="controls">
            <button id="startButton" onclick="startGame()">調理開始</button>
        </div>
    </div>

    <script>
        let gameState = 'ready';
        let score = 0;
        let marinadeTime = 0;
        let temperature = 160;
        let isFrying = false;

        const images = {
            start: 'start.png',              // スタートのロゴ
            character: 'fried_chicken.png',   // からあげキャラクター
            pot: 'frying_pan.png'            // 鍋
        };

        function startGame() {
            gameState = 'marinate';
            document.getElementById('message').textContent = '下味をつけましょう。適度な時間を見計らってください!';
            const gameImage = document.getElementById('gameImage');
            gameImage.src = images.character;
            gameImage.className = 'game-character';
            
            const controls = document.getElementById('controls');
            controls.innerHTML = `
                <div class="progress-bar">
                    <div class="progress-fill" id="marinadeProgress"></div>
                </div>
                <button onclick="addMarinade()">下味をつける</button>
                <button onclick="startFrying()">揚げ始める</button>
            `;
        }

        function addMarinade() {
            if (marinadeTime < 100) {
                marinadeTime += 20;
                document.getElementById('marinadeProgress').style.width = marinadeTime + '%';
            }
        }

        function startFrying() {
            gameState = 'fry';
            isFrying = true;
            document.getElementById('message').textContent = '油温を調整して揚げましょう';
            document.getElementById('gameImage').src = images.pot;
            
            const controls = document.getElementById('controls');
            controls.innerHTML = `
                <div class="temperature">🌡️ <span id="tempDisplay">${temperature}</span>℃</div>
                <button onclick="adjustTemperature(-5)">温度を下げる</button>
                <button onclick="adjustTemperature(5)">温度を上げる</button>
            `;

            setTimeout(finishCooking, 3000);
        }

        function adjustTemperature(amount) {
            temperature = Math.min(200, Math.max(100, temperature + amount));
            document.getElementById('tempDisplay').textContent = temperature;
        }

        function finishCooking() {
            gameState = 'done';
            isFrying = false;
            
            const optimalMarinadeScore = Math.abs(60 - marinadeTime);
            const baseScore = 100 - optimalMarinadeScore;
            
            const tempScore = temperature >= 160 && temperature <= 170 ? 100 : 
                           temperature >= 150 && temperature <= 180 ? 50 : 20;
            
            score = Math.floor((baseScore + tempScore) / 2);
            
            document.getElementById('score').textContent = score;
            document.getElementById('gameImage').src = images.character;
            
            let message = '';
            if (score >= 90) {
                message = '完璧な唐揚げができました!';
            } else if (score >= 70) {
                message = '美味しい唐揚げができました!';
            } else {
                message = 'もう少し工夫が必要かも...';
            }
            document.getElementById('message').textContent = message;
            
            const stars = score >= 90 ? '⭐️⭐️⭐️' : score >= 70 ? '⭐️⭐️' : '⭐️';
            const controls = document.getElementById('controls');
            controls.innerHTML = `
                <div class="stars">${stars}</div>
                <button onclick="resetGame()">もう一度チャレンジ</button>
            `;
        }

        function resetGame() {
            gameState = 'ready';
            score = 0;
            marinadeTime = 0;
            temperature = 160;
            isFrying = false;
            
            document.getElementById('score').textContent = '0';
            document.getElementById('message').textContent = '調理開始を押してください';
            const gameImage = document.getElementById('gameImage');
            gameImage.src = images.start;
            gameImage.className = 'start-image';
            document.getElementById('controls').innerHTML = '<button onclick="startGame()">調理開始</button>';
        }
    </script>
</body>
</html>

動作は以下のような表示とになっていました。

実際に動かすには上記のhtmlファイルと画像ファイルを同じフォルダにいれて、htmlファイルをブラウザで開きます。

おわりに

わずか10分程度のカスタマイズ時間でしたが、それなりの形になっている(動く)のは素晴らしいですね。また、LLMがもっている特徴が垣間見えたように思います。

双方の特徴

  • ChatGPTは実装の簡単さと実用性を重視
  • Claude3はゲーム性の複雑さとUI/UXを重視

からあげ帝国の聖典にもある「面倒なことはChatGPTLLMにやらせよう」の精神は今後も使えそうです💪

/* -----codeの行番号----- */