やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

pyxelでテトリスを作った(720行)

 きっちり詰めて消す。キモチイイ!

成果物

demo_play demo_config

特徴

  • キーコンフィグで任意のキー設定ができる

苦労した所

苦労した所

衝突判定

  • 落下予測
  • 落下時ブロック固定

 たまに下端より1ブロック分だけ下にめり込むバグがある……。

 コードが汚すぎてヤバイ。

回転

 テトリミノをどうやって回転させるか。実際のパターンを書いてみて、法則を推論してみる。

 結論からいえば、行列変換(アフィン変換)をすればいい。

 だが、上記Wikipediaをみてもさっぱりわからん。暗号にしか見えない。

0,1,2,3,
4,5,6,7,
8,9,A,B,
C,D,E,F

 右1回すると以下。

C,8,4,0,
D,9,5,1,
E,A,6,2,
F,B,7,3

 配列のインデックス値は以下のように変化した。

0 3 3
1 7 6
2 11 9
3 15 12
4 2 -2
5 6 1
6 10 4
7 14 7
8 1 -7
9 5 -4
A 9 -1
B D 2
C 0 -12
D 4 -9
E 8 -6
F C -3

 法則っぽいのがある。差をみると前半の37-1をかけて逆順にしたら、後半の-7-3になる。1行ごとに差は+3。でも、この数列の計算式が謎。

 まあいいや。この数列をハードコーディングして加算しちゃおう。バカ丸出しだけど。

 一応、一回転させてみる。

 右1回すると以下。

F,E,D,C,
B,A,9,8,
7,6,5,4,
3,2,1,0

 右1回すると以下。

3,7,B,F,
2,6,A,E,
1,5,9,D,
0,4,8,C

 右1回すると最初に戻る。

 次は左回転について。

0,1,2,3,
4,5,6,7,
8,9,A,B,
C,D,E,F

 左1回すると以下。

3,7,B,F,
2,6,A,E,
1,5,9,D,
0,4,8,C
0 C 12
1 8 7
2 4 2
3 0 -3
4 D 9
5 9 4
6 5 -1
7 1 -6
8 E 6
9 A 1
A 6 -4
B 2 -9
C F 3
D B -2
E 7 -7
F 3 -12

 やhり法則っぽいのがある。差をみると前半の12-6-1をかけて逆順にしたら、後半の6-12になる。1行ごとに差は-5。でも、この数列の計算式が謎。

テトリミノ

 テトリスで落下してくるブロックの形は7種類。それらを「テトリミノ」という。wikipediaが詳しい。

 以下のように形状を定義する。

I

[1,1,1,1,
 0,0,0,0,
 0,0,0,0,
 0,0,0,0]

 右1回すると以下。

[1,0,0,0,
 1,0,0,0,
 1,0,0,0,
 1,0,0,0]

 配列のインデックス値は以下のように変化した。

0 0
1 4
2 8
3 12

 右1回すると最初に戻る。

S

[0,1,1,0,
 1,1,0,0,
 0,0,0,0,
 0,0,0,0]

 右1回すると以下。

[1,0,0,0,
 1,1,0,0,
 0,1,0,0,
 0,0,0,0]

 配列のインデックス値は以下のように変化した。

1 5
2 9
4 0
5 4

 右1回すると最初に戻る。

L

[0,0,1,0,
 1,1,1,0,
 0,0,0,0,
 0,0,0,0]

 右1回すると以下。

[1,0,0,0,
 1,0,0,0,
 1,1,0,0,
 0,0,0,0]

 右1回すると以下。

[1,1,1,0,
 1,0,0,0,
 0,0,0,0,
 0,0,0,0]

 右1回すると以下。

[1,1,0,0,
 0,1,0,0,
 0,1,0,0,
 0,0,0,0]

 右1回すると最初に戻る。

T

[0,1,0,0,
 1,1,1,0,
 0,0,0,0,
 0,0,0,0]

 右1回すると以下。

[1,0,0,0,
 1,1,0,0,
 1,0,0,0,
 0,0,0,0]

 右1回すると以下。

[1,1,1,0,
 0,1,0,0,
 0,0,0,0,
 0,0,0,0]

 右1回すると以下。

[0,1,0,0,
 1,1,0,0,
 0,1,0,0,
 0,0,0,0]

 右1回すると最初に戻る。

左寄せ

 テトリミノを回転させたあと、左寄せする必要があった。

 たとえばI型ミノの場合。

[1,1,1,1,
 0,0,0,0,
 0,0,0,0,
 0,0,0,0]

 右1回すると以下。

[0,0,0,1,
 0,0,0,1,
 0,0,0,1,
 0,0,0,1]

 上記を左寄せして以下のようにしたい。

[1,0,0,0,
 1,0,0,0,
 1,0,0,0,
 1,0,0,0]

 インデックス位置ごとにおける変化をみてみる。それぞれに異なる識別子を与えてみる。

0,1,2,3,
4,5,6,7,
8,9,A,B,
C,D,E,F,

 左寄せすると以下。右列はすべて0になる。

1,2,3,0,
5,6,7,0,
8,9,A,B,0,
D,E,F,0,

 変更前後における差はすべて-1

0 -
1 0 -1
2 1 -1
3 2 -1
4 -
5 4 -1
6 5 -1
7 6 -1
8 -
9 8 -1

課題

  • 消去時
    • 効果音
    • 効果アニメーション
  • 得点の算出工夫
  • ゲームモード追加
    • 徐々に落下速度があがる

所感

 わりといい感じにできた。

 でもバグがある。そして数学がわからんので、冗長かつ煩雑なコードになってしまっている気がする。

 誰か、もっとキレイに書き直して。

パクれなかった

 pyxelてテトリスなんて、きっと誰かがとっくの昔に作っているに違いない。探してみるとあった。でも、コードが読めなかった……。

 動画はあるけどコードがない……。

対象環境

$ uname -a
Linux raspberrypi 4.19.97-v7l+ #1294 SMP Thu Jan 30 13:21:14 GMT 2020 armv7l GNU/Linux