2009-03-14 3 views
17

Tôi lập trình một bản sao Tetris và trong trò chơi của tôi, tôi lưu trữ các khối tetromino của tôi dưới dạng mảng 4x4 khối. Bây giờ tôi cần để có thể xoay các vị trí số nguyên trong các mảng để tôi có được một khối tetris xoay. Tôi không thể chỉ đơn giản là xoay kết cấu bởi vì tất cả các phát hiện va chạm của tôi, vv đã được thiết kế để làm việc với mảng 2D. Trò chơi được viết bằng C# bằng cách sử dụng XNA.Làm thế nào để xoay một mảng 2D của số nguyên

Làm cách nào tôi có thể xoay mảng ints 2D của mình bằng 90 độ theo chiều kim đồng hồ/ngược chiều kim đồng hồ.

Đây là cách khối 'L' của tôi được lưu trữ làm ví dụ.

0 1 0 0 
0 1 0 0 
0 1 1 0 
0 0 0 0 

Cảm ơn sự giúp đỡ của bạn.

+0

Cả C# và C++? –

Trả lời

29

Nếu chúng là một mảng 2D, bạn có thể thực hiện xoay bằng cách sao chép với các lệnh truy cập mảng khác nhau.

ví dụ, đối với một xoay chiều kim đồng hồ, hãy thử:

int [,] newArray = new int[4,4]; 

for (int i=3;i>=0;--i) 
{ 
    for (int j=0;j<4;++j) 
    { 
     newArray[j,3-i] = array[i,j]; 
    } 
} 

Counter-chiều kim đồng hồ là tương tự.

+0

Giải pháp tốt, nhưng quá mức cần thiết cho miền có vấn đề. –

+0

kiểm tra mã này ngay bây giờ ... –

+0

Tôi đang bỏ phiếu này, nó phải được đánh dấu là giải pháp. Bạn không chắc chắn những gì bạn có nghĩa là rde6173, trừ khi bạn cũng được chứng từ để lưu trữ 4 mảng định hướng. – Ricket

4

Nếu bạn muốn xoay một khối 4 x 4, bạn chỉ cần di chuyển các vị trí:

A B C A 
C D D B 
B D D C 
A C B A 

Mỗi Một chuyển sang A tiếp theo, và tương tự cho B, C và D.

/-----\ 
    |  | 
    |  V 
    A B C A 
/->C D>D B--\ 
| B D D C | 
| A C B A | 
| |^ | 
| | | | 
\----/ \----/  
+0

Tôi nghĩ rằng hình ảnh của bạn là một chút, không chắc chắn chính xác những gì bạn đang cố làm rõ với nó và các mũi tên dường như trỏ b -> c và a -> c thay vì hỗ trợ các chỉ dẫn của bạn. fmsf, lớn lên. – Ricket

+0

@Ricket cảm ơn, sửa chữa nó. –

6

Trong tetris cổ điển, có rất ít hoán vị đối tượng. Tôi chỉ đơn giản sẽ có một mảng liên tục cho mỗi "tetromino", tại mỗi vị trí trong 4 vị trí và logic đơn giản để chọn một vị trí thích hợp dựa trên đầu vào.

Tại sao các chu kỳ CPU bị lãng phí cố gắng xoay vòng?

+0

Toán học đơn giản như vậy trong trường hợp này, có lẽ chỉ cần xoay nhanh để thực hiện tìm kiếm hoán vị dựa trên vị trí khối + vị trí hiện tại. –

+0

Điều đó thật lố bịch. –

+0

Tôi cũng sẽ thêm điều đó từ trò chơi và điểm thiết kế của chế độ xem, có thể tốt hơn là nên đặt các xoay vòng được đặt trước. Bạn sẽ làm gì khi bạn nhận được mảnh 4x1 dài? Nếu bạn xoay nó hai lần, nó có thực sự là một không gian đầy đủ qua một bên (mà nó sẽ là nếu bạn sử dụng toán học thuần túy)? –

11

Không xoay các đoạn có mã. Chỉ cần lưu trữ một mảng của các định hướng mảnh khác nhau và chu kỳ qua chúng khi mảnh được xoay. Không cần xoay động trong trò chơi Tetris.

Vì miền có vấn đề là Tetris, bạn sẽ thấy thuật toán xoay gây ra các hiệu ứng không mong muốn, chẳng hạn như Tetronimo dài không xen kẽ giữa hai vị trí (giống như trong thực tế).

+0

-1; Không có lợi thế để lưu trữ 4 định hướng của từng phần thay vì chỉ xoay. Bạn nên tập trung vào việc trả lời câu hỏi của mình, không khuyến khích anh ta, trừ khi anh ấy mắc lỗi nghiêm trọng; mà chắc chắn là không. – Ricket

+0

Nó sẽ đưa tôi ít thời gian hơn để viết một đôi cho vòng lặp như đã được đề xuất ở trên. –

+4

Ricket, dễ dàng trên tông màu ở đó. Tôi đã cập nhật câu trả lời của mình để cho biết lý do xoay vòng là một ý tưởng tồi trong trường hợp này. – Jon

1

Tôi muốn lưu trữ tọa độ (x, y) của "ô" và sử dụng ma trận xoay để xoay chúng. Ví dụ: Xem Drawing a Rotated Rectangle. Bạn có thể phải làm tròn kết quả đến mức tăng 0,5 gần nhất.

0

js mã cho cả hai chiều kim đồng hồ và ngược chiều kim đồng hồ:

function arrRotation90(arr, clockwise) { 
      var arr_rotated = []; 
      for (var i = 0; i < arr[0].length; i++) { 
       arr_rotated[i] = []; 
      } 
      if (clockwise) { 
       for (var i = 0; i < arr.length; i++) { 
        for (var j = 0; j < arr[i].length; j++) { 
         arr_rotated[arr[i].length-1-j][i] = arr[i][j]; 
        } 
       } 
      } else { 
       for (var i = 0; i < arr.length; i++) { 
        for (var j = 0; j < arr[i].length; j++) { 
         arr_rotated[j][arr.length - 1 - i] = arr[i][j]; 
        } 
       } 
      } 
      return arr_rotated; 
     }