Tetris
The implementation is split into two different parts: the internal game model - tetris.py, which is independent of all graphics and is the core of the game, and the graphics engine - gfx_engine.py which provides a user interface to the internal game model, as well as handling drawing and graphics-related stuff through the use of PyGame.
Each Piece
has an array of rotation configurations associated with it, as well as a function which calculates the width of the piece, used for when pieces are spawned (to make sure they aren’t cut off).
The Board
object handles almost all of the actual game logic such as gravity, collision (overlapping blocks), line clearing, etc. At any one time, there is only ever a single Piece
instance, which is the currently falling piece. Once that falling piece is at rest, it’s block data is committed to the board’s block data, and the object is replaced with new, randomly spawned Piece
instance. There is no need to keep an object for every piece that has ever fallen - that would make things overcomplicated, especially considering the fact that once a Piece is at rest, it can’t be moved by the user anymore and its blocks seem to act independently from each other.
I am planning to implement some sort of AI for this in the future.