# Broken Ark

**Contract Bridge × Hearts — a 4-player trick-taking card game. Play in your browser. No install.**

V0.8 · [中文帮助文档](HELP.md) · [Deployment Guide](DEPLOY.md)

---

## What is Broken Ark?

Broken Ark combines the bidding system of **Contract Bridge** with the card-point scoring of **Hearts**, plus a unique *detention* mechanic that lets players alter score multipliers mid-game.

- **4 players** in two teams: North/South vs East/West
- **52-card deck**, 13 cards each, up to 16 boards per match
- **Bidding + Detention** (combined phase) → **Play** (13 tricks per board) → **Score**
- Victory: highest total score after 16 boards (or early finish via blowout/slam)

Unlike traditional Bridge, there is no dummy hand — all four players play their own cards independently.

---

## Quick Start

### Play Online

```
https://www.zhaojunjie.cc?seat=South
```

Share the link with 3 friends — each picks a different seat (`South`, `North`, `East`, `West`). Game starts when all 4 connect.

### Self-Host (30 seconds)

```bash
cd ZJBridge/python
python3 -m venv .venv
.venv/bin/pip install websockets
.venv/bin/python3 ws_server.py --port 9556 --human SOUTH,NORTH,EAST,WEST
```

Open `web/index.html` in 4 browser tabs (or serve via nginx/Caddy), each with `?seat=South`, `?seat=North`, etc.

---

## Features

| Feature | Details |
|---------|---------|
| **Bidding** | Full contract bridge ladder: 1♣–7NT, Double, Redouble |
| **Detention** | Face-Up / Face-Down / Flip — alter score multipliers for ♠Q, ♦J, ♣10, ♥A |
| **Scoring** | Trick score (standard bridge) + Card score (Hearts-style with detention modifiers) |
| **Vulnerability** | 4-board rotation: None → NS → EW → Both |
| **PWA** | Install to home screen, works offline (cached resources) |
| **Canvas 2D** | Zero-dependency rendering — radial gradient table, card fan layout, animations |
| **WebSocket** | Real-time multiplayer, hidden-information (each player sees only their own cards) |
| **AI Opponents** | 3 difficulty levels (Easy / Normal / Hard) for practice mode |
| **Keyboard + Touch** | Full keyboard shortcuts + mouse/touch click support |

---

## Game Rules

Broken Ark is bridge at its core, with added detention and card-point scoring from Hearts.

### Cards

Standard 52-card deck. **16 score cards** affect your points:

| Card | Base Value | Detainable |
|------|-----------|------------|
| ♠Q | −100 | ✓ |
| ♦J | +100 | ✓ |
| ♣10 | +50 (or ×2 multiplier) | ✓ |
| ♥A | Controls heart multiplier | ✓ |
| ♥5–♥K (9 cards) | −10 to −40 each, scaled by ♥A multiplier | — |
| ♥2, ♥3, ♥4 | 0 (never counted) | — |

### Detention (unique Broken Ark mechanic)

During bidding, players can "detain" up to 4 special cards to change scoring:

| Card | Not Detained | Face-Down | Face-Up |
|------|-------------|-----------|---------|
| ♠Q | −100 | −200 | −400 |
| ♦J | +100 | +200 | +400 |
| ♣10 (solo) | +50 | +100 | +200 |
| ♣10 (multiplier) | ×2 | ×4 | ×8 |
| ♥A multiplier | ×1 | ×2 | ×4 |

Flip a face-down card to face-up on a later turn.

### Scoring = Trick Score + Card Score

- **Trick Score**: Standard contract bridge scoring (game/slam bonuses, undertrick penalties, doubles)
- **Card Score**: Each player's collected score cards, modified by detention state
- Team total = Trick Score (offense only) + sum of both teammates' Card Scores

For the full rulebook, see [HELP.md](HELP.md) (Chinese / Broken Ark manual).

---

## Tech Stack

| Layer | Technology |
|-------|-----------|
| **Client** | Single-file HTML5 Canvas 2D (~1130 lines JS), zero dependencies |
| **Server** | Python 3.8+, `websockets` library, asyncio |
| **Game Engine** | `zjbridge/` — pure Python: models, rules (bidding/play/detention/scoring), AI |
| **PWA** | Web App Manifest + Service Worker for installability and offline cache |
| **Desktop** | PyGame client for local/terminal play (legacy, see `python/pygame_network.py`) |

No Node.js, no npm, no build step for the game itself.

---

## Project Structure

```
broken-ark/
├── web/                        # PWA frontend
│   ├── index.html              # Canvas game client (all rendering + networking)
│   ├── manifest.json           # PWA manifest
│   ├── sw.js                   # Service Worker (offline cache)
│   └── DEPLOY.md               # Production deployment guide
├── python/
│   ├── ws_server.py            # WebSocket game server (689 lines)
│   ├── server.py               # TCP server (legacy, PyGame mode)
│   ├── pygame_network.py       # PyGame desktop client
│   ├── terminal_client.py      # Terminal-based client
│   ├── batch_sim.py            # Batch AI simulation + stats
│   └── zjbridge/               # Core game library
│       ├── models.py           # Seat, Suit, Card, Hand, Contract, etc.
│       ├── game.py             # Deal engine
│       ├── ai.py               # AI (3 difficulty levels)
│       ├── engine/
│       │   ├── deal.py         # Deal generation
│       │   └── evaluator.py    # Hand evaluation (HCP, distribution, losers)
│       └── rules/
│           ├── bidding.py      # Bidding legality + completion
│           ├── play.py         # Trick play + winner determination
│           ├── detention.py    # Detention/Flip rules
│           └── scoring.py      # Trick + card scoring
├── HELP.md                     # Full player manual (Chinese)
├── README.md                   # This file
├── VERSION                     # Current version (V0.8)
├── AGENTS.md                   # Developer guide (for AI coding assistants)
└── stats/                      # Batch simulation output
```

---

## Development

### Local Setup

```bash
cd ZJBridge/python
python3 -m venv .venv
.venv/bin/pip install websockets
```

### Run Locally

```bash
# Start WebSocket server
.venv/bin/python3 ws_server.py --port 9556 --human SOUTH,NORTH,EAST,WEST

# Open client in browser
# file:///home/you/broken-ark/web/index.html?host=localhost&port=9556&seat=South
```

Or serve static files:

```bash
python3 -m http.server 8080 --directory web/
# Then: http://localhost:8080?host=localhost&port=9556&seat=South
```

### Batch Testing

```bash
.venv/bin/python3 batch_sim.py    # 100 AI-only games + statistics
```

---

## Deployment

See [DEPLOY.md](DEPLOY.md) for:
- nginx reverse proxy + WebSocket configuration
- systemd service setup
- Let's Encrypt HTTPS
- Firewall rules

---

## License

TBD

---

## Version History

| Version | Highlights |
|---------|-----------|
| **V0.8** | Parity trick scoring, Broken Ark rename, descending trick seq |
| V0.6 | Card themes (Dark/Classic), lobby system, waiting screen |
| V0.5 | Start screen, settings system (anim speed/AI pacing/card style/sound), deal animation, trick win pulse |
| V0.4 | Negation cards (FLIP: ♣5+♦5), trick sequence scoring |
| V0.3 | Combined bidding+detention phase, 4-consecutive-pass ending |
