1
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とオセロで対戦できるWebゲーム

Posted at

【API連携】猫キャラAIとオセロで対戦できるWebゲームを作ってみた

はじめに

本記事に掲載しているコードは、生成AI(Claude )によって作成されました。
この記事はClaudeによって書かれています。
最近、生成AIが身近になってきましたが、「実際にAIと遊べるゲームを作ってみたい!」と思ったことはありませんか?

今回は、Google の Gemini API を使って、猫キャラの「オセロにゃん」とオセロで対戦できる Web アプリケーションを作成しました。AIが思考プロセスをチャットで教えてくれる、ちょっとユニークなオセロゲームです。

スクリーンショット 2025-08-22 163826.png

作ったもの

  • フロントエンド: HTML/CSS/JavaScript でオセロ盤面とチャット機能
  • バックエンド: Flask (Python) で Gemini API との連携
  • AI キャラクター: 語尾に「にゃん」をつける猫のオセロプレイヤー

特徴

  • リアルタイムでAIと対戦
  • AIの思考プロセスがチャットで表示される
  • レスポンシブデザイン
  • 日本語対応

技術スタック

  • フロントエンド: HTML, CSS, JavaScript
  • バックエンド: Python (Flask)
  • AI API: Google Gemini API
  • その他: CORS 対応、dotenv for 環境変数管理

ファイル構成

project/
├── othello.html    # フロントエンド(ゲーム画面)
├── server.py       # バックエンド(Flask サーバー)
└── .env           # 環境変数(APIキー)

実装のポイント

1. フロントエンド(othello.html)

// オセロの基本ロジック
function isValidMove(x, y, player) {
  if (board[y][x] !== EMPTY) return false;
  // 8方向をチェックして、ひっくり返せる石があるか判定
  for (const [dx, dy] of directions) {
    // ... 省略(詳細は後述)
  }
  return false;
}

// AIの手番処理
async function handleAITurn() {
  const boardText = boardToText(board);
  const validMovesStr = validMoves.map(m => 
    `${String.fromCharCode(65 + m[1])}${m[0] + 1}`
  ).join(", ");
  
  const response = await fetch(`/api/get_ai_move`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      board_text: boardText,
      valid_moves_str: validMovesStr
    })
  });
  
  // AIの応答を解析して石を配置
}

2. バックエンド(server.py)

@app.route('/api/get_ai_move', methods=['POST'])
def handle_ai_move():
    """AIの次の手を取得するAPIエンドポイント"""
    try:
        data = request.json
        board_text = data.get('board_text')
        valid_moves_str = data.get('valid_moves_str')
        
        # Gemini APIを呼び出してAIの応答を取得
        ai_response_text = get_ai_response(board_text, valid_moves_str)
        
        return jsonify({'response_text': ai_response_text})
    
    except Exception as e:
        return jsonify({'detail': 'サーバー内部でエラーが発生しました。'}), 500

3. Gemini API との連携

def get_ai_response(board_text, valid_moves_str):
    """Gemini APIを呼び出してAIに次の手を決定させる"""
    
    prompt = f"""
あなたは猫のオセロプレイヤー「オセロにゃん」です。
語尾には必ず「にゃん」や「にゃ」をつけてください。

# 現在の盤面:
{board_text}

# あなたが置ける有効な場所: [{valid_moves_str}]

思考プロセスを述べた後、`MOVE: [座標]` の形式で答えてください。
例: 「角が取れるからF5が有利だにゃん。MOVE: F5」
"""
    
    # API呼び出し処理
    response = requests.post(API_URL, headers=headers, data=json.dumps(payload))
    # ... レスポンス処理

工夫したポイント

1. AIキャラクターの個性

Gemini API に送るプロンプトで、AI に猫のキャラクター設定を与えました。語尾に「にゃん」をつけることで、親しみやすいキャラクターを演出しています。

2. エラーハンドリング

AI が不正な手を選んだ場合や、API 通信でエラーが発生した場合には、ランダムな有効手で代替する仕組みを実装しました。

3. リアルタイムなチャット表示

AI の思考中には「考え中にゃ...」というアニメーション付きのメッセージを表示し、ユーザーエクスペリエンスを向上させています。

4. 盤面の視覚的な表現

CSS Grid を使用してオセロ盤を実装し、有効な手には hover エフェクトを追加して直感的な操作を可能にしました。

セットアップ方法

1. 必要なライブラリのインストール

pip install flask flask-cors requests python-dotenv

2. Gemini API キーの取得

  1. Google AI Studio でAPI キーを取得
  2. .env ファイルを作成
GEMINI_API_KEY=your_api_key_here

3. アプリケーションの起動

python server.py

ブラウザで http://localhost:5001 にアクセスしてゲーム開始!

実際に遊んでみた感想

AIは意外と戦略的で、角を狙ったり、相手の選択肢を減らすような手を打ってきます。また、「ここは守りを固めるにゃん」「攻撃的に行くにゃん」など、思考プロセスを教えてくれるのも面白いポイントです。

ただし、API の応答に時間がかかることがあるので、実際のサービスでは応答速度の最適化が課題になりそうです。

今後の改善案

  • 難易度設定: 初心者向け〜上級者向けの AI レベル調整
  • 対戦履歴: 勝敗記録の保存機能
  • マルチプレイ: 人間同士の対戦モード
  • AI キャラクター追加: 猫以外のキャラクターとの対戦
  • 音声機能: AI の発言を音声で読み上げ

まとめ

生成 AI を使ったインタラクティブなゲームを作ることで、AI の可能性を実感できました。従来のルールベースの AI と異なり、自然言語でコミュニケーションを取りながらゲームを楽しめるのは、生成 AI ならではの魅力だと思います。

コード全体

詳細なコードは https://github.com/ishikawamasahito/othello-game で公開しています。

1
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
1
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?