pons 0.10.0

Rust package for contract bridge
Documentation

Pons

Crates.io Docs.rs Build Status

This library provides tools for analyzing and simulating hands in the card game contract bridge. It is named after an anatomical part of the brainstem and also "bridge" in Latin.

Modules

  • biddingTrie-based representation of a bidding system. Auction primitives (Call, Auction, etc.) live in the contract-bridge crate.
  • stats — numerically stable accumulators and double-dummy par scoring over histograms.

Card sets and shuffling live in contract-bridge::deck; hand-evaluation kernels in contract-bridge::eval.

Feature flags

  • serde — derive Serialize/Deserialize for the library's value types. Off by default.

Quick start

Deal 10 random hands and evaluate the North hand with several point counts:

use contract_bridge::Seat;
use contract_bridge::deck::full_deal;
use contract_bridge::eval::{self, HandEvaluator};

let mut rng = rand::rng();
for _ in 0..10 {
    let deal = full_deal(&mut rng);
    let north = deal[Seat::North];

    let hcp: u8 = eval::SimpleEvaluator(eval::hcp).eval(north);
    let nltc: f64 = eval::NLTC.eval(north);
    let zar: u8 = eval::zar(north);

    println!("{}  HCP={hcp}  NLTC={nltc}  Zar={zar}", deal.display(Seat::North));
}

Estimate NS par from random fill-in deals (requires ddss's solver, linked via ddss-sys in dev-dependencies; see examples/average-ns-par):

use contract_bridge::deck;
use contract_bridge::{AbsoluteVulnerability, Builder, Hand, Seat};
use ddss::{NonEmptyStrainFlags, Solver};
use pons::stats;
# let north_hand: Hand = "T9762.AT54.JT75.".parse().unwrap();
# let south_hand: Hand = "A.KQ962.A86.Q642".parse().unwrap();

let cards = Builder::new()
    .north(north_hand)
    .south(south_hand)
    .build_partial()
    .expect("north and south hands are disjoint and ≤13 each");
let solutions = Solver::lock().solve_deals(
    &deck::fill_deals(&mut rand::rng(), cards).take(90).collect::<Vec<_>>(),
    NonEmptyStrainFlags::ALL,
);
let par = stats::average_ns_par(
    solutions.into_iter().collect(),
    AbsoluteVulnerability::NONE,
    Seat::North,
);

Examples

The examples/ directory has runnable programs; run any with cargo run --example <name>. Bare names are user-facing; dev/research tooling is grouped by prefixab- (A/B match), dump- (data generator), eval- (evaluator calibration), probe- (diagnostic).

User-facing:

  • american — bid out random boards with the 2/1 game-forcing system.
  • practice-bidding — bid one seat on random deals and get feedback.
  • render-book — print every authored bidding node as readable prose.
  • average-ns-par — Monte-Carlo NS par score for a partial deal.

Dev / research harnesses (a sampler of each family):

  • ab-* — A/B duplicate matches pitting a convention or floor against a baseline (ab-landy, ab-lebensohl, ab-defend-2sx-or-3nt, …).
  • eval-nltc, eval-zar, eval-calibrate — validate hand-evaluation methods against double-dummy results.
  • dump-*, probe-* — AI-bidder data generation and diagnostics (most need --features search).

Benchmarking against BBA/EPBot

The bba-gen / bba-score example pair benchmarks pons's bidding against BBA/EPBot, Edward Piwowar's mature reference engine, driven natively through its C ABI: bba-gen bids the boards and writes a JSON dump, bba-score reads dumps and reports IMPs (plain or perfect-defense scoring). EPBot is bundled as the vendor/bba git submodule — free for non-commercial use and redistribution per its author — so fetch it once and the default library path resolves:

git submodule update --init vendor/bba
cargo run --release --features serde --example bba-gen -- --count 1000 -o bba.json
cargo run --release --features serde --example bba-score -- bba.json

EPBot is single-threaded; scripts/bba-gen-parallel.sh shards a large run across processes with disjoint seeds.

Set BBA_LIB to override the library path. Published comparison numbers credit EPBot as the reference engine.

Two examples that don't need pons live one level down the stack: generate-deals in contract-bridge and notrump-tricks in ddss (with a parallel copy in dds-bridge).

Research and contributor notes

Design docs live in docs/: the bidding-module architecture and its invariants (bidding-architecture.md), the A/B measurement playbook (measurement.md), the AI-bidder design effort (ai-bidder/), raw bidding-theory notes (bidding-theorems.md), and how to run heavy data generation on a shared machine (shared-machine-data-gen.md).