{
  "schema": "leumas.docs.page/1",
  "id": "adapter:domain/brackets",
  "slug": "adapters/domain/brackets",
  "kind": "capabilities",
  "bucket": "package",
  "title": "brackets — tournament brackets + competitive ranking (domain adapter)",
  "name": "brackets",
  "eyebrow": "tournament brackets + competitive ranking (domain adapter)",
  "chip": null,
  "summary": "Tournament bracket + competitive ranking pack for sports, esports and gaming leagues: generate single-elimination and double-elimination brackets (seeded, bye-padded, with...",
  "keywords": [
    "brackets",
    "tournament",
    "sports",
    "single-elimination",
    "double-elimination",
    "brackets api",
    "leumas brackets",
    "bye-padded"
  ],
  "audience": "both",
  "funnel": {
    "product": null,
    "cta": null
  },
  "body": "# brackets — tournament brackets + competitive ranking (domain adapter)\n\nPure-JavaScript capability pack for running competitions: generate tournament structures, seed and\npair players, compute rankings (Elo + league standings), and simulate whole events. **Zero npm\ndependencies** — Node built-ins only, self-contained in one `index.js`.\n\nPart of the Leumas2 adapter engine. It follows the one adapter contract\n(`export default { metadata, adapters }`), so the middleware registry auto-discovers it and it is\ncallable via `/api/adapters`, the MCP bridge, and chatbot functioncalls.\n\n## Tools\n\n| Tool | Input | Output |\n|---|---|---|\n| `singleElim` | `{ players, simulate?, seed? }` | Seeded, bye-padded single-elimination bracket (Round → Semifinals → Final). `simulate:true` plays it out to a champion. |\n| `doubleElim` | `{ players }` | Double-elimination structure: winners + losers brackets + grand final; you must lose twice to be eliminated. |\n| `roundRobin` | `{ players, doubleRound? }` | Round-robin schedule (circle method); everyone plays everyone. `doubleRound:true` adds a reversed home/away round. |\n| `swiss` | `{ players, round?, results? }` | Swiss-system pairings for the next round: groups by score, avoids rematches, assigns a bye. |\n| `elo` | `{ ratingA, ratingB, score, k? }` | New Elo ratings after one head-to-head (`score`: 1=A wins, 0.5=draw, 0=A loses). |\n| `winProbability` | `{ ratingA, ratingB }` | Elo win probability for each side (no rating change). |\n| `standings` | `{ results, points? }` | League table / leaderboard from results: points, W/D/L, goal diff, tie-broken sort. |\n| `seed` | `{ players, byRating? }` | Ranked draw order + bracket slot per seed (by explicit seed, by rating, or as given). |\n| `nextMatches` | `{ schedule, results?, limit? }` | The unplayed, currently-playable matches from a schedule/bracket given what's been played. |\n| `simulate` | `{ players, seed?, format? }` | Play out a whole `singleElim` (with champion path) or `roundRobin` event; Elo-weighted, reproducible with `seed`. |\n\n### `players` input is flexible\n\nAny of these work anywhere a tool takes `players`:\n\n- a **count**: `8` → auto-named `Player 1..8`\n- a **name string**: `\"Alice, Bob, Carol, Dave\"` (comma or newline separated)\n- a **JSON array**: `[{ \"name\": \"Alice\", \"rating\": 1600, \"seed\": 1 }, { \"name\": \"Bob\", \"rating\": 1500 }]`\n\nWhen ratings are present, `simulate`/`singleElim` weight match outcomes by Elo; when seeds are present\nthey drive the bracket draw; otherwise input order is used.\n\n## Usage example\n\n```js\nimport brackets from './index.js';\n\n// Seeded 6-player single-elimination bracket (2 byes, top seeds protected)\nbrackets.adapters.singleElim({ players: ['A','B','C','D','E','F'] });\n\n// Elo update after A (1600) beats B (1500)\nbrackets.adapters.elo({ ratingA: 1600, ratingB: 1500, score: 1 });\n// → { newRatingA: 1611.5, newRatingB: 1488.5, ... }\n\n// League table from results\nbrackets.adapters.standings({ results: [\n  { a: 'A', b: 'B', scoreA: 2, scoreB: 1 },\n  { a: 'A', b: 'C', winner: 'draw' },\n] });\n\n// Reproducible full-tournament simulation\nbrackets.adapters.simulate({ players: 8, seed: 42 });\n```\n\nVia the adapter registry / API:\n\n```\nPOST /api/adapters/brackets/simulate   { \"players\": 16, \"seed\": 7 }\n```\n\n## DRY boundary\n\nThis is a **new capability** — tournament structure + competitive ranking. It does not duplicate:\n\n- **`dice`** — generic randomness (dice notation, loot tables, shuffles). `brackets` only uses a tiny\n  inlined seeded RNG so `simulate` is reproducible; it is not a randomness toolkit.\n- **`statistics` / `numbers`** — descriptive stats and multi-criteria `weightedScoring`. Elo and\n  standings here are head-to-head competitor ranking, which those packs do not cover.\n\nKeep bracket/ranking logic here; keep general math in `numbers`/`statistics` and general randomness in\n`dice`.\n",
  "source": {
    "path": "shared/engines/adapters/domain/brackets/README.md",
    "blobSha": "",
    "commit": "",
    "committedAt": "",
    "provenance": "no-git",
    "bytes": 4135,
    "hash": "c6882da015ec0f2b89b98be025a3b4ef19e0da74"
  },
  "urls": {
    "html": "/p/adapters/domain/brackets",
    "json": "/docs/adapters/domain/brackets.json",
    "md": "/docs/adapters/domain/brackets.md"
  },
  "links": {
    "composes": [],
    "usedBy": [],
    "product": [],
    "howTo": [],
    "skills": []
  }
}
