Much work fleshing out cards and hands.
This commit is contained in:
100
src/card.rs
Normal file
100
src/card.rs
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
use rand::Rng;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Eq, PartialEq)]
|
||||||
|
pub enum CardSuit {
|
||||||
|
Diamonds,
|
||||||
|
Clubs,
|
||||||
|
Hearts,
|
||||||
|
Spades,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)]
|
||||||
|
pub enum CardValue {
|
||||||
|
Two = 2,
|
||||||
|
Three,
|
||||||
|
Four,
|
||||||
|
Five,
|
||||||
|
Six,
|
||||||
|
Seven,
|
||||||
|
Eight,
|
||||||
|
Nine,
|
||||||
|
Ten,
|
||||||
|
Jack,
|
||||||
|
Queen,
|
||||||
|
King,
|
||||||
|
Ace,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq)]
|
||||||
|
pub struct PlayingCard {
|
||||||
|
pub value: CardValue,
|
||||||
|
pub suit: CardSuit,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ord for PlayingCard {
|
||||||
|
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||||
|
self.value.cmp(&other.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for PlayingCard {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||||
|
self.value.partial_cmp(&other.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for PlayingCard {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
let suit = match self.suit {
|
||||||
|
CardSuit::Clubs => "♣",
|
||||||
|
CardSuit::Diamonds => "♦",
|
||||||
|
CardSuit::Hearts => "♥",
|
||||||
|
CardSuit::Spades => "♠",
|
||||||
|
};
|
||||||
|
|
||||||
|
write!(f, "{:?}{}", self.value, suit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw_card(deck: &mut Vec<PlayingCard>) -> PlayingCard {
|
||||||
|
let num = rand::thread_rng().gen_range(0..deck.len());
|
||||||
|
let card = deck.remove(num);
|
||||||
|
|
||||||
|
card
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_deck() -> Vec<PlayingCard> {
|
||||||
|
let mut deck: Vec<PlayingCard> = vec![];
|
||||||
|
let suits = [
|
||||||
|
CardSuit::Diamonds,
|
||||||
|
CardSuit::Clubs,
|
||||||
|
CardSuit::Hearts,
|
||||||
|
CardSuit::Spades,
|
||||||
|
];
|
||||||
|
|
||||||
|
let values = [
|
||||||
|
CardValue::Two,
|
||||||
|
CardValue::Three,
|
||||||
|
CardValue::Four,
|
||||||
|
CardValue::Five,
|
||||||
|
CardValue::Six,
|
||||||
|
CardValue::Seven,
|
||||||
|
CardValue::Eight,
|
||||||
|
CardValue::Nine,
|
||||||
|
CardValue::Ten,
|
||||||
|
CardValue::Jack,
|
||||||
|
CardValue::Queen,
|
||||||
|
CardValue::King,
|
||||||
|
CardValue::Ace,
|
||||||
|
];
|
||||||
|
|
||||||
|
for s in suits {
|
||||||
|
for i in values {
|
||||||
|
let card = PlayingCard { suit: s, value: i };
|
||||||
|
deck.insert(0, card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deck
|
||||||
|
}
|
||||||
174
src/hand.rs
Normal file
174
src/hand.rs
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
use crate::card::{CardValue, PlayingCard};
|
||||||
|
use core::fmt;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
|
||||||
|
pub enum HandType {
|
||||||
|
HighCard,
|
||||||
|
OnePair,
|
||||||
|
TwoPair,
|
||||||
|
ThreeOfAKind,
|
||||||
|
Straight,
|
||||||
|
Flush,
|
||||||
|
FullHouse,
|
||||||
|
FourOfAKind,
|
||||||
|
StraightFlush,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PokerHand {
|
||||||
|
cards: Vec<PlayingCard>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for PokerHand {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
let s = match self.hand_type() {
|
||||||
|
HandType::HighCard => write!(f, "{}", self.cards[4]),
|
||||||
|
HandType::OnePair => {
|
||||||
|
for val in self.hash_map() {
|
||||||
|
if val.1 == 2 {
|
||||||
|
return write!(f, "Pair of {:?}'s", val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return write!(f, "???");
|
||||||
|
}
|
||||||
|
HandType::TwoPair => todo!(),
|
||||||
|
HandType::ThreeOfAKind => todo!(),
|
||||||
|
HandType::Straight => todo!(),
|
||||||
|
HandType::Flush => todo!(),
|
||||||
|
HandType::FullHouse => todo!(),
|
||||||
|
HandType::FourOfAKind => todo!(),
|
||||||
|
HandType::StraightFlush => todo!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PokerHand {
|
||||||
|
fn new(mut cards: Vec<PlayingCard>) -> Self {
|
||||||
|
assert!(cards.len() == 5);
|
||||||
|
cards.sort_unstable();
|
||||||
|
PokerHand { cards }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hash_map(&self) -> HashMap<CardValue, u8> {
|
||||||
|
let mut count: HashMap<CardValue, u8> = HashMap::new();
|
||||||
|
|
||||||
|
for card in &self.cards {
|
||||||
|
*count.entry(card.value).or_insert(0) += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
count
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hand_type(&self) -> HandType {
|
||||||
|
if is_straight_flush(self) {
|
||||||
|
return HandType::StraightFlush;
|
||||||
|
}
|
||||||
|
|
||||||
|
if is_four_of_a_kind(self) {
|
||||||
|
return HandType::FourOfAKind;
|
||||||
|
}
|
||||||
|
|
||||||
|
if is_full_house(self) {
|
||||||
|
return HandType::FullHouse;
|
||||||
|
}
|
||||||
|
|
||||||
|
if is_flush(self) {
|
||||||
|
return HandType::Flush;
|
||||||
|
}
|
||||||
|
|
||||||
|
if is_straight(self) {
|
||||||
|
return HandType::Straight;
|
||||||
|
}
|
||||||
|
|
||||||
|
if is_three_of_a_kind(self) {
|
||||||
|
return HandType::ThreeOfAKind;
|
||||||
|
}
|
||||||
|
|
||||||
|
if is_two_pair(self) {
|
||||||
|
return HandType::TwoPair;
|
||||||
|
}
|
||||||
|
|
||||||
|
if is_one_pair(self) {
|
||||||
|
return HandType::OnePair;
|
||||||
|
}
|
||||||
|
|
||||||
|
return HandType::HighCard;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_straight_flush(hand: &PokerHand) -> bool {
|
||||||
|
let hand = &hand.cards;
|
||||||
|
assert!(hand.len() == 5);
|
||||||
|
|
||||||
|
let suit = hand[0].suit;
|
||||||
|
let mut min_val = CardValue::Two;
|
||||||
|
let mut max_val = CardValue::Ace;
|
||||||
|
|
||||||
|
// Must all be the same suit
|
||||||
|
for i in 0..5 {
|
||||||
|
let card = &hand[i];
|
||||||
|
|
||||||
|
for k in (i + 1)..5 {
|
||||||
|
if hand[k].value == card.value {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if card.value < min_val {
|
||||||
|
min_val = card.value;
|
||||||
|
};
|
||||||
|
|
||||||
|
if card.value > max_val {
|
||||||
|
max_val = card.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if card.suit != suit {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let max_val = max_val as u8;
|
||||||
|
let min_val = min_val as u8;
|
||||||
|
|
||||||
|
if max_val - min_val > 4 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_four_of_a_kind(hand: &PokerHand) -> bool {
|
||||||
|
for e in hand.hash_map() {
|
||||||
|
if e.1 == 4 {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_full_house(hand: &PokerHand) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_flush(hand: &PokerHand) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_straight(hand: &PokerHand) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_three_of_a_kind(hand: &PokerHand) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_two_pair(hand: &PokerHand) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_one_pair(hand: &PokerHand) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
143
src/main.rs
143
src/main.rs
@@ -1,154 +1,41 @@
|
|||||||
use rand::Rng;
|
#![allow(dead_code)]
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::fmt;
|
|
||||||
use std::vec;
|
use std::vec;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Eq, PartialEq)]
|
mod card;
|
||||||
enum CardSuit {
|
mod hand;
|
||||||
Diamonds,
|
|
||||||
Clubs,
|
|
||||||
Hearts,
|
|
||||||
Spades,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct PlayingCard {
|
use crate::card::{create_deck, CardSuit, CardValue, PlayingCard};
|
||||||
value: u8,
|
use crate::hand::HandType;
|
||||||
suit: CardSuit,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_straight_flush(hand: &Vec<PlayingCard>) -> bool {
|
|
||||||
assert!(hand.len() == 5);
|
|
||||||
|
|
||||||
let suit = hand[0].suit;
|
|
||||||
let mut min_val = 15;
|
|
||||||
let mut max_val = 1;
|
|
||||||
|
|
||||||
// Must all be the same suit
|
|
||||||
for i in 0..5 {
|
|
||||||
let card = &hand[i];
|
|
||||||
|
|
||||||
for k in (i + 1)..5 {
|
|
||||||
if hand[k].value == card.value {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if card.value < min_val {
|
|
||||||
min_val = card.value;
|
|
||||||
};
|
|
||||||
|
|
||||||
if card.value > max_val {
|
|
||||||
max_val = card.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if card.suit != suit {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if max_val - min_val > 4 {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_four_of_a_kind(hand: &Vec<PlayingCard>) -> bool {
|
|
||||||
let mut count: HashMap<u8, u8> = HashMap::new();
|
|
||||||
|
|
||||||
for card in hand {
|
|
||||||
*count.entry(card.value).or_insert(0) += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for e in count {
|
|
||||||
if e.1 == 4 {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for PlayingCard {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
let val = match self.value {
|
|
||||||
2 => "Two",
|
|
||||||
3 => "Three",
|
|
||||||
4 => "Four",
|
|
||||||
5 => "Five",
|
|
||||||
6 => "Six",
|
|
||||||
7 => "Seven",
|
|
||||||
8 => "Eight",
|
|
||||||
9 => "Nine",
|
|
||||||
10 => "Ten",
|
|
||||||
11 => "Jack",
|
|
||||||
12 => "King",
|
|
||||||
13 => "Queen",
|
|
||||||
14 => "Ace",
|
|
||||||
_ => "???",
|
|
||||||
};
|
|
||||||
|
|
||||||
let suit = match self.suit {
|
|
||||||
CardSuit::Clubs => "Clubs",
|
|
||||||
CardSuit::Diamonds => "Diamonds",
|
|
||||||
CardSuit::Hearts => "Hearts",
|
|
||||||
CardSuit::Spades => "Spades",
|
|
||||||
};
|
|
||||||
|
|
||||||
write!(f, "{} of {}", val, suit)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn draw_card(deck: &mut Vec<PlayingCard>) -> PlayingCard {
|
|
||||||
let num = rand::thread_rng().gen_range(0..deck.len());
|
|
||||||
let card = deck.remove(num);
|
|
||||||
|
|
||||||
card
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_deck() -> Vec<PlayingCard> {
|
|
||||||
let mut deck: Vec<PlayingCard> = vec![];
|
|
||||||
|
|
||||||
for s in [
|
|
||||||
CardSuit::Diamonds,
|
|
||||||
CardSuit::Clubs,
|
|
||||||
CardSuit::Hearts,
|
|
||||||
CardSuit::Spades,
|
|
||||||
] {
|
|
||||||
for i in 2..14 {
|
|
||||||
let card = PlayingCard { suit: s, value: i };
|
|
||||||
deck.insert(0, card);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
deck
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut deck = create_deck();
|
let mut deck = create_deck();
|
||||||
|
|
||||||
let card1: PlayingCard = PlayingCard {
|
let card1: PlayingCard = PlayingCard {
|
||||||
suit: CardSuit::Clubs,
|
suit: CardSuit::Clubs,
|
||||||
value: 2,
|
value: CardValue::Five,
|
||||||
};
|
};
|
||||||
let card2: PlayingCard = PlayingCard {
|
let card2: PlayingCard = PlayingCard {
|
||||||
suit: CardSuit::Clubs,
|
suit: CardSuit::Clubs,
|
||||||
value: 2,
|
value: CardValue::Five,
|
||||||
};
|
};
|
||||||
let card3: PlayingCard = PlayingCard {
|
let card3: PlayingCard = PlayingCard {
|
||||||
suit: CardSuit::Clubs,
|
suit: CardSuit::Clubs,
|
||||||
value: 2,
|
value: CardValue::Five,
|
||||||
};
|
};
|
||||||
let card4: PlayingCard = PlayingCard {
|
let card4: PlayingCard = PlayingCard {
|
||||||
suit: CardSuit::Clubs,
|
suit: CardSuit::Clubs,
|
||||||
value: 2,
|
value: CardValue::Five,
|
||||||
};
|
};
|
||||||
let card5: PlayingCard = PlayingCard {
|
let card5: PlayingCard = PlayingCard {
|
||||||
suit: CardSuit::Clubs,
|
suit: CardSuit::Clubs,
|
||||||
value: 3,
|
value: CardValue::Five,
|
||||||
};
|
};
|
||||||
|
|
||||||
let hand = vec![card1, card2, card3, card4, card5];
|
let hand = vec![card1, card2, card3, card4, card5];
|
||||||
|
|
||||||
println!("{}", is_four_of_a_kind(&hand));
|
let hand1 = HandType::Flush;
|
||||||
|
let hand2 = HandType::StraightFlush;
|
||||||
|
|
||||||
|
println!("{}", hand1 >= hand2);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user