JavaScript

JavaScriptでリバーシを作ろう (part.1)

JavaやC#といった言語だと、はじめての人が使うには環境構築やらなにやらで結構とりかかるまでに時間を要しますよね。その点JavaScriptは、テキストエディタとブラウザがあれば簡単に試しながら作れるので、プログラミング初学者でも比較的手を出しやすいです。

また、プログラミングの勉強が進んで来ると、「勉強のために何を作ったらいいかわからない」といったことに困ることがあります。そのような時は、身近なものですでにルール化されているものを再現してみると、作ることに集中できるためおすすめです。

本稿では、HTMLとJavaScriptを用いて、身近なボードゲーム「リバーシ(オセロ)」を作る手順を、3回に分けて解説します。

準備

用意するもの

  • テキストエディタ
  • ブラウザ(Google Chrome推奨)

ルールの確認

リバーシ(オセロ)の基本的なルールを確認しましょう。

  1. 8×8のマス目の緑色のオセロ盤に、図のように右上を黒として、石を黒白2個ずつ置き、ゲームを開始する。
  2. プレイヤーは交互に黒石、白石を打つ。石は両面が白と黒になっており、石を打つとき、縦・横・斜め方向に相手色の石を自色で挟み、挟まれた石を自色に返す。相手の石を返すことができないマスに石を打つことはできない。
  3. 打てるマスが全くない場合はパスとなり、相手が続けて打つことになる。パスの回数に制限はないが、返せる相手の石が1つでもある場合、パスをすることは認められない。
  4. 最後まで打って、石が多い方が勝ちである。なお最後とは「マスが全て埋まった場合」「両者とも打てるマスがなくなった場合」のいずれかである。

Wikipediaより引用)

作成手順の整理

前項ではリバーシのルールを確認しました。では実際にどういった手順で作成していくかを整理します。

  1. ゲーム開始の用意
    1. 8×8のマス目のゲーム盤を作る(HTML)
    2. ゲーム盤中央に黒白2つの石を置く(JavaScript)
  2. ゲーム進行
    1. 黒石・白石を交互に打つ(JavaScript)
    2. 相手色を挟んで裏返す(JavaScript)
    3. 挟めない場所には打てないように制御する(JavaScript)
  3. パスルール
    1. 打てる場所がまったくない場合はパスとする(JavaScript)
  4. ゲーム終了
    1. 「最後」になる条件を満たしたらそれぞれの石の数を計上し勝敗を決める(JavaScript)

次項より、整理した手順に沿ってゲームを実装します。

8×8のマス目のゲーム盤を作る(HTML)

HTML上にマス目を用意する手段としていくつかありますが、シンプルにでき表示崩れの心配も少ないため、ここではtable要素でゲーム盤を作ります。

<table>: 表要素

  • ゲーム盤全体をtableとして定義(赤の枠)
  • 横1列につき1つのtrとして定義(橙の枠)
  • マス1つにつき1つのtdとして定義(黄の枠)

上のイメージでHTMLを作成すると次のようになります。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Reversi</title>
    <style>
        /* 盤全体を黒色にする */
        .board {
            background-color: black;
        }
        /* マス1つ1つを緑色の正方形にする */
        .board tr td {
            background-color: seagreen;
            width: 16px;
            height: 16px;
            line-height: 16px;
        }
    </style>
</head>
<body>
<table id="myBoard" class="board">
    <!-- 1 -->
    <tr>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
    </tr>
    <!-- 2 -->
    <tr>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
    </tr>
    <!-- 3 -->
    <tr>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
    </tr>
    <!-- 4 -->
    <tr>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
    </tr>
    <!-- 5 -->
    <tr>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
    </tr>
    <!-- 6 -->
    <tr>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
    </tr>
    <!-- 7 -->
    <tr>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
    </tr>
    <!-- 8 -->
    <tr>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
    </tr>
</table>
</body>
</html>

よく見るあのゲーム盤ができました。

ゲーム盤中央に黒白2つの石を置く(HTML)

ゲーム盤ができたので、続いては石を置いていきます。黒石と白石2種類なので、それぞれ「●」と「○」を置いてみましょう。

    <!-- 4 -->
    <tr>
        <td></td>
        <td></td>
        <td></td>
        <td>○</td>
        <td>●</td>
        <td></td>
        <td></td>
        <td></td>
    </tr>
    <!-- 5 -->
    <tr>
        <td></td>
        <td></td>
        <td></td>
        <td>●</td>
        <td>○</td>
        <td></td>
        <td></td>
        <td></td>
    </tr>

この場合、「○」では背景色が透けてしまい、白石にはなりません。

では黒白両方とも「●」「●」として、片方の文字色を白にしてみるとどうでしょうか。

    <!-- 4 -->
    <tr>
        <td></td>
        <td></td>
        <td></td>
        <td>○</td>
        <td>●</td>
        <td></td>
        <td></td>
        <td></td>
    </tr>
    <!-- 5 -->
    <tr>
        <td></td>
        <td></td>
        <td></td>
        <td>●</td>
        <td>○</td>
        <td></td>
        <td></td>
        <td></td>
    </tr>

背景色が透けず、白石を作ることができました。

黒石と白石のクラスを定義する

これからJavaScriptで黒を打ったり白を打ったりする制御するなかで、「ここに●文字を置いて」「styleを追加して」「横並びは挟まれたからstyleを変更して」「ゲーム終了したから数を数えよう」とした時、styleで直接指定するのはなかなか不便なものがありますし、同じような指定が複数箇所にあると見通しも悪いです。ですので、黒石と白石をcssで定義してコードをすっきりさせましょう。

         /* 黒石 */
        .kuro:before {
            color: black;
            content: "●";
        }
        /* 白石 */
        .shiro:before {
            color: white;
            content: "●";
        }
    <!-- 4 -->
    <tr>
        <td></td>
        <td></td>
        <td></td>
        <td class="shiro"></td>
        <td class="kuro"></td>
        <td></td>
        <td></td>
        <td></td>
    </tr>
    <!-- 5 -->
    <tr>
        <td></td>
        <td></td>
        <td></td>
        <td class="kuro"></td>
        <td class="shiro"></td>
        <td></td>
        <td></td>
        <td></td>
    </tr>

tdの中身は空ですが、kuroやshiroを定義するとcontentにより「●」が挿入され、それぞれの文字色で表示される仕掛けです。

ABOUT ME
sasakiyu
ひ弱で優しい少年だったが、デーモンと合体。 強大な力を得つつも人間の心を失わないデベルマンとなる。