JavaScript を使わず,スタイルシートだけでハノイの塔を作ってみます.
(これはキャプチャ画像です.これで遊ぶことはできません.)
使い方と仕組みについて説明します.
使い方
「ディスク枚数」でディスクの枚数を選びます.
動かしたいディスクのあるマスをクリックすると,対象のディスクが選択されます.選択したディスクはオレンジ色に変わります.
移動先のマスをクリックすると,選択したディスクが移動先のマスに移り,ディスクは緑色に戻ります.
選択した後移動を中止したいときは,もう一度元のマスをクリックします.
ディスクの状態の保持
各ディスクが現在どのマスにあるかということと,ディスクが選択された状態かどうかの情報をラジオ ボタンを使って保持しています.
それぞれのディスクについて 6 個のラジオ ボタンを使います.
各ラジオ ボタンが次のような状態を表します.(左端の数字は説明のためにつけた番号で,数値に意味はありません.)
| 位置 | 選択状態 |
1 | 左端のマス | 選択されていない |
2 | 中央のマス | 選択されていない |
3 | 右端のマス | 選択されていない |
4 | 左端のマス | 選択されている |
5 | 中央のマス | 選択されている |
6 | 右端のマス | 選択されている |
選択されているディスクが無い状態では,各ディスクについて,そのディスクがあるマスに対応して 1 番から 3 番のラジオ ボタンの何れかがチェックされます.
ディスクを選択すると,選択したディスクについて,そのディスクがあるマスに対応して 4 番から 6 番のラジオ ボタンの何れかがチェックされます.
最初は,すべてのディスクについて 1 番のラジオ ボタンがチェックされている状態です.
ディスクの移動
以下のような方法で,マスをクリックしたときにラジオ ボタンのチェック状態が変更されるようにします.
ラジオ ボタンは非表示にしておき,各ラジオ ボタンに対してラベル(LABEL タグ)を関連付けます.ラベルの大きさをマスと同じにし,位置は対応するマスに合わせます.
ディスクの状態に応じてラベルとマスやディスクの表示の重ね順を変えて,チェックできるラジオ ボタンに対応するラベルがマスやディスクの前面になるようにし,それ以外のラベルはマスの背面になるようにして,クリックできないようにします.
上述の説明の 4 番から 6 番のラジオ ボタンに対応するラベルのうち,そのディスクがあるマスのものを,マスやディスクの前面に重ねます.つまり,1 番のラジオ ボタンがチェックされていたら 4 番のラジオ ボタン,2 番のラジオ ボタンがチェックされていたら 5 番のラジオ ボタンというように,同じマスのラジオ ボタンに対応するラベルを前面に重ねます.
同じマスに複数のディスクがあるときは,より小さいディスクに対応するラベルがより前面になるように重ねます.
マスの位置をクリックすると,一番小さいディスクのラベルがクリックされ,対応するラジオ ボタンがチェックされます.(そのディスクが選択された状態になります.)
何れかのディスクが選択されたら,他のディスクが同時に選択されないように,4 番から 6 番のラジオ ボタンに対応するラベルはすべて,display:none
を指定して隠します.
ディスクが選択されている状態のときは,選択されているディスクの 1 番から 3 番のラジオ ボタンのうち,そのディスクより小さいディスクが同じマスに無いもの(つまり,選択されているディスクを移動できるマスのラジオ ボタン)に対応するラベルを,マスやディスクの前面に重ねます.
マスの位置をクリックすると,そのマスにあるラベルがクリックされ,対応するラジオ ボタンがチェックされます.(そのディスクがクリックしたマスに移動します.)
このおもちゃは Firefox 78 以上および Opera 74 以上用に作っていますが,Google Chrome 107 で動くことが確認できています.Google Chrome の他のバージョンでの動作は未確認です.