じゃんけんアプリ開発：Reactで作るシンプルじゃんけんアプリをDockerで動かすまでの手順

## はじめに
本記事では、Docker環境でReactを使用してシンプルなじゃんけんアプリを作成する手順について説明します。

今回はじゃんけんの基本的な勝敗判定のみを実装しており、プレイヤー同士で気軽に遊べるシンプルなアプリになっています。

本記事はITスクールの課題としてアウトプット学習を目的に作成したもので、個人の備忘録レベルの内容ですので、ご了承ください。

## 必要なツール

:::note
**私の環境はM1チップ搭載のMacOSですが、本記事のハンズオンで使用するツールは以下の通りです。**
・``Docker``
・``Docker Compose``
・``Node.js（バージョン14以上推奨）``
・``npm（Node Package Manager）``
:::

## 作成したじゃんけんアプリのデモ動画
以下はじゃんけんアプリの対戦デモ動画です。プレイヤーが「グー」「チョキ」「パー」を選択し、コンピュータの手と比較して勝敗が決まります。

![タイトルなし.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/4d6f6810-d5bb-dc1c-30b1-88192ce63989.gif)


## ディレクトリ構成
以下のようなディレクトリ構成でReactアプリを構築します。この構成により、じゃんけんアプリのファイルを適切に配置し、Docker環境で動作させることができます。

```bash
janken/
│
├── node_modules/         # Node.jsのモジュールが格納されるディレクトリ
│
├── public/               # 公開用のファイル
│   └── index.html        # アプリケーションのエントリーポイントとなるHTMLファイル
│
├── src/                  # ソースコードのディレクトリ
│   ├── Janken.js         # じゃんけんのロジック
│   ├── Janken.css        # じゃんけんのスタイルシート
│   ├── index.js          # アプリケーションのエントリーポイント
│   └── index.css         # アプリケーションのスタイルシート
│
├── .dockerignore         # Dockerビルド時に無視するファイル
├── Dockerfile            # Dockerイメージを作成するための設定ファイル
├── docker-compose.yml    # Docker Composeの設定ファイル
├── package.json          # プロジェクトの依存関係やスクリプトを管理するファイル
└── README.md             # プロジェクトの説明や使い方を記載したファイル(任意)
```

このディレクトリ構成を作成するために、以下のコマンドを実行して初期ファイルを生成し、不要なファイルを削除して整理します。

```bash
npx create-react-app janken
```


:::note warn
**上記のコマンドを実行するとデフォルトで多数のファイルが作成されますが、ここでは不要なファイルを削除して進めます。**
:::

## ステップ1: プロジェクトの作成
### Dockerfileの作成
まず、プロジェクトのルートディレクトリに以下の内容で ``Dockerfile`` を作成します。

```Dockerfile
# Dockerfile
FROM node:14

# 作業ディレクトリの設定
WORKDIR /app

# 依存関係のインストール
COPY package*.json ./
RUN npm install

# アプリケーションのソースをコピー
COPY . .

# アプリケーションをビルド
RUN npm run build

# アプリケーションを提供する
CMD ["npm", "start"]
```

この ``Dockerfile`` は、Dockerイメージを作成するための設定ファイルです。Node.js 環境を構築し、アプリケーションの依存関係をインストールし、最終的にアプリをビルドします。

### docker-compose.ymlの作成
次に、プロジェクトのルートディレクトリに以下の内容で ``docker-compose.yml`` を作成します。

```docker-compose.yml
version: '3'
services:
  app:
    build: .
    ports:
      - "3000:3000"
    volumes:
      - .:/app
    environment:
      - CHOKIDAR_USEPOLLING=true
```

このファイルは、Docker Composeを使用してアプリケーションのサービス構成を定義するものです。アプリケーションのビルド、ポートの公開、ボリュームの設定などを管理します。

## ステップ2: Reactアプリの作成

ここでは、じゃんけんアプリの機能を実装するためのファイルをプロジェクトに追加します。

### Janken.js
以下は ``Janken.js`` のコードです。このコードでは、じゃんけんの手と勝敗判定の基本ロジックを実装しています。

```Janken.js
// src/Janken.js
import React, { useState } from 'react';
import './Janken.css';

const Janken = () => {
  const [result, setResult] = useState("");
  const [userChoice, setUserChoice] = useState("");
  const choices = ["グー", "チョキ", "パー"];

  const handleClick = (choice) => {
    const computerChoice = choices[Math.floor(Math.random() * choices.length)];
    setUserChoice(choice);

    if (choice === computerChoice) {
      setResult("あいこです！");
    } else if (
      (choice === "グー" && computerChoice === "チョキ") ||
      (choice === "チョキ" && computerChoice === "パー") ||
      (choice === "パー" && computerChoice === "グー")
    ) {
      setResult("あなたの勝ちです！");
    } else {
      setResult("あなたの負けです…");
    }
  };

  return (
    <div className="container">
      <h1>じゃんけん</h1>
      <div className="choices">
        {choices.map((choice) => (
          <button key={choice} onClick={() => handleClick(choice)}>
            {choice}
          </button>
        ))}
      </div>
      <p>あなたの手: {userChoice}</p>
      <p>結果: {result}</p>
    </div>
  );
};

export default Janken;
```

### Janken.css
以下は ``Janken.css`` のコードです。じゃんけんの選択ボタンと結果表示にスタイルを適用しています。

```Janken.css
/* src/Janken.css */
body {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  background-color: #f7d1e5;
  margin: 0;
}

.container {
  text-align: center;
  font-family: 'Arial', sans-serif;
}

.choices button {
  font-size: 24px;
  margin: 5px;
  padding: 10px 20px;
  border-radius: 5px;
  cursor: pointer;
}

p {
  font-size: 20px;
}
```

### index.js
以下は ``index.js`` のコードです。Reactのエントリーポイントとして、アプリケーションをレンダリングしています。


```index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import Janken from './Janken';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <Janken />
  </React.StrictMode>
);
```

### index.css
次に、全体のスタイルを設定するための ``index.css`` ファイルをプロジェクトに追加します。

```index.css
/* src/index.css */
body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  background-color: #f0f0f0;
}
```

## ステップ3: アプリの起動
最後に、以下のコマンドでアプリケーションを起動します。

```bash
# Docker Composeを使ってアプリケーションを起動
docker-compose up
```

ブラウザで、``http://localhost:3000/``を入力すると、以下のページが表示されていれば成功です。

![スクリーンショット 2024-11-03 15.24.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/7f5377a8-5438-d7d2-7ffd-5d3c4b6643db.png)

今回は、じゃんけんの基本的な勝敗判定のみを実装しており、プレイヤー同士で気軽に遊べるシンプルなアプリになっています。

![スクリーンショット 2024-11-03 15.23.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/d5e8e81f-f3a0-1e14-0947-d7900e782ae3.png)

残念ながら負けてしまいましたね（笑）。

## まとめ
本記事では、Dockerを使用してReactでじゃんけんアプリを作成しました。

現時点では基本的な勝敗判定のみのシンプルな機能ですが、今後さらに学びを深め、コンピュータのAI対戦やネットワーク対戦機能を追加できればと考えています。

Reactについては、一度学んで基礎が身につくと、他のアプリでも応用が効くようになってきたと感じています。

## 参考文献

https://zenn.dev/st43/articles/602e20be5f8823

https://www.wantedly.com/companies/jointcrew/post_articles/892486