0
0

7行テトリスをMonicaを使って分解してみるテスト

Last updated at Posted at 2024-09-19

7行テトリスをMonicaを使って分解してみる

7_line_tetris.html

<body id=D onKeyDown=K=event.keyCode-38><script>Z=X=[B=A=12];function Y(){for(C
    =[q=c=i=4];f=i--*K;c-=!Z[h+(K+6?p+K:C[i]=p*A-(p/9|0)*145)])p=B[i];for(c?0:K+6?h
    +=K:t?B=C:0;i=K=q--;f+=Z[A+p])k=X[p=h+B[q]]=1;h+=A;if(f|B)for(Z=X,X=[l=228],B=[
    [-7,-20,6,h=17,-9,3,3][t=++t%7]-4,0,1,t-6?-A:2];l--;)for(l%A?l-=l%A*!Z[l]:(P+=
    k++,c=l+=A);--c>A;)Z[ c]=Z[c-A];for(S="";i<240;S+=X[i]|(X[i]=Z[i]|=++i%A<2|i>228
    )?i%A?"":"■<br>":"_");D.innerHTML=S+P;Z[5]||setTimeout(Y,i-P)}Y(h=K=t=P=0)
    </script>

ネタ枠な投稿テストなので読んでもあまり面白くないと思います

前提知識

onkeydown
キー コード
SPACE 32
37
38
39
40

Hi! Monica

適度な改行を入れて読みやすくしてください。

<body id="D" onKeyDown="K=event.keyCode-38">
    <script>
        Z = X = [B = A = 12];

        function Y() {
            for (C = [q = c = i = 4]; 
                 f = i-- * K; 
                 c -= !Z[h + (K + 6 ? p + K : C[i] = p * A - (p / 9 | 0) * 145)]) {
                p = B[i];
            }

            for (c ? 0 : K + 6 ? h += K : t ? B = C : 0; 
                 i = K = q--; 
                 f += Z[A + p]) { 
                k = X[p = h + B[q]] = 1;
            }

            h += A;

            if (f | B) {
                for (Z = X, X = [l = 228], B = [
                    [-7, -20, 6, h = 17, -9, 3, 3][t = ++t % 7] - 4, 0, 1, t - 6 ? -A : 2
                ]; 
                l--;) {
                    for (l % A ? l -= l % A * !Z[l] : (P += k++, c = l += A); 
                         --c > A;) {
                        Z[c] = Z[c - A];
                    }
                }
            }

            for (S = ""; i < 240; S += X[i] | (X[i] = Z[i] |= ++i % A < 2 | i > 228) ? 
                 i % A ? "" : "■<br>" : "_"
            ); 
            D.innerHTML = S + P;

            Z[5] || setTimeout(Y, i - P);

        }

        Y(h = K = t = P = 0);
    </script>
</body>
【参考】フローチャート

各変数の値の変化に着目して、スクリプトの流れを説明してください

Monica
以下に、各変数の値の変化に着目してスクリプトの流れを説明します。

初期化
Z, X, B, Aのすべてが12で初期化されます。これにより、ZとXは配列であり、最初の要素が12になります。

Z = X = [B = A = 12];

関数 Y() の呼び出し
h, K, t, Pがすべて0で初期化され、Y()関数が呼び出されます。

Y(h = K = t = P = 0);

最初のループ
初期化: C, q, c, iが4に設定されます。
fの計算: fはi-- * Kで計算されます。最初にiは4で、Kは0なので、fは0になります。iは3に減少します。
条件式: cはZ[h + (K + 6 ? p + K : C[i])]の結果に基づいて減少します。最初はhは0、Kは0なので、C[i]の計算が行われます。
pの更新: pはB[i]で更新されます。最初はB[3](初期化時にBは12)となります。
このループは、iが0になるまで続きます。

for (C = [q = c = i = 4]; 
     f = i-- * K; 
     c -= !Z[h + (K + 6 ? p + K : C[i] = p * A - (p / 9 | 0) * 145)])
) {
    p = B[i];
}

次のループ
初期化: cの値に基づいて、hやBが更新されます。
i, Kの更新: iとKはq--の結果で更新されます。
fの加算: fはZ[A + p]の値が加算されます。
kの設定: X[p]に1が代入され、pが更新されます。

for (c ? 0 : K + 6 ? h += K : t ? B = C : 0; 
     i = K = q--; 
     f += Z[A + p]) { 
    k = X[p = h + B[q]] = 1;
}

条件チェックと新しい配列の初期化
fまたはBが真であれば、ZをXで更新し、新しい配列をXに設定します。
内部ループでは、lが0になるまで処理が行われ、条件に基づいてZの内容が更新されます。

if (f | B) {
    for (Z = X, X = [l = 228], B = [[...]]; 
         l--;) {
        for (l % A ? l -= l % A * !Z[l] : (P += k++, c = l += A); 
             --c > A;) {
            Z[c] = Z[c - A];
        }
    }
}

最終的な出力
出力文字列の生成: SにX[i]やZ[i]の値に基づいて文字列を追加します。
D.innerHTMLの更新: 最終的な文字列SとPをD要素に設定します。
再帰呼び出し
Z[5]が0であれば、Y()を再度呼び出します。

for (S = ""; i < 240; S += X[i] | (X[i] = Z[i] |= ++i % A < 2 | i > 228) ? 
     i % A ? "" : "■<br>" : "_"
); 

D.innerHTML = S + P;
Z[5] || setTimeout(Y, i - P);

まとめ
このスクリプトは、変数の値を動的に更新しながら、条件に基づいて様々な処理を行います。特にiの値の変化に注目すると、ループの各段階での変数の状態がどのように変わるかがわかります。最終的には、生成された文字列がHTMLに表示され、必要に応じて再帰的に関数が呼び出されます。

何気に嵌った所

  • フローチャートの作図

フローチャートの作図でエラーを吐くのを修正できないので、
各ノードのテキストをダブルクォーテーションで囲むように指示をして修正したよ

  • 「K+6?」の解釈

event.keyCodeは、押されたキーのASCIIコードを返します。これを基に、次のようにKが計算されます

Key K
SPACE (32) K = 32 - 38 = -6
← (37) K = 37 - 38 = -1
↑ (38) K = 38 - 38 = 0
→ (39) K = 39 - 38 = 1
↓ (40) K = 40 - 38 = 2
for (c ? 0 : K + 6 ? h += K : t ? B = C : 0; 
     i = K = q--; 
     f += Z[A + p]) { 
    k = X[p = h + B[q]] = 1;
}

「K + 6が真の場合、h += Kが実行され、hがKの値だけ増加します。ただし、SPACE(K = -6)の場合は何も実行されません。」
この回答に至るまでに、K = event.keyCode - 38の計算の説明とASCIIコードの説明をする必要がありました:thinking:

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0