Skip to main content

Core engine (game logic, features, data) for a triangle puzzle game.

Project description

CI Status codecov PyPI version License: MIT Python Version

Triangle Engine (trianglengin)

trianglengin logo

This library provides the core, reusable components for reinforcement learning agents playing a triangle puzzle game.

It encapsulates:

  1. Core Game Logic: Environment rules, state representation, actions.
  2. Basic Visualization: Pygame rendering for interactive play/debug modes.
  3. Interaction Handling: Input processing for interactive modes.
  4. Utilities: General helpers, geometry functions, shared types.
  5. Configuration: Pydantic models for environment and display settings.
  6. (Planned) Feature Extraction: Logic to convert game state to NN input format.
  7. (Planned) Data Management Framework: Structure for saving/loading checkpoints and buffers.
  8. (Planned) Statistics Collection: Components for tracking game/training stats.

๐ŸŽฎ The Ultimate Triangle Puzzle Guide ๐Ÿงฉ

Get ready to become a Triangle Master! This guide explains everything you need to know to play the game, step-by-step, with lots of details!

1. Introduction: Your Mission! ๐ŸŽฏ

Your goal is to place colorful shapes onto a special triangular grid. By filling up lines of triangles, you make them disappear and score points! Keep placing shapes and clearing lines for as long as possible to get the highest score before the grid fills up and you run out of moves. Sounds simple? Let's dive into the details!

2. The Playing Field: The Grid ๐Ÿ—บ๏ธ

  • Triangle Cells: The game board is a grid made of many small triangles. Some point UP (๐Ÿ”บ) and some point DOWN (๐Ÿ”ป). They alternate like a checkerboard pattern based on their row and column index (specifically, (row + col) % 2 != 0 means UP).
  • Shape: The grid itself is rectangular overall, but the playable area within it is typically shaped like a triangle or hexagon, wider in the middle and narrower at the top and bottom.
  • Playable Area: You can only place shapes within the designated playable area.
  • Death Zones ๐Ÿ’€: Around the edges of the playable area (often at the start and end of rows), some triangles are marked as "Death Zones". You cannot place any part of a shape onto these triangles. They are off-limits! Think of them as the boundaries within the rectangular grid.

3. Your Tools: The Shapes ๐ŸŸฆ๐ŸŸฅ๐ŸŸฉ

  • Shape Formation: Each shape is a collection of connected small triangles (๐Ÿ”บ and ๐Ÿ”ป). They come in different colors and arrangements. Some might be a single triangle, others might be long lines, L-shapes, or more complex patterns.
  • Relative Positions: The triangles within a shape have fixed positions relative to each other. When you move the shape, all its triangles move together as one block.
  • Preview Area: You will always have three shapes available to choose from at any time. These are shown in a special "preview area" on the side of the screen.

4. Making Your Move: Placing Shapes ๐Ÿ–ฑ๏ธโžก๏ธโ–ฆ

This is the core action! Here's exactly how to place a shape:

  • Step 4a: Select a Shape: Look at the three shapes in the preview area. Click on the one you want to place. It should highlight ๐Ÿ’ก to show it's selected.
  • Step 4b: Aim on the Grid: Move your mouse cursor over the main grid. You'll see a faint "ghost" image of your selected shape following your mouse. This preview helps you aim.
  • Step 4c: The Placement Rules (MUST Follow!)
    • ๐Ÿ“ Rule 1: Fit Inside Playable Area: ALL triangles of your chosen shape must land within the playable grid area. No part of the shape can land in a Death Zone ๐Ÿ’€.
    • ๐Ÿงฑ Rule 2: No Overlap: ALL triangles of your chosen shape must land on currently empty spaces on the grid. You cannot place a shape on top of triangles that are already filled with color from previous shapes.
    • ๐Ÿ“ Rule 3: Orientation Match! This is crucial!
      • If a part of your shape is an UP triangle (๐Ÿ”บ), it MUST land on an UP space (๐Ÿ”บ) on the grid.
      • If a part of your shape is a DOWN triangle (๐Ÿ”ป), it MUST land on a DOWN space (๐Ÿ”ป) on the grid.
      • ๐Ÿ”บโžก๏ธ๐Ÿ”บ (OK!)
      • ๐Ÿ”ปโžก๏ธ๐Ÿ”ป (OK!)
      • ๐Ÿ”บโžก๏ธ๐Ÿ”ป (INVALID! โŒ)
      • ๐Ÿ”ปโžก๏ธ๐Ÿ”บ (INVALID! โŒ)
    • Visual Feedback: The game helps you!
      • ๐Ÿ‘ Valid Spot: If the position under your mouse follows ALL three rules, the ghost preview will usually look solid and possibly greenish. This means you can place the shape here.
      • ๐Ÿ‘Ž Invalid Spot: If the position breaks any of the rules (out of bounds, overlaps, wrong orientation), the ghost preview will usually look faded and possibly reddish. This means you cannot place the shape here.
  • Step 4d: Confirm Placement: Once you find a valid spot (๐Ÿ‘), click the left mouse button again. Click! The shape is now placed permanently on the grid! โœจ

5. Scoring Points: How You Win! ๐Ÿ†

You score points in two main ways:

  • Placing Triangles: You get a small number of points for every single small triangle that makes up the shape you just placed. (e.g., placing a 3-triangle shape might give you 3 * tiny_score points).
  • Clearing Lines: This is where the BIG points come from! You get a much larger number of points for every single small triangle that disappears when you clear a line (or multiple lines at once!). See the next section for details!

6. Line Clearing Magic! โœจ (The Key to High Scores!)

This is the most exciting part! When you place a shape, the game immediately checks if you've completed any lines. This section explains how the game finds and clears these lines.

  • What Lines Can Be Cleared? There are three types of lines the game looks for:

    • Horizontal Lines โ†”๏ธ: A straight, unbroken line of filled triangles going across a single row.
    • Diagonal Lines (Top-Left to Bottom-Right) โ†˜๏ธ: An unbroken diagonal line of filled triangles stepping down and to the right.
    • Diagonal Lines (Bottom-Left to Top-Right) โ†—๏ธ: An unbroken diagonal line of filled triangles stepping up and to the right.
  • How Lines are Found: Pre-calculation of Maximal Lines

    • The Idea: Instead of checking every possible line combination all the time, the game pre-calculates all maximal continuous lines of playable triangles when it starts. A maximal line is the longest possible straight segment of playable triangles (not in a Death Zone) in one of the three directions (Horizontal, Diagonal โ†˜๏ธ, Diagonal โ†—๏ธ).
    • Tracing: For every playable triangle on the grid, the game traces outwards in each of the three directions to find the full extent of the continuous playable line passing through that triangle in that direction.
    • Storing Maximal Lines: Only the complete maximal lines found are stored. For example, if tracing finds a playable sequence A-B-C-D, only the line (A,B,C,D) is stored, not the sub-segments like (A,B,C) or (B,C,D). These maximal lines represent the potential lines that can be cleared.
    • Coordinate Map: The game also builds a map linking each playable triangle coordinate (r, c) to the set of maximal lines it belongs to. This allows for quick lookup.
  • Defining the Paths (Neighbor Logic): How does the game know which triangle is "next" when tracing? It depends on the current triangle's orientation (๐Ÿ”บ or ๐Ÿ”ป) and the direction being traced:

    • Horizontal โ†”๏ธ:
      • Left Neighbor: (r, c-1) (Always in the same row)
      • Right Neighbor: (r, c+1) (Always in the same row)
    • Diagonal โ†˜๏ธ (TL-BR):
      • If current is ๐Ÿ”บ (Up): Next is (r+1, c) (Down triangle directly below)
      • If current is ๐Ÿ”ป (Down): Next is (r, c+1) (Up triangle to the right)
    • Diagonal โ†—๏ธ (BL-TR):
      • If current is ๐Ÿ”ป (Down): Next is (r-1, c) (Up triangle directly above)
      • If current is ๐Ÿ”บ (Up): Next is (r, c+1) (Down triangle to the right)
  • Visualizing the Paths:

    • Horizontal โ†”๏ธ:
      ... [๐Ÿ”ป][๐Ÿ”บ][๐Ÿ”ป][๐Ÿ”บ][๐Ÿ”ป][๐Ÿ”บ] ...  (Moves left/right in the same row)
      
    • Diagonal โ†˜๏ธ (TL-BR): (Connects via shared horizontal edges)
      ...[๐Ÿ”บ]...
      ...[๐Ÿ”ป][๐Ÿ”บ] ...
      ...     [๐Ÿ”ป][๐Ÿ”บ] ...
      ...         [๐Ÿ”ป] ...
      (Path alternates row/col increments depending on orientation)
      
    • Diagonal โ†—๏ธ (BL-TR): (Connects via shared horizontal edges)
      ...           [๐Ÿ”บ]  ...
      ...      [๐Ÿ”บ][๐Ÿ”ป]   ...
      ... [๐Ÿ”บ][๐Ÿ”ป]        ...
      ... [๐Ÿ”ป]            ...
      (Path alternates row/col increments depending on orientation)
      
  • The "Full Line" Rule: After you place a piece, the game looks at the coordinates (r, c) of the triangles you just placed. Using the pre-calculated map, it finds all the maximal lines that contain any of those coordinates. For each of those maximal lines (that have at least 2 triangles), it checks: "Is every single triangle coordinate in this maximal line now occupied?" If yes, that line is complete! (Note: Single isolated triangles don't count as clearable lines).

  • The Poof! ๐Ÿ’จ:

    • If placing your shape completes one or MORE maximal lines (of any type, length >= 2) simultaneously, all the triangles in ALL completed lines vanish instantly!
    • The spaces become empty again.
    • You score points for every single triangle that vanished. Clearing multiple lines at once is the best way to rack up points! ๐Ÿฅณ

7. Getting New Shapes: The Refill ๐Ÿช„

  • The Trigger: The game only gives you new shapes when a specific condition is met.
  • The Condition: New shapes appear only when all three of your preview slots become empty at the exact same time.
  • How it Happens: This usually occurs right after you place your last available shape (the third one).
  • The Refill: As soon as the third slot becomes empty, BAM! ๐Ÿช„ Three brand new, randomly generated shapes instantly appear in the preview slots.
  • Important: If you place a shape and only one or two slots are empty, you do not get new shapes yet. You must use up all three before the refill happens.

8. The End of the Road: Game Over ๐Ÿ˜ญ

So, how does the game end?

  • The Condition: The game is over when you cannot legally place any of the three shapes currently available in your preview slots anywhere on the grid.
  • The Check: After every move (placing a shape and any resulting line clears), and after any potential shape refill, the game checks: "Is there at least one valid spot on the grid for Shape 1? OR for Shape 2? OR for Shape 3?"
  • No More Moves: If the answer is "NO" for all three shapes (meaning none of them can be placed anywhere according to the Placement Rules), then the game immediately ends.
  • Strategy: This means you need to be careful! Don't fill up the grid in a way that leaves no room for the types of shapes you might get later. Always try to keep options open! ๐Ÿค”

That's it! Now you know all the rules. Go forth and conquer the Triangle Puzzle! ๐Ÿ†


Purpose

The primary goal is to provide a self-contained, installable library for the core logic and basic interactive UI of the triangle puzzle game. This allows different RL agent implementations or other applications to build upon a consistent and well-defined game backend, avoiding code duplication.

Installation

# For standard use (once published or built):
pip install trianglengin

Running Interactive Modes

After installing (pip install trianglengin), you can run the interactive modes directly:

  • Play Mode:
    trianglengin play [--seed 42] [--log-level INFO]
    
  • Debug Mode:
    trianglengin debug [--seed 42] [--log-level DEBUG]
    

Local Development & Testing

These instructions are for developers contributing to trianglengin.

  1. Clone the Repository:

    git clone https://github.com/lguibr/trianglengin.git
    cd trianglengin
    
  2. Create and Activate Virtual Environment:

    • Using venv (Recommended):
      python -m venv venv
      # On Linux/macOS:
      source venv/bin/activate
      # On Windows (Command Prompt):
      # .\venv\Scripts\activate
      # On Windows (PowerShell):
      # .\venv\Scripts\Activate.ps1
      
    • Using conda:
      conda create -n trianglengin python=3.10
      conda activate trianglengin
      

    IMPORTANT: Ensure your virtual environment is activated in your terminal before proceeding to the next step. You should see (venv) or (trianglengin) at the beginning of your terminal prompt.

  3. Install in Editable Mode with Dev Dependencies:

    • Make sure your virtual environment is active!
    • Run the following command from the project root directory (where pyproject.toml is located):
      # Use quotes to prevent shell expansion issues (especially in Zsh)
      pip install -e '.[dev]'
      
      Note the syntax: '.[dev]' includes the optional development dependencies, and the quotes prevent the shell from misinterpreting the brackets. This installs the trianglengin package itself in a way that your code changes are immediately reflected, and it installs all the tools needed for testing and development (pytest, ruff, mypy, etc.).
  4. Running Checks:

    • Make sure your virtual environment is active!
    • Tests & Coverage:
      pytest tests/ --cov=trianglengin --cov-report=xml
      
      (This generates coverage.xml for upload if using Codecov). To just run tests: pytest
    • Linting:
      ruff check .
      
    • Formatting:
      ruff format .
      
    • Type Checking:
      mypy trianglengin/
      
  5. Troubleshooting "command not found" errors:

    • If you see errors like pytest: command not found, ruff: command not found, or mypy: command not found, the most likely cause is that your virtual environment is not activated. Go back to Step 2 and activate it.
    • If the environment is active, double-check that you ran pip install -e '.[dev]' correctly in Step 3 (with the quotes and square brackets).

Project Structure

trianglengin/
โ”œโ”€โ”€ .github/workflows/      # GitHub Actions CI/CD
โ”‚   โ””โ”€โ”€ ci_cd.yml
โ”œโ”€โ”€ trianglengin/           # Source code for the library package
โ”‚   โ”œโ”€โ”€ __init__.py         # Exposes public API
โ”‚   โ”œโ”€โ”€ app.py              # Interactive mode application runner
โ”‚   โ”œโ”€โ”€ cli.py              # CLI definition (play/debug)
โ”‚   โ”œโ”€โ”€ core/               # Core game logic
โ”‚   โ”‚   โ”œโ”€โ”€ __init__.py
โ”‚   โ”‚   โ”œโ”€โ”€ structs/        # Triangle, Shape, constants
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ README.md   # Link: trianglengin/core/structs/README.md
โ”‚   โ”‚   โ””โ”€โ”€ environment/    # GameState, GridData, GridLogic, ShapeLogic, ActionCodec
โ”‚   โ”‚       โ””โ”€โ”€ README.md   # Link: trianglengin/core/environment/README.md
โ”‚   โ”œโ”€โ”€ interaction/        # User input handling for interactive modes
โ”‚   โ”‚   โ””โ”€โ”€ README.md       # Link: trianglengin/interaction/README.md
โ”‚   โ”œโ”€โ”€ visualization/      # Basic Pygame rendering components
โ”‚   โ”‚   โ”œโ”€โ”€ __init__.py
โ”‚   โ”‚   โ”œโ”€โ”€ core/           # Visualizer, layout, colors, fonts, coord_mapper
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ README.md   # Link: trianglengin/visualization/core/README.md
โ”‚   โ”‚   โ””โ”€โ”€ drawing/        # Specific drawing functions (grid, shapes, previews, hud)
โ”‚   โ”‚       โ””โ”€โ”€ README.md   # Link: trianglengin/visualization/drawing/README.md
โ”‚   โ”œโ”€โ”€ features/           # Feature extraction logic (Planned)
โ”‚   โ”‚   โ””โ”€โ”€ README.md       # Link: trianglengin/features/README.md
โ”‚   โ”œโ”€โ”€ data/               # Data management framework (Planned)
โ”‚   โ”‚   โ””โ”€โ”€ README.md       # Link: trianglengin/data/README.md
โ”‚   โ”œโ”€โ”€ stats/              # Statistics collection actor (Planned)
โ”‚   โ”‚   โ””โ”€โ”€ README.md       # Link: trianglengin/stats/README.md
โ”‚   โ”œโ”€โ”€ utils/              # General utilities
โ”‚   โ”‚   โ””โ”€โ”€ README.md       # Link: trianglengin/utils/README.md
โ”‚   โ””โ”€โ”€ config/             # Shared configuration models
โ”‚       โ”œโ”€โ”€ __init__.py
โ”‚       โ”œโ”€โ”€ env_config.py   # Environment configuration (EnvConfig)
โ”‚       โ””โ”€โ”€ display_config.py # Display configuration (DisplayConfig)
โ”œโ”€โ”€ tests/                  # Unit tests for trianglengin components
โ”‚   โ”œโ”€โ”€ __init__.py
โ”‚   โ”œโ”€โ”€ conftest.py         # Shared test fixtures
โ”‚   โ”œโ”€โ”€ core/
โ”‚   โ”‚   โ”œโ”€โ”€ __init__.py
โ”‚   โ”‚   โ”œโ”€โ”€ environment/    # Contains test_grid_logic.py now
โ”‚   โ”‚   โ””โ”€โ”€ structs/
โ”‚   โ””โ”€โ”€ README.md           # Link: tests/README.md
โ”œโ”€โ”€ .gitignore
โ”œโ”€โ”€ pyproject.toml          # Build config, dependencies
โ”œโ”€โ”€ README.md               # This file
โ”œโ”€โ”€ LICENSE
โ””โ”€โ”€ MANIFEST.in

Core Components

  • trianglengin.core: Contains the fundamental game logic.
  • trianglengin.config: Contains shared configuration models (EnvConfig, DisplayConfig).
  • trianglengin.visualization: Basic Pygame rendering (Visualizer, drawing functions, colors, fonts, layout). (visualization/README.md)
  • trianglengin.interaction: Input handling for interactive modes (InputHandler). (interaction/README.md)
  • trianglengin.app: Integrates components for interactive modes.
  • trianglengin.cli: Command-line interface for play/debug.
  • trianglengin.utils: General utility functions and types. (utils/README.md)

Contributing

Contributions are welcome! Please open an issue or submit a pull request on the GitHub repository. Ensure that changes maintain code quality (pass tests, linting, type checking) and keep READMEs updated.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

trianglengin-1.0.6.tar.gz (73.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

trianglengin-1.0.6-py3-none-any.whl (88.4 kB view details)

Uploaded Python 3

File details

Details for the file trianglengin-1.0.6.tar.gz.

File metadata

  • Download URL: trianglengin-1.0.6.tar.gz
  • Upload date:
  • Size: 73.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for trianglengin-1.0.6.tar.gz
Algorithm Hash digest
SHA256 d7624d73994d2824f725a934e6597c0c048ae3042d101cdb4df383103cba7220
MD5 f9c8a284f7b1f94b42b30e0aa204efb8
BLAKE2b-256 0c1a1a9b1c6a7bb4c8f7dde7d9ddb5ef09b9400c6b7256f71bd4a4fecfe838cd

See more details on using hashes here.

Provenance

The following attestation bundles were made for trianglengin-1.0.6.tar.gz:

Publisher: ci_cd.yml on lguibr/trianglengin

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file trianglengin-1.0.6-py3-none-any.whl.

File metadata

  • Download URL: trianglengin-1.0.6-py3-none-any.whl
  • Upload date:
  • Size: 88.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for trianglengin-1.0.6-py3-none-any.whl
Algorithm Hash digest
SHA256 86f1db760ed4d6c83920afea23ac6ced2729b918efc3d79cb3b8f8576b8c874b
MD5 59627de0e4c073a63da48645507533b1
BLAKE2b-256 0491f5448ee7719f991796d33aeb0b9c0e4c3eeac53f4dc8b28d2d96cad198a0

See more details on using hashes here.

Provenance

The following attestation bundles were made for trianglengin-1.0.6-py3-none-any.whl:

Publisher: ci_cd.yml on lguibr/trianglengin

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page