2位:hogeover30 様 のコード (202文字)
元のコード
整形コード
for(
r=[a=4];
a--;
)
for(
p=y=r[a]="";
y<40;
p-=y%8?-1:3
)
for(
x=!y++;
x<81;
r[a]+="_%*|-\n"[x++?f:5]
)
for(
i=f=
41-p<x&x<p+41;
i<160;
f=(q=2*d*d+c*c)>2?f:q+2
)
t=(a+i)*i++*49999-5537&65535,
c=t%38+2-y,
d=t%78+2-x;
return r
解説付きコード
/*
* アニメの制御
*/
for(
r=[a=4]; // 配列数と4要素の配列を初期化
a--; // 配列数分の処理を行い、aが0になれば終了
)
/*
* y軸の制御
*/
for(
p=y=r[a]=""; // 変数を初期化 0値の変数は""で初期化を統合
y<40; // 高さの回数計算
p-=y%8?-1:3 // 「y%8」が0(false)になる時は、木のジグザグ
// が発生する場所なので「3」を引く。
// 通常の場合は、1段y軸が下がるごとに1ずつ
// 木のすそ野の幅を広くしていく
)
/*
* x軸の制御
*/
for(
x=!y++; // 最初の1回目のみ、xをtrue(1)で初期化
// 2回目からは、xをfalse(0)で初期化
// 2回目の0から、文字列の改行を参照する
// ようになる
x<81; // 横幅の回数計算
r[a]+="_%*|-\n"[x++?f:5] // xが0の場合は改行
// その他の場合は
// アスキーアートを描画
)
/*
* イルミネーションと背景と木
*/
for(
i=f=
41-p<x&x<p+41;
// 背景なのか木なのかを判定
// 背景なら0(_)、木なら1(%)の文字列を参照
// 文字の位置を参照するfには0か1が入る
// この値と同じ値を使い、イルミネーションの
// ループを回すiを初期化する
// 「i = 1」なら、ループの開始位置0にならない
// のではという問題は、iが0の場合は一意に
// x=18,y=36となり、ここは背景の位置なので
// 「i = 0」の判定を行う必要がない。
// なので、「i = 0」を飛ばして、「i = 1」から
// 開始して構わない
i<160; // イルミネーションの数だけ確認
f=(q=2*d*d+c*c)>2?f:q+2
// イルミネーションの中心座標からの距離が2超なら
// f(以前に入った値と同じ値)を取る
// 2未満ならqを取る(新たな値になる)
// 0は中心、1は縦線(c*c)、2は横線(2*d*d)
// この0~2に2を足すことで、文字列「"_%*|-\n"」の
// 「*|-」を取得することができる
)
t=(a+i)*i++*49999-5537&65535, // 乱数もどき
// iの値を利用した後1増やす
// 0xFFFF = 65535
// 59999-(0x10000)=-5537
// →「+59999 & 0xFFFF」と「-5537 & 0xFFFF」は等価
// 例)0xF = 15 = b1111
// 9 の場合は 9+(0x10) = 9+16 = 25
// 9 の場合は 9-(0x10) = 9-16 = -7
// 10+ 25 & 15 → 35 & 15 →b100011 & b1111 → b11
// 10+ 9 & 15 → 19 & 15 → b10011 & b1111 → b11
// 10- 7 & 15 → 3 & 15 → b11 & b1111 → b11
// マスクする値+1を足したり引いたりした値でも
// 同じ結果になる
c=t%38+2-y, // 「(t%38+1)-(y-1)」
d=t%78+2-x; // 「(t%78+1)-(x-1)」
// 距離を取る。1を引いているのは
// x, y は1で開始しているから
return r
同文字数別解
元のコード
整形コード
for(
r=[a=4];
a--;
)
for(
p=y=r[a]="";
y<40;
p-=++y%8?-1:3
)
for(
x=!y;
x<81;
r[a]+="_%*|-\n"[x++?f:5]
)
for(
i=f=
41-p<x&x<p+41;
i<160;
f=q>4?f:q
)
t=(a+i)*i++*49999-5537&65535,
c=t%38+1-y,
d=t%78+2-x,
q=2*d*d+c*c+2;
return r