Rather than having several BlockComponents that represent blocks, consider having a single ShapeComponent that has a 2D array of blocks - these can be a simple binary matrix ('true' where block present, 'false' where not). You will find rotation around a point much easier to implement mathematically this way, and collision is a breeze. Your ShapeComponent can then expose methods to manipulate it (ShapeComponent.RotateClockwise(), for example).
A Piece entity would be defined as:
- PositionComponent (integer X,Y co-ordinates)
- ShapeComponent (as described above)
- RenderComponent (marks the entity as renderable, probably defines a colour)
- MoveableComponent (marks the entity as moveable each game tick)
The 'board' doesn't really exist...! All you need to do is implement two constraints on your active piece:
- it may not move below 0 on the Y axis
- it may not move outside of 0-10 on the X axis
This logic should be performed by the system in charge of updating piece position. If the piece violates #1 it should be stopped as if it had rested on top of another block. If it violates #2 the movement should simply be ignored.
Bear in mind that you need not completely eschew the OO paradigm when implementing an Entity-Component-System architecture. Rather, the ECS approach is based on one of the basic principles of good OO design, Prefer composition over inheritance.