塵芥回顧録

なるべく更新していきたいが、ネタがない。

懐かしのライツアウト(p5js)

ライツアウトをp5jsで作成しました。

ライツアウト - Wikipedia

 

目次

 

ライツアウトとは

ライツアウトは点灯しているパネルを全部消灯させるとクリアとなるパズルゲームで、
ボタンを押すと押したパネルとそのパネルの上下左右の点灯消灯が反転されます。

 

プログラムについて

コードはp5jsの右上にある</>を押すと見れます。

最初に書かれているarray=5でサイズ5×5を指定しています。正方形である必要はなかったので横と縦で分けて指定してもよかったかもしれません。

f:id:nupepon:20220323090354p:plain

プログラムの流れ

このプログラムは上図のような流れで動作します。

・setup
点灯した時の色、消灯した時の色、クリアした時の文字色を指定して、問題作成(makeprob関数)を呼び出しています。

・makeprob
gusu=round(random(1))で最低手順を偶数回にするか奇数回にするかを決め、消灯状態からマスの数又はマスの数-1回無作為にボタンを押しています。消灯状態から押しているのでクリア不可能な問題は出現しません。また、clear_judgeがtrueを返した場合既にクリアした状態となるため再度問題を作り直します。(trueを返す確率はかなり低いと思いますが。)

・drawlights
現在の点灯状態を描画します。

・lightchenge
押したボタンとそのボタンの上下左右を反転させます。ゲーム中のマウスクリックや問題作成時に使用されます。
変数chxとchyでマスの端かどうかを判定し、枠外のマスを反転させてしまうのを防ぎます。
chy,chxの判定が無い場合、例えばy座標*1の判定が無い場合、配列の範囲を超えてしまうため、バグ*2が発生してしまう恐れがあります。x座標*3の判定が無い場合、本来反転しないマス*4が反転してしまいます。

・clear_judge
全部消灯していたらtrue、点灯しているマスがあればfalseを返します。
javaだと(配列).reduce( (a, b) => a + b, 0 )でその配列の合計値を返すようです。便利ですね。一応仕組みとしてはaに合計値とbに次の要素が入っているらしく2引数は初期値だそうです。
完璧に理解している訳では無いですが、
例えばarray={0,1,2}だとしてarray.reduce( (a, b) => a + b, 10 )を実行すると
1回目a=10 b=0 a+b=10
2回目a=10 b=1 a+b = 11
3回目a=11 b= 2 a+b = 13
実行結果 13
になる……のかな?間違ってたらすみません…
これを利用して合計値が0ならtrueそれ以外であればfalseを返しています。true≠0、false=0と定義されており*5、今回のプログラムでは消灯をfalse、点灯をtrueとしているので合計値を求めることでクリアしているか否かの判定が可能となっています。

・mouseClicked
mouseClickedは押して離す動作により動作する関数です。押した時に反応するmousePressedの方がマウスでプレイする分には操作が快適なのでPressedの方が良いのですが、Pressedだとスマホ等でプレイすると1回のタップのつもりでも多重反応しまともにプレイできませんでした。なのでClickedを使用しています。

 

実装した方がよさそうなもの

手数や最小手数の表示、時間表示。ランダムではなく問題が自作できるシステムを実装した方が良いかなと思いました。
別のゲームになってしまいますが、多色のライツアウトもあるみたいなので、そっちを作ってみるのもありかな。

*1:変数chy

*2:ぬるぽ

*3:変数chx

*4:5×5の場合(x,y)=(0,1)で(4,0)が反転、(4,1)で(0,2)が反転

*5:実際にはfalseの種類は他にもある