I actually did look at alleytris before, but didn't really learn anything from it.
Can't blame you for that.
Rotation for Tetris pieces is pretty easy. If you have the coordinates of each each block in the piece in a list, you just go through the list and transform every pair of coordinates like:
(x, y) -> (-y, x)
That corresponds to a 90 degree rotation.
That's the gist of it, at least.
It's not quite that easy. Or at least if it is I went the long way on Alleytris. The problem with that idea is it rotates around a center point at the corner.
For the panda of it I'll try to recreate the thought process that ended in the rx function in alleytris.
What you need to do is adjust how you're reading the data, so when you write it the normal way it appears rotated. In otherwords for a 4x4 block 90
o clockwise rotation means you start in the lower left corner and read bottom to top. For 180
o start in the lower right and read right to left, bottom to top. For 270
o start in the upper left and read top to bottom, right to left.
You following so far?
So when I was writing alleytris I started doing some drawings and ended up with this table and stared at it until I got the last line:
| X,Y | 90 | 180 | 270 |
| (0,0) | (0,4) | (4,4) | (4,0) |
| (1,0) | (0,3) | (3,4) | (4,1) |
| (1,1) | (1,3) | (3,3) | (3,1) |
| (4,4) | (4,0) | (0,0) | (4,0) |
| (x,y) | (y,4-x) | (4-x,4-y) | (4-y,x) |
So I figured I needed 2 rotations functions which would take the rotation given (which by then I had simplified to 0,1,2,and 3) and the x, y coordinate and return either the x or y. At first I used a case statement, and that's when I noticed the similarity between rx (for rotation x) and ry (for rotation y), that was that ry(rot,x,y) was the same as rx(rot+1,x,y). So deleted ry (which in retrospect I should have kept and just rewritten ry to call rx) and changed all calls to ry to calls to rx.
Then someone on the cprogramming forums pointed out a way to do away with the case statement and I ended up with the current version of rx :
int rx (int r, int y, int x) { /* Used for piece rotation. */
int n;
n = (r % 2 ? y : x);
if(r / 2) n = 3 - n;
return n;
}
clip() and drawpiece() use rx to read the data rotated as it draws the piece.
Now you know why alleytris was not as instructive. It was the tail end of a long thought process which works, but doesn't educate much.
So even if alleytris wasn't informative I hope this was.