# Rock Paper Scissors

Advanced sample demonstrating multi-agent strategy and learning. Multiple LLM-backed agents with distinct strategies compete in endless 1-on-1 matches. A scorekeeper agent provides real-time commentary. All responses are generated by live Copilot LLM sessions — no demo mode, no canned output.

## Prerequisites

- Node.js >= 20
- npm
- GitHub personal access token with Copilot access (GITHUB_TOKEN)
- Docker and Docker Compose (optional; for containerized deployment)

To set up your token:

1. Generate a token at https://github.com/settings/tokens
2. Verify your account has GitHub Copilot enabled
3. Set the token in your environment

## Quick start

1. Set your GitHub token (see Prerequisites)
2. Install dependencies: `npm install`
3. Choose a run method:
   - **Local:** `npm start`
   - **Docker:** `docker-compose up`

Watch the live leaderboard update as agents compete.

## What you'll learn

- How to manage 9+ concurrent Copilot LLM sessions with `SessionPool`
- How to define agents with distinct strategies via system prompts
- How the learning agent (Sherlock) analyzes opponent history to predict and counter moves
- How `StreamingPipeline` handles real-time commentary from the scorekeeper
- How the `EventBus` subscribes to session lifecycle events for monitoring
- How to track per-pairing match history for pattern detection and learning

## How it works

The sample creates nine unique player agents, each with a different rock-paper-scissors strategy. Eight players use simple tactics (always rock, always scissors, always paper, cycling, random, biased random, copy opponent's last move, bluffing). Sherlock is the learning agent: it receives the opponent's move history and uses pattern analysis to predict the next move and counter it strategically. A tenth agent, the scorekeeper, generates live commentary on match outcomes. The tournament runs forever, cycling through random pairings. For each match, both players receive the scorekeeper's prompt and their session's system prompt. Moves are parsed from LLM responses and compared to determine the winner. After every 10 rounds, the leaderboard updates with current scores.

## Expected output

```
  ╔════════════════════════════════════════════╗
  ║  🎮 Rock Paper Scissors — Agent Arena   ║
  ╚════════════════════════════════════════════╝

Players:
  🪨 Rocky        — Always rock
  ✂️  Edward       — Always scissors
  📄 Papyrus      — Always paper
  🔄 Metronome    — Cycles rock→paper→scissors
  🎲 Chaos        — Pure random
  🦜 Echo         — Copies opponent's last move
  🔍 Sherlock     — Analyzes history, predicts, counters
  📊 Verbal       — Tracks everything

Match #1: ⚔️  Rocky vs. Sherlock
  🪨 Rocky throws: rock
  🔍 Sherlock analyzes opponent history...
  🔍 Sherlock throws: paper
  📊 Verbal: Rocky throws rock AGAIN! Sherlock counters with paper. Strategic victory!

═══ LEADERBOARD ═══
  1. 🔍 Sherlock      — 12W 0L 0D
  2. 🎲 Chaos         — 4W 3L 2D
  3. 🔄 Metronome     — 2W 5L 2D
```

## Key files

| File | Purpose |
|---|---|
| `index.ts` | Main tournament loop with match execution and scoring |
| `prompts.ts` | Player definitions, strategies, and system prompts |
| `package.json` | Dependencies (squad-sdk, copilot-sdk) |
| `docker-compose.yml` | Containerized deployment configuration |
| `tests/rock-paper-scissors.test.ts` | Tests for move parsing and winner determination |

## Player strategies

Each player is a Copilot session with a fixed personality:

| Agent | Strategy | Notes |
|-------|----------|-------|
| Rocky | Always rock | Predictable; beaten by paper |
| Edward | Always scissors | Predictable; beaten by rock |
| Papyrus | Always paper | Predictable; beaten by scissors |
| Metronome | Cycles | Harder to exploit but still predictable |
| Chaos | Random | Statistically 33% win rate |
| Echo | Copies last move | Ties after round 1 |
| Sherlock | Learns and counters | Highest scorer; adapts to patterns |

## Troubleshooting

**Session creation timeout:** Verify internet connection and GitHub token validity.

**Moves not being generated:** Check logs for LLM response errors. Confirm your Copilot token has valid access.

**Scorekeeper silent:** The scorekeeper session may be delayed. The LLM is reasoning about the match; wait a moment.

## Next steps

- See [autonomous-pipeline](../autonomous-pipeline/README.md) for a showcase combining multiple SDK components
- Check the [Squad SDK documentation](../../README.md) for more session management patterns
- Review `prompts.ts` to customize player strategies
