feat(cli): annotate PBN trees in place, and only where analysis is missing - #8
Merged
Conversation
…ssing The binary could already write Bridge Composer compatible DD and par tags, but only one file at a time, always recomputing, and it fabricated results for boards that have no deal. A build could not simply point it at a collection. Now it can. Skip incomplete deals. A board written as [Deal "N:... ... ... ..."] — Bridge Composer's form for an auction-only teaching board — parses successfully into empty hands, so it was solved and stamped with an all-zero table plus [OptimumScore "NS 0"] and [ParContract "NS Pass"]. On one real lesson file that produced 19 annotated boards where 6 were analyzable. Hands::is_complete now gates the pass and such boards are left untouched. Fill in only what is missing. A board that already carries [DoubleDummyTricks] is passed through byte-for-byte; --recalculate redoes those. A stray par tag without a DD table does not count as analyzed, so it still gets filled in and the orphaned value replaced. Accept several inputs, and directories, searched recursively for *.pbn, with --in-place to rewrite them. Unchanged files are not rewritten, so a re-run touches nothing and mtimes do not churn; in-place writes go through a temporary file and a rename. Naming more than one file without --in-place is an error rather than a surprise. Verified against Bridge Composer's own output: across 25 files it had already analyzed, all 102 distinct DoubleDummyTricks values were reproduced exactly. Annotating a 63-file, 828-deal collection in one command added analysis to every deal, produced no all-zero tables, removed no lines, and the second run updated nothing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A newer stable clippy added `manual_isolate_lowest_one`, which flags `m & m.wrapping_neg()` in pack_bits/unpack_bits and turns CI's Lint job red on main. Its suggested `isolate_lowest_one()` is still unstable, so adopting it would raise this crate's minimum Rust version for no gain in a hot path. Suppress the lint locally instead, paired with `unknown_lints` so compilers predating it stay quiet about the allow itself. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sets bit 0x00080000 ("double-dummy data has been verified") in each annotated
board's [BCFlags], adding the tag if the board has none and preserving every
bit already present.
This records provenance only. No documented BCFlags bit controls whether the
DD table is displayed, and Bridge Composer does not set this one itself: across
388 boards in files where it had written DoubleDummyTricks, the bit was set
zero times, and the flag values there (1f, 17, df, 40001f) are indistinguishable
from files with no analysis at all. The flag is therefore off by default and
documented for what it does rather than what it might be assumed to do.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The example uses `analyse_play`, which is gated behind `play-analysis`, but unlike bench_fixtures beside it, it had no [[example]] block. Auto-discovered with no required-features, it failed to compile under CI's featureless `clippy --workspace --all-targets` pass and turned Lint red on main. Declare it the same way its sibling is declared, so the pass skips it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The binary could already write Bridge Composer compatible DD and par tags, but only one file at a time, always recomputing, and it fabricated results for boards that have no deal. A build could not simply point it at a collection. Now it can:
bridge-solver -w -i Curated/ # fill in what's missing, recursivelySkip incomplete deals (bug fix)
A board written as
[Deal "N:... ... ... ..."]— Bridge Composer's form for an auction-only teaching board — parses successfully into empty hands, so it was solved and stamped with an all-zero table plus[OptimumScore "NS 0"]and[ParContract "NS Pass"]. On one real lesson file that produced 19 annotated boards where only 6 were analyzable.Hands::is_complete()now gates the pass; such boards are left untouched.Fill in only what is missing
A board that already carries
[DoubleDummyTricks]is passed through byte-for-byte.--recalculateredoes those. A stray par tag without a DD table does not count as analyzed, so it still gets filled in and the orphaned value replaced.Several inputs, directories, in place
-itakes multiple paths; directories are searched recursively for*.pbn.-w/--in-placerewrites them. Unchanged files are not rewritten, so a re-run touches nothing and mtimes do not churn; in-place writes go through a temporary file and a rename. Naming more than one file without--in-placeis an error rather than a surprise.Verification
Against Bridge Composer's own output — 25 files it had already analyzed — all 102 distinct
DoubleDummyTricksvalues were reproduced exactly, zero mismatches. That covers the full hex range (11- and 12-trick cells) and boards where the N and S groups differ, which is what would expose a wrong declarer or strain ordering.Annotating a 63-file, 828-deal collection in one command:
39 tests pass (
--features cli --lib --bins), fmt and clippy clean, verified underdev-build.sh --ci.Version bumped 0.4.0 → 0.5.0.
🤖 Generated with Claude Code