From: MA Beaudet Date: Sun, 7 Nov 2021 19:49:07 +0000 (+0100) Subject: feat!: add array ref as args for eval_5hand and eval_7hand X-Git-Url: https://git.beaudet.xyz/?a=commitdiff_plain;h=c6554c5cec38d67a4b186896df65ffd16f99b0f0;p=poker-eval.git feat!: add array ref as args for eval_5hand and eval_7hand eval_5hand now transmutes (unsafe rust) the `&[Card; 5]`. It "should" not be unsafe as Card has the same repr as u32. Looking for suggestions on how to convert slice newtype to inner. --- diff --git a/src/lib.rs b/src/lib.rs index 6a72610..d102a5a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,6 +7,7 @@ pub mod constants; use std::{ collections::HashMap, convert::{TryFrom, TryInto}, + mem::transmute, rc::Rc, str::FromStr, sync::{Arc, Mutex}, @@ -116,7 +117,9 @@ impl Evaluator { .hands .iter() .map(|player| match self.algorithm { - Algorithm::CactusKev => self.eval_5hand(player.as_ref().clone()), + Algorithm::CactusKev => { + self.eval_5hand(&player.as_ref().0[..5].try_into().unwrap()) + } }) .enumerate() .collect(), @@ -132,7 +135,7 @@ impl Evaluator { .collect() }) .map(|player: Vec| match self.algorithm { - Algorithm::CactusKev => self.eval_7hand(Cards(player)), + Algorithm::CactusKev => self.eval_7hand(&player.try_into().unwrap()), }) .enumerate() .collect(), @@ -140,33 +143,29 @@ impl Evaluator { result } - pub fn eval_5hand(&self, cards: Cards) -> u16 { - let cards: Vec = cards.0.into_iter().map(|c| u32::from(c)).collect(); - if let [c1, c2, c3, c4, c5] = cards[..5] { - let mut q = (c1 | c2 | c3 | c4 | c5) >> 16; - if c1 & c2 & c3 & c4 & c5 & 0xF000 != 0 { - FLUSHES[q as usize] - } else if UNIQUE5[q as usize] != 0 { - UNIQUE5[q as usize] - } else { - q = (c1 & 0xff) * (c2 & 0xff) * (c3 & 0xff) * (c4 & 0xff) * (c5 & 0xff); - HASH_VALUES[find_fast((q as usize).try_into().unwrap()) as usize] - } + pub fn eval_5hand(&self, cards: &[Card; 5]) -> u16 { + let [c1, c2, c3, c4, c5]: &[u32; 5] = unsafe { transmute(cards) }; + let q = (c1 | c2 | c3 | c4 | c5) >> 16; + if c1 & c2 & c3 & c4 & c5 & 0xF000 != 0 { + FLUSHES[q as usize] + } else if UNIQUE5[q as usize] != 0 { + UNIQUE5[q as usize] } else { - 9999 + let q = (c1 & 0xff) * (c2 & 0xff) * (c3 & 0xff) * (c4 & 0xff) * (c5 & 0xff); + HASH_VALUES[find_fast(q) as usize] } } /// Non-optimized method of determining the best five-card hand possible of seven cards. - pub fn eval_7hand(&self, cards: Cards) -> u16 { + pub fn eval_7hand(&self, cards: &[Card; 7]) -> u16 { let mut subhand: [Card; 5] = [Card(0); 5]; let mut best = 9999; for i in 0..21 { for j in 0..5 { - subhand[j] = cards.0[..][PERM7[i][j] as usize]; + subhand[j] = cards[..][PERM7[i][j] as usize]; } - let q = self.eval_5hand(Cards(subhand.into())); + let q = self.eval_5hand(&subhand); if q < best { best = q; }