楽屋裏 - 酔っ払いの虫 (Drunk Bug) - e-Gadget - プログラム関数電卓
http://egadget.blog.fc2.com/blog-entry-445.html
以下では、この記事を「原作」と記しております。まずは、TI-83+への移植を試みました。
TI-83+版のコード
PROGRAM:DRUNK :ClrDraw :94/2→V:62/2→W :While 1 :Pxl-Change(W,V) :2*randInt(0,1)-1→S :2*randInt(0,1)-1→T :If V+S≧0 and V+S≦94 and W+T≧0 and W+T≦62 :Then :V+S→V:W+T→W :End :EndrandInt(Begin, End)は、Begin,Endの間の整数乱数を返す関数で、randInt(0,1)は、0もしくは1を返します。
2*randInt(0,1)-1 の部分で、-1, +1の整数乱数にしております。
原作ではMODを使っておりましたが、まったく同じでは芸がないので、少しひねってみました。
今回、Pxl-Change()を使って判ったのですが、不規則ながらもグラフィクスコマンドを使う所で、一部変数の値が書き換わってしまうケースがあります。CASIO BASICと同じ様な感じです。
マニュアルには「ただし、変数X,Y,T,θ,Tはグラフを描く際、更新されることがあるので、グラフ関係以外の値を代入することは避けたほうが賢明です」(ページ A-50)と明記されておりました。
原作の興味深い所としては、酔歩の「移動の等方性」を担保するため、斜め方向の移動のみを行っている所です。
斜め方向の移動は、縦、横の移動と較べると、√2倍の距離の移動になります。縦、横の移動と斜め方向の移動とでは、単位時間での移動速度が異なる事になりますが、縦、横の移動、もしくは斜め方向の移動だけならば、移動の等方性が確保されます。原作の場合、斜め方向の移動のみを行う事で、移動の等方性を確保し、更に視覚的にも面白い表現を実現しています。
直交座標系では、縦、横と斜め移動の等方性について考える事が必要になりますが、四角ではなく六角形を敷き詰めたマス目空間(Hexagonal field)では、黙っていても移動の等方性が確保されます。少し工夫をする事で、直交座標系のピクセル空間にHexagonal fieldを擬似的に表現できます。
PROGRAM:HXDRNK :ClrDraw :94/2→V:62/2→W :While 1 :Pxl-Change(W,V) :Pxl-Change(W,V+1) :Pxl-Change(W+1,V) :Pxl-Change(W+1,V+1) :randInt(0,5)→D :(iPart(D/2)-1)*2→T :2(fPart(D/2)*2)-1→S :If T=0 :Then :S*2→S :End :If V+S≧0 and V+S≦94 and W+T≧0 and W+T≦61 :Then :V+S→V:W+T→W :End :End
図が必要な事もあり、詳しい内容は、いずれ折を見て述べましょうか。
更に、HP Prime向けコードも。
// title : Diagonal random walk for HP Prime // begin : 2015-08-02 // note : EXPORT drunk() BEGIN // Clean the screen (G0) RECT(); LOCAL i, p; LOCAL x, y, v, w; x := 320/2; y := 240/2; WHILE GETKEY() == -1 DO p := B→R(GETPIX_P(x, y)); IF p<>0 THEN PIXON_P(x, y); ELSE PIXOFF_P(x, y); END; v := RANDINT*2-1; w := RANDINT*2-1; IF x+v>=0 AND x+v<320 AND y+w>=0 AND y+w<240 THEN x := x+v; y := y+w; END; // WAIT(0.1); END; // key wait loop REPEAT UNTIL GETKEY() == -1; FREEZE; END;
実行中に適当なキーを押すと、停止します。更にもう一度キーを押す事で、プログラムの終了となります。
エミュレータで動かすと「爆速」ですが、そんな時にはコメントになっている「WAIT(0.1)」を使ってみて下さい。
お次はHexagonal field版
// title : Hexagonal random walk for HP Prime // begin : 2015-08-02 // note : EXPORT hexdrunk() BEGIN // Clean the screen (G0) RECT(); LOCAL i, p, d; LOCAL x, y, v, w; x := 320/2; y := 240/2; WHILE GETKEY() == -1 DO p := B→R(GETPIX_P(x, y)); IF p<>0 THEN PIXON_P(x, y); PIXON_P(x+1, y); PIXON_P(x, y+1); PIXON_P(x+1, y+1); ELSE PIXOFF_P(x, y); PIXOFF_P(x+1, y); PIXOFF_P(x, y+1); PIXOFF_P(x+1, y+1); END; d := RANDINT(5); w := (IP(d/2)-1)*2; v := 2*(FP(d/2)*2)-1; If w==0 THEN v := 2*v; END; IF x+v>=0 AND x+v<320 AND y+w>=0 AND y+w<240 THEN x := x+v; y := y+w; END; // WAIT(0.1); END; // key wait loop REPEAT UNTIL GETKEY() == -1; FREEZE; END;
HP PrimeのPPL (Prime Programming Language)での注意ですが、「変数への代入には := を使うべし」です。
実は、ピクセル値の値を取得する所で「p = B→R(GETPIX_P(x, y));」とやって、かなりハマってしまいました。
これでは代入ではなく「比較」になってしまうのですが、構文上は問題がないのでそのまま実行出来てしまい、エラー発見に手こずる事になります。
小中学生の皆様はもう新学期だそうで、今更「夏休みの自由研究」でもないのですが、来年の自由研究のネタに使えるかも知れません (鬼が笑うとりますがな)。