2

私は楽しいサイド プロジェクトとして Java で Tetris を構築しており、現在はローテーションに取り組んでいます。

私は元々、各ローテーションをハードコーディングしていましたが、これは非常に面倒でした。

そうは言っても、線形代数を使用して行列回転を試みるつもりでしたが、Mathematics.SEの誰かが転置を試すことを勧めました。彼の説明を受けて、私はそれを描いてみました。図面は正しく作成されましたか?

ここに画像の説明を入力

そのため、転置をコーディングしようとしているわけではありませんが、今ではコードで完全に失われています。

public void getTranspose() {
    Tile[][] gridTranspose = transpose();
    System.out.println();
    System.out.println("B`:");
    for (int j = 0; j < gridTranspose.length; j++) {
        for (int i = 0; i < gridTranspose[j].length-1; i++) {
            System.out.print("(" + i + ", " + j + ") ");
        }
        System.out.println();
    }
}

public Tile[][] transpose() {
    Tile gridT[][];
    gridT = new Tile[width][height];
    System.out.println("B:");
    for(int i = 0; i < grid.length; i++) {
        for(int j = 0; j < grid[i].length-1; j++) {
            System.out.print("(" + i + ", " + j + ") ");
            gridT[j][i] = grid[i][j]; 
        }
        System.out.println();
    }
    return gridT;   
}

これは一見正しい転置グラフを出力しますか?

B:

(0, 0) (0, 1) (0, 2) (0, 3) (0, 4) (0, 5) (0, 6) (0, 7) (0, 8) 
(1, 0) (1, 1) (1, 2) (1, 3) (1, 4) (1, 5) (1, 6) (1, 7) (1, 8) 
(2, 0) (2, 1) (2, 2) (2, 3) (2, 4) (2, 5) (2, 6) (2, 7) (2, 8) 
(3, 0) (3, 1) (3, 2) (3, 3) (3, 4) (3, 5) (3, 6) (3, 7) (3, 8) 
(4, 0) (4, 1) (4, 2) (4, 3) (4, 4) (4, 5) (4, 6) (4, 7) (4, 8) 
(5, 0) (5, 1) (5, 2) (5, 3) (5, 4) (5, 5) (5, 6) (5, 7) (5, 8) 
(6, 0) (6, 1) (6, 2) (6, 3) (6, 4) (6, 5) (6, 6) (6, 7) (6, 8) 
(7, 0) (7, 1) (7, 2) (7, 3) (7, 4) (7, 5) (7, 6) (7, 7) (7, 8) 
(8, 0) (8, 1) (8, 2) (8, 3) (8, 4) (8, 5) (8, 6) (8, 7) (8, 8) 
(9, 0) (9, 1) (9, 2) (9, 3) (9, 4) (9, 5) (9, 6) (9, 7) (9, 8) 

B`:

(0, 0) (1, 0) (2, 0) (3, 0) (4, 0) (5, 0) (6, 0) (7, 0) (8, 0) 
(0, 1) (1, 1) (2, 1) (3, 1) (4, 1) (5, 1) (6, 1) (7, 1) (8, 1) 
(0, 2) (1, 2) (2, 2) (3, 2) (4, 2) (5, 2) (6, 2) (7, 2) (8, 2) 
(0, 3) (1, 3) (2, 3) (3, 3) (4, 3) (5, 3) (6, 3) (7, 3) (8, 3) 
(0, 4) (1, 4) (2, 4) (3, 4) (4, 4) (5, 4) (6, 4) (7, 4) (8, 4) 
(0, 5) (1, 5) (2, 5) (3, 5) (4, 5) (5, 5) (6, 5) (7, 5) (8, 5) 
(0, 6) (1, 6) (2, 6) (3, 6) (4, 6) (5, 6) (6, 6) (7, 6) (8, 6) 
(0, 7) (1, 7) (2, 7) (3, 7) (4, 7) (5, 7) (6, 7) (7, 7) (8, 7) 
(0, 8) (1, 8) (2, 8) (3, 8) (4, 8) (5, 8) (6, 8) (7, 8) (8, 8) 
(0, 9) (1, 9) (2, 9) (3, 9) (4, 9) (5, 9) (6, 9) (7, 9) (8, 9) 

だから私の質問は:

1) 上の私の絵は彼の説明の正しい解釈ですか?

2) 転置グラフを正しく生成していますか?

grid[row][col]3) もしそうなら、回転したブロックをどのようにペイントすればよいtranspose()ですか?

public void paintComponent(Graphics g) {
    g.setColor(Color.black);
    g.fillRect(0, 0, getWidth(), getHeight());
    for(int row = 0; row < grid.length; row++) {
        for(int col = 0; col < grid[row].length; col++) {
            if(grid[row][col] != null) {
                //if there is a non-null space, that is a Tetris piece.. fill it red
                if (grid[row][col].getColor() != null) {
                    g.setColor(grid[row][col].getColor());
                    g.fillRect(row * tilesize, col * tilesize, tilesize, tilesize);
                    g.setColor(Color.WHITE);
                    g.drawString("(" + row + ", " + col + ")", row * tilesize, col * tilesize+10);
                }           
            }
        }
    }
}

ありがとう!

4

1 に答える 1

3

転置だけでは、通常のテトリスのすべてのピースでは機能しません。たとえば、次のような形状のピースを考えてみましょう。

xx_
_xx
___

これを転置すると、次のようになります。

x__
xx_
_x_

したがって、特定のピースについて考えるのではなく、角にラベルが付けられた正方形で作業するとどうなるかを考えてみてください。

a_b
___
d_c

これにより、回転が良いかどうかが非常に明確になります。それでは、転置を見てみましょう。

a_d
___
b_c

時計回りの回転を取得するには、横に反転するだけです。

d_a
___
c_b

同じ操作をもう一度実行すると、開始位置から完全に半回転するはずです。転置してみましょう:

d_c
___
a_b

そしてそれを裏返します:

c_d
___
b_a

したがって、時計回りの回転を行うには、単純に転置して反転させます。反対のことをして、それをひっくり返してから転置するとどうなるでしょうか? 前の向きから作業して、反転すると次のようになります。

d_c
___
a_b

次に転置します。

d_a
___
c_b

そして、1 回回転した後、反時計回りの回転に戻ります。したがって、移調だけでは機能しませんが、水平方向の反転と組み合わせて移調すると、必要なすべてが実行されます。

ご質問については、

  1. あなたの絵が正しい解釈であるかどうかはわかりません。あなたが残したコメントに基づいて、私はそれらを誤解したのではないかと疑っています.

  2. はい、それは正しく転置されたグラフです。おそらく、ループで使用したくないでしょう。これgridTranspose[j].length-1により、1 つの列が切り取られるからです。

  3. 回転したブロックをペイントするには、現在のピースを保持するための別の変数を用意することをお勧めします。作品が にあった場合、メソッドx,yに次のようなものを入れます。paintComponent

    for(int row = 0; row < piece.length(); row++) {
        for(int col = 0; col < piece.width(); piece++) {
            if(piece.hasBlockAt(row, col) {
                g.setColor(piece.getColorAt(row, col));
                g.fillRect((row+x) * tilesize, (col+y) * tilesize, tilesize, tilesize);
            }
        } 
    } 
    
于 2013-04-18T18:55:18.310 に答える