点灯パズルのルール
5x5の計25枚のパネルがあって、パネルを押すとそのパネルと隣接するパネルの点灯/消灯が反転する。全部消灯したらクリア。
って内容の玩具が昔あった。好きだった。jQueryで作ろう。
HTML(抜粋)
<table border=1>
<tr>
<td><input type="checkbox" value="on" class="light"></td>
<td><input type="checkbox" value="on" class="light"></td>
<td><input type="checkbox" value="on" class="light" checked="checked"></td>
<td><input type="checkbox" value="on" class="light"></td>
<td><input type="checkbox" value="on" class="light"></td>
</tr>
<tr>
<td><input type="checkbox" value="on" class="light"></td>
<td><input type="checkbox" value="on" class="light"></td>
<td><input type="checkbox" value="on" class="light" checked="checked"></td>
<td><input type="checkbox" value="on" class="light"></td>
<td><input type="checkbox" value="on" class="light"></td>
</tr>
<tr>
<td><input type="checkbox" value="on" class="light" checked="checked"></td>
<td><input type="checkbox" value="on" class="light" checked="checked"></td>
<td><input type="checkbox" value="on" class="light"></td>
<td><input type="checkbox" value="on" class="light" checked="checked"></td>
<td><input type="checkbox" value="on" class="light" checked="checked"></td>
</tr>
<tr>
<td><input type="checkbox" value="on" class="light"></td>
<td><input type="checkbox" value="on" class="light"></td>
<td><input type="checkbox" value="on" class="light" checked="checked"></td>
<td><input type="checkbox" value="on" class="light"></td>
<td><input type="checkbox" value="on" class="light"></td>
</tr>
<tr>
<td><input type="checkbox" value="on" class="light"></td>
<td><input type="checkbox" value="on" class="light"></td>
<td><input type="checkbox" value="on" class="light" checked="checked"></td>
<td><input type="checkbox" value="on" class="light"></td>
<td><input type="checkbox" value="on" class="light"></td>
</tr>
</table>
5x5のパネルの表現を今回はチェックボックスで代用した。
ところどころcheckedが入っているのは初期点灯。
JS
$("input").click(function(){
// 押されたチェックボックスがページ内で何番目のものかを取得
var index = $("input").index(this);
// 右隣に対して、チェックボックスの反転を行う
if($(this).parent().next().children().prop("checked")){
$(this).parent().next().children().prop("checked", false);
}else{
$(this).parent().next().children().prop("checked", true);
}
// 左隣に対して、チェックボックスの反転を行う
if($(this).parent().prev().children().prop("checked")){
$(this).parent().prev().children().prop("checked", false);
}else{
$(this).parent().prev().children().prop("checked", true);
}
// 上に対して、チェックボックスの反転を行う
if(index-5 >= 0){
if($("input").eq(index-5).prop("checked")){
$("input").eq(index-5).prop("checked", false);
}else{
$("input").eq(index-5).prop("checked", true);
}
}
// 下に対して、チェックボックスの反転を行う
if(index+5 < 25){
if($("input").eq(index+5).prop("checked")){
$("input").eq(index+5).prop("checked", false);
}else{
$("input").eq(index+5).prop("checked", true);
}
}
// 全てのマスの点灯判定を行う
var clear_flg = 1;
if(0 < $("input:checked").size()){
clear_flg = 0;
}else{
clear_flg = 1;
}
});
.index(this)で押されたチェックボックスの位置(インデックス番号)を取得し、それを軸に点灯/消灯処理を行う。
左右は.next()、.prev()で指定できるとして、上下は.eq(インデックス番号±5)を指定することで実現した。
他、角の場合とかそういうのを泥臭く分岐している。
指定したチェックボックスに対して.prop("checked", boolean)で、checkedプロパティを付与し点灯/消灯を行う。
チェック状態のチェックボックスがあるかを$("input:checked").size()で確認してクリアに関するフラグを書き換える。
以上をチェックボックスが押された際の処理として書けば完成。
まあこのままだと初期配置を変えるのにいちいちHTMLを書き換えなきゃいけないので、例えばゲーム開始用のボタン用意してそれ押すまでは自由にチェックボックスをクリックして初期配置を設定できるようにするとかボタン一発でランダムに初期配置を生成するとかしてみても面白いかもしれない(クリア不可能な配置も存在するので注意)。