武器の作り方入門

この記事はペンシルパズルII Advent Calendar 2021の記事です。

みなさんこんにちは。ウドと申します。PBR2ではデュアルへやわけの簡易プレーヤーを作ったり、PBR3ではシステム屋さんとしてハニアプレーヤーを作ったりと(じつはあの盤面は直接塗れるのです)、野良の武器屋として活動(?)しています。

そこで(???)この記事では、それらの武器をつくるなかで得たノウハウ、簡単なペンシルパズルプレーヤーの作り方をお伝えしようと思います。武器を作るのは難しくないよということが伝わればさいわいです。あ、でも、ちょこっとプログラミングをしますので、アルファベットアレルギーの方は早めに治しておきましょう。冬休みの自由研究として提出すれば人気者間違いなし!え、penpa-editっていいんじゃないかって?うーん……。

使用言語

プログラミングと言うとCだとかPythonなどを思い浮かべる方もいるとおもいますが、今回はwebページで使われるHTMLや、Javascriptを使って作ります。将来的には自分のwebサイトでプレーヤーを公開したり、自作プレーヤーを使ったオリジナルパズルの大会……など、夢がふくらみんぐですね。プログラミングだけに。特別な環境構築が不要で、普段使っているブラウザで動作が簡単に確認できるのもよいところです。

用意するもの

  • パソコン。windowsでもmacでもよいです。スマホは厳しいです。

  • お好みのブラウザ。普段使っているChromeとかFirefoxとかで構いません。

  • お好みのエディタ。エディタって何?という方はVSCodeがオススメです。メモ帳だと厳しいです。リンク先の「今すぐダウンロード」ボタンから使用しているOSのものをダウンロードして、指示に従ってインストールしましょう。ついでにこのへんを参照して日本語化するとよいです。あと、必須ではないですが、このへんを参照してカラーテーマを変えれば、気分はもうスーパープログラマーです。気分は大事です。

あ、おわかりかと思いますが、この記事は上ぐらいのざっくりした指示でソフトの導入をこなせる方が対象です。「インストールってナニ?」のレベルだと、ちょっと厳しいかも。

作り方の流れ

今回はハニーアイランドのプレーヤーを作っていこうと思います。ただ、六角形の盤面を用意するのはちょっとハードルが高いので、盤面が四角のハニーアイランドのプレーヤーを作ることにします。盤面は6x6にして、6マスの領域が……4つぐらい入る感じで行きましょう。果たしてパズルになるのだろうか。
作成の流れは以下のようになります。

  1. 準備

  2. 盤面を作る

  3. 黒マスを作る

  4. クリックしたらマスを塗れるようにする

これだけです。簡単ですね!

1.準備

さて、今回の武器は3つのファイルからなります。
・HTMLファイル……盤面の骨組みを担当します。
・CSSファイル……盤面の見た目を担当します。
・JS(Javascript)ファイル……クリックしたらマスを塗るなど、動きの部分を担当します。
それでは早速、3つのファイル……の前に、これらを入れておくフォルダを作りましょう。散らかってしまいますからね。デスクトップなど、わかりやすい所にお好きな名前のフォルダを作ってください。
フォルダを作ったら、さっきDLしたVSCodeを開きます。
上部の「ファイル」メニュー→「新規ファイル」 を選ぶと、このような画面が現れるので……

言語の選択をクリックして、「HTML」を選びます。もしこの文章が出ていないなら、右下あたりに「plain text」とか書いてあるとこがあると思いますので、そこを選択してください。


そこに以下のコードをコピペして、先程作ったフォルダに「weapon.html」という名前をつけて保存してください。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>はじめての武器</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    Hello, HoneyIsland!
    <script src="script.js"></script>
</body>
</html>

このファイルの中身は……まあ、全部おまじないだと思ってください。<body>の下の部分が実際に表示される部分です。今回はHello, HoneyIsland!と書いてありますね。その下のscriptなんちゃらのところからはまたおまじないですので、消さないように注意しましょう。

同じように、
新規ファイル→言語の選択を「CSS」→「style.css」という名前で、
新規ファイル→言語の選択を「Javascript」→「script.js」という名前で保存しましょう。これら2つは中身は空で構いません。
ここまで出来たら、フォルダには3つのファイルがあるはずです。

「weapon.html」をクリックして、表示を確認してみましょう。お使いのブラウザが開くはずです……Windows11の方は、Edgeが開くかもしれませんが。

うまく表示されたでしょうか?今後はこのファイルをいろいろ弄って、盤面を作っていきます。

2.盤面を作る

さて、土台はできましたから、まずは盤面をつくりましょう。盤面はテーブルという機能を使って作ります。本来は表をつくるための機能なのですが、パズルの盤面を作るのにもうってつけです。
というわけで、Hello, HoneyIsland!と書いてある部分はもう不要ですから消して、そこに次のコードを貼り付けてください。別に残しておいてもよいですが。

    <table>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
    </table>

長いですね。これが盤面の骨組みです。
では表示してみましょう。さっき開いたページを更新してください。

……何も表示されませんでしたか?それは正常です。HTMLはただの骨組みなので、大きさをどうするとか、マスを何色にするとか、そういうことを指定してあげないと何も表示されないのです。そういう見た目の部分はCSSファイルに記述します。
というわけで、style.cssファイルに次のコードを貼り付けてください。

table {
    border-collapse: collapse;
}

td {
    background-color: white;
    width: 40px;
    height: 40px;
    border: 1px solid gray ;
}

するとこんな感じになります。これで盤面ができました!

ちょっと脱線

この節は余裕のある人だけ読んでください。先に進む前に、ちょっとだけこの呪文の説明をしておきましょう。HTMLは骨組みを表すといいましたが、その骨組みを実際に示すのがタグです。<こんな>やつですね。

<b>
タグはこんな感じで使います。
/が付いてないのが開始タグ、付いてるのが終了タグで、
開始タグと終了タグに挟まれた部分が中身となります。
この例では、b(bold)タグで挟んでいるので、文字が太字になります。
</b>
この部分は、bタグに挟まれていないので、太字にはなりません。

余裕のある方は、↑のコードをさっき貼ったやつの下あたりに追加して、どう表示されるか確かめてみましょう。

tableタグはここからここまでが表だよ、trタグは横列だよ、tdタグはセル(マス)だよ、という意味です。今後はtdのことをマスと呼ぶことにします。

CSSファイルの中身も見てみましょう。tableはこういう風に表示してね、tdはこういう風に表示してね。ということが書いてあります。border-collapseはおまじないなので置いておいて、background-colorは背景色, width, heightは大きさ, borderは罫線です。なんとなく名前から何を指定しているかわかるでしょうか?余裕のある人は、数字や色の名前を弄ったりして遊んでみましょう。自由研究もキットそのままじゃいい点はもらえないですからね。

3. 黒マスを作る

これで盤面ができました。ハニーアイランドプレーヤーを作るためには、あとはマスをクリックしたら黒マスになる機能が必要です。その準備として、まずは黒マスをどうやって表現するかを見ていきましょう。見た目に関することですので、CSSの出番です。具体的にはCSSのクラスという機能を使います。
というわけで、まずは何も聞かず、style.cssに以下を追記してください。

.filled {
    background-color: black;
}

また、HTMLの好きなところの

<td></td>

<td class="filled"></td>

に変えてみましょう。何個変えてもいいです。3個ぐらい変えましょう。
変えたらもう一度表示してみましょう。

こんな感じになったでしょうか。これで黒マスができました。

またまた脱線

何をやっているか見てみましょう、まずはcssファイルに、filledというクラスを定義しています。クラスというのは属性みたいなもので、この場合は黒マス属性を定義して、この属性がついてるマスは黒く塗ってね、ということを書いています。CSSファイルにクラスの内容を設定するときは、先頭に.をつけて書くのがお約束です。
この名前は自由に決められますので、blackでもkuromasuでもyumeでも何でもよいです。filledが気に入らない人は好きな名前にしましょう。また、属性は何個でも付けられます。ツンデレ属性とか妹属性とかドジ属性など、マスをお好みにカスタマイズできるということですね。
そして、HTMLのほうにclass="filled" というのを追加しています。こう書くことでマスにfilledクラスを設定できます。すると、マスに黒マス属性がついて黒く表示される、という寸法です。

4. クリックしたら塗れるようにする

さて、いよいよプレーヤーのプレーヤーたる部分です。クリックしたら塗れるようにしましょう。具体的にはさっき、filledクラス……黒マス属性を定義しましたね。ということは、クリックしたらこの黒マス属性を切り替えるようなプログラムを書けばいいわけです。
というわけで、満を持してJSファイルの出番です。script.jsファイルに以下をコピペしてください。あ、あと、さっきつけたHTMLファイルのfilledクラスを取っといてください。

for ( let cell of document.getElementsByTagName("td") ) {
    cell.addEventListener("click", function(){
        this.classList.toggle("filled")
    })
}

保存したら開いて、マスをクリックしてみましょう。黒マスが塗れるようになりました!これでプレーヤーは完成です!

みたび脱線

さて、わずか5行のプログラムですが、やってることはちょっとむずかしいです。ここは分解してみましょう。まずは外側です。

for ( let cell of document.getElementsByTagName("td") ) {
    ...
}

HTMLファイルの中からマス(tdタグ)を全部探してきて、マスひとつひとつに、…の中身に書いてあることをやりますよー、という意味です。

つぎにその内側です。

    cell.addEventListener("click", function(){
        ...
    })

これはマスに対して、もしクリックされたら…の中身に書いてあることをやっといてね、ということを言っています。これを一回言っておくだけで、以降はクリックするたびにマスが自分で色を変える動作をやってくれるイメージです。便利ですね。

そして最後、真ん中です。

this.classList.toggle("filled")

これは自分にfilled属性があれば取って、なければ付けてね、という意味です。クリックしたときの処理ですね。この中身はマスに対してこれをやってねという指示書のようなものなので、this(自分)に対して処理をしています。このへんは難しいのでわからなければ流しましょう。

以上をまとめると、このプログラムは
「全てのマスに対して」
「クリックされたときに」
「黒マス属性を切り替えるように」指示をしています。まさにプレーヤーがやっていることですね!

おわりに

駆け足でしたがこれでプレーヤーができました。色を変えたり、マスの大きさを変えたりすれば、あなただけのオリジナルプレーヤーになります。もし、わからないことがあれば、@udop_まで気軽に聞いてください。できる限り対応します。それでは、それでは、自作プレーヤーでよきクリスマスを!

発展:問題入力モードがほしい!

作ったプレイヤーを使っていると、致命的な問題があることがわかります。それは、問題が表現できない、ということです。問題と回答の黒マスが同じであっては、解いてる間に消えてしまって不便ですね。というわけで、問題入力モードを作りましょう。
まずはHTMLファイル、構造ファイルのほうに、モード切り替えを作ります。こういうのはラジオボタンが一番簡単です。
HTMLファイルの<body>の真下に、以下を追加してください。

<form>
    <input type="radio" name="mode" id="mode_q"><label for="mode_q">問題入力モード</label>
    <input type="radio" name="mode" id="mode_a" checked><label for="mode_a">回答入力モード</label>
</form>

するとどこにでもあるラジオボタンが現れます。

このラジオボタンが問題入力モードならば問題の黒マス属性を、回答入力モードならば回答の黒マス属性を切り替える、という風にすればよいわけですね。
ということで、問題の黒マスと、回答の黒マスを定義します。style.cssの.filledのところを消して、次のように書いてください。

.filled{
    background-color: dimgray;
}

.question{
    background-color: black;
}

filledクラスは黒をやめて濃いめのグレーに、questionクラスは真っ黒に指定しています。もちろん好きな色に書き換えてもらっても構いません。

さて、そしたら最後にJavascriptです。ファイル全体を次のように書き換えてください。

for ( let cell of document.getElementsByTagName("td") ) {
    cell.addEventListener("click", function(){
        if (document.getElementById("mode_q").checked) {
            this.classList.toggle("question")
        } else {
            this.classList.toggle("filled")
        }
    })
}

もし、mode_q……問題入力モードのラジオボタンがチェックされていれば、questionクラスを、そうでなければfilledクラスを付け外しするような指示に書き換えました。これで問題入力モードができました!これで冬休みの自由研究も完璧ですね!

こうなると、今度はドラッグでセルを塗りたいだとか、問題公開モードがほしいだとか、欲望は際限なく高まっていきますが、それらは気が向いたら公開したいとおもいます。