5

私は Tetris クローンを作成しており、C# でプロトタイピングを行っています。最終的なコードは組み込みシステム (8 ビット CPU と非常に小さな RAM を使用) で実行することになっているため、単純なアルゴリズムを使用してライン クリアを実行しようとしています。

現在、私のプレイフィールドは 2D 配列です。

private readonly TetrominoType[][] _playfield;

(ここTetrominoTypeで、None またはブロックの色付けに使用される 7 つのタイプのいずれかを示す列挙型)

行がクリアされたら、この配列をその場で変更したいのですが、これが私の問題です。次の例を見てください。

   Before       After
0 #      #     #      #
1 #      #     #      #
2 #      #     #      #
3 #      #     #      #
4 #      #     #      #
5 #xxxxxx#     #      #
6 #x   xx#     #      #
7 #xxxxxx#     #      #
8 #xxxxxx#     #x   xx#
9 #x xxxx#     #x xxxx#
  ########     ########

ライン 5、7、および 8 を削除する必要があるため、他のラインを削除する必要があると既に判断しており、右側の状態が残ります。

私の素朴な方法は、基本的に、逆方向に反復して、クリアされた行の上の行をコピーすることです。

for(int iy = 9; iy >= 0; iy--) {
    if(_linesToClear.Contains(iy)) {
        for(int ix = 0; ix < 6; ix++) {
            _playfield[iy][ix] = _playfield[iy-1][ix];
        }
    }
 }

ここでの問題は、上の行もクリアされる可能性があり (たとえば、iy == 87 行目ではなく 6 行目をコピーしたい場合)、コピーした行をクリアする必要があること ( iy-1)、またはその上の行をコピーする必要があることです。それは今度は上向きにトリクルする必要があります。

すでにスキップした行数を数えてみましたが、それは新しい配列を作成してから交換した場合にのみ機能しますが、プレイフィールド配列のインプレース変更の数学作業を取得できません。

おそらく非常に単純ですが、アルゴリズムがわかりません。どうすればこれを行うことができるか、誰かが洞察を持っていますか?

4

2 に答える 2

2

主な問題は複数のクリアされた行です。そのため、複数のクリアされた行が連続している場合は、それらすべてを下に移動する必要があります。クリアする必要がある行のリストがあるので、その上の行を単にコピーするのではなく、次のクリアされていない行がどれだけ上にあるかを調べ、その上のすべての行をその行の下に移動できます。たとえば、次のようにします。

for(int iy = 9; iy >= 0; iy--)
{
    if(_linesToClear.Contains(iy))
    {
        int nextLineIndex = iy-1;
        while( _linesToClear.contains(nextLineIndex) && nextLineIndex >= 0 )
        {
            nextLineIndex--;
        }
        if ( nextLineIndex >= 0 )
        {
            int amountToDrop = iy - nextLineIndex
            for(int ix = 0; ix < 6; ix++)
            {
                _playfield[iy][ix] = _playfield[iy-amountToDrop][ix];
            }
        }
    }
 }

これにより、連続してクリアされた行がいくつあるかがわかり、その数の行にすべてがドロップされます。これが役立つことを願っています!

于 2014-02-04T03:10:39.867 に答える
1

それはうまくいくでしょうか?

int k = 0;
for(int iy = 9; iy >= 0; iy--) {
    if(!_linesToClear.Contains(iy)) {
        for(int ix = 0; ix < 6; ix++) {
            _playfield[iy + k][ix] = _playfield[iy][ix];
        }
    }
    else
        k++;
}
于 2014-02-04T03:34:23.423 に答える