I... Love... Tetris!
Alright, I'd REALLY like to help you with this (I know how much deadlines can SUCK, especially for a school project).
There is a distinct order to how Tetris logic is executed. First, a block is created at the top of the screen, i.e. a group of blocks treated as a single entity. Here, it's just a matter of keeping the shape intact and moving down bit by bit. Once it hits something, it is no longer active. It simply rests on whatever it hits. Then, the system checks for any completed horizontal lines. If any are found, those chunks are removed and everything ABOVE the removed lines act upon their physics and fall down (You could make this REALLY interesting if you had multicolored "clusters" that stuck together). Score is calculated and the logic loops.
Once you examine the core functions, it shouldn't be too hard to write the code for the game.
Now to the rotation query:
As most shapes only has 4 distinct forms when rotated (The I-block has only 2, and the Cube-Block has only 1), as BenJames8 stated, they can easily be represented by a 4x4 array of boolean values. The classic L-block could be represented as:
0100 0000 1100 0010
0100 1110 0100 1110
0110 1000 0100 0000
0000 0000 0000 0000
The only logic that needs to be performed is, in essence, the active block in motion. Each shape generally rotates on the axis of the second block of the second row:
0000
0X00 <-That one right there...
0000
0000
It'd probably be easiest to hold each shape and each rotation in memory as native boolean arrays, and use a value (1-4) to calculate which rotation of the active block to display, as well as a value to calculate which block is to be displayed.
Let me know if there's anything I can do to help out more!
Tunnel vision yet? Have a carrot!