【ゲーム】JavaScript:35 じゃんけんゲーム

 「✊✌️✋ じゃんけんゲーム」は、プレイヤー(👨‍🦱)とCPU(🤖)がグー・チョキ・パーを先に3回勝利するまで対戦するシンプルなブラウザゲームです。背景画像や手のパネルをクリックして遊びます。

遊び方と操作方法

  1. タイトル画面の「スタート ▶️」ボタンをクリック
  2. ゲーム画面で、自分の出したい手(✊✌️✋)のパネルをクリック
  3. CPUの手がランダムに決まり、勝敗が判定される
  4. 先に3勝した方が最終勝者となり、終了画面へ

ルール

  • グー(✊)はチョキ(✌️)に勝ち、チョキはパー(✋)に勝ち、パーはグーに勝つ。
  • 同じ手の場合は引き分け(再試行)。
  • プレイヤーかCPUが3回勝利した時点でゲーム終了。

🎮ゲームプレイ

以下のリンク先から実際にプレイできます。

35 じゃんけんゲーム

素材のダウンロード

以下のリンクから使用する素材をダウンロードできます。

janken_title.pngjanken_bg.png

ゲーム画面イメージ

プログラム全文(janken.html)

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>✊✌️✋ じゃんけんゲーム ✊✌️✋</title>
  <style>
    /* ===== 全体リセット ===== */
    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }
    body {
      /* 背景画像を全面に表示 */
      background: url('janken_bg.png') no-repeat center center fixed;
      background-size: cover;
      font-family: 'Arial', sans-serif;
      height: 100vh;
      user-select: none;
      position: relative;
      color: #333;
    }
    .hidden {
      display: none;
    }

    /* ===== オーバーレイ(タイトル・終了画面)共通設定 ===== */
    .overlay {
      position: absolute;
      top: 50%; left: 50%;
      transform: translate(-50%, -50%);
      background-color: rgba(255,255,255,0.95);
      padding: 20px;
      border-radius: 10px;
      width: 600px;            /* 横幅を560pxに設定 */
      max-width: 90%;
      box-shadow: 0 4px 8px rgba(0,0,0,0.3);
      z-index: 10;
    }

    /* ===== タイトル画面 ===== */
    #title-screen h1 {
      text-align: center;
      font-size: 2em;
      margin-bottom: 10px;
    }
    #title-screen .title-image {
      display: block;
      margin: 0 auto 10px;
      max-width: 80%;
      height: auto;
    }
    #title-screen .instructions-title {
      text-align: center;
      font-weight: bold;
      margin-top: 10px;
      font-size: 1.1em;
    }
    #title-screen .instructions {
      text-align: left;
      margin: 10px 0;
      line-height: 1.4;
      font-size: 0.95em;
    }
    #title-screen .btn {
      display: block;
      margin: 20px auto 0;
    }

    /* ===== 共通ボタンスタイル ===== */
    .btn {
      padding: 10px 20px;
      font-size: 1em;
      font-weight: bold;
      color: #fff;
      background-color: #007bff;
      border: none;
      border-radius: 5px;
      cursor: pointer;
      transition: background-color 0.2s, transform 0.1s;
    }
    .btn:hover {
      background-color: #0056b3;
      transform: translateY(-2px);
    }
    .btn:active {
      transform: translateY(0);
    }

    /* ===== ゲーム画面 ===== */
    #game-screen {
      width: 100%;
      height: 100%;
      text-align: center;
      padding-top: 40px;
    }
    /* ゲーム領域の幅も560pxに */
    #game-screen .game-area {
      display: inline-block;
      background-color: rgba(255,255,255,0.85);
      padding: 30px;
      border-radius: 10px;
      box-shadow: 0 4px 8px rgba(0,0,0,0.2);
      width: 560px;
      max-width: 90%;
    }
    /* スコア表示を大きく */
    #scoreboard {
      font-size: 1.6em;
      margin-bottom: 20px;
    }
    #choices {
      margin-top: 20px;
    }
    .choice-panel {
      display: inline-block;
      width: 100px;
      height: 100px;
      margin: 0 15px;
      font-size: 3em;
      line-height: 100px;
      text-align: center;
      border: 2px solid #333;
      border-radius: 10px;
      background-color: rgba(255,255,255,0.8);
      cursor: pointer;
      transition: background-color 0.2s, transform 0.1s;
    }
    .choice-panel:hover {
      background-color: rgba(0,123,255,0.2);
      transform: translateY(-3px);
    }
    /* 結果表示も少し大きく */
    #result-message {
      margin-top: 30px;
      padding: 12px 20px;
      display: inline-block;
      background-color: rgba(0,0,0,0.7);
      color: #fff;
      border-radius: 5px;
      font-size: 1.3em;
    }

    /* ===== 終了画面 ===== */
    #end-screen h2 {
      text-align: center;
      font-size: 1.5em;
      margin-bottom: 10px;
    }
    /* 終了メッセージをさらに大きく */
    #end-screen .game-message {
      text-align: center;
      margin-bottom: 20px;
      font-size: 1.5em;
    }
    /* 終了画面の戻るボタンをセンタリング */
    #end-back-btn {
      display: block;
      margin: 0 auto;
    }
  </style>
</head>
<body>

  <!-- タイトル画面 -->
  <div id="title-screen" class="overlay">
    <!-- タイトル画像 -->
    <img src="janken_title.png" alt="じゃんけんゲーム タイトル" class="title-image">
    <!-- ゲームタイトル -->
    <h1>✊✌️✋ じゃんけんゲーム ✊✌️✋</h1>
    <!-- ルール説明見出し -->
    <div class="instructions-title">📖 遊び方・ルール</div>
    <!-- ルール説明文(左寄せ) -->
    <div class="instructions">
      <p>・「✊✌️✋」のパネルをクリックして選ぶ</p>
      <p>・🤖(CPU)と👨‍🦱(プレイヤー)で対戦します</p>
      <p>・先に3回勝利した方が最終勝者</p>
      <p>・「✊ vs ✌️ → グーはチョキに勝ち」などで判定</p>
    </div>
    <!-- スタートボタン -->
    <button id="start-btn" class="btn">スタート ▶️</button>
  </div>

  <!-- ゲーム画面 -->
  <div id="game-screen" class="hidden">
    <div class="game-area">
      <!-- スコア表示 -->
      <div id="scoreboard">👨‍🦱: 0 vs 🤖: 0</div>
      <!-- じゃんけん選択パネル -->
      <div id="choices">
        <div class="choice-panel" data-choice="0">✊</div>
        <div class="choice-panel" data-choice="1">✌️</div>
        <div class="choice-panel" data-choice="2">✋</div>
      </div>
      <!-- 判定結果メッセージ -->
      <div id="result-message">手を選んでください</div>
    </div>
  </div>

  <!-- 終了画面 -->
  <div id="end-screen" class="overlay hidden">
    <!-- 終了タイトル -->
    <h2>🎉 ゲーム終了 🎉</h2>
    <!-- 終了時の判定メッセージ -->
    <div id="end-message" class="game-message">---</div>
    <!-- タイトルに戻るボタン(中央寄せ) -->
    <button id="end-back-btn" class="btn">タイトル画面に戻る ↩️</button>
  </div>

  <script>
  // ===== 定数設定 =====
  const WIN_TARGET = 3;                // 先に3回勝利でゲーム終了
  const HANDS = ['✊','✌️','✋'];        // グー・チョキ・パーを配列で保持

  // ===== ゲーム状態変数 =====
  let playerWins = 0;  // プレイヤーの勝利回数
  let cpuWins    = 0;  // CPUの勝利回数

  // ===== DOM 要素取得 =====
  const titleScreen = document.getElementById('title-screen');
  const gameScreen  = document.getElementById('game-screen');
  const endScreen   = document.getElementById('end-screen');
  const startBtn    = document.getElementById('start-btn');
  const choices     = document.querySelectorAll('.choice-panel');
  const scoreboard  = document.getElementById('scoreboard');
  const resultMsg   = document.getElementById('result-message');
  const endBackBtn  = document.getElementById('end-back-btn');
  const endMessage  = document.getElementById('end-message');

  /**
   * タイトル画面を表示する
   */
  function showTitle() {
    titleScreen.classList.remove('hidden');
    gameScreen.classList.add('hidden');
    endScreen.classList.add('hidden');
  }

  /**
   * ゲーム画面を表示し、状態を初期化する
   */
  function showGame() {
    titleScreen.classList.add('hidden');
    gameScreen.classList.remove('hidden');
    endScreen.classList.add('hidden');
    initGame();  // ゲーム状態の初期化
  }

  /**
   * 終了画面を表示する
   * @param {'player'|'cpu'} winner - 勝者
   * @param {string} pHand - プレイヤーの手
   * @param {string} cHand - CPUの手
   */
  function showEnd(winner, pHand, cHand) {
    gameScreen.classList.add('hidden');
    titleScreen.classList.add('hidden');
    endScreen.classList.remove('hidden');
    // 終了メッセージを設定
    if (winner === 'player') {
      endMessage.textContent = `👨‍🦱${pHand} vs 🤖${cHand} → プレイヤーの勝ち!`;
    } else {
      endMessage.textContent = `👨‍🦱${pHand} vs 🤖${cHand} → CPUの勝ち…`;
    }
  }

  /**
   * ゲーム状態を初期化する
   */
  function initGame() {
    playerWins = 0;
    cpuWins    = 0;
    updateScoreboard();
    resultMsg.textContent = '手を選んでください';
  }

  /**
   * スコアボードを更新する
   */
  function updateScoreboard() {
    scoreboard.textContent = `👨‍🦱: ${playerWins} vs 🤖: ${cpuWins}`;
  }

  /**
   * 勝敗を判定する
   * @param {number} player - プレイヤーの手 (0-2)
   * @param {number} cpu - CPUの手 (0-2)
   * @returns {'player'|'cpu'|'draw'}
   */
  function judge(player, cpu) {
    if (player === cpu) return 'draw';
    // (player - cpu + 3) % 3 === 1 の場合プレイヤー勝ち
    return ((player - cpu + 3) % 3 === 1) ? 'player' : 'cpu';
  }

  // グー・チョキ・パー文字列保持(終了画面用)
  let pHand = '', cHand = '';

  // ===== パネルクリック時の処理 =====
  choices.forEach(panel => {
    panel.addEventListener('click', () => {
      // プレイヤーの選択を取得
      const playerChoice = Number(panel.dataset.choice);
      // CPUの選択をランダムに決定
      const cpuChoice = Math.floor(Math.random() * 3);

      pHand = HANDS[playerChoice];  // プレイヤー手のテキスト
      cHand = HANDS[cpuChoice];     // CPU手のテキスト

      // 勝敗判定
      const result = judge(playerChoice, cpuChoice);

      // 結果メッセージを表示
      if (result === 'draw') {
        resultMsg.textContent = `👨‍🦱${pHand} vs 🤖${cHand} → 引き分け`;
      } else if (result === 'player') {
        playerWins++;
        resultMsg.textContent = `👨‍🦱${pHand} vs 🤖${cHand} → プレイヤーの勝ち`;
      } else {
        cpuWins++;
        resultMsg.textContent = `👨‍🦱${pHand} vs 🤖${cHand} → CPUの勝ち`;
      }

      // スコアボードを更新
      updateScoreboard();

      // 先に3勝した方で終了
      if (playerWins === WIN_TARGET) {
        setTimeout(() => showEnd('player', pHand, cHand), 500);
      } else if (cpuWins === WIN_TARGET) {
        setTimeout(() => showEnd('cpu', pHand, cHand), 500);
      }
    });
  });

  // ===== ボタンイベント登録 =====
  startBtn.addEventListener('click', showGame);
  endBackBtn.addEventListener('click', showTitle);

  // ===== 初期表示 =====
  document.addEventListener('DOMContentLoaded', showTitle);
  </script>
</body>
</html>

アルゴリズムの流れ

ステップ説明関数・処理
1タイトル画面を表示showTitle()
2「スタート」を押したらゲーム画面へ切替し状態を初期化showGame()initGame()
3プレイヤーがパネルをクリックchoices.forEach イベント
4CPUの手をランダム生成Math.floor(Math.random()*3)
5勝敗を判定judge(player, cpu)
6勝敗に応じてスコア更新playerWins++ / cpuWins++
7先に3勝したプレイヤーを終了画面へshowEnd(winner)

関数の詳細解説

関数名役割
showTitle()タイトル画面を表示し、他画面を非表示にする
showGame()ゲーム画面を表示し、タイトルと終了画面を非表示にする
initGame()playerWinscpuWins を0にリセットし、スコア表示を初期化
updateScoreboard()スコアボード (👨‍🦱 vs 🤖) のテキストを更新
judge(player,cpu)グー・チョキ・パーの勝敗を (player - cpu + 3) % 3 === 1 で判定
showEnd(winner)終了画面を表示し、勝者に応じたメッセージを設定

改造のポイント

  • 勝利判定の条件変更
    先に N 勝(例:5勝)まで遊べるように WIN_TARGET を設定可能。
  • UIカスタマイズ
    手のアイコンや背景を差し替えてオリジナルデザインに。パネルのホバーエフェクトを強化しても良いでしょう。
  • 連続プレイカウンタ
    ローカルストレージに勝敗履歴を保存し、連勝数や対戦ログを残す機能を追加。
  • AIの強化
    完全ランダムから、過去の統計に基づく手選択へ進化させると対戦相手として面白くなります。
  • マルチプレイヤー対応
    WebSocket や Firebase を使い、遠隔の友達と対戦できるよう拡張可能です。

最後に
「じゃんけん」はシンプルながらも、プログラム入門やUIカスタマイズの練習に最適な題材です。ぜひ本記事を参考に、オリジナル要素を加えてさらに楽しいゲームに育ててください!