Skip to content

๐ŸŽฎ Biquadris (A 2 Player Remake of Tetris)

Notifications You must be signed in to change notification settings

Marcus990/Tetris

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

38 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Biquadris Logo

๐ŸŽฎ Biquadris

The Ultimate Block Challenge โ€ข A Modern Two-Player Tetris Variant

C++20 Build License Modules

A sophisticated object-oriented implementation featuring C++20 modules, smart pointers, and design patterns

Features โ€ข Installation โ€ข Gameplay โ€ข Commands โ€ข Architecture โ€ข Credits


๐Ÿ“– Table of Contents


๐ŸŽฏ Overview

Biquadris is an advanced two-player Tetris variant developed as a CS246 course project. Built with modern C++ practices, it demonstrates sophisticated software engineering principles including design patterns, modular architecture, and clean code practices.

Unlike traditional Tetris, Biquadris introduces competitive multiplayer gameplay where clearing multiple rows triggers special effects that can sabotage your opponent. With five difficulty levels, dynamic block generation, and both text and graphical interfaces, Biquadris offers depth and replayability.

๐ŸŒŸ Why Biquadris?

  • ๐Ÿ—๏ธ Modern C++20 โ€” Utilizes C++20 modules for improved encapsulation and compilation
  • ๐ŸŽจ Dual Display Modes โ€” Beautiful X11 graphics or classic terminal text display
  • โš”๏ธ Competitive Multiplayer โ€” Special attacks and effects between players
  • ๐ŸŽฒ Five Difficulty Levels โ€” From scripted sequences to challenging random generation
  • ๐Ÿงฉ Extensible Design โ€” Clean architecture makes adding features straightforward
  • ๐ŸŽฎ Rich Command System โ€” Intuitive command prefix matching and multipliers

โœจ Features

๐ŸŽฎ Core Gameplay

  • Two-Player Competitive Mode โ€” Race against your opponent on side-by-side boards
  • Seven Classic Tetrominos โ€” I, J, L, O, S, Z, and T blocks with full rotation support
  • Smooth Controls โ€” Move, rotate, and drop blocks with responsive commands
  • Command Multipliers โ€” Execute commands multiple times (e.g., 3left, 5down)
  • Prefix Matching โ€” Type partial commands (e.g., lef โ†’ left)

๐ŸŽฒ Difficulty Levels

Level Description Special Features
Level 0 Scripted sequence from file Perfect for testing and learning
Level 1 Random with S/Z bias S and Z blocks appear less frequently
Level 2 Uniform random distribution All blocks equally likely
Level 3 Heavy blocks + S/Z boost Blocks drop 1 extra row after moves, S/Z more common
Level 4 Extreme challenge Everything from Level 3 + center block drops every 5 turns

โšก Special Effects

Trigger special attacks by clearing 2+ rows at once!

  • ๐Ÿ”ฒ Blind Effect โ€” Obscures opponent's board with ? characters (rows 3-12, columns 3-9)
  • โš“ Heavy Effect โ€” Makes opponent's blocks drop 2 extra rows after every move
  • ๐ŸŽฏ Force Block โ€” Choose which block type your opponent receives next

๐Ÿ–ฅ๏ธ Display Modes

Text Display

Clean ASCII rendering perfect for terminals:

Level:    1                     Level:    1
Score:  450                     Score:  320
Hi Score: 1200                  Hi Score: 1200
-----------                     -----------
           
           T                             
          TTT                    
    J                                  S  
    JJJ                              SS  
  IIII                            S   Z 
-----------                     -----------
Next:                           Next:
  OO                              I
  OO                              I
                                  I
                                  I

Graphical Display (X11)

Beautiful arcade-style rendering with:

  • ๐ŸŽจ Colorful tetromino blocks with 3D shading
  • ๐Ÿ“Š Live score and statistics
  • ๐Ÿ‘๏ธ Next block preview panels
  • ๐ŸŽน Visual control indicators
  • ๐Ÿ•น๏ธ Retro arcade machine aesthetic

๐Ÿš€ Installation

Prerequisites

  • C++ Compiler with C++20 module support (GCC 11+ or Clang 15+)
  • X11 Development Libraries (for graphical mode)
    • macOS: brew install xquartz
    • Ubuntu/Debian: sudo apt-get install libx11-dev
    • Fedora: sudo dnf install libX11-devel

Building from Source

# Clone the repository
git clone <your-repo-url>
cd Tetris

# Build the project
make

# Clean build (if needed)
make clean
make

Compilation Details

The project uses a custom Makefile that:

  • Precompiles standard library headers for faster builds
  • Compiles C++20 modules with -fmodules-ts
  • Links X11 libraries for graphical display
  • Generates the biquadris executable

๐ŸŽฌ Getting Started

Basic Usage

# Launch with default settings (graphical mode)
./biquadris

# Text-only mode (no graphics)
./biquadris -text

# Set random seed for reproducibility
./biquadris -seed 12345

# Start at a specific level (0-4)
./biquadris -startlevel 3

# Use custom sequence files for Level 0
./biquadris -scriptfile1 sequence1.txt -scriptfile2 sequence2.txt

Command-Line Options

Option Description Example
-text Text-only mode (no graphics) ./biquadris -text
-seed N Set random seed to N ./biquadris -seed 42
-scriptfile1 FILE Player 1's Level 0 sequence file ./biquadris -scriptfile1 custom.txt
-scriptfile2 FILE Player 2's Level 0 sequence file ./biquadris -scriptfile2 custom.txt
-startlevel N Start at level N (0-4) ./biquadris -startlevel 2

๐ŸŽฎ Gameplay

Game Modes

Level 0: Scripted Sequence

Reads block types from a file for deterministic gameplay. Perfect for:

  • ๐Ÿงช Testing specific scenarios
  • ๐Ÿ“š Learning block mechanics
  • ๐ŸŽฏ Practicing specific moves

Level 1-2: Random Generation

Progressive difficulty with different probability distributions:

  • Level 1 reduces S/Z frequency (easier)
  • Level 2 provides uniform distribution

Level 3-4: Advanced Challenge

  • Heavy blocks that auto-drop after lateral moves
  • Level 4 adds center block drops every 5 turns without row clears
  • Requires strategic planning and quick reflexes

Special Effects

When you clear 2 or more rows simultaneously, you can choose a special effect:

Special Action! Choose effect:
1. blind     - Obscure opponent's view
2. heavy     - Make opponent's blocks heavier
3. force <T> - Force opponent to receive block type T

Effect Details:

  • Blind: Lasts until opponent drops a block, covering center region with ?
  • Heavy: Blocks drop 2 extra rows after left/right/rotate (stackable with level heavy)
  • Force: Immediately replaces opponent's current block with your choice (I/J/L/O/S/Z/T)

Scoring System

Points are awarded when blocks are placed:

Score = (level + number of rows cleared)ยฒ + (level + number of rows cleared)

Examples:

  • Drop at Level 2, clear 1 row: (2+1)ยฒ + (2+1) = 12 points
  • Drop at Level 3, clear 3 rows: (3+3)ยฒ + (3+3) = 42 points
  • Drop at Level 0, clear 4 rows: (0+4)ยฒ + (0+4) = 20 points

Bonus: Clearing multiple rows at higher levels yields exponentially more points!

Winning Conditions

  • Opponent's board becomes full (a block can't spawn)
  • High score persists across games in the current session
  • Restart anytime to begin a new match

โŒจ๏ธ Commands

Movement Commands

Command Shortcut Multiplier Description
left lef โœ… Move block one cell left
right ri โœ… Move block one cell right
down d โœ… Move block one cell down (soft drop)
drop dr โŒ Hard drop block to bottom

Examples:

left          # Move left once
3left         # Move left three times
10down        # Soft drop 10 cells
drop          # Hard drop

Rotation Commands

Command Shortcut Multiplier Description
clockwise cw โœ… Rotate 90ยฐ clockwise
counterclockwise ccw โœ… Rotate 90ยฐ counter-clockwise

Examples:

cw            # Rotate clockwise once
2ccw          # Rotate counter-clockwise twice

Level Commands

Command Shortcut Description
levelup levelu Increase difficulty by 1 level (max: 4)
leveldown leveld Decrease difficulty by 1 level (min: 0)

Mode Commands

Command Description
random Switch to random block generation (Levels 1-4)
norandom FILE Read block sequence from FILE instead of random
sequence FILE Execute commands from FILE
restart Start a new game

Testing Commands

Replace the current block with a specific type (useful for testing):

I    # Replace with I block (straight line)
J    # Replace with J block
L    # Replace with L block
O    # Replace with O block (square)
S    # Replace with S block
Z    # Replace with Z block
T    # Replace with T block

Special Actions (Multi-Row Clears)

When prompted after clearing 2+ rows:

blind           # Apply blind effect to opponent
heavy           # Apply heavy effect to opponent
force I         # Force opponent to receive an I block
force T         # Force opponent to receive a T block

Help & Utility

Command Description
help Display command reference

๐Ÿ—๏ธ Architecture

Biquadris is built with modern software engineering principles, emphasizing separation of concerns, extensibility, and maintainability.

Core Components

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                         GAME LAYER                          โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚  โ”‚  Game: Orchestrates gameplay, manages turns, handles โ”‚   โ”‚
โ”‚  โ”‚        player switching and win conditions           โ”‚   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                            โ”‚
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚                   โ”‚                   โ”‚
        โ–ผ                   โ–ผ                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Board (P1)   โ”‚   โ”‚ ScoreKeeper  โ”‚   โ”‚   Displays   โ”‚
โ”‚  Board (P2)   โ”‚   โ”‚  Level (P1)  โ”‚   โ”‚   Commands   โ”‚
โ”‚               โ”‚   โ”‚  Level (P2)  โ”‚   โ”‚              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
        โ”‚
        โ”œโ”€โ”€โ”€โ”€ Grid (Cell[][])
        โ”œโ”€โ”€โ”€โ”€ Current & Next Blocks
        โ”œโ”€โ”€โ”€โ”€ Active Effects
        โ””โ”€โ”€โ”€โ”€ Observers (Display updates)

Key Design Decisions

1. Module-Based Architecture (C++20)

Each component is organized into interface (.cc) and implementation (-impl.cc) files:

  • โœ… Enforces encapsulation
  • โœ… Reduces compilation dependencies
  • โœ… Represents modern C++ best practices

2. Smart Pointer Memory Management

  • std::unique_ptr for owned resources (blocks, levels, displays)
  • Eliminates memory leaks and dangling pointers
  • Clear ownership semantics

3. Observer Pattern Decoupling

  • Board notifies displays of state changes
  • Adding new display types requires no changes to game logic
  • Text and graphical displays coexist seamlessly

๐ŸŽจ Design Patterns

Biquadris employs classic design patterns for flexibility and maintainability:

1. Observer Pattern

Used for: Display updates

ISubject (Board)  โ”€โ”€notifiesโ”€โ”€>  IObserver (TextDisplay, GraphicsDisplay)

Implementation: observer.cc, textdisplay.cc, graphicsdisplay.cc, board.cc


2. Strategy Pattern

Used for: Difficulty levels and block generation

Level (abstract)
    โ”œโ”€ Level0: Sequential from file
    โ”œโ”€ Level1: Random with S/Z bias
    โ”œโ”€ Level2: Uniform random
    โ”œโ”€ Level3: Heavy blocks, S/Z boost
    โ””โ”€ Level4: + Center block drops

Implementation: level.cc, level-impl.cc


3. Command Pattern

Used for: User input handling

CommandInterpreter
    โ””โ”€ Registry<string, Command>
        โ”œโ”€ LeftCommand
        โ”œโ”€ RightCommand
        โ”œโ”€ DropCommand
        โ”œโ”€ RotateClockwiseCommand
        โ””โ”€ ...

Implementation: command.cc, command-impl.cc


4. Inheritance Hierarchy

Used for: Tetromino blocks

Block (abstract)
    โ”œโ”€ IBlock: โ–ˆโ–ˆโ–ˆโ–ˆ
    โ”œโ”€ JBlock: โ–„โ–ˆ
    โ”œโ”€ LBlock:  โ–ˆโ–„
    โ”œโ”€ OBlock: โ–„โ–„
    โ”œโ”€ SBlock:  โ–„โ–ˆโ–„
    โ”œโ”€ ZBlock: โ–„โ–ˆโ–„ 
    โ”œโ”€ TBlock: โ–„โ–ˆโ–„
    โ””โ”€ SingleBlock: โ–ˆ (Level 4 center drop)

Implementation: block.cc, blocks.cc


๐Ÿ“‚ Project Structure

Tetris/
โ”‚
โ”œโ”€โ”€ ๐Ÿ“„ README.md                    โ† You are here!
โ”œโ”€โ”€ ๐Ÿ“„ DESIGN_DOCUMENT.md           โ† Detailed architecture documentation
โ”œโ”€โ”€ ๐Ÿ“„ Makefile                     โ† Build configuration
โ”œโ”€โ”€ ๐Ÿ–ผ๏ธ  BiquadrisLogo.png            โ† Project logo
โ”‚
โ”œโ”€โ”€ ๐ŸŽฎ Core Game Logic
โ”‚   โ”œโ”€โ”€ main.cc                     โ† Entry point and command-line parsing
โ”‚   โ”œโ”€โ”€ game.cc / game-impl.cc      โ† Game orchestration and turn management
โ”‚   โ”œโ”€โ”€ board.cc / board-impl.cc    โ† Board state and game rules
โ”‚   โ””โ”€โ”€ constants.cc                โ† Game constants and configuration
โ”‚
โ”œโ”€โ”€ ๐Ÿงฉ Block System
โ”‚   โ”œโ”€โ”€ block.cc / block-impl.cc    โ† Abstract block interface
โ”‚   โ””โ”€โ”€ blocks.cc / blocks-impl.cc  โ† Concrete block implementations (I/J/L/O/S/Z/T)
โ”‚
โ”œโ”€โ”€ ๐ŸŽฒ Level System
โ”‚   โ””โ”€โ”€ level.cc / level-impl.cc    โ† Strategy pattern for difficulty levels
โ”‚
โ”œโ”€โ”€ โšก Effects System
โ”‚   โ””โ”€โ”€ effect.cc                   โ† Blind, Heavy, and Force effects
โ”‚
โ”œโ”€โ”€ ๐ŸŽจ Display System
โ”‚   โ”œโ”€โ”€ observer.cc                 โ† Observer pattern interfaces
โ”‚   โ”œโ”€โ”€ textdisplay.cc / textdisplay-impl.cc       โ† ASCII rendering
โ”‚   โ”œโ”€โ”€ graphicsdisplay.cc / graphicsdisplay-impl.cc โ† X11 graphics
โ”‚   โ””โ”€โ”€ window.cc / window-impl.cc  โ† X11 window wrapper
โ”‚
โ”œโ”€โ”€ โŒจ๏ธ  Command System
โ”‚   โ””โ”€โ”€ command.cc / command-impl.cc โ† Command pattern implementation
โ”‚
โ”œโ”€โ”€ ๐Ÿ“Š Supporting Components
โ”‚   โ”œโ”€โ”€ cell.cc                     โ† Individual grid cell
โ”‚   โ””โ”€โ”€ scorekeeper.cc              โ† Score tracking
โ”‚
โ”œโ”€โ”€ ๐Ÿ“ Game Data Files
โ”‚   โ”œโ”€โ”€ biquadris_sequence1.txt     โ† Default Player 1 Level 0 sequence
โ”‚   โ”œโ”€โ”€ biquadris_sequence2.txt     โ† Default Player 2 Level 0 sequence
โ”‚   โ”œโ”€โ”€ sequence1.txt               โ† Additional test sequence
โ”‚   โ”œโ”€โ”€ sequence2.txt               โ† Additional test sequence
โ”‚   โ””โ”€โ”€ tests/
โ”‚       โ””โ”€โ”€ effect_test.txt         โ† Effect testing sequence
โ”‚
โ””โ”€โ”€ ๐Ÿ”จ Build Output
    โ””โ”€โ”€ biquadris                   โ† Compiled executable (after make)

Module Organization

Using C++20 modules, code is organized as:

<component>.cc        โ†’ Module interface (declarations, exports)
<component>-impl.cc   โ†’ Module implementation (definitions)

๐Ÿ› ๏ธ Development

Adding New Features

The modular architecture makes extensions straightforward:

Adding a New Block Type

  1. Create class inheriting from Block in blocks-impl.cc
  2. Implement rotateClockwise() and rotateCounterClockwise()
  3. Add to Level::createBlockFromType()
  4. Update relevant level generation logic

No changes needed: Board, Cell, Display, or Command classes

Adding a New Difficulty Level

  1. Create Level5 class inheriting from Level
  2. Implement generateBlock() and isHeavy()
  3. Add instantiation to Game::createLevels()
  4. Update MAX_LEVEL in constants.cc

No changes needed: Board, Display, or Command logic

Adding a New Special Effect

  1. Create class inheriting from Effect
  2. Implement isExpired() and update()
  3. Add handling in Board::addEffect() and Board::updateEffects()
  4. Add to special action prompt in Game::drop()

No changes needed: Other game components

Adding a New Command

  1. Create class inheriting from Command
  2. Implement execute() and optionally canMultiply()
  3. Register in CommandInterpreter::registerCommands()

No changes needed: Parsing logic or other commands


Testing

The project includes sequence files for deterministic testing:

# Use custom test sequences
./biquadris -scriptfile1 tests/effect_test.txt -startlevel 0

# Execute command sequences
# In game: sequence tests/effect_test.txt

Test Sequence Format:

I
drop
J
left
left
drop
...

Compilation Notes

Precompiled Headers: The Makefile precompiles standard library headers for faster builds:

HEADERS = chrono vector utility map memory algorithm iostream cstdlib fstream random cctype string

Module Cache: GCC stores module cache in gcm.cache/. Clean it if you encounter module issues:

make clean

X11 Linking: The project links against X11 for graphical display:

LDFLAGS = -L/opt/X11/lib -lX11

On macOS, ensure XQuartz is installed and in the expected path.


๐Ÿ† Credits

Biquadris was developed as the final project for CS246: Object-Oriented Software Development (Fall 2025) at the University of Waterloo.

Development Team

  • Matthew Mo (mzmo)
  • Marcus Ng (mcng)
  • James Cai (j239cai)

๐Ÿ“š Additional Resources


๐Ÿ“ License

This project was developed for academic purposes as part of CS246 coursework.

About

๐ŸŽฎ Biquadris (A 2 Player Remake of Tetris)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •