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

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


```javascript: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 

適度な改行を入れて読みやすくしてください。
```javascript
<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>
```

<details><summary>【参考】フローチャート</summary>

```mermaid
graph TD
  A["初期化: Z, X, B, A = 12"] --> B["関数 Y() を呼び出す"]
  B --> C["変数の初期化: C, q, c, i = 4"]
  C --> D["計算: f = i-- * K"]
  D --> E{"K + 6 ?"}
  E -->|Yes| F["h += K"]
  E -->|No| G{"t ?"}
  G -->|Yes| H["B = C"]
  G -->|No| I["c -= !Z[h + C[i]]"]
  
  I --> J["p = B[i]"]
  J --> K{"i > 0?"}
  K -->|Yes| D
  K -->|No| L["次のループ"]
  
  L --> M{"f | B ?"}
  M -->|Yes| N["Z = X, X = [l = 228], B の初期化"]
  N --> O["l--"]
  O --> P{"l % A ?"}
  P -->|Yes| Q["l -= l % A * !Z[l]"]
  P -->|No| R["P += k++, c = l += A"]
  R --> S{"c > A?"}
  S -->|Yes| T["Z[c] = Z[c - A]"]
  
  T --> O
  S -->|No| U["最終出力"]
  U --> V["Sに文字列を追加"]
  V --> W["D.innerHTML = S + P"]
  W --> X{"Z[5] ?"}
  X -->|No| Y["setTimeout(Y, i - P)"]
  X -->|Yes| Z["終了"]
```

</details>



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

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

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

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

```javascript
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になるまで続きます。

```javascript
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が更新されます。

```javascript
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の内容が更新されます。

```javascript
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()を再度呼び出します。

```javascript
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|

```javascript
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: