feat: add incremental trie lookup API and Deck::without_cards

- Add TrieCursor struct for partial Supersonic LUT trie traversal
- Add init_lookup/advance_lookup/finish_* methods for 5/6/7-card incremental eval
- Add raw_init/raw_advance/raw_finish_* zero-cost API (no depth tracking)
- Add Deck::without_cards() for constructing remaining decks
- Re-export TrieCursor from evaluator module
- Add comprehensive tests for all new APIs
- Update .gitignore for docs/REFERENCES.md
This commit is contained in:
Jan-Peter von Hunnius 2026-05-25 19:44:21 +02:00
parent 912445d992
commit 156904f2bf
4 changed files with 455 additions and 0 deletions

View file

@ -210,6 +210,42 @@ impl Deck {
pub fn cards(&self) -> &[Card] {
&self.cards
}
/// Creates a new deck excluding the specified cards.
///
/// Useful for constructing a "remaining deck" that omits known cards
/// (hero's hole cards, board cards) — typically resulting in a 45–47 card
/// deck for enumeration-based equity calculations.
///
/// # Examples
///
/// ```rust
/// use holdem_core::{Deck, Card};
/// use std::str::FromStr;
///
/// let deck = Deck::new();
/// let excluded = vec![
/// Card::from_str("As").unwrap(),
/// Card::from_str("Kh").unwrap(),
/// ];
/// let remaining = deck.without_cards(&excluded);
/// assert_eq!(remaining.remaining(), 50);
/// ```
///
/// # Panics
///
/// This method does not panic.
pub fn without_cards(&self, excluded: &[Card]) -> Deck {
use std::collections::HashSet;
let exclude_set: HashSet<Card> = excluded.iter().copied().collect();
let cards: Vec<Card> = self
.cards
.iter()
.copied()
.filter(|c| !exclude_set.contains(c))
.collect();
Deck { cards }
}
}
impl Default for Deck {