use parking_lot::Mutex;
use std::sync::LazyLock;
static THREAD_POOL: LazyLock<Mutex<()>> = LazyLock::new(|| {
unsafe { crate::SetMaxThreads(0) };
Mutex::new(())
});
#[allow(clippy::large_types_passed_by_value)]
fn check(
deal: crate::ddTableDeal,
solution: crate::ddTableResults,
pars: [crate::parResultsMaster; 2],
) {
#[allow(clippy::cast_possible_wrap)]
const SUCCESS: i32 = crate::RETURN_NO_FAULT as i32;
let mut tricks = crate::ddTableResults::default();
let status = unsafe {
let _guard = THREAD_POOL.lock();
crate::CalcDDtable(deal, &raw mut tricks)
};
assert_eq!(status, SUCCESS);
assert_eq!(tricks, solution);
let mut result = [crate::parResultsMaster::default(); 2];
let status = unsafe { crate::SidesParBin(&raw mut tricks, &raw mut result[0], 0) };
assert_eq!(status, SUCCESS);
assert_eq!(result, pars);
}
const NO_CONTRACT: crate::contractType = crate::contractType {
level: 0,
denom: 0,
seats: 0,
underTricks: 0,
overTricks: 0,
};
#[test]
fn solve_four_13_card_straight_flushes() {
const MASK: core::ffi::c_uint = ((1 << 13) - 1) << 2;
const DEAL: crate::ddTableDeal = crate::ddTableDeal {
cards: [
[0, 0, 0, MASK], [0, 0, MASK, 0], [0, MASK, 0, 0], [MASK, 0, 0, 0], ],
};
const SOLUTION: crate::ddTableResults = crate::ddTableResults {
resTable: [
[0, 13, 0, 13], [13, 0, 13, 0], [0, 13, 0, 13], [13, 0, 13, 0], [0, 0, 0, 0], ],
};
const CONTRACTS: [crate::contractType; 10] = [
crate::contractType {
level: 7,
denom: 1, seats: 5,
underTricks: 0,
overTricks: 0,
},
NO_CONTRACT,
NO_CONTRACT,
NO_CONTRACT,
NO_CONTRACT,
NO_CONTRACT,
NO_CONTRACT,
NO_CONTRACT,
NO_CONTRACT,
NO_CONTRACT,
];
const NS: crate::parResultsMaster = crate::parResultsMaster {
score: -1510,
number: 1,
contracts: CONTRACTS,
};
const EW: crate::parResultsMaster = crate::parResultsMaster {
score: 1510,
number: 1,
contracts: CONTRACTS,
};
check(DEAL, SOLUTION, [NS, EW]);
}
#[test]
fn solve_par_5_tricks() {
const AKQJ: core::ffi::c_uint = 0xF << 11;
const T987: core::ffi::c_uint = 0xF << 7;
const XXXX: core::ffi::c_uint = 0xF << 3;
const X: core::ffi::c_uint = 1 << 2;
const DEAL: crate::ddTableDeal = crate::ddTableDeal {
cards: [
[AKQJ, X, XXXX, T987], [XXXX, T987, AKQJ, X], [X, AKQJ, T987, XXXX], [T987, XXXX, X, AKQJ], ],
};
const SOLUTION: crate::ddTableResults = crate::ddTableResults {
resTable: [[5; 4]; 5],
};
const PAR: crate::parResultsMaster = crate::parResultsMaster {
score: 0,
number: 1,
contracts: [NO_CONTRACT; 10],
};
check(DEAL, SOLUTION, [PAR; 2]);
}
#[test]
#[allow(clippy::unusual_byte_groupings)]
fn solve_everyone_makes_1nt() {
const A54: core::ffi::c_uint = 0b10000_0000_1100_00;
const QJ32: core::ffi::c_uint = 0b00110_0000_0011_00;
const K976: core::ffi::c_uint = 0b01000_1011_0000_00;
const T8: core::ffi::c_uint = 0b00001_0100_0000_00;
const DEAL: crate::ddTableDeal = crate::ddTableDeal {
cards: [
[A54, QJ32, K976, T8], [T8, A54, QJ32, K976], [K976, T8, A54, QJ32], [QJ32, K976, T8, A54], ],
};
const SOLUTION: crate::ddTableResults = crate::ddTableResults {
resTable: [[6; 4], [6; 4], [6; 4], [6; 4], [7; 4]],
};
const NS: crate::parResultsMaster = crate::parResultsMaster {
score: 90,
number: 1,
contracts: [
crate::contractType {
level: 1,
denom: 0, seats: 4,
underTricks: 0,
overTricks: 0,
},
NO_CONTRACT,
NO_CONTRACT,
NO_CONTRACT,
NO_CONTRACT,
NO_CONTRACT,
NO_CONTRACT,
NO_CONTRACT,
NO_CONTRACT,
NO_CONTRACT,
],
};
const EW: crate::parResultsMaster = crate::parResultsMaster {
score: 90,
number: 1,
contracts: [
crate::contractType {
level: 1,
denom: 0, seats: 5,
underTricks: 0,
overTricks: 0,
},
NO_CONTRACT,
NO_CONTRACT,
NO_CONTRACT,
NO_CONTRACT,
NO_CONTRACT,
NO_CONTRACT,
NO_CONTRACT,
NO_CONTRACT,
NO_CONTRACT,
],
};
check(DEAL, SOLUTION, [NS, EW]);
}