1手詰め将棋アプリ開発：Reactで作るシンプル詰将棋アプリをDockerで動かすまでの手順

## はじめに
本記事では、Docker環境でReactを使用して詰将棋アプリを作成する手順を説明します。

ただし、詰将棋の実装方法について十分に調べる時間がなかったため、今回は将棋盤の表示と持ち駒の簡単な移動のみを実装しています。

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

## 必要なツール

:::note
**私の環境では、M1チップ搭載のMacOSを使用していますが、今回のハンズオンに必要なツールは以下の通りです。**
・``Docker``
・``Docker Compose``
・``Node.js（バージョン14以上推奨）``
・``npm（Node Package Manager）``
:::

## 作成した詰将棋アプリのデモ動画

今回のReactアプリにはほとんど機能が実装されていませんが、実際の対戦デモ動画になります。

![タイトルなし.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/bfac040f-65a8-9d8a-bc46-e9758830a1bf.gif)


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

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

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

```
npx create-react-app tsumeshogi
```

:::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アプリの作成
次に、以下のファイルをプロジェクトに追加します。

### Shogi.js

以下は ``Shogi.js`` のコードです。このコードでは、将棋の盤面と駒の簡単な移動を実装しています。

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

const BOARD_SIZE = 9;

// 1手詰めの初期局面を設定
const initializeBoard = () => {
  const board = Array(BOARD_SIZE).fill(null).map(() => Array(BOARD_SIZE).fill(null));
  board[0][8] = '玉';  // 玉将の位置を右端に配置
  board[2][6] = '金';  // 金を玉の2つ前に配置
  return board;
};

const Shogi = () => {
  const [board, setBoard] = useState(initializeBoard);
  const [selectedPiece, setSelectedPiece] = useState(null);

  const handleClick = (row, col) => {
    if (selectedPiece) {
      // 駒の移動ロジック
      const newBoard = board.map(row => [...row]);
      newBoard[row][col] = selectedPiece;
      setBoard(newBoard);
      setSelectedPiece(null);
    } else {
      setSelectedPiece(board[row][col]);
    }
  };

  const moveGold = () => {
    // 金を一マス右に移動させて詰みを実現
    const newBoard = board.map(row => [...row]);
    newBoard[1][7] = '金'; // 金を1マス右に移動
    newBoard[0][6] = null; // 元の位置の金を消す
    setBoard(newBoard);
  };

  const renderBoard = () => {
    return (
      <div className="board">
        {board.map((row, i) => (
          <div key={i} className="row">
            {row.map((cell, j) => (
              <div
                key={j}
                onClick={() => handleClick(i, j)}
                className="cell"
              >
                {cell}
              </div>
            ))}
          </div>
        ))}
      </div>
    );
  };

  return (
    <div className="container">
      <h1>詰将棋</h1>
      <button onClick={moveGold}>金を移動させて詰める</button>
      {renderBoard()}
    </div>
  );
};

export default Shogi;
```

### Shogi.css

以下は ``Shogi.css`` のコードです。将棋盤と駒の表示にスタイルを適用しています。

```Shogi.css
/* src/Shogi.css */
.container {
  text-align: center;
  font-family: 'Arial', sans-serif;
}

.board {
  display: flex;
  flex-direction: column;
  margin: 20px auto;
  width: 450px;
  background-color: #D2B48C; /* 将棋盤風の色 */
}

.row {
  display: flex;
}

.cell {
  width: 50px;
  height: 50px;
  display: flex;
  justify-content: center;
  align-items: center;
  border: 1px solid #333;
  font-size: 24px;
}
```

### index.js

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

```index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import Reversi from './Shogi'; // 'App'を'Shogi'に変更

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <Reversi />
  </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;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  background-color: #f5f5f5;
}
```

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

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

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

![スクリーンショット 2024-11-02 23.42.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/425a7bb3-590b-78fb-5520-81ba1712e928.png)

ここでは、「``金を移動させて詰める``」ボタンをクリックすると、玉を詰めるための一手詰めが実行されます。笑

![スクリーンショット 2024-11-02 23.46.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/ccd65c9c-e538-8a70-0846-d1775434a562.png)

## まとめ
本記事では、Dockerを利用してReactで1手詰め将棋を作成しました。

機能としてはまだ限られていますが、時間や学習コストの観点から今回はこの段階までとしました。

今後は、ボット形式で判断し逃げるなどの動作も実装できるよう、さらに調べてみる予定です。

## 参考記事

https://qiita.com/kz23szk/items/0fa9267b8fa7d7ce03ee