スタイルシート ペグ ソリティア の説明
戻る


JavaScript を使わず,スタイルシートだけでペグ ソリティアを作ってみます.
全くのお遊びです.これが何か実用の役に立つようなことは多分無いでしょう.スタイルシートは本来,動作を記述するものではありませんので,かなり力ずくで作っています.
画面
(これはキャプチャ画像です.これで遊ぶことはできません.)
使い方と仕組みについて説明します.


使い方

このおもちゃではペグをボールのような形に表示しています.

移動するペグをクリックして選択します.
ペグの選択
移動先の穴をクリックすると選択したペグがそこに移動し,飛び越えられたペグが取り除かれます.
移動先の選択



移動後
ペグの選択を取り消して別のペグを選択したいときは,そのまま別のペグをクリックすれば,元のペグの選択が取り消され,後からクリックした方のペグが選択されます.
選択したペグをもう一度クリックすると,選択を取り消すことができます.

「やり直し」で最初からやり直すことができます.


考え方

ペグ ソリティアの操作は,あるペグの隣にもペグがあり,その隣にはペグが無い配置になっているときに,そのペグを隣のペグを飛び越えて移動させ,隣にあったペグを取り除くということの繰り返しになります.
JavaScript なら,その動作をそのまま作ればよいのですが,スタイルシートでその動作を真似るのは無理ではないかと思います.

そこで,考え方を変えます.
隣り合う 2 つのペグとその隣の空きを合わせたペグ 3 個分の場所の状態を考えます.ペグを移動する前と後では,その場所にペグがあるか無いかの状態がこのように変わります.
移動による状態の変化
つまり,ペグの有無の状態が反転することになります.
さらに別の移動を行うと,その場所の状態も反転します.両方の移動で重なっている場所があると,その場所の状態はまた反転して元に戻ることになります.
複数回の移動による状態の変化
このように,ペグの移動を繰り返すということは,連続した 3 つの場所の状態の反転が繰り返されるということです.
このように考えると,各ペグの位置を追跡する必要は無く,各場所のペグの有無を管理すればよいことになります.


ペグ選択の処理

ペグを選択する処理のために,ペグを置く場所のそれぞれに対応してラジオ ボタンを使います.ラジオ ボタンは非表示にしておき,各ラジオ ボタンに対してラベル(LABEL 要素)を関連付けて,それをペグを置く場所に置いています.
ある場所にペグがあり,そのペグが移動できる場所があるとき,そのペグの場所に対応するラベルが前面になるように Z オーダーをセットして,クリックできるようにします.
ペグをクリックすると対応するラジオ ボタンが :checked 状態になるので,後述の「反転の処理」で書いた処理を行います.
それ以外の場所のラベルは背面に隠して,クリックできないようにします.

選択を解除する処理のために,もうひとつラジオ ボタンを使います.ラジオ ボタンは非表示にしておき,ラジオ ボタンに対してラベルを関連付けて,それをペグを置く場所に置いています.ラジオ ボタンはひとつですがラベルは複数用意して,すべての場所に置きます.
ペグを選択したらそのラベルを前面にします.選択したペグをもう一度クリックすると,今度はそのラベルがクリックされます.選択を解除するためのラジオ ボタンがチェックされ,ペグを選択するラジオ ボタンのチェックが外れるので,選択が解除されます.
移動できるが選択されていないペグ選択されたペグ
ラベルの重なり 1 ラベルの重なり 2
ペグを選択した後,別の移動できるペグをクリックすると,そちらの場所に対応する選択のラジオ ボタンがチェックされ,先に選択したペグのラジオ ボタンのチェックが外れます.その場合は,上記の解除の操作を行わなくても,先に行った選択は自動的に解除されます.


反転の処理

ペグの有無の反転は連続した 3 つの場所に対して発生します.
横方向に移動するときの反転する場所はこのようになります(グレーで示した部分).全部で 19 個所あります.
横方向の反転範囲
縦方向に移動するときの反転する場所はこのようになります.こちらも 19 個所あります.
縦方向の反転範囲
横方向に移動するとき左右どちらの向きに移動するかは,反転の処理には関係ありません.左右どちらに移動しても 3 つの場所の状態が反転することに変わりはありません.
左右の移動による状態の変化
同様に,縦方向に移動するとき上下どちらの向きに移動するかは,反転の処理には関係ありません.

反転の状態を保持するために,この 3 つの場所のグループ(計 38 個所)のそれぞれに対応してチェック ボックスを使います.チェック ボックスのチェックはその 3 つの場所が反転していることを表します.
チェック ボックスは,チェックされた状態で(ラベルを)クリックするとチェックされていない状態に戻ります.それにより,反転した場所をもう一度反転すると反転していない状態になるという動作を行うことができます.

チェック ボックスは非表示にしておき,各チェック ボックスに対してラベルを関連付けます.
ペグが選択されたら,その移動先にラベルの位置を合わせ,ラベルが前面になるように Z オーダーをセットして,クリックできるようにします.移動先は複数ある場合もあります.
移動先のラベルの位置
移動先をクリックするとチェック ボックスのチェック状態が切り替わります.チェック ボックスの :checked 状態で反転の処理を行います.
移動できない場所のラベルは背面に隠して,クリックできないようにします.

ある場所の反転の状態は,その場所に関係するすべてのチェック ボックスのチェック状態を合わせたものです.
たとえば,この図の濃いグレーで示した場所の状態は,薄いグレーで示した場所に対応するチェック ボックスのチェック状態を合わせたものになります.
関係するチェック ボックス
関係するチェック ボックスのチェックの数が偶数のときは初期状態と同じ状態で,奇数のときは初期状態から反転した状態になります.

反転すると選択したペグの場所はペグが無い状態になりますが,選択のためのラジオ ボタンは他のペグを選択するまでチェック状態のままです.そのため「ペグが選択されている」という条件をラジオ ボタンのチェック状態だけで判定すると不都合が生じます.その場所にペグがあるかどうかも合わせて判定する必要があります.


戻る