前回、8パズルの最短手数のもとめる処理を考えたのでこれでゲームを作ってみることにします。8パズルは15ゲームの簡略版であり簡単なので、最短手数以外は不正解とし、どこまで解くことができるかを競うゲームとします。実際にXで公開してみたところ、パズルガチ勢が多数参加し、全問クリアされてしまいました。パズルガチ勢恐るべし・・・

HTML部分

まずHTML部分を示します。

style.css

グローバル変数

グローバル変数を示します。

1~9のピースの初期配置を’1’~’9’で構成される文字列(2次元配列を通常の配列に変換したもの)で表し、これをquestions[0]~questions[31]に格納します(詳しくは後述)。そしてquestions[4], questions[8], questions[10], それ以降は連番から1つを取り出し、これを問題とします。

Pieceクラスの定義

各ピースを描画するためのクラスを定義します。

QueueStackクラスの定義

幅優先探索の処理をするのですが、JavaScriptにはQueueクラスがないので自分で実装します。通常の配列だとpushやpopの動作は速いのですが、配列の先頭や途中に要素を挿入したり削除する処理をしようとすると時間がかかります。

なのでEnqueue用とDequeue用のふたつの配列を定義して、DequeueするときはDequeue用の配列からpopし、もしこれが空のときはEnqueue用の配列の要素を全部Dequeue用の配列に移動させてからpopします。移動させるときに前後関係が入れ替わるので、先頭の要素を取り出すときに時間がかかるunshift関数ではなくpop関数で代用できるのがポイントです。

ページが読み込まれたときの処理

ページが読み込まれたときにおこなわれる処理を示します。

イベントリスナの追加

キー操作やボタンを押下したときに適切に動作させるため、イベントリスナを追加します。

幅優先探索で問題を生成する

幅優先探索で問題を生成する処理を示します。

その準備として引数として与えられた文字列のなかから遷移可能な状態の文字列を取得する処理を示します。例えば’413296758’であれば9番ピースは真ん中にあるので、上のピースを下にずらせば’493216758’が得られます。ずらしかたは他にも3つあるので、’413256798′, ‘413926758’, ‘413269758’が得られます。

幅優先探索をして遷移可能な状態とそこまでの手数を取得する処理を示します。

ピースの生成と描画

ピースを生成する処理を示します。

setPieces関数は生成されたピースに番号をつけ引数の文字列で指定された初期位置にセットするためのものです。

描画処理を示します。

ステージクリアかどうかを判定する処理を示します。各ピースの番号からあるべき位置を取得し、これと照合しているだけです。

全問クリア時に’全問クリア’の文字列を描画させる処理です(それ以外のときはcongratulation_yが大きな値なので見えない位置に描画される)。

ボリューム調整を可能にする処理

もはや定番となったレンジスライダーでボリューム調整を可能にするための処理です。

長くなってしまったので続きは次回とします。