プログラミングにおける、パズルを解くような楽しさ
パズルには楽しさ、例えばルービック・キューブには解き方のルールがあって、そのルールに従って面を揃えることではなく、そのルールを見つけ出すという楽しさがあります。解くためのルールを考え、それを使ってパズルが解けたときの快感はたまりません。
プログラミングにもそんな楽しさがあります。
プログラミングで何かを解決する手段は一つじゃなく、いろんな方法があります。シンプルでエレガントな方法を使って解決できたときはとても気持ちがいいものです。
さて、今回作るものではそんな気持ちよさを味わえるでしょうか?
この記事は全文無料でお読みいただけます。もしお気に召しましたら投げ銭お願いしますね。😉✨
今回作ろうとしたもの。
おもちが上下左右に動き続ける、橋本 麦(@_baku89)さんの Web作品があります。
このおもちさん、気ままに動いてるように見えて、ぶつかることも重なることもなく整然と動き続けています。各々が勝手に動いているようなのに全体の動きが破綻しない様が不思議で、パズル的な魅力を感じます。
こちらの記事で作り方を書いてくださっているので、文中の「向きつけを維持したままループを作る方法」で作ってみることにしました。
シンプルなルールを見つけ出せ!
用心深い私はいきなりコードを書き始めたりはしません。(というか、そんなこと出来ないんですけど😝)
この手のは一見単純そうに見えて、甘く見てるとドロ沼にハマってコードがぐちゃぐちゃになるタイプのやつです。動きの中のルール、それも根底にあるシンプルなルールを突き止めなきゃいけない、そう感じます。
まずはどういうデータが必要か?から考えます。この図の場合だと 6列 4行のグリッド、6x4個のセル、6x4個のノードが必要そうです。
(7列 5行にも見えますが、キャンバスの端は反対側の端に繋がってるという扱いで、6列 4行になります)
各セルには 4個のノードがあり、隣のセルとノードを共有しています。
4個のノードはセル内の位置、 北西(nw)、北東(ne)、南西(sw)、南東(se) で判別することにします。
おもちが移動する場面を考えると移動の方向(東西南北)も必要ですね。
次にそれらのデータの間にどういうルールがあるかを考えます。このとき、コードでどう表すかを何となくイメージしながら考えていきます。
例えば、セル内の 4つのノードの位置と移動方向を、キャンバスの x,y 軸と絡めてこのように表現することにします。
すると、おもちが動く道筋の繋ぎ変えを「(ノードの位置+移動方向)の反対方向」というルールで表すことができるようになるんです。
ルールがシンプルならコードもシンプルになる
具体例でお見せしますね。
この繋ぎ変えのシーンで、2つのノードの移動方向が変化していきます。
対象ノードは nw と se、変化前の移動方向はそれぞれ s と n でした。
それが道筋の繋ぎ変えで e と w に変わります。
「(ノードの位置+移動方向)の反対方向」を計算してみます。反対方向は -1 として、
nw のノードの場合
(nw + s) * (-1)
↓
((-1, -1) + (0, +1)) * (-1)
↓
(-1, 0) * (-1)
↓
(+1, 0) = e
se のノードの場合
(se + n) * (-1)
↓
((+1, +1) + (0, -1)) * (-1)
↓
(+1, 0) * (-1)
↓
(-1, 0) = w
という具合です。
このルールなら繋ぎ変え部分のコードはシンプルに書けそうですね。
もし上手くコードを書けそうになければルールがマズい場合が多いので、前に戻って考え直します。
ルールが見つかればこっちのもの
シンプルなルールを見つけ出せたらパズルは解けたも同然。コードも楽にシンプルに書けるはずです。ということで、こういうものが出来上がりました。おもちじゃなくて目玉の行進にしてみました。
Processing で書いたコードがこちらにあります。
シンプルでエレガントな方法を求めて
どういうデータが必要か?から始めて、ルールを探し、それを元にして動作するコードを書くことが出来ました。
しかし、このルールで正解だったのでしょうか?このルールは「シンプルでエレガント」でしょうか?
プログラムを書き終えた後、もっと他によい方法があったのでは?と、いつも心にモヤモヤが残ります。シンプルにエレガントに書けた!という気持ちよさを味わえることは滅多にないんです。あぁ、どこかに「シンプルでエレガント」なルールを見つける「シンプルでエレガント」な方法はないものでしょうか…。
そんな方法あるわけないですね。「シンプルでエレガント」なルールを見つけ出す力、見極める目、それらを地道に養っていくしかありません。
自分でルールを見つけ出してパズルを解いたときのような気持ちよさを味わうには、それに見合う勉強と経験が必要です。
実は経験豊富?
ところで、今回のコードで工夫を要した問題がありました。
目玉がキャンバスの端を超えて移動するとき、急に出現したり消滅したりで動きがとても不自然になるという問題です。
それぞれの端で目玉の一部分だけを描画できればいいのですが、それはちょっと難しい。そこで、白い縁で上書きして不自然な部分を隠してしまいました。
こういう小ずるいテクの経験は豊富なんですけどねぇ… 🤣
📘 他にも note でいろんな記事書いています。
🎨 こちらのブログはソースコード付きのクリエイティブ・コーディング作品集になってます。
🐦 Twitter でもいろいろ面白いの上げてるのでぜひフォローしてください。
ここでこの記事はおしまいです。もしこの記事がお気に召しましたら投げ銭お願いします。😉✨
ここから先は
¥ 100
この記事が面白かったらサポートしていただけませんか? ぜんざい好きな私に、ぜんざいをお腹いっぱい食べさせてほしい。あなたのことを想いながら食べるから、ぜんざいサポートお願いね 💕