/Tetris

Tetris made with Pygame

Primary LanguagePythonMIT LicenseMIT

Tetris

Tetris game!, made with Python 🐍 and love ❤️.

Prerequisites

  • It is recommended to create and activate a Python virtual environment

  • Install the requirements libraries with:

    make requirements (mingw32-make requirements)

Run

make run (mingw32-make run)

Controls

  • ↑ Turn the piece
  • → Go right
  • ← Go left
  • ↓ Fall faster

Resources

Sound Source

Code style

We use ruff as a linter, to format the code.

You can run the check with:

make style (mingw32-make style)

Tests

To run the Test Suite, you could run the next command:

make test (mingw32-make test)

To see a Coverage Report, you could run the next command:

make coverage (mingw32-make coverage)

Technical Details

Each block have an associated name, and is represented with a Class.

To Do

  • Function and Argument names should be lowercase, with words separated by underscores as necessary to improve readability (snake-case).

  • Max line length should be 120 characters, fix the lines that are longer than that.

  • Add type hints to the functions, see ref, this is a good way to document the code defining the parameters types and the return type.

  • Add docstrings to the functions, see ref, in order to document the code.

  • Reduce the use of global variables, and use the parameters or attributes instead. And if is really necessary to use global variables, define them in uppercase, and in the beginning of the file.

  • Create a main function, and move the code that is in the global scope to this function, and call it at the end of the file.

    def main():
        # Code here, instead of the global scope
        pass
    
    if __name__ == "__main__":
        main()
  • Instead of using block numbers to identify the different block shapes, you could create a class for each piece shape, that inherits from a base class. Something like:

    class Block:
        # Base class for the blocks
        pass
    
    class BlockI(Block):
        # Class for the I block, with the specific methods for this block
        def start(self): 
          pass 
    
        def turn(self): 
          pass 
    
    class BlockJ(Block):
        # Class for the J block, with the specific methods for this block
        def start(self): 
          pass 
    
        def turn(self): 
          pass 
  • Create unit tests for the functions, see unittest, or the alternative pytest.

  • Reorganize the code in different files, for example, you could create a file for the utils functions, another for the Block classes, and another for the main function.

  • The DB management could be defined in a class, to encapsulate the logic.

  • The time tracking could be defined in a class, to encapsulate the logic.

  • Send to settings.py the configs constant variables, maybe like the screen size, the colors, etc.

  • Check the different rules for the linter, and add the ones that you consider necessary to the configuration file.

  • Subdivide the db_and_time.py file in two files, one for the DB management, and another for the time tracking.

  • Maybe a Block must not inherit from a Tetris, in order to decrease the dependency between those classes.

  • Exist the Class BackgroundBlock and the function color_the_block, maybe those elements are related and is better to be together in the same class? The idea is relate the "same things", and unrelate the "things that are different".

  • Maybe rename the Block classes, to a little more representative name as: BlockO, BlockL, etc. Taking into account the different block type defined in #technical-details.

  • Increase the code coverage of the test suite, you could run make coverage and see which lines are not covered by the test suite: img.png coverage

License

This project is licensed under the MIT licence - see the LICENSE file for details.