вращение с тетрисом в питоне с системой координат - PullRequest
0 голосов
/ 25 апреля 2019

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

Я пробовал в основном все из Алгоритм вращения фигуры Тетриса

система координат:

 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]]

где [x, y]

Я просто хочу вращение тетриса, вот так: https://tetris.fandom.com/wiki/SRS

1 Ответ

0 голосов
/ 19 июня 2019

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

Если вы хотите вращать фрагмент по часовой стрелке, сначала инвертируйте координаты каждого блокаэто составляет часть.Это означает, что меняйте координаты 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

}

, где LEFT = 0, RIGHT = 1, UP= 2 и DOWN = 3

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

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

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

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

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

Изображение

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

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

...