# Pytris

```
 .----------------.  .----------------.  .----------------.  .----------------.  .----------------.  .----------------. 
| .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. |
| |   ______     | || |  ____  ____  | || |  _________   | || |  _______     | || |     _____    | || |    _______   | |
| |  |_   __ \   | || | |_  _||_  _| | || | |  _   _  |  | || | |_   __ \    | || |    |_   _|   | || |   /  ___  |  | |
| |    | |__) |  | || |   \ \  / /   | || | |_/ | | \_|  | || |   | |__) |   | || |      | |     | || |  |  (__ \_|  | |
| |    |  ___/   | || |    \ \/ /    | || |     | |      | || |   |  __ /    | || |      | |     | || |   '.___`-.   | |
| |   _| |_      | || |    _|  |_    | || |    _| |_     | || |  _| |  \ \_  | || |     _| |_    | || |  |`\____) |  | |
| |  |_____|     | || |   |______|   | || |   |_____|    | || | |____| |___| | || |    |_____|   | || |  |_______.'  | |
| |              | || |              | || |              | || |              | || |              | || |              | |
| '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' |
 '----------------'  '----------------'  '----------------'  '----------------'  '----------------'  '----------------' 
```

A terminal-based Tetris clone written in Python. Features a persistent leaderboard, AI and hint modes, and a ghost piece. Inspired by Michael Fogleman's original QBasic implementation from 2000.

---

## Requirements

- Python 3.7 or higher
- Windows only: `windows-curses` (see below)
- All other dependencies are Python standard library (`curses`, `json`, `os`, `datetime`)

---

## Installation

### From PyPI

```bash
pip install Pytris-B1
```

### From source

```bash
git clone https://github.com/basanta-bhandari/Pytris.git
cd Pytris
pip install .
```

### Windows

`windows-curses` is listed as a conditional dependency and installs automatically via pip. If running from source manually:

```bash
pip install windows-curses
python main.py
```

---

## Running

If installed via pip:

```bash
pytris
```

If running from source:

```bash
python main.py
```

On startup, the banner is printed and you are prompted for a username before the game launches:

```
 .----------------.  .----------------. ...

  >>> Enter Username: basanta
```

Pressing Enter without a name sets the username to `anonymous`.

---

## Game Modes

Select a mode from the main menu using the number keys.

| Key | Mode | Description |
|-----|------|-------------|
| 1 | Normal | Standard Tetris |
| 2 | Hint | Ghost piece + AI suggested landing spot shown in cyan |
| 3 | Computer | Fully automated — AI plays the game |
| 4 | Leaderboard | View the top 10 scores |

---

## Controls

| Key | Action |
|-----|--------|
| Left / Right | Move piece |
| Up | Rotate (with wall kick) |
| Down | Soft drop (+1 point per row) |
| Space | Hard drop (+2 points per row) |
| P | Pause / Resume |
| ESC | Save score and return to menu |
| Q | Save score and quit |

---

## Scoring

| Action | Points |
|--------|--------|
| 1 line cleared | 100 × level |
| 2 lines cleared | 300 × level |
| 3 lines cleared | 500 × level |
| 4 lines cleared | 800 × level |
| Soft drop | 1 per row |
| Hard drop | 2 per row |

Level increases every 10 lines. Fall speed increases with level.

---

## Leaderboard

Scores are saved to `scores.json` in the same directory as `main.py`. Each player keeps only their personal best. The top 10 are shown on the leaderboard screen.

`scores.json` format:

```json
[
  {
    "user": "basanta",
    "score": 4200,
    "lines": 12,
    "level": 3,
    "date": "2025-02-27"
  }
]
```

On game over, your rank and whether you set a new personal best are shown before auto-returning to the menu after 5 seconds.

---

## AI

The computer mode evaluates every valid (x, rotation) placement for the current piece using a weighted heuristic:

- Completed lines: rewarded
- Gaps below pieces: penalised
- Aggregate stack height: penalised
- Bumpiness: penalised

The highest-scoring placement is chosen each turn. Hint mode uses the same logic to overlay the suggested drop position without taking control.

---

## File Structure

```
Pytris/
├── main.py          # entire game
├── scores.json      # created automatically on first game over
├── setup.py
├── requirements.txt
└── README.md
```

---

**Basanta Bhandari** — [github.com/basanta-bhandari](https://github.com/basanta-bhandari)

