こんにちはappyです!
and factoryでフロントエンドの開発をしています。
この記事はand factory.inc Advent Calendar 2025 14日目の記事です。
昨日はkamesan1577さんの Tauriは気になる。でもRustはつらい…という人へ。Goで作れるデスクトップアプリ開発フレームワーク「Wails」でした!
はじめに
フロントエンドメンバーとの雑談で、最近人狼ゲームは陽キャがやるらしいと聞き、人生一発逆転を狙って人狼ゲームを作ろうと思います。
「陽キャ(ようきゃ)」とは、「陽気なキャラクター」の略で、明るく社交的で、人付き合いが上手な人を指す若者言葉です。
技術スタック
- フレームワーク: Next.js 16.0.11
- 言語: TypeScript
- 状態管理: Zustand
- UIライブラリ: shadcn/ui
- スタイリング: Tailwind CSS
Claude Codeプロンプト
あなたは熟練のフロントエンドエンジニアです。Next.js(App Router)と TypeScript と shadcn/ui を使って、以下仕様の人狼ゲーム Web アプリを実装してください。
【技術条件】
- Next.js 16+ , TypeScript
- UI ライブラリ: shadcn/ui(Button, Card, Dialog, Tabs, Progress など必要に応じて)
- スマホ優先(1台のスマホを回して遊ぶ想定)・レスポンシブ対応
- 状態管理はクライアントサイドのみ(React state or Zustand など)で完結
- サーバー API / DB / 認証 なし
- デザインはシンプルで見やすいダーク系でもOK
【ゲーム仕様】
- スマホ1台で複数人が一緒に遊ぶ“回しプレイ”
- 人数: 5〜10人
- 役職: 村人 / 人狼 / 占い師(MVPではこの3種類のみ)
- 役職の配分は「おすすめ構成」をプリセットとして自動決定してよい
- ゲームフロー:
1. タイトル画面
- 「ゲーム開始」ボタン
2. 設定画面
- プレイヤー人数の選択(5〜10人、Stepper UI)
- 役職構成はプリセット(例:人数に応じて人狼数と占い師1人)
- 「役職配布を始める」ボタン
3. 役職配布画面
- プレイヤー番号(プレイヤー1〜プレイヤーN)で扱う(名前入力は不要)
- 「プレイヤー1にスマホを渡してください」→「役職を見る」ボタン→役職表示→「次のプレイヤーへ」ボタン
- N人分終わったら「ゲーム開始」ボタン
4. 夜ターン
- 手順は画面ごとにガイドテキストで表示(誰がスマホを見るべきか)
- 人狼フェーズ: 生存プレイヤー一覧から襲撃対象を1人選択
- 占い師フェーズ: 生存プレイヤー一覧から1人選択し、翌朝に陣営(人狼かそうでないか)を知る
5. 朝ターン
- 「昨夜は ○○ が襲撃されました」or「昨夜は誰も死にませんでした」
- 必要なら「占い結果を見る」ボタンで占い師専用の結果表示(シンプル化のため全体公開でもOK)
- 「昼の議論を始める」ボタン
6. 昼ターン(議論)
- 口頭で議論する前提のため、画面はシンプルに「議論中です」+「投票へ進む」ボタンのみ
7. 投票フェーズ
- 生存プレイヤー一覧をボタンで表示
- 1人ずつ順番にスマホを渡し、「今はプレイヤーXの投票です」と表示しつつ、処刑したい相手を1人選択
- 全員の投票が終わったら「集計」ボタンで票数を計算
8. 処刑結果
- 最多得票者を1人選び「○○が処刑されました」と表示
- 同票の処理は簡易に「ランダムで1人処刑」ルールで実装
9. 勝敗判定
- 人狼勝利: 生存人狼数 ≥ 生存市民陣営数
- 村人勝利: 生存人狼数 = 0
- どちらも満たさない場合は次の夜ターンへ
10. 結果画面
- 勝利陣営の表示(「村人陣営の勝ち」「人狼陣営の勝ち」)
- 全プレイヤーとその役職の一覧
- 「もう一度遊ぶ」ボタン(新しいゲームとして state をリセット)
【UI要件(ざっくり)】
- 全画面でヘッダーに現在フェーズ(例: 夜 / 朝 / 投票)を表示
- プレイヤーボタンはスマホで押しやすいように大きめの shadcn/ui Button / Card を使用
- 危険な操作(ゲームリセットなど)は Dialog で確認を挟む
- 画面遷移は Next.js のページ遷移ではなく、基本的に単一ページ内でフェーズごとに表示を切り替える実装でOK
【成果物】
- 動作する Next.js プロジェクトのコード一式
- pages/app 構成、主要コンポーネント、状態管理ロジックを含む
- 必要な shadcn/ui コンポーネントの import と使用例
- 主要なファイル構成とそれぞれの役割が分かるコメントを適度に含める
以上を満たす実装コードを生成してください。
5分後
ゲームタイトル画面ができました
shadcn/uiのCardコンポーネント使っているのでデザインもいい感じに整っています。
コード読んでみる
"use client";
import { useGameStore } from "@/lib/store";
import { GameHeader } from "@/components/game/GameHeader";
import { TitleScreen } from "@/components/game/TitleScreen";
import { SetupScreen } from "@/components/game/SetupScreen";
import { RoleDistribution } from "@/components/game/RoleDistribution";
import { NightPhase } from "@/components/game/NightPhase";
import { MorningPhase } from "@/components/game/MorningPhase";
import { DiscussionPhase } from "@/components/game/DiscussionPhase";
import { VotingPhase } from "@/components/game/VotingPhase";
import { ExecutionResult } from "@/components/game/ExecutionResult";
import { GameResult } from "@/components/game/GameResult";
export default function Home() {
const { gameState } = useGameStore();
const renderPhase = () => {
switch (gameState.phase) {
case "title":
return <TitleScreen />;
case "setup":
return <SetupScreen />;
case "roleDistribution":
return <RoleDistribution />;
case "night":
return <NightPhase />;
case "morning":
return <MorningPhase />;
case "discussion":
return <DiscussionPhase />;
case "voting":
return <VotingPhase />;
case "execution":
return <ExecutionResult />;
case "result":
return <GameResult />;
default:
return <TitleScreen />;
}
};
return (
<main className="min-h-screen bg-slate-900 text-slate-100">
<GameHeader />
<div className="p-4">{renderPhase()}</div>
</main>
);
}
Zustandで管理しているゲームのフェーズgameState.phaseに応じて、表示する画面コンポーネントを切り替えてます。
Vercelにデプロイ
GitHub連携するだけで完了です。
https://werewolf-appy.vercel.app/
終わりに
次は友達を集めて実際にプレイして、陽キャに一歩近づこうと思います!
AIに任せれば誰でもサクッと作れるので、ぜひみなさんも思いついたアイデアをゲーム化して遊んでみてください。

