スタイルシート マスターマインド の説明
戻る


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


使い方

マスターマインドにはいろいろなバリエーションがありますが,このおもちゃは 6 つの色の中から 4 つの色を当てるタイプです.色の重複や空きはありません.つまり,同じ色が 2 回以上使われたり色が無い箇所ができることはありません.
12 回まで解答することができます.

画面下部に 6 つの色が並んでいます.推測した色を順番にクリックして選択します.4 つの色を選んだら「OK」をクリックします.
色も位置も合っているものの数が赤で,色は合っているが位置が違うものの数が白で表示されます.
選択を変更したいときは「取消」をクリックすると選択した色が取り消されるので,再度選択を行ってください.一部の色だけを変更することはできません.4 つの色を最初から選択し直してください.


問題の作り方

問題の色の組み合わせをランダムに決めるためにアニメーションの機能を使います.
各色に数値を対応させ,カスタム プロパティの値がそのうちのひとつになるようなアニメーションを無限に繰り返すように設定します.そして,ゲーム開始時にそのときの値を後述の「プロパティの値の保持」の方法で保存して,その数値に対応する色を問題にします.ゲームを開始するタイミングによって色の組み合わせが変わります.

1 番目の色については 1 〜 6 の数値で 6 つの色のうちのひとつを選びます.2 番目の色については 1 〜 5 の数値で,1 番目で選んだ色を除く 5 つの色のうちのひとつを選びます.同様に,1 〜 4 の数値で 3 番目の色,1 〜 3 の数値で 4 番目の色を選びます.

値を保存するタイミングは,ゲーム開始直後ではなく最初の解答で「OK」をクリックしたときにしています.ゲーム開始直後だと最初のゲームのときに値がばらつかないので,アニメーションを開始してからある程度時間が経ってから値を保存するよう,そのような処理にしています.


クリックの検知

色の選択肢や「OK」などがクリックされたことを検知するためにボタン(TYPE 属性 BUTTON の INPUT タグ)を使います.ボタンは非表示にしておき,各ボタンに対してラベル(LABEL タグ)を関連付けます.ラベルにスタイル付けして色の選択肢や「OK」などにしています.
ボタンの :active 状態でクリックを検知して,必要な処理を行います.マウス ボタンが放されるとボタンは :active 状態ではなくなるので,:active 状態でなくなった後もクリックを検知した状態を保持しておきたい場合は,必要な情報を後述の「プロパティの値の保持」の方法で保持しておきます.


4 つの色を順番に選択する方法

色の選択肢が並んでいる部分は画面では 1 組しか見えませんが,実際には同じものを 4 組用意して 4 つの色に対応させています.それを同じ位置に重ねて配置して,1 番目の色に対応するものから順に前面になるようにしておきます.
選択肢をクリックすると 1 番目の色に対応する選択肢のどれかがクリックされるので,それで 1 番目の色を決定します.そして 1 番目の色に対応する選択肢を非表示にします.そうすると 2 番目の色に対応する選択肢が前面になります.
色の選択の仕方
2 回目に選択肢をクリックすると 2 番目の色に対応するものがクリックされるので,それで 2 番目の色を決定します.
そのようにして 4 つの色を順に選択します.
「OK」で選択を確定するか「取消」で選択を取り消したら,選択肢の表示状態を元に戻して,また 1 番目の色から順に選択されるようにします.


12 回の解答を順番に行う方法

推測した色を選択すると,それが解答の回数に対応する行に表示されますが,行の表示を直接変えている訳ではありません.
各行の色の表示領域とは別に,選択した色を一時的に表示する領域を用意して,それを現在の解答の行の位置に重ねています.そこに選んだ色を表示しておいて,「OK」をクリックしたときに該当の行の表示を更新します.内部的に保持している色の情報も,「OK」をクリックするまでは一時的に使用するプロパティに設定しておいて,「OK」をクリックしたときに行毎のプロパティに設定します.
行の更新の仕方 1
「OK」は画面ではひとつしか見えませんが,実際には同じものを 12 個用意して各行に対応させています.それを同じ位置に重ねて配置して,1 行目に対応するものから順に前面になるようにしておきます.
「OK」をクリックすると 1 行目に対応するものがクリックされるので,1 行目について上記のような処理を行います.そして 1 行目に対応する「OK」の Z オーダーを変えて背面に回します.そうすると 2 行目に対応するものが前面になります.
行の更新の仕方 2
2 回目の解答で「OK」をクリックすると 2 行目に対応するものがクリックされるので,2 行目について上記のような処理を行います.
そのようにして各行の処理を順番に行います.


プロパティの値の保持

色の選択肢や「OK」などに対応するボタンの :active 状態で visibilityz-index,カスタム プロパティの値を変更しますが,:active 状態でなくなった後もそれらの値を保持しておく必要があります.そのために transition の機能を流用します.
transition では,プロパティの設定値が変更されてから実際に値が変わり始めるまでのディレイを設定できます.値を保持したいプロパティに,このようにディレイを設定します.
transition:visibility 0s 10000s;
そうすると,ボタンが :active 状態でなくなっても,ディレイで指定した時間が経過するまでは設定した値が保持されます.ディレイに充分大きな値を指定することで設定した値を保持します.
ただし,値を設定するときにディレイが設定されていると,その時間が経過するまで値が変わらなくなってしまいますので,値を設定するときには transition を無効にします.

カスタム プロパティに transition を適用するために,後述のように @ルールの @property でプロパティをアニメーション可能に設定しています.


カスタム プロパティの定義

このプログラム(?)では,いくつかのカスタム プロパティを @ルールの @property で定義しています.
@property の定義は,たとえばこのように書きます.
@property --a {
  syntax:'<integer>';
  inherits:true;
  initial-value:0;
}
上述したように,プロパティの値を保持するために transition を使っている他,問題の作成でカスタム プロパティにアニメーションを使っています.カスタム プロパティに計算値によるアニメーションや transition を使うためには,プロパティのデータ型を定義する必要があります.
@propertysyntax<integer><color> を指定することで,そのプロパティを計算値によるアニメーション可能にしています.


このおもちゃは Firefox 128 以上および Opera 80 以上用に作っていますが,Google Chrome 107 で動くことが確認できています.Google Chrome の他のバージョンでの動作は未確認です.


戻る