【ゼロから始めるJavaScript】JavaScriptでマルバツゲームを作ってみよう!

JavaScript/TypeScript
この記事を書いた人
柊あい

生成AI研究家。新卒で一般企業に就職するも、日々の過酷な残業でメンタルを崩し、退職。
そんな中、生成AIに出会い、当時はまだ珍しかったAI活用フリーランサーとして活動。現在はAI活用を広めるインフルエンサーとして、本サイトの記事の執筆を担当。

公式SNSをフォローする

JavaScriptは、Webブラウザで動作するプログラム言語で、インタラクティブな要素をWebページに追加するために使われます。今回は、そのJavaScriptを使ってシンプルなマルバツゲームを作成していきます。

JavaScriptでマルバツゲームを作る

マルバツゲームとは?

まずは、マルバツゲームがどんなゲームなのか説明します。これは3×3のボード上で「X」と「O」を交互に配置し、縦、横、斜めに同じ記号が3つ揃うと勝利するというシンプルなゲームです。

必要な機能

  • ボードの表示
  • ユーザー入力の処理
  • 勝利条件のチェック
  • ゲームの状態(勝者がいるか、引き分けか)の判断
  • ゲームのリセット

ステップバイステップガイド

ステップ1: HTMLでボードを作成しよう

まずは、HTMLでマルバツゲームの3×3のボードを作成します。今回は、各マスをボタンで表現していきます。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>マルバツゲーム</title>
    <style>
        .board {
            display: grid;
            grid-template-columns: repeat(3, 100px);
            grid-template-rows: repeat(3, 100px);
            gap: 10px;
        }
        .cell {
            width: 100px;
            height: 100px;
            font-size: 2em;
            text-align: center;
            vertical-align: middle;
        }
        #message {
            margin-top: 20px;
            font-size: 1.5em;
        }
    </style>
</head>
<body>
    <h1>マルバツゲーム</h1>
    <div class="board">
        <button class="cell" id="cell-0"></button>
        <button class="cell" id="cell-1"></button>
        <button class="cell" id="cell-2"></button>
        <button class="cell" id="cell-3"></button>
        <button class="cell" id="cell-4"></button>
        <button class="cell" id="cell-5"></button>
        <button class="cell" id="cell-6"></button>
        <button class="cell" id="cell-7"></button>
        <button class="cell" id="cell-8"></button>
    </div>
    <div id="message"></div>
    <script src="script.js"></script>
</body>
</html>

解説:

  • HTMLで3×3のグリッド状のボードを作成し、各マスをボタンで表現しました。id属性でボタンを識別し、後ほどJavaScriptで操作できるようにしています。
  • CSSを使ってボタンの大きさや配置を整えています。

ステップ2: JavaScriptでゲームボードを初期化する

次に、JavaScriptでボードの状態を管理し、ゲームを初期化するロジックを実装します。ボードの状態は配列で管理し、プレイヤーが交互に記号を置けるようにします。

let board = ["", "", "", "", "", "", "", "", ""];
let currentPlayer = "X";  // 'X'からゲーム開始
let gameActive = true;  // ゲームがアクティブかどうかを管理するフラグ

// ボードを初期化する関数
function initializeBoard() {
    board = ["", "", "", "", "", "", "", "", ""];
    currentPlayer = "X";
    gameActive = true;  // ゲームを再びアクティブに
    document.querySelectorAll('.cell').forEach(cell => cell.textContent = "");
    document.querySelector("#message").textContent = "";  // メッセージをクリア
}

解説:

  • initializeBoard関数でゲームの状態をリセットし、画面上のボタンも空に戻します。
  • board配列で各マスの状態を管理し、初期化時に空の状態にリセットします。
  • currentPlayerは現在のプレイヤーを表し、gameActiveフラグでゲームが進行中かどうかを管理します。

AIを使ってJavaScriptのプログラムを簡単に生成したい方にオススメ!

ChatGPT活用塾
「起業家として成功したい」「フリーランスで稼ぎたい」「副業で稼ぎたい」そんな方々向けのChatGPT講座。eラーニング+コーチングであなたの業務を効率化させます。

ステップ3: プレイヤーのターンを制御する

次に、プレイヤーがクリックしたボタンに応じて、マスに「X」または「O」を置き、ターンを交代するロジックを作成します。

// プレイヤーのターンを処理する関数
function handleClick(event) {
    const cellIndex = event.target.id.split('-')[1];  // クリックされたセルのIDからインデックスを取得
    if (board[cellIndex] === "" && gameActive) {
        board[cellIndex] = currentPlayer;
        event.target.textContent = currentPlayer;
        currentPlayer = currentPlayer === "X" ? "O" : "X";  // ターンを交代
    }
}

解説:

  • handleClick関数で、クリックされたマスが空かどうかをチェックし、空であれば現在のプレイヤーの記号をそのマスに置きます。
  • ターンが終わると、currentPlayerを交代させます。

ステップ4: 勝敗条件と引き分けを実装しよう

ゲームの勝敗や引き分けを判断するロジックを追加します。特定のパターンで「X」または「O」が揃ったら勝利です。

// 勝利条件をチェックする関数
function checkWin() {
    const winPatterns = [
        [0, 1, 2], [3, 4, 5], [6, 7, 8],  // 横
        [0, 3, 6], [1, 4, 7], [2, 5, 8],  // 縦
        [0, 4, 8], [2, 4, 6]              // 斜め
    ];

    for (let pattern of winPatterns) {
        const [a, b, c] = pattern;
        if (board[a] && board[a] === board[b] && board[a] === board[c]) {
            return true;
        }
    }
    return false;
}

// 引き分けをチェックする関数
function checkDraw() {
    return !board.includes("");
}

解説:

  • checkWin関数では、あらかじめ定義した勝利パターンを使って、勝者が決定したかをチェックします。すべてのパターンを順に確認し、同じ記号が揃っている場合は勝利です。
  • checkDraw関数では、ボードがすべて埋まっていて勝者がいない場合、引き分けとします。

ステップ5: メッセージ表示とゲームのリセットを追加しよう

勝敗や引き分けが決まった際に、画面にメッセージを表示し、2秒後にゲームをリセットします。

// メッセージを表示する関数
function displayMessage(message) {
    const messageElement = document.querySelector("#message");
    messageElement.textContent = message;
}

// ゲームをリセットする関数
function resetGame() {
    initializeBoard();
}

// 勝利や引き分けが決まった場合の処理
if (checkWin()) {
    displayMessage(`プレイヤー ${currentPlayer} の勝利です!`);
    gameActive = false;
    setTimeout(resetGame, 2000);  // 2秒後にリセット
} else if (checkDraw()) {
    displayMessage("引き分けです!");
    gameActive = false;
    setTimeout(resetGame, 2000);  // 2秒後にリセット
}

解説:

  • displayMessage関数で、メッセージを画面上に表示します。
  • 勝敗や引き分けが決定したら、メッセージを表示し、setTimeoutを使って2秒後にゲームをリセットします。

ステップ6: クリックイベントでゲームを動かしてみよう

最後に、各マスにクリックイベントを設定して、ゲーム全体を動かせるようにします。

// クリックイベントを設定し、ゲームのロジックを実装
document.querySelectorAll('.cell').forEach(cell => {
    cell.addEventListener('click', handleClick);
});

解説:

  • 各マスにクリックイベントを設定し、クリックされたときにhandleClick関数が呼び出されるようにします。

コード全体

marubatsu.html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>マルバツゲーム</title>
    <style>
        .board {
            display: grid;
            grid-template-columns: repeat(3, 100px);
            grid-template-rows: repeat(3, 100px);
            gap: 10px;
        }
        .cell {
            width: 100px;
            height: 100px;
            font-size: 2em;
            text-align: center;
            vertical-align: middle;
        }
        #message {
            margin-top: 20px;
            font-size: 1.5em;
        }
    </style>
</head>
<body>
    <h1>マルバツゲーム</h1>
    <div class="board">
        <button class="cell" id="cell-0"></button>
        <button class="cell" id="cell-1"></button>
        <button class="cell" id="cell-2"></button>
        <button class="cell" id="cell-3"></button>
        <button class="cell" id="cell-4"></button>
        <button class="cell" id="cell-5"></button>
        <button class="cell" id="cell-6"></button>
        <button class="cell" id="cell-7"></button>
        <button class="cell" id="cell-8"></button>
    </div>
    <div id="message"></div>
    <script src="script.js"></script>
</body>
</html>

script.js

let board = ["", "", "", "", "", "", "", "", ""];
let currentPlayer = "X";  // 'X'からゲーム開始
let gameActive = true;  // ゲームがアクティブかどうかを管理するフラグ

// ボードを初期化する関数
function initializeBoard() {
    board = ["", "", "", "", "", "", "", "", ""];
    currentPlayer = "X";
    gameActive = true;  // ゲームを再びアクティブに
    document.querySelectorAll('.cell').forEach(cell => cell.textContent = "");
    document.querySelector("#message").textContent = "";  // メッセージをクリア
}

// プレイヤーのターンを処理する関数
function handleClick(event) {
    const cellIndex = event.target.id.split('-')[1];  // クリックされたセルのIDからインデックスを取得
    if (board[cellIndex] === "" && gameActive) {
        board[cellIndex] = currentPlayer;
        event.target.textContent = currentPlayer;
        if (checkWin()) {
            displayMessage(`プレイヤー ${currentPlayer} の勝利です!`);
            gameActive = false;  // ゲーム終了
            setTimeout(resetGame, 2000);  // 2秒後にリセット
        } else if (checkDraw()) {
            displayMessage("引き分けです!");
            gameActive = false;  // ゲーム終了
            setTimeout(resetGame, 2000);  // 2秒後にリセット
        } else {
            currentPlayer = currentPlayer === "X" ? "O" : "X";  // ターンを交代
        }
    }
}

// 勝利条件をチェックする関数
function checkWin() {
    const winPatterns = [
        [0, 1, 2], [3, 4, 5], [6, 7, 8],  // 横
        [0, 3, 6], [1, 4, 7], [2, 5, 8],  // 縦
        [0, 4, 8], [2, 4, 6]              // 斜め
    ];

    for (let pattern of winPatterns) {
        const [a, b, c] = pattern;
        if (board[a] && board[a] === board[b] && board[a] === board[c]) {
            return true;
        }
    }
    return false;
}

// 引き分けをチェックする関数
function checkDraw() {
    return !board.includes("");
}

// メッセージを表示する関数
function displayMessage(message) {
    const messageElement = document.querySelector("#message");
    messageElement.textContent = message;
}

// ゲームをリセットする関数
function resetGame() {
    initializeBoard();
}

// クリックイベントを設定し、ゲームのロジックを実装
document.querySelectorAll('.cell').forEach(cell => {
    cell.addEventListener('click', handleClick);
});

まとめ

さて、このチュートリアルでは、JavaScriptで簡単なマルバツゲームを作成しました。

ここでここまで記事を読んでいただいた皆さんにお知らせしなければならないことがあります…

実は、このプログラム、ChatGPTに全て書いてもらっているのです。

ChatGPTを使えば、今までエンジニアが数時間掛けて書いていたコードを、ものの3分で作成してくれます。

これからエンジニアとして活躍したい方、文系からエンジニアを目指したい方は、ぜひChatGPTの活用方法を学んで、高度なIT人材になりましょう!

ChatGPTを使ってJavaScriptでゲームを制作したい方は、こちらのAIスクールがおすすめです!

ChatGPT活用塾
「起業家として成功したい」「フリーランスで稼ぎたい」「副業で稼ぎたい」そんな方々向けのChatGPT講座。eラーニング+コーチングであなたの業務を効率化させます。