use super::board::Board;
use super::ffi;
use super::tricks::TrickCount;
use crate::hand::{Card, Holding};
use arrayvec::ArrayVec;
use core::ffi::c_int;
use dds_bridge_sys as sys;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct PlayTrace {
pub board: Board,
pub cards: ArrayVec<Card, 52>,
}
#[repr(transparent)]
pub(super) struct PlayTraceBin(pub(super) sys::playTraceBin);
impl From<&ArrayVec<Card, 52>> for PlayTraceBin {
fn from(cards: &ArrayVec<Card, 52>) -> Self {
let mut play = sys::playTraceBin {
#[allow(clippy::cast_possible_truncation, clippy::cast_possible_wrap)]
number: cards.len() as c_int,
..Default::default()
};
for (i, card) in cards.iter().enumerate() {
play.suit[i] = 3 - card.suit as c_int;
play.rank[i] = c_int::from(card.rank.get());
}
Self(play)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PlayAnalysis {
pub tricks: ArrayVec<TrickCount, 53>,
}
impl From<sys::solvedPlay> for PlayAnalysis {
fn from(solved: sys::solvedPlay) -> Self {
let number = ffi::count_from_sys(solved.number, solved.tricks.len());
Self {
tricks: solved.tricks[..number]
.iter()
.copied()
.map(ffi::trick_count_from_sys)
.collect(),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Play {
pub card: Card,
pub equals: Holding,
pub score: TrickCount,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct FoundPlays {
pub plays: ArrayVec<Play, 13>,
pub nodes: u32,
}
impl From<sys::futureTricks> for FoundPlays {
fn from(future: sys::futureTricks) -> Self {
let cards = ffi::count_from_sys(future.cards, future.suit.len());
let plays = (0..cards)
.map(|i| Play {
card: Card {
suit: ffi::suit_from_desc_index(future.suit[i]),
rank: ffi::rank_from_sys(future.rank[i]),
},
#[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
equals: Holding::from_bits_truncate(future.equals[i] as u16),
score: ffi::trick_count_from_sys(future.score[i]),
})
.collect();
Self {
plays,
#[allow(clippy::cast_sign_loss)]
nodes: future.nodes as u32,
}
}
}