views:

4285

answers:

8

What are the best algorithms (and explanations) for representing and rotating the pieces of a tetris game? I always find the piece rotation and representation schemes confusing.

Most tetris games seem to use a naive "remake the array of blocks" at each rotation:

http://www.codeplex.com/Project/ProjectDirectory.aspx?ProjectSearchText=tetris

However, some use pre-built encoded numbers and bit shifting to represent each piece:

http://www.codeplex.com/wintris

Is there a method to do this using mathematics (not sure that would work on a cell based board)?

+13  A: 

There is a limited amount of shapes, so I would use a fixed table and no calculation. That saves time.

But there are rotation algorithms.

Chose a centerpoint and rotate pi/2.

If a block of a piece starts at (1,2) it moves clockwise to (2,-1) and (-1,-2) and (-1, 2). Apply this for each block and the piece is rotated.

Each x is the previous y and each y - the previous x. Which gives the following matrix:

[  0   1 ]
[ -1   0 ]

For counterclockwise rotation, use:

[  0  -1 ]
[  1   0 ]
Gamecat
A: 

I have used a shape position and set of four coordinates for the four points in all the shapes. Since it's in 2D space, you can easy apply a 2D rotational matrice to the points.

The points are divs so their css class is turned from off to on. (this is after clearing the css class of where they were last turn.)

mspmsp
+3  A: 

Personally I've always just represented the rotations by hand - with very few shapes, it's easy to code that way. Basically I had (as pseudo-code)

class Shape
{
    Color color;
    ShapeRotation[] rotations;
}

class ShapeRotation
{
    Point[4] points;
}

class Point
{
    int x, y;
}

At least conceptually - a multi-dimensional array of points directly in shape would do the trick too :)

Jon Skeet
+3  A: 

Since there are only 4 possible orientations for each shape, why not use an array of states for the shape and rotating CW or CCW simply increments or decrements the index of the shape state (with wraparound for the index)? I would think that might be quicker than performing rotation calculations and whatnot.

AgentThirteen
Arnis L.
For Tetris, it's very easy. This is my favorite way to do it.
Nosredna
+1  A: 

This is how I did it recently in a jQuery/CSS based tetris game.

Work out the centre of the block (to be used as a pivot point), i.e. the centre of the block shape. Call that (px, py).

Each brick that makes up the block shape will rotate around that point. For each brick, you can apply the following calculation...

Where each brick's width and height is q, the brick's current location (of the upper left corner) is (x1, y1) and the new brick location is (x2, y2):

x2 = (y1 + px - py)

y2 = (px + py - x1 - q)

To rotate the opposite direction:

x2 = (px + py - y1 - q)

y2 = (x1 + py - px)

This calculation is based on a 2D affine matrix transformation. If you are interested in how I got to this let me know.

Dave Cluderay
+1  A: 

If you're doing this in python, cell-based instead of coordinate pairs it's very simple to rotate a nested list.

rotate = lambda tetrad: zip(*tetrad[::-1])
tetrad = rotate(tetrad)
BeMasher
+1  A: 

I derived a rotation algorithm from matrix rotations here. To sum it up: If you have a list of coordinates for all cells that make up the block, e.g. [(0, 1), (1, 1), (2, 1), (3, 1)] or [(1, 0), (0, 1), (1, 1), (2, 1)]:

 0123       012
0....      0.#.
1####  or  1###
2....      2...
3....

you can calculate the new coordinates using

x_new = y_old
y_new = 1 - (x_old - (me - 2))

for clockwise rotation and

x_new = 1 - (y_old - (me - 2))
y_new = x_old

for counter-clockwise rotation. me is the maximum extent of the block, i.e. 4 for I-blocks, 2 for O-blocks and 3 for all other blocks.

mdm
A: 

Since can't post photos... link text

Ricardo Sousa