@echecs/tournament

中文文档
3.3.0发布于 2026/05/28MITTypeScriptES Module零依赖构建来源已验证近 30 天下载 3139

任何FIDE配对系统的高级国际象棋锦标赛指挥员 支持瑞士语,圆形robin,和加速格式. 零从属.

中文使用文档
文档目录10 节
  1. 安装
  2. 快速启动
  3. API 密码
  4. Tournament
  5. bakuAcceleration(players)
  6. 兼容对等系统
  7. 类型
  8. GameKind 验证
  9. 参考文献
  10. 许可证

比赛

npm Coverage License: MIT Spec

比赛 是一个用于组织国际象棋锦标赛的 TypeScript 库 任何FIDE配对系统。 它提供一种状态 Tournament 管理类 整个生命周期——配对回合、记录结果、计算站位—— (单位:千美元) bakuAcceleration() c.04.7. 零运行时间 依赖性.

配对系统被作为函数参数注入. 自取自来 @echecs/swiss, (中文(简体) ), @echecs/round-robin,或一个 自定义执行.

安装

npm install @echecs/tournament

快速启动

import { Tournament } from '@echecs/tournament';
import { pair } from '@echecs/swiss/dutch';
import type { Game, GameKind, Player, Tiebreak } from '@echecs/tournament';

const players: Player[] = [
  { id: 'alice', rating: 2100 },
  { id: 'bob', rating: 1950 },
  { id: 'carol', rating: 1870 },
  { id: 'dave', rating: 1820 },
];

const tournament = new Tournament({
  pairingSystem: pair,
  players,
  rounds: 3,
});

// Round 1
const round1 = tournament.pairRound();
// round1.pairings = [{ black: 'carol', white: 'alice' }, ...]
// round1.byes    = [{ player: 'dave' }]

tournament.recordResult({ black: 'carol', result: 1, white: 'alice' });
tournament.recordResult({ black: 'dave', result: 0.5, white: 'bob' });

// Round 2
const round2 = tournament.pairRound();
// ...record results...

// Standings (no tiebreaks)
const table = tournament.standings();
// [{ player: 'alice', rank: 1, score: 2, tiebreaks: [] }, ...]

API 密码

Tournament

class Tournament {
  constructor(options: TournamentOptions);

  clearResult(round: number, white: string, black: string): void;
  pairRound(): PairingResult;
  recordResult(game: Game): void;
  standings(tiebreaks?: Tiebreak[]): Standing[];
  updateResult(round: number, game: Game): void;

  get currentRound(): number;
  get games(): readonly (readonly Game[])[];
  get isComplete(): boolean;
  get players(): readonly Player[];
  get rounds(): number;
  get tiebreaks(): readonly string[];

  toJSON(): TournamentSnapshot;
  static fromJSON(
    snapshot: TournamentSnapshot,
    pairingSystem: PairingSystem,
    acceleration?: AccelerationMethod,
  ): Tournament;
}

constructor(options)

创建新的锦标赛.

interface TournamentOptions {
  acceleration?: AccelerationMethod; // e.g. bakuAcceleration(players)
  pairingSystem: PairingSystem; // e.g. pair from @echecs/swiss/dutch
  players: Player[]; // all participants
  rounds: number; // total number of rounds
  tiebreaks?: string[]; // opaque IDs preserved through serialization
}

掷出 RangeError 如果少于2名或少于1轮.

pairRound()

使用注射配对系统生成下一轮的配对. 回返 (单位:千美元) PairingResult 与对接和再见.

掷出 RangeError 如果联赛结束,或者本轮比赛结束 未记录结果.

clearResult(round, white, black)

删除先前记录的由圆数和玩家识别的结果 双人 检查两个颜色,所以呼叫者可以通过 white 财务报告和审定财务报表 black 无论是哪种顺序.

tournament.clearResult(1, 'alice', 'carol');

清空后,圆形变为不完整并可以重新记录配对 通过 recordResult。 。 。 .

掷出 RangeError 如果该回合无效或没有匹配结果.

recordResult(game)

记录本轮比赛的比赛结果.

tournament.recordResult({
  black: 'carol',
  result: 1, // 1 = white wins, 0.5 = draw, 0 = black wins
  white: 'alice',
});

可选 kind?: GameKind 字段对游戏类型进行分类。 提供时, 结果必须与类型一致(见 GameKind 验证 页:1.

tournament.recordResult({
  black: 'carol',
  kind: 'forfeit-win',
  result: 1,
  white: 'alice',
});

掷出 RangeError 如果选手在本轮比赛中不匹配任何配对, 或如果 kind 财务报告和审定财务报表 result 不一致.

updateResult(round, game)

替换任意回合中的现有结果。 游戏由 white编号 :black 玩家配对(在两种命令中都选中). 存储游戏保留 它最初的颜色分配.

// Change round 1 result from white-wins to draw
tournament.updateResult(1, {
  black: 'carol',
  result: 0.5,
  white: 'alice',
});

// Add a kind to an existing result
tournament.updateResult(1, {
  black: 'carol',
  kind: 'forfeit-win',
  result: 1,
  white: 'alice',
});

掷出 RangeError 如果回合无效,则没有匹配结果,或 kind 财务报告和审定财务报表 result 不一致.

standings(tiebreaks?)

返回玩家按分数排序,并按顺序应用可选的平分符. 每个 bringbreak 函数收到 (playerId, games, players) 然后返回一个数字.

import { buchholz } from '@echecs/buchholz';
import { sonnebornBerger } from '@echecs/sonneborn-berger';

const table = tournament.standings([buchholz, sonnebornBerger]);
// [{ player: 'alice', rank: 1, score: 2.5, tiebreaks: [7.5, 6.25] }, ...]

断接功能符合 :

type Tiebreak = (
  playerId: string,
  games: Game[][],
  players: Player[],
) => number;

toJSON() 编号 : fromJSON()

串行并恢复联赛状态. 配对系统功能必须是 在恢复时重新提供, 因为功能不能连续运行.

const snapshot = tournament.toJSON();
const json = JSON.stringify(snapshot);

// Later...
const restored = Tournament.fromJSON(JSON.parse(json), pair);
const nextRound = restored.pairRound();

bakuAcceleration(players)

function bakuAcceleration(players: Player[]): AccelerationMethod;

返回 a AccelerationMethod 执行 C.04.7 巴库加速。 。 。 .

将玩家分为两组(GA =上半部,GB = 休息部)并添加虚拟 在第一轮比赛中给GA球员的分数打分,导致更强大的球员 早点见面.

import { Tournament, bakuAcceleration } from '@echecs/tournament';
import { pair } from '@echecs/swiss/dutch';

const tournament = new Tournament({
  acceleration: bakuAcceleration(players),
  pairingSystem: pair,
  players,
  rounds: 9,
});

虚拟点 :

  • 上半轮加速弹: GA 玩家获得一分
  • 下半速发: GA 玩家获得0.5分
  • 在加速回合后: 0 点
  • GB 播放器: 总是0分

虚拟点只影响对等——它们从未被存储在游戏历史中 或反映于地位.

兼容对等系统

符合 PairingSystem 签名工作 :

type PairingSystem = (players: Player[], games: Game[][]) => PairingResult;
软件包子路径FIDE 规则
@echecs/swiss@echecs/swiss/dutch页:1
@echecs/swiss/dubov页:1
@echecs/swiss/burstein第C.04.4.2条
@echecs/swiss/lim页:1
@echecs/swiss/double第C.04.5号决定
@echecs/swiss/team第C.04.6号决定
@echecs/round-robin@echecs/round-robin第05条

所有子路径导出 a pair 符合 PairingSystem 签名.

类型

interface Player {
  id: string;
  rating?: number;
}

interface Game {
  black: string;
  kind?: GameKind; // optional: classifies unplayed rounds
  result: Result;
  white: string;
}

type GameKind =
  | 'forfeit-loss'
  | 'forfeit-win'
  | 'full-bye'
  | 'half-bye'
  | 'pairing-bye'
  | 'zero-bye';

type Result = 0 | 0.5 | 1;

interface Pairing {
  black: string;
  white: string;
}

interface Bye {
  player: string;
}

interface PairingResult {
  byes: Bye[];
  pairings: Pairing[];
}

interface Standing {
  player: string;
  rank: number;
  score: number;
  tiebreaks: number[];
}

type Tiebreak = (
  playerId: string,
  games: Game[][],
  players: Player[],
) => number;

type PairingSystem = (players: Player[], games: Game[][]) => PairingResult;

interface AccelerationMethod {
  virtualPoints: (player: Player, round: number, totalRounds: number) => number;
}

interface TournamentSnapshot {
  currentRound: number;
  games: Game[][];
  players: Player[];
  roundPairings: Record<string, PairingResult>;
  rounds: number;
  tiebreaks?: string[];
}

GameKind 验证

何时 kind 以 recordResult 或者说 updateResult,则 result 必须 相匹配的。 匹配的。 投错 RangeError。 。 。 .

kind需求 resultFIDE 参考文件
forfeit-win1第16.2.2条
forfeit-loss0第16.2.4条
full-bye1—— 说
half-bye0.5第16.2.5条
pairing-bye1第16.2.1条
zero-bye0第16.2.3条

何时 kind 删除,则接受任何结果.

参考文献

许可证

麻省理工学院

版本与发布记录

@echecs/tournament 共发布 10 个版本,首次发布于 2026/03/22;过去 12 个月发布了 10 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
3.3.0latest2026/05/285 个月前
3.2.02026/05/265 个月前
3.1.12026/05/155 个月前
3.1.02026/05/096 个月前
3.0.02026/05/096 个月前
2.1.22026/04/186 个月前

关于 @echecs/tournament 的常见问题

@echecs/tournament 是什么?

任何FIDE配对系统的高级国际象棋锦标赛指挥员 支持瑞士语,圆形robin,和加速格式. 零从属.

如何安装 @echecs/tournament?

在项目目录运行 npm install @echecs/tournament,或使用 pnpm add / yarn add / bun add。

@echecs/tournament 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@echecs/tournament 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@echecs/tournament 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@echecs/tournament 可以商用吗?

@echecs/tournament 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@echecs/tournament 的下载量有多少?

根据 npm 官方下载统计,@echecs/tournament 在 2026/10/13 – 2026/11/11 这 30 天内被下载 3,139 次,日均约 105 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@echecs/tournament 还在维护吗?

最新版本 3.3.0 发布于 2026/05/28(5 个月前);至今共发布 10 个版本,其中过去 12 个月发布了 10 个;首次发布于 2026/03/22。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。