なでしこを明後日の方向に

日本語プログラム言語なでしこを応援しています

なでしこでテトリスブロックをスーパーローテーションさせる

プログラムの練習で作るゲームといえばテトリス
ネックとなる「ブロックを回転させる」プログラムを作ります。

知ってる? スーパーローテーションシステム(SRS)

テトリスブロックを回転させるためにはSRSの存在を知らなければなりません。

ブロックを回転させたとき、何かにぶつかったら回転軸をずらして再試行する機構です。
これを実装しないと「壁けり」や「Tスピントリプル」が発生せず、テトリスの練習に使うことができません。

wikipediaにあるT-Spin Tripleの概略図
(https://ja.wikipedia.org/wiki/%E3%83%86%E3%83%88%E3%83%AA%E3%82%B9)

実践例だとこちらが見やすいと思います https://www.mintscore333.com/2018-09-05-203200/

前提

右がXのプラス方向、下がYのプラス方向、回転は角度は右回転方向とします。
回転していない状態を「状態0」として、右回転ごとに状態1・状態2・状態3とします。

初期回転軸を[0,0]としたブロックを定義する!

ここでは初期回転軸を[0,0]としてブロックを定義します。

この座標[0,0]は回転する「点」であり、「ブロックの中心点」となります。

T字ブロックは [[0,0],[1,0],[-1,0],[ 0,-1]] です。(上の状態0の図を参照)
カドの部分は0.5ズレた座標になります。

……I字ブロックは [[-1.5,-0.5],[-0.5,-0.5],[0.5,-0.5],[1.5,-0.5]]です(小声)

通常時の座標の回転

座標を回転させましょう。
座標[x,y]を回転軸[0,0]で右に90度だけ回転するのだから、一般的に回転後の座標は

 x' = x * cos(90度) - y * sin(90度)
 y' = x * sin(90度) - y * cos(90度)

で求められます。

テトリスだと90度単位しか使わないので sin(90度) = 1、cos(90度)=0で計算すると

 x' = -y
 y' = x

となります。

逆回転の場合は sin(-90度) = -1、cos(-90度)=0なので

 x' = y
 y' = -x

となります。

なでしこ3では複数変数への代入文が使えるので このように書けます。

 x,y = [-y, x]      //回転する(右回転)

回転、かんたんですね!

複数変数への代入文について(v3.2.6以降) なでしこさん マニュアル - 文法/代入文

実例

T字ブロックの状態0は[[0,0],[1,0],[-1,0],[ 0,-1]]。
右回転すると状態1の座標[[0,0],[0,1],[0,-1],[1,0]になるはず。
なでしこ3で式を入れて確認してみましょう。

[[0,0],[1,0],[-1,0],[ 0,-1]]を反復
    x,y = 対象
    x,y= [-y,x]
    [x,y]を表示
ここまで

座標[[0,0],[0,1],[0,-1],[1,0]が表示されました!

SRSに対応する回転式

テトリス99やぷよぷよテトリスなどでは、床についたT字ブロックを右回転すると、壁際に立ちます。

このとき、「ブロックは[0,-1]を中心に回転した」はずです。

中心が[0,0]でない場合、「回転の中心」を引いて、回転して、「回転の中心」を足します。
これをプログラムしてみます。

中心X,中心Y=[0,-1]

[[0,0],[1,0],[-1,0],[ 0,-1]]を反復
 x,y = 対象
 x,y = [x-中心X,y-中心Y] //中心を引く
 x,y = [-y,x]     //回転する(右回転)
 x,y = [x+中心X,y+中心Y] //中心を足す
 [x,y]を表示
ここまで

実行結果は[[-1,-1],[-1,0],[-1,-2],[0,-1]]を示しています。 これで合ってます!

Tスピントリプルの回転

Tスピントリプルの場合も中心が違うだけです。
右回転によるTスピントリプルの回転中心は[-1.5,0.5]です。
(ブロックの中心が[0,0]なので、角は0.5ずれた座標になります)

回転の中心座標テーブルを用意する

ブロックを回転した時に衝突判定をして、なにかにぶつかったら別の回転中心を使います。
[0,0]で右回転してダメだったら[-0.5,-0.5]、そこもだめなら[0,-1]、[-1,1]、[-1.5,0.5]の順に回転の中心を変更して衝突判定します。

[0,0]、[-0.5,-0.5]、[0,-1]、[-1,1]、[-1.5,0.5]

上記の座標は「T字ブロックが、状態0から、右回転するとき」の座標です。
この座標は、ブロック種類と状態と回転方向で変わりますから、座標をテーブルでもつ必要があります。

棒以外のテーブル

棒のテーブル

※ 間違いがあればお気軽にコメント欄でおねがいします
テトリスちゃんねるさんの図には間違いがあります


これで美しい残像をもったTスピントリプルが描画できそうです。