add more code for 54 (WIP)
This commit is contained in:
+16
-224
@@ -1,237 +1,29 @@
|
|||||||
#![allow(dead_code, unused_imports)]
|
#![allow(dead_code)]
|
||||||
use std::{
|
|
||||||
cmp::max,
|
|
||||||
collections::{HashMap, HashSet},
|
|
||||||
};
|
|
||||||
|
|
||||||
type Cards = [Card; 5];
|
mod card;
|
||||||
type Values = [Value; 5];
|
mod evaluation;
|
||||||
|
mod game;
|
||||||
const ROYAL_FLUSH: [Value; 5] = [
|
mod hand;
|
||||||
Value::Ten,
|
mod suit;
|
||||||
Value::Jack,
|
mod value;
|
||||||
Value::Queen,
|
|
||||||
Value::King,
|
|
||||||
Value::Ace,
|
|
||||||
];
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Hello, world!");
|
println!("Hello, world!");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Clone)]
|
|
||||||
struct Card {
|
|
||||||
value: Value,
|
|
||||||
suit: Suit,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Card {
|
|
||||||
fn from_str(s: &str) -> Self {
|
|
||||||
assert_eq!(s.len(), 2);
|
|
||||||
let mut chars = s.chars();
|
|
||||||
let value = Value::from_char(chars.next().unwrap());
|
|
||||||
let suit = Suit::from_char(chars.next().unwrap());
|
|
||||||
Self { value, suit }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Hash, Eq, Clone, PartialOrd, Ord)]
|
|
||||||
enum Suit {
|
|
||||||
Diamonds,
|
|
||||||
Hearts,
|
|
||||||
Spades,
|
|
||||||
Clubs,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Suit {
|
|
||||||
fn from_char(c: char) -> Self {
|
|
||||||
match c {
|
|
||||||
'D' => Self::Diamonds,
|
|
||||||
'H' => Self::Hearts,
|
|
||||||
'S' => Self::Spades,
|
|
||||||
'C' => Self::Clubs,
|
|
||||||
_ => panic!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Clone)]
|
|
||||||
enum Value {
|
|
||||||
Two,
|
|
||||||
Three,
|
|
||||||
Four,
|
|
||||||
Five,
|
|
||||||
Six,
|
|
||||||
Seven,
|
|
||||||
Eight,
|
|
||||||
Nine,
|
|
||||||
Ten,
|
|
||||||
Jack,
|
|
||||||
Queen,
|
|
||||||
King,
|
|
||||||
Ace,
|
|
||||||
}
|
|
||||||
|
|
||||||
const VALUES: [Value; 13] = [
|
|
||||||
Value::Two,
|
|
||||||
Value::Three,
|
|
||||||
Value::Four,
|
|
||||||
Value::Five,
|
|
||||||
Value::Six,
|
|
||||||
Value::Seven,
|
|
||||||
Value::Eight,
|
|
||||||
Value::Nine,
|
|
||||||
Value::Ten,
|
|
||||||
Value::Jack,
|
|
||||||
Value::Queen,
|
|
||||||
Value::King,
|
|
||||||
Value::Ace,
|
|
||||||
];
|
|
||||||
|
|
||||||
impl Value {
|
|
||||||
fn from_char(c: char) -> Self {
|
|
||||||
match c {
|
|
||||||
'2' => Self::Two,
|
|
||||||
'3' => Self::Three,
|
|
||||||
'4' => Self::Four,
|
|
||||||
'5' => Self::Five,
|
|
||||||
'6' => Self::Six,
|
|
||||||
'7' => Self::Seven,
|
|
||||||
'8' => Self::Eight,
|
|
||||||
'9' => Self::Nine,
|
|
||||||
'T' => Self::Ten,
|
|
||||||
'J' => Self::Jack,
|
|
||||||
'Q' => Self::Queen,
|
|
||||||
'K' => Self::King,
|
|
||||||
'A' => Self::Ace,
|
|
||||||
_ => panic!("{c}"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Hand {
|
|
||||||
cards: [Card; 5],
|
|
||||||
evaluation: Evaluation,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Game {
|
|
||||||
player1: Hand,
|
|
||||||
player2: Hand,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, PartialOrd)]
|
|
||||||
enum Evaluation {
|
|
||||||
High,
|
|
||||||
OnePair,
|
|
||||||
TwoPair,
|
|
||||||
ThreeOfAKind,
|
|
||||||
Straight,
|
|
||||||
Flush,
|
|
||||||
FullHouse,
|
|
||||||
FourOfAKind,
|
|
||||||
StraightFlush(Card),
|
|
||||||
RoyalFlush,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Game {
|
|
||||||
fn from_line(line: &str) -> Self {
|
|
||||||
assert_eq!(line.len(), 29);
|
|
||||||
let (p1, p2) = Self::divide_into_two_hands(line);
|
|
||||||
let player1 = Hand::from_line(p1);
|
|
||||||
let player2 = Hand::from_line(p2);
|
|
||||||
Self { player1, player2 }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn divide_into_two_hands(line: &str) -> (&str, &str) {
|
|
||||||
let (p1, p2) = line.split_at(15);
|
|
||||||
(&p1[..14], p2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Hand {
|
|
||||||
fn from_line(line: &str) -> Self {
|
|
||||||
assert_eq!(line.len(), 14);
|
|
||||||
let vec: Vec<_> = line.split_whitespace().map(Card::from_str).collect();
|
|
||||||
let cards: [Card; 5] = vec.try_into().unwrap_or_else(|_| panic!());
|
|
||||||
let evaluation = Evaluation::from_cards(&cards);
|
|
||||||
Self { cards, evaluation }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait Contains<T> {
|
|
||||||
fn contains_value(&self, x: &T) -> bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Contains<Value> for &Cards {
|
|
||||||
fn contains_value(&self, x: &Value) -> bool {
|
|
||||||
for card in self.iter() {
|
|
||||||
if card.value == *x {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait CardTrait {
|
|
||||||
fn have_matching_suits(&self) -> bool;
|
|
||||||
fn contain_all_values_of(&self, values: &Values) -> bool;
|
|
||||||
fn get_highest_card(&self) -> Card;
|
|
||||||
fn have_consecutive_values(&self) -> bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CardTrait for Cards {
|
|
||||||
fn have_matching_suits(&self) -> bool {
|
|
||||||
self[1..]
|
|
||||||
.iter()
|
|
||||||
.zip(self[..4].iter())
|
|
||||||
.all(|(c1, c2)| c1.suit == c2.suit)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn contain_all_values_of(&self, values: &Values) -> bool {
|
|
||||||
values.iter().all(|v| self.contains_value(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_highest_card(&self) -> Card {
|
|
||||||
self.iter()
|
|
||||||
.reduce(|accum, item| max(accum, item))
|
|
||||||
.unwrap()
|
|
||||||
.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn have_consecutive_values(&self) -> bool {
|
|
||||||
VALUES.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Evaluation {
|
|
||||||
fn from_cards(cards: &Cards) -> Self {
|
|
||||||
if Self::is_royal_flush(cards) {
|
|
||||||
Self::RoyalFlush
|
|
||||||
} else if Self::is_straight_flush(cards) {
|
|
||||||
Self::StraightFlush(cards.get_highest_card())
|
|
||||||
} else {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_straight_flush(cards: &Cards) -> bool {
|
|
||||||
cards.have_matching_suits() && cards.have_consecutive_values()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_royal_flush(cards: &Cards) -> bool {
|
|
||||||
cards.have_matching_suits() && cards.contain_all_values_of(&ROYAL_FLUSH)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use crate::{Card, Game};
|
use crate::game::{Game, Player as P};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn example1() {
|
fn example1() {
|
||||||
let line = "5H 5C 6S 7S KD 2C 3S 8S 8D TD";
|
let line = "5H 5C 6S 7S KD 2C 3S 8S 8D TD";
|
||||||
let game = Game::from_line(line);
|
let game = Game::from(line);
|
||||||
assert_eq!(game.player1.cards[0], Card::from_str("5H"));
|
assert_eq!(
|
||||||
|
game.winner,
|
||||||
|
P::Player2,
|
||||||
|
"player 1: {:#?}\nplayer 2: {:#?}",
|
||||||
|
game.player1.evaluation,
|
||||||
|
game.player2.evaluation
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user