HTMLとJavaScriptで自作スロットマシンに挑戦！

## はじめに

今回は、HTMLとJavaScriptを使って、簡単なスロットマシンを作ってみたいと思います。自宅でカジノ気分を味わいたい方や、プログラミングの練習としてもおすすめです！コードの構成はシンプルですが、少しおしゃれな見た目に仕上げていますので、楽しく挑戦してみてください。

### 完成品イメージ
![スクリーンショット 2024-09-20 20.10.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75802/b631ed28-2d84-2fad-1ecc-98029ba11ee2.png)

3つのリールが回転し、それぞれに「ストップ」ボタンが付いています。リールを停止させ、3つのリールに同じ絵柄が揃えば「大当たり！」が表示されます。違う絵柄だと「残念！」という結果になります。コードを一部変更するだけで、見た目や挙動を簡単にカスタマイズすることも可能です！

---

## スロットマシンを作る手順

### 1. 必要なファイル
今回のスロットマシンは、次の3つのファイルで構成されています。
- `index.html`：HTMLファイル
- `style.css`：スタイルシート
- `slot.js`：JavaScript

---

### 2. HTMLファイル (`index.html`)

まず、`index.html`で基本的なスロットマシンのレイアウトを作ります。各リールの回転とストップボタンを配置し、見やすいデザインを意識します。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>スロットマシン</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <h1>スロットマシン</h1>
        <div class="slot-container">
            <div>
                <div id="slot1" class="slot">7</div>
                <button id="stopButton1" class="stopButton">ストップ</button>
            </div>
            <div>
                <div id="slot2" class="slot">7</div>
                <button id="stopButton2" class="stopButton">ストップ</button>
            </div>
            <div>
                <div id="slot3" class="slot">7</div>
                <button id="stopButton3" class="stopButton">ストップ</button>
            </div>
        </div>
        <div class="control">
            <button id="startButton" class="startButton">スタート</button>
            <p id="result"></p>
        </div>
    </div>

    <script src="slot.js"></script>
</body>
</html>
```

---

### 3. CSSファイル (`style.css`)

次に、スロットマシンを少しおしゃれにするために、CSSファイルを使ってデザインをカスタマイズします。背景色、ボタンのスタイル、リールの見た目などを指定します。

```css
body {
    font-family: 'Arial', sans-serif;
    background-color: #f7f9fc;
    color: #333;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
}

.container {
    text-align: center;
    padding: 20px;
    background-color: #fff;
    border-radius: 15px;
    box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
    width: 80%;
    max-width: 600px;
}

h1 {
    margin-bottom: 30px;
    color: #4a90e2;
}

.slot-container {
    display: flex;
    justify-content: center;
    margin: 20px 0;
}

.slot {
    font-size: 50px;
    width: 100px;
    height: 100px;
    display: flex;
    justify-content: center;
    align-items: center;
    border-radius: 10px;
    background-color: #fff;
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
    margin: 0 10px;
    transition: transform 0.2s ease;
}

.slot:hover {
    transform: scale(1.1);
}

.stopButton, .startButton {
    margin-top: 10px;
    padding: 12px 20px;
    font-size: 16px;
    font-weight: bold;
    color: white;
    background-color: #4a90e2;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    transition: background-color 0.3s ease, transform 0.3s ease;
}

.stopButton:hover, .startButton:hover {
    background-color: #357ABD;
    transform: translateY(-3px);
}

.control {
    margin-top: 30px;
}

#result {
    font-size: 20px;
    margin-top: 20px;
    color: #333;
    font-weight: bold;
}
```

---

### 4. JavaScriptファイル (`slot.js`)

最後に、JavaScriptでスロットマシンの動きを実装します。リールが回転する処理や、ストップボタンを押したときの動作を定義します。

```javascript
const slots = [document.getElementById('slot1'), document.getElementById('slot2'), document.getElementById('slot3')];
const symbols = ['🍎', '🍌', '🍇', '🍒', '🍊', '7']; // スロットに表示するシンボル
let slotTimers = [];
let isSpinning = [false, false, false]; // 各リールの状態を管理

// スロットを開始する関数
function startSlot() {
    document.getElementById('result').textContent = ''; // 結果をクリア
    
    for (let i = 0; i < slots.length; i++) {
        if (!isSpinning[i]) {
            isSpinning[i] = true;
            slotTimers[i] = setInterval(() => {
                slots[i].textContent = symbols[Math.floor(Math.random() * symbols.length)];
            }, 100); // スロットが高速で回転
        }
    }
}

// スロットを停止する関数（リールごと）
function stopSlot(reelIndex) {
    if (isSpinning[reelIndex]) {
        clearInterval(slotTimers[reelIndex]);
        isSpinning[reelIndex] = false;

        // 全てのリールが停止したら結果を判定
        if (!isSpinning.includes(true)) {
            checkResult();
        }
    }
}

// 結果の判定関数
function checkResult() {
    const result = slots.map(slot => slot.textContent);
    if (result[0] === result[1] && result[1] === result[2]) {
        document.getElementById('result').textContent = '大当たり！';
    } else {
        document.getElementById('result').textContent = '残念！';
    }
}

// イベントリスナーをボタンに追加
document.getElementById('startButton').addEventListener('click', startSlot);
document.getElementById('stopButton1').addEventListener('click', () => stopSlot(0));
document.getElementById('stopButton2').addEventListener('click', () => stopSlot(1));
document.getElementById('stopButton3').addEventListener('click', () => stopSlot(2));
```



### JavaScript (`slot.js`) のプログラム説明
このプログラムでは、3つのスロットリールがランダムに回転し、ストップボタンを押すとリールが停止します。3つのリールの絵柄が全て揃うと「大当たり！」、揃わなければ「残念！」と表示されます。

---

### 1. **変数と要素の取得**
```javascript
const slots = [document.getElementById('slot1'), document.getElementById('slot2'), document.getElementById('slot3')];
const symbols = ['🍎', '🍌', '🍇', '🍒', '🍊', '7']; // スロットに表示するシンボル
let slotTimers = [];
let isSpinning = [false, false, false]; // 各リールの状態を管理
```

- **`slots`**: 3つのスロットリールのHTML要素（`slot1`, `slot2`, `slot3`）を配列として取得しています。
- **`symbols`**: スロットリールに表示されるシンボル（絵文字）を配列で定義しています。この中からランダムに選ばれます。
- **`slotTimers`**: 各リールの回転を制御するためのタイマーIDを保持します。
- **`isSpinning`**: 各リールが回転中かどうかを示すフラグです。`true`ならリールが回転中、`false`なら停止中です。

---

### 2. **スロットを回転させる関数: `startSlot()`**
```javascript
function startSlot() {
    document.getElementById('result').textContent = ''; // 結果をクリア
    
    for (let i = 0; i < slots.length; i++) {
        if (!isSpinning[i]) {
            isSpinning[i] = true;
            slotTimers[i] = setInterval(() => {
                slots[i].textContent = symbols[Math.floor(Math.random() * symbols.length)];
            }, 100); // スロットが高速で回転
        }
    }
}
```

- **`startSlot`**: 「スタート」ボタンを押したときに呼び出される関数です。
- **`document.getElementById('result').textContent = '';`**: 前回の結果（「大当たり」や「残念」）をリセットします。
- **`for (let i = 0; i < slots.length; i++)`**: 各リールについてループ処理を行い、回転させます。
- **`isSpinning[i]`**: リールが停止中であれば、回転させる準備をします。
- **`setInterval()`**: 100ミリ秒ごとにリールの表示をランダムに切り替えるタイマーです。この関数は、リールが高速で回転しているように見せます。

---

### 3. **スロットを停止させる関数: `stopSlot()`**
```javascript
function stopSlot(reelIndex) {
    if (isSpinning[reelIndex]) {
        clearInterval(slotTimers[reelIndex]);
        isSpinning[reelIndex] = false;

        // 全てのリールが停止したら結果を判定
        if (!isSpinning.includes(true)) {
            checkResult();
        }
    }
}
```

- **`stopSlot(reelIndex)`**: 各リールの「ストップ」ボタンを押したときに、対応するリールを停止させる関数です。
- **`if (isSpinning[reelIndex])`**: 指定されたリールが回転中であれば、停止処理を行います。
- **`clearInterval()`**: リールの回転を止めます。これにより、リールの絵柄の切り替えが止まります。
- **`isSpinning[reelIndex] = false;`**: リールが停止したことを示すフラグを`false`に設定します。
- **`!isSpinning.includes(true)`**: 全てのリールが停止したかどうかを確認しています。全リールが停止している場合のみ結果判定を行います。

---

### 4. **結果の判定関数: `checkResult()`**
```javascript
function checkResult() {
    const result = slots.map(slot => slot.textContent);
    if (result[0] === result[1] && result[1] === result[2]) {
        document.getElementById('result').textContent = '大当たり！';
    } else {
        document.getElementById('result').textContent = '残念！';
    }
}
```

- **`checkResult()`**: 全てのリールが停止した後に呼び出され、スロットの結果を判定する関数です。
- **`result`**: 各リールに表示されているシンボルを配列として取得します。
- **`if (result[0] === result[1] && result[1] === result[2])`**: 3つのリールに表示されているシンボルがすべて同じ場合に「大当たり！」と表示します。異なる場合は「残念！」と表示します。

---

### 5. **イベントリスナー**
```javascript
document.getElementById('startButton').addEventListener('click', startSlot);
document.getElementById('stopButton1').addEventListener('click', () => stopSlot(0));
document.getElementById('stopButton2').addEventListener('click', () => stopSlot(1));
document.getElementById('stopButton3').addEventListener('click', () => stopSlot(2));
```

- **`startButton`**: 「スタート」ボタンがクリックされたときに`startSlot()`を呼び出し、リールを回転させます。
- **`stopButton1`, `stopButton2`, `stopButton3`**: 各リールの「ストップ」ボタンに対応しており、クリックすると対応するリールの回転が止まります。

---

### jsまとめ
- **`startSlot()`**: スロットの回転を開始します。
- **`stopSlot(reelIndex)`**: 各リールを停止します。
- **`checkResult()`**: リールが全て停止したら、結果を判定します。
- **イベントリスナー**: 「スタート」ボタンと各「ストップ」ボタンに対して、回転開始と停止の動作を紐付けています。

---

## 全体まとめ

いかがでしたか？このスロットマシンの作成はとても簡単ですが、JavaScriptで動きをコントロールする面白さや、CSSで見た目をカスタマイズする楽しさを感じていただけたと思います。これをベースに、リールの数を増やしたり、当たりの条件を変更したりして、オリジナルのスロットマシンに発展させてみてください！