notrump_tricks/
main.rs

1use dds_bridge::contract::Strain;
2use dds_bridge::deal::{Deal, Seat};
3use dds_bridge::solver;
4use std::process::ExitCode;
5
6/// Histogram of notrump tricks
7#[derive(Debug, Clone, Copy, Default)]
8struct Histogram {
9    /// Histogram of notrump tricks for each player
10    each: [u32; 14],
11    /// Histogram of right-sided notrump tricks for each pair
12    right: [u32; 14],
13    /// Histogram of maximum notrump tricks for each deal
14    max: [u32; 14],
15}
16
17fn to_cumulative_probability(histogram: [u32; 14]) -> [f64; 14] {
18    let mut acc = 0;
19    let mut cumsum = [0; 14];
20    for (i, x) in histogram.into_iter().rev().enumerate() {
21        acc += x;
22        cumsum[13 - i] = acc;
23    }
24    cumsum.map(|x| f64::from(x) / f64::from(cumsum[0]))
25}
26
27fn analyze_deals(n: usize) -> Result<(), solver::Error> {
28    let deals: Vec<_> = core::iter::repeat_with(|| Deal::new(&mut rand::rng()))
29        .take(n)
30        .collect();
31
32    let histogram = solver::solve_deals(&deals, solver::StrainFlags::NOTRUMP)?
33        .into_iter()
34        .map(|table| table[Strain::Notrump])
35        .fold(Histogram::default(), |mut acc, row| {
36            let (n, e, s, w) = (
37                usize::from(row.get(Seat::North)),
38                usize::from(row.get(Seat::East)),
39                usize::from(row.get(Seat::South)),
40                usize::from(row.get(Seat::West)),
41            );
42            acc.each[n] += 1;
43            acc.each[e] += 1;
44            acc.each[s] += 1;
45            acc.each[w] += 1;
46            acc.right[n.max(s)] += 1;
47            acc.right[e.max(w)] += 1;
48            acc.max[n.max(e).max(s).max(w)] += 1;
49            acc
50        });
51
52    dbg!(&to_cumulative_probability(histogram.each)[6..]);
53    dbg!(&to_cumulative_probability(histogram.right)[6..]);
54    dbg!(&to_cumulative_probability(histogram.max)[6..]);
55    Ok(())
56}
57
58#[doc = include_str!("README.md")]
59fn main() -> Result<ExitCode, solver::Error> {
60    match std::env::args().nth(1) {
61        Some(string) => {
62            if let Ok(n) = string.parse::<usize>() {
63                analyze_deals(n)
64            } else {
65                eprintln!("{}", include_str!("README.md"));
66                return Ok(ExitCode::FAILURE);
67            }
68        }
69        None => analyze_deals(100),
70    }?;
71    Ok(ExitCode::SUCCESS)
72}