ハイアンドローゲームをHTMLとJavaScriptで作成してみた


# はじめに
今回は、HTMLとJavaScriptを使ってトランプのハイアンドローゲームを作成しました。カードのランク（数字やJ、Q、Kなど）を見て、次のカードが「高い」か「低い」かを予測するシンプルなゲームです。デザインも少しオシャレにしてみたので、ぜひご覧ください！

## 完成したゲームのデモ
![スクリーンショット 2024-09-24 17.33.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75802/d24242e3-ffa5-0b65-8f01-f3bc7bba608d.png)


このゲームでは、現在のカードが表示され、その後プレイヤーが次のカードが「高い」か「低い」かを予測します。正解すると連続正解数が増え、不正解になると連続正解数がリセットされます。

## 使用技術
- **HTML**
- **CSS**
- **JavaScript**

それでは、具体的な実装に入っていきましょう。

---

## HTMLの構成

まずは、HTMLの構成です。この部分では、ゲームのレイアウトやボタンの配置を定義しています。

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>High and Low - Card Game</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <h1>High and Low - Card Game</h1>
        <div class="card-display">
            <p id="current-card">Current Card: ?</p>
        </div>
        <div class="buttons">
            <button onclick="guess('high')">High</button>
            <button onclick="guess('low')">Low</button>
        </div>
        <p id="result"></p>
        <p id="score">Streak: 0</p>
    </div>

    <script src="card-game.js"></script>
</body>
</html>
```

### 解説
- `<h1>`タグでゲームのタイトルを表示。
- `id="current-card"`で現在のカードの情報を表示する場所を作り、ボタンを押すことで次のカードと比較します。
- ボタンは2つあり、「High」「Low」を選択できるようにしています。
- JavaScriptファイル（`card-game.js`）を最後に読み込んでおり、クリックイベントでゲームの処理が実行されるようにします。

---

## CSSでスタイリッシュなデザインを作成

次に、CSSで見た目をスタイリッシュにします。背景色やボタンのホバーエフェクトなどを設定し、オシャレなデザインに仕上げます。

```css
/* 全体のスタイル */
body {
    font-family: 'Arial', sans-serif;
    background-color: #f4f4f9;
    color: #333;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
}

.container {
    text-align: center;
    background-color: #ffffff;
    padding: 30px;
    border-radius: 15px;
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
    width: 300px;
}

/* タイトルのスタイル */
h1 {
    font-size: 24px;
    margin-bottom: 20px;
    color: #333;
}

/* カードの表示スタイル */
.card-display {
    background-color: #ffe0e6;
    border-radius: 10px;
    padding: 20px;
    margin-bottom: 20px;
    box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.1);
}

#current-card {
    font-size: 24px;
    font-weight: bold;
    color: #333;
}

/* ボタンのスタイル */
.buttons button {
    background-color: #007bff;
    color: white;
    padding: 10px 20px;
    border: none;
    border-radius: 5px;
    margin: 5px;
    cursor: pointer;
    transition: background-color 0.3s ease;
    font-size: 16px;
}

.buttons button:hover {
    background-color: #0056b3;
}

/* 結果とスコアのスタイル */
#result, #score {
    font-size: 18px;
    margin-top: 10px;
}
```

### 解説
- 全体的にシンプルでクリーンなデザインにするため、白を基調にし、シャドウを使って立体感を出しています。
- ボタンにはホバースタイルを追加し、押したときの感覚をユーザーに与えるようにしています。
- カードの表示エリアには少し柔らかいピンクを使い、視覚的に楽しめるようにしています。

---

## JavaScriptの実装

ゲームロジックの中心となる部分がJavaScriptです。ランダムにカードを引き、プレイヤーの予測が正しいかどうかを判定し、連続正解数を管理します。

```javascript
// カードのスートとランクの定義
const suits = ["♠", "♥", "♦", "♣"];
const ranks = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"];

// 現在のカードとスコア
let currentCard = drawCard();
let streak = 0;  // 連続正解数
document.getElementById("current-card").innerText = `Current Card: ${currentCard.rank} ${currentCard.suit}`;

// カードを引く関数
function drawCard() {
    let suit = suits[Math.floor(Math.random() * suits.length)];
    let rank = ranks[Math.floor(Math.random() * ranks.length)];
    return { suit: suit, rank: rank, rankValue: ranks.indexOf(rank) };
}

// ゲームの予測関数
function guess(prediction) {
    let newCard = drawCard();
    let resultText = '';

    if ((prediction === 'high' && newCard.rankValue > currentCard.rankValue) || 
        (prediction === 'low' && newCard.rankValue < currentCard.rankValue)) {
        resultText = `Correct! The new card is ${newCard.rank} ${newCard.suit}.`;
        streak++;  // 正解した場合、連続正解数を増やす
    } else {
        resultText = `Wrong! The new card is ${newCard.rank} ${newCard.suit}.`;
        streak = 0;  // 間違えた場合、連続正解数をリセット
    }

    // 結果と連続正解数の更新
    document.getElementById("result").innerText = resultText;
    document.getElementById("score").innerText = `Streak: ${streak}`;
    
    // 新しいカードをセット
    currentCard = newCard;
    document.getElementById("current-card").innerText = `Current Card: ${currentCard.rank} ${currentCard.suit}`;
}
```

### 解説
- **drawCard関数**: スートとランクをランダムに選んでカードを引く関数です。スートとランクの配列からランダムに1つずつ選び、現在のカードとして設定します。
- **guess関数**: プレイヤーの選択（「High」か「Low」）に応じて、次のカードが今のカードより高いか低いかを判定し、正解か不正解かを表示します。正解すれば`streak`が増え、不正解であれば0にリセットされます。
- **スコア表示**: 連続正解数を画面上に表示するようにしています。

---

### demo (CodePen)
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="dyxPNKg" data-pen-title="Untitled" data-user="domlzqyy-the-decoder" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/domlzqyy-the-decoder/pen/dyxPNKg">
  Untitled</a> by 野口正人 (<a href="https://codepen.io/domlzqyy-the-decoder">@domlzqyy-the-decoder</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## まとめ

このように、HTML、CSS、そしてJavaScriptを使って、簡単なハイアンドローゲームを作成できます。トランプカードの要素を取り入れ、シンプルでオシャレなデザインに仕上げることができました。さらに、このゲームにはスコアシステムを追加して、プレイヤーが連続正解数を競えるようにしています。