8・15パズルの盤面
本ツールにおけるスライドパズルは,3x3のグリッドで構成される8パズル(初期設定)と,4x4のグリッドで構成される15パズルの2種類の盤面サイズを動的に切り替えて描画する仕様となっています.内部的なデータ構造としては,二次元配列ではなく一次元配列として状態を管理しており,例えば3x3の場合は0から8までの整数値(0は空マスを意味する)が格納されます.
画面上の各タイルは,CSSのGridレイアウトを用いて配置され,インデックス番号から行と列の座標を逆算することで,正確な位置関係を維持したままレンダリングされます.タイルの移動判定においては,現在の空マス(値が0の要素)のインデックスを取得し,そこから上下左右に隣接するインデックスの配列を動的に計算します.
ユーザーが特定のタイルをクリックした際,そのタイルのインデックスが空マスの隣接インデックス配列に含まれている場合にのみ,配列内の要素の交換処理が実行され,Reactの状態更新を通じて画面の再描画が行われます.斜め方向への移動や,離れた位置にあるタイルの移動は物理的に不可能となるよう,厳密な境界チェックが実装されています.
手動移動とシャッフル
プレイモードにおける手動操作は,クリックまたはタップのみに限定されており,キーボード操作やドラッグ&ドロップによるスワイプには対応していません.タイルが移動するたびに手数カウンターがインクリメントされ,目標状態(1から順に並び,最後が空マスとなる配列)と現在の配列が完全に一致した時点でクリア判定が下される仕組みです.
クリア時には視覚的なエフェクトが追加され,ユーザーに達成感を提示します.シャッフル機能においては,単なるランダム配列の生成ではなく,完成状態から逆算して有効なスライド移動を連続的に実行する手法を採用しています.これにより,パリティ条件(可解性)を確実に維持したまま盤面をスクランブルすることが可能です.
具体的には,直前に移動したマスを記録して元の位置に即座に戻るような無駄な往復移動を排除しつつ,3x3サイズでは40回,4x4サイズでは20回の移動を30ミリ秒間隔で連続的に適用することで,アニメーションを伴うシャッフルを実現しています.この回数設定により,適度な難易度の初期配置を迅速に提供し,シャッフル中もユーザーが進行状況を視覚的に追えるように配慮されています.
問題編集と整数入力
手元のパズルや特定の配置を再現するための「問題を配置・編集」モードでは,2つの直感的な入力インターフェースが用意されています.一つは,盤面上のタイルを2つ順番にタップして直接位置を入れ替えるスワップ操作です.また,画面下部に配置された数字パレットから特定の整数を選択し,指定したマスに直接値を上書き割り当てを行うことも可能です.
このパレット操作時,もし同じ値がすでに別のマスに存在している場合は,両者の値を自動的に交換することで重複を作らないよう厳密に制御されます.さらに,テキストベースの一括入力機能も搭載しています.ユーザーがテキストエリアに入力した文字列は,スペース,カンマ,セミコロンなどを区切り文字としてパースされ,整数の配列に変換されます.
この入力処理の際,最大1000 UTF-16コード単位という入力上限が設けられています.部分的な数字や小数を含まない純粋な整数の配列であるか,指定された盤面サイズと要素数が完全に一致するか,0から最大値までの整数が重複なく1回ずつ含まれているかが厳密に検証され,条件を一つでも満たさない場合はエラーメッセージが表示されて処理は中断されます.
可解性とパリティ
ユーザーが編集モードで配置を設定した際,その盤面状態が目標状態へ到達可能であるか(可解であるか)を数学的に判定するパリティチェックがリアルタイムで実行されます.パズルを一次元配列として評価したときの「反転数(Inversion Count)」,すなわち自分より右側にありながら自分より小さい数字の個数の総和がこの判定の基盤となります.
重要な点として,この反転数の計算においては,空マスを表す「0」のタイルを除外してカウントを行います.単なる文字列全値の評価ではありません.3x3(奇数サイズ)の場合,この0を除く反転数が偶数であれば解ける配置として判定されます.一方,4x4(偶数サイズ)の場合は,空マスが下から何行目に位置するかという行座標を加味し,0を除く反転数と空マス行位置の和が奇数である場合にのみ解ける配置と判定されます.
14と15を単に入れ替えただけのような配置はパリティが不一致となり,システムは「理論上クリア不可能な配置」として即座に警告を表示し,プレイの継続を未然に防ぎます.なお,この判定はあくまで数学的な可能性を示すものであり,後述の探索上限内での経路発見を常に保証するものではありません.
A*探索と再生上限
パズルの自動攻略には,最短経路を効率的に発見するA*(エースター)アルゴリズムが実装されています.ヒューリスティック関数として,各タイルが現在の位置から目標位置までに移動すべき行数と列数の差の絶対値の総和である「マンハッタン距離」を採用しています.探索プロセスでは,初期状態からの実際の移動手数と,マンハッタン距離による推定残手数の和が最小となる状態ノードを優先的に展開し,訪問済みの状態を記録することでループを回避します.
しかし,このアルゴリズムはWeb Worker等ではなくブラウザのメインスレッド上で同期的に実行されます.そのため,展開するノードの反復回数には厳格な上限が設けられています.具体的には,3x3サイズでは30,000回,状態空間が膨大な4x4サイズでは12,000回を上限とし,これを超過した場合は解の探索限界として中断されます.
必ず最短経路を算出できるわけではなく,無条件にすべての状態を解析できるわけではありません.また,上限の範囲内であっても,メインスレッド同期実行の性質上,計算中は短いUIの停止(フリーズ状態)が発生することがあります.探索が成功した場合,400ミリ秒間隔で1手ずつ盤面状態を更新する再生処理が実行されます.
画像と保存・負荷
数字のみのパズルに加え,ユーザーが選択した任意の画像をパズルの背景として適用する機能が実装されています.ユーザーがデバイスから画像ファイルを選択すると,ブラウザ内でFileReader APIが稼働し,画像データをBase64エンコードされたData URIスキーム文字列として読み込みます.
読み込まれた画像文字列は,各タイルのCSS background-image プロパティとして適用されます.画像をCanvas等で物理的に分割・クロップするのではなく,background-size を盤面サイズに応じたパーセンテージ(3x3なら300%)に設定し,background-position を各タイルの本来のインデックス座標(正解位置)に合わせて動的にずらして配置する手法により,一枚の画像を複数のタイルに分割して表示する視覚効果を実現しています.
また,本ツールではセーブデータやプレイ履歴,読み込んだ画像データなどをローカルストレージ(localStorage)等に永続化して保存する機能は持っていません.そのため,ページの再読み込みやブラウザを閉じることによって全ての状態は直ちに破棄され,初期状態へとリセットされます.