вращение с тетрисом в питоне с системой координат

Мне нужен алогритм для поворота блоков в тетрисе, я пытался просмотреть stackoverflow, но для всех решений нужна какая-то точка поворота, а что нет, я понятия не имею, как это найти, поэтому мне интересно, может ли кто-нибудь мне помочь

Я пробовал в основном все, начиная с алгоритма вращения фрагмента Tetris.

система сетки это:

 x 1 2 3 4 5 6 7 8 9 10
y
10
9
8
7
6
5
4
3
2
1

список заблокированных выглядит так:

block = [[3, 5], [4, 5], [5, 5], [6, 5]]

где [х, у]

По сути, я просто хочу чередовать тетрис, например: https://tetris.fandom.com/wiki/SRS< /а>


person jooshoi1    schedule 25.04.2019    source источник


Ответы (1)


Я обнаружил, что для вращения фрагмента любого размера, существующего в сетке, требуется всего две графические операции.

Если вы хотите повернуть фигуру по часовой стрелке, сначала поменяйте местами координаты каждого блока, из которого она состоит. Это означает поменять местами координаты x и y каждого блока.

В коде это может выглядеть примерно так

for (int i = 0; i < sizeOfPiece; i++)
{

    int temp = piece[i].X;
    piece[i].X = piece[i].Y;
    piece[i].Y = temp;

}

Затем отразите вашу недавно обработанную деталь по оси Y. Это можно сделать, взяв x-координату каждого блока и установив ее равной ширине всего куска - x-координате.

Код может выглядеть примерно так:

for (int i = 0; i < sizeOfPiece; i++)
{

    piece[i].X = pieceWidth - piece[i].X;

}

где int pieceWidth = piece[RightEdge].X - piece[leftEdge].X;

Если у вас возникли проблемы с поиском правого и левого краев фрагмента, это должно работать нормально.

int edges[4] = {0,    0,     0,  0};

for (int i = 1; i < sizeOfPiece; i++)
{

    if (piece[i].X < piece[edges[LEFT]].X) edges[LEFT] = i;   //Check for a block on the left edge
    if (piece[i].X > piece[edges[RIGHT]].X) edges[RIGHT] = i; //Check for a block on the right edge
    if (piece[i].Y < piece[edges[UP]].Y) edges[UP] = i;       //Check for a block on the upper edge
    if (piece[i].Y > piece[edges[DOWN]].Y) edges[DOWN] = i;   //Check for a block on the bottom edge

}

где ВЛЕВО = 0, ВПРАВО = 1, ВВЕРХ = 2 и ВНИЗ = 3

В этом случае массив ребер хранит идентификаторы одного блока, который находится на каждом из четырех ребер фрагмента. Для определения ширины нужны только правое и левое ребра, но другие ребра могут быть полезны в какой-то другой момент.

В этом случае ранее упомянутая формула pieceWidth на самом деле выглядела бы так:

int pieceWidth = piece[edges[RIGHT]].X - piece[edges[LEFT]].X;

Если вы хотите повернуть против часовой стрелки, просто сделайте наоборот. Это означает, что вы сначала зеркально отражаете часть по оси Y, а затем инвертируете ее координаты.

Я нарисовал небольшое визуальное представление этих графических переводов в действии:

Изображение

На приведенном выше рисунке красная часть представляет собой исходную часть, синий переход показывает часть после того, как она была перевернута, а зеленая часть показывает предыдущую часть после того, как она была отражена по оси Y.

Верхний пример вращается по часовой стрелке, а нижний пример вращается против часовой стрелки.

person user3322166    schedule 19.06.2019