「本ページはプロモーションが含まれています」
こんにちは。これまでの連載では、
- 第1回:モンスター育成ゲームAPIの概要/フレームワーク選定
- 第2回:Mermaidでシーケンス図を描き、モンスター入手フローを可視化
- 第3回:MermaidでDB設計を考え、SQLiteに落とし込む
- 第4回:FastAPI環境構築&フォルダ構成
- 第5回:ユーザー管理APIを実装(CRUD)
- 第6回:モンスター管理APIを実装(モンスター種を登録・取得)
ここまででユーザーもモンスター種も用意できました。次は「ガチャを引く」要素を作り、ランダムにモンスターを入手できるようにしてみます。 ソシャゲ的なワクワク感が加わり、一気に“ゲームらしさ”が増すはずです。
1. ガチャ実装の概要
1.1 抽選の流れ
- ユーザーが「ガチャを引く」エンドポイント(例:POST /gacha?user_id=xxx)にリクエスト
- サーバーでモンスター種をレア度などの確率に応じてランダム抽選
- 当選したモンスターをuser_monstersテーブルに登録(所有モンスターとして追加)
- レスポンスに「どのモンスターが当たったか」を返す
1.2 レア度の確率管理
- rarity("common" / "rare" / "legendary" など)と、その出現率を設定
- 例: "common":70%, "rare":25%, "legendary":5%
- もし「レア度の概念」を使わないなら、モンスター種すべてを一律の確率で抽選する方法もあり
2. DBのおさらい
第3回でMermaid ER図を描いたように、MONSTERSテーブルに各モンスター種が登録され、USER_MONSTERSテーブルでユーザーが所有する個体を管理します。
erDiagram USERS ||--o{ USER_MONSTERS : "owns" MONSTERS ||--o{ USER_MONSTERS : "instances of" USERS { int id PK string username datetime created_at } MONSTERS { int id PK string name string rarity int base_hp int base_attack int base_defense } USER_MONSTERS { int id PK int user_id FK int monster_id FK int level int exp datetime obtained_at }
ガチャではMONSTERSから1体をランダムに選出し、USER_MONSTERSにINSERTする形をとります。
3. ガチャAPIのサンプル実装
3.1 gacha.py (APIRouter)
# app/routers/gacha.py import random from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.orm import Session from app.database import get_db from app.models import User, Monster, UserMonster from pydantic import BaseModel from typing import Optional router = APIRouter() # レア度ごとの確率 (例) RARITY_PROB = { "common": 0.7, "rare": 0.25, "legendary": 0.05 } class GachaResult(BaseModel): user_id: int monster_id: int monster_name: str monster_rarity: str message: str @router.post("/", response_model=GachaResult) def pull_gacha( user_id: int = Query(..., description="ガチャを引くユーザーID"), db: Session = Depends(get_db) ): """ ユーザーがガチャを引いて、ランダムにモンスターを入手するエンドポイント。 """ # 1. ユーザーの存在確認 user = db.query(User).filter(User.id == user_id).first() if not user: raise HTTPException(status_code=404, detail="User not found") # 2. レア度を抽選 (random.choicesで確率的に選択) rarities = list(RARITY_PROB.keys()) # ["common", "rare", "legendary"] probs = list(RARITY_PROB.values()) # [0.7, 0.25, 0.05] chosen_rarity = random.choices(rarities, probs)[0] # 3. 選ばれたレア度に該当するモンスター一覧を取得 monsters = db.query(Monster).filter(Monster.rarity == chosen_rarity).all() if not monsters: raise HTTPException(status_code=500, detail="No monsters found for this rarity") # 4. 一覧の中からランダムで1体ピック chosen_monster = random.choice(monsters) # 5. user_monstersに所有記録を追加 new_owned = UserMonster( user_id=user_id, monster_id=chosen_monster.id, level=1, exp=0 ) db.add(new_owned) db.commit() db.refresh(new_owned) # 6. 結果を返却 return GachaResult( user_id=user_id, monster_id=chosen_monster.id, monster_name=chosen_monster.name, monster_rarity=chosen_monster.rarity, message=f"You got a {chosen_monster.name}!" )
- レア度の確率は random.choices() を使って重み付き抽選を行う。
- 取得したモンスターを UserMonster にINSERTし、ユーザーが所有する個体として記録。
- データベースに一切モンスターが登録されていないレア度だと動かないため、初期データを仕込み。
3.2 main.py にルーターを追加
from app.routers import users, monsters, gacha app.include_router(gacha.router, prefix="/gacha", tags=["gacha"])
- これで POST /gacha?user_id=1 のように呼び出すとガチャが引けるようになるはず!
- Swagger UIで、クエリパラメータ user_id に値を入れて Execute する
4. 動作確認 (簡易テスト項目書)
- 前提:
- ユーザー(usersテーブル)が存在
- モンスター種(monstersテーブル)にいくつか登録され、rarityが"common"/"rare"/"legendary"などで設定済み
- uvicorn app.main:app --reload でサーバー起動
- POST /gacha?user_id=1
6回ほど実行してやっと。。。
20回実行してやっと。。。
5. 7回連載を終えて
これまで7回にわたって、Python+FastAPIでモンスター育成ゲームのバックエンドAPIを作る過程を紹介してきました。最初は「本当に形になるのかな…」と不安でしたが、一歩ずつ進めるうちに、ユーザー管理やモンスター管理、ガチャ機能など、ゲームらしい機能が揃ってきましたね。
全体のおさらい
- 第1回:ゲームの概要とFastAPI選定
- 第2回:Mermaidを使ってシーケンス図を描き、モンスター入手フローを可視化
- 第3回:ER図とSQLiteでDB設計
- 第4回:FastAPI環境構築とフォルダ構成
- 第5回:ユーザー管理APIを実装(CRUD処理)
- 第6回:モンスター管理APIを実装し、レア度やステータスをCRUD
- 第7回:ガチャ機能を作って、ユーザーがランダムにモンスターを手に入れる仕組みを実装
それぞれの記事で、Mermaidでの図解やSQLiteを使ったDB設計のポイント、FastAPIのルーター分割、Pydanticによるバリデーションなど、学んだ要素がたくさんあったと思います。連載を通して、設計から実装までの流れを体験できたかなと思います。 一応、GitHubに上げてます。
今後の展望
- 認証・セキュリティ: トークンベースの認証やOAuthなどを導入して、ユーザーのログイン機能をしっかり作り込む。
- バトル機能・レベルアップ: ユーザーが所有するモンスターで戦って経験値を稼ぎ、レベルアップや進化をする要素を追加。
- UI・フロントエンド: ReactやVueなどで簡単な画面を用意すれば、さらにゲーム感がアップ。
- 本番運用: Dockerやクラウドサービス(AWS、GCP、Renderなど)にデプロイして、多人数で遊べるように整備。
- この連載で作ったAPIは、あくまでも「最初の試作」とも言える内容なので、さらに機能を付け足して自分好みのゲームに仕上げていくとか?
- コストを抑えて、DynamoDBで運用できるようにv2を作るのも良いかな
まとめ
いろいろな試行錯誤をしながらコードを書き、エラーに悩まされ、機能を少しずつ増やすうちに、モンスター育成ゲームAPIの大枠が形になったかな。。。
よくありそうな、開発の順で書いてみています。 超簡易設計 => 超簡易実装 => 簡易テストと、ゲームだろうがC#のソフトウェアだろうが、あまり流れは変わらない気がしますね。。
- FastAPIのおかげで、APIのプロトタイプを素早く構築できた
- Mermaidを使うと、フロー図やER図がテキストで管理できるため、仕様変更にも対応しやすかった
- SQLiteはシンプルながら、CRUDやガチャ機能を実装するには十分な力を発揮
ありがとうございました。
次回は、全然違う、雑多なことでもしようかなと思います。