7行テトリスを解説!コード付きでゲームもできる!

ゲーム
Pocket

こんにちは!プログラミングとレトロゲームが大好物なみなさん!
今回のテーマは…なんと「7行で動くテトリス」!

「えっ、あのブロックがカシャカシャ落ちてくるテトリスを、たった7行で?」
そう思った方、めちゃくちゃ普通です。でもマジなんです。

この「7行テトリス」は、コード界隈でひっそりと語り継がれてきた“伝説の最小実装”のひとつ。HTMLで書かれたその短すぎるコードは、一見どう動くのかわからないようで、実は究極に無駄がない美しさを持っています。

今回はその7行テトリスの全貌を、初心者にもわかりやすく解説していきます!
コードの構造、動作の仕組み、そしてなぜこんなに短くできるのか——その秘密を一緒に覗いてみましょう♪

記事の先頭にも埋め込みで遊べるようにしていますが、この7行テトリスの元のゲームページはこちらです(新しいタブで開きます)。

\当サイトではリンク広告を利用しています。/

🧩 7行テトリスとは?

「7行テトリス」は、JavaScriptで書かれた超短縮版テトリスです。
その名の通り、たった7行(約300文字)でテトリスのプレイが可能!

この作品は、「コードゴルフ」や「ショートコーディング」と呼ばれる分野で知られる代表的なスクリプトです。

コードゴルフとは:
目的の機能を、できるだけ短く実装することを競うプログラミング遊びのこと。

※なぜゴルフにたとえられているのかというと、ゴルフはできるだけ打数を少なくした方が勝ちだからですね。

ゲームとして遊べるだけでなく、プログラミングの圧縮技術の極致としても注目されています。


🔍 7行テトリスを解説!

以下が実際のコードです(コピペで遊べます。遊び方は後述。):

<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;if(e=!e)if(h+=A,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,99-P)}Y(h=e=
K=t=P=0)</script>

すごく読みにくいですよね。でも、大丈夫です。以下のように段階的に分解していけば、中で何をしているのかがわかってきます。

▶ 7行テトリスの遊び方!

冒頭の埋め込みでも遊べますが、ほかのやり方としては自分の環境で遊ぶこともできます。

最も基本的な方法は、実際にこのコードをメモ帳などのテキストエディタに貼り付けます。

保存の時、適当な名前をつけ、テキストファイルではなく「すべてのファイル」を選択し「.html」の拡張子をつけてHTMLとして保存します。

それをブラウザで開いて実行すると、テトリスがプレイできます!
ターミナル風の「■」「_」で表示されるので、まるで懐かしいDOSゲームのような雰囲気です。

もう一つの方法としては、codepenなどのHTMLがリアルタイムで編集・表示できるウェブツールを使い、そこにコピペすることです。

すると保存などをしなくてもコピペで動作します。


🎮 ゲームの仕組み:段階解説

それではゲームの動く仕組みを段階的に解説していきましょう。

1. 入力処理(キーボード)

<body id=D onKeyDown=K=event.keyCode-38>
  • キーが押されたとき、K にキーコードを格納。
  • 矢印キー(←→↑↓)に対応。
    • ↑:K=0
    • ←:K=-1
    • →:K=1
    • ↓:K=2

2. ゲームの初期化

Z = X = [B = A = 12];
  • A = 12:盤面の横幅(12列)
  • X:現在の盤面
  • Z:次の状態を保持する配列(Xと同一参照)

3. ブロックの生成と回転処理

B = [[-7,-20,6,h=17,-9,3,3][t=++t%7]-4, 0, 1, t-6?-A:2];
  • t はブロックの種類(0~6)
  • 各値は、テトリミノを構成するブロックの相対座標。

4. 移動・当たり判定

for(c -= !Z[h+(K+6?p+K:C[i]=p*A-(p/9|0)*145)]) ...

ここは最も難解な部分ですが、要するに「押されたキーに応じて回転・左右移動・下移動を試み、衝突がないなら位置を更新する」という処理。

5. 行消去

for(Z=X, X=[l=228], ...; l--;) {
for(l%A ? l -= l%A*!Z[l] : (P+=k++, c=l+=A); --c>A;)
Z[c]=Z[c-A];
}
  • 行が埋まった場合、その行を削除して上を落とす。
  • P はスコア(行数)

6. 描画処理

for(S=""; i<240; S+=X[i]|(X[i]=Z[i]|=++i%A<2|i>228)?i%A?"■":"■<br>":"_");
D.innerHTML=S+P;
  • X[i]:現在の盤面状態
  • 画面にブロックがあるかどうかで または _ を出力
  • 改行は <br> を使用

7. 再描画(ゲームループ)

Z[5] || setTimeout(Y, 99 - P)
  • ブロックが詰まったら終了(Z[5])
  • それ以外なら 100ms – スコア だけ待って Y() を再呼び出し(加速処理)

なぜ回転できないの?

7行テトリスでは、上ボタンを押しても回転がうまく働きません。

これは以下の理由によります。

7行テトリスでは、ブロックの回転処理が基本的に存在しないか、非常に限定的な方法でしか行われていません。そのため、回転キー(↑キー)を押しても、回転しない/期待通りに動かないのが仕様です。


🔍 理由1:コードサイズを最優先しているため

7行テトリスは、コードゴルフ(=とにかく短く書くことが目的)の作品です。そのため、以下のような「通常のゲーム開発」では重要な機能が削られています:

一般のテトリス7行テトリスでは
ブロック回転実装されていない / 固定形状
壁蹴り回転実装されていない
回転毎に衝突判定実装されていない

🔍 理由2:回転操作(↑キー)に機能を割り当てていない

以下のようなコード片でキー入力が処理されていますが:

for(C=[q=c=i=4];f=i--*K; c-=!Z[...] ) p=B[i];

ここで K = event.keyCode - 38 によって上下左右を扱っているように見えますが、↑キー(keyCode = 38 → K = 0)の処理が事実上無視されています。

そのため、そもそも回転キーを押しても何の効果もないんです。


💡 読みやすく書き直したらこうなる!

この7行コードはすごいけど、やっぱり読みづらい。
もし、これを普通のJavaScriptで書いたら、100〜200行くらいにはなります。

例えば、以下のようにモジュールごとに分けると読みやすくなります。

  • drawField():盤面の描画
  • checkCollision():衝突判定
  • moveBlock(dir):ブロックの移動
  • rotateBlock():回転処理
  • dropBlock():1段下に落とす
  • fixBlock():ブロックを固定
  • clearLines():揃った行の削除

このようにして、機能を分離すれば、学習にも再利用にも便利なコードになります。


🧾 まとめ

  • 「7行テトリス」は、コードゴルフの神業的作品。
  • 非常に短いが、入力処理・ブロック生成・当たり判定・描画・行消去・ループすべてが詰まっている。
  • 圧縮されすぎて読みづらいが、段階的に見ていけば理解可能。
  • 学習には読みやすい構造の再構成がおすすめ!

「7行テトリス」は、プログラミングの奥深さと楽しさを凝縮した芸術作品です。
ぜひ、あなたの目と指で、そのミニマルな世界を体験してみてください!