Skip to content

Commit d7184e0

Browse files
authored
Add table and move basic models to different source files (#4)
1 parent 64c9056 commit d7184e0

File tree

9 files changed

+348
-86
lines changed

9 files changed

+348
-86
lines changed

Cargo.lock

Lines changed: 133 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bin/src/main.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1+
use deck::{models::deck::Deck, models::table::Table};
12

23
fn main() {
34
println!("Here will be a card game!");
5+
let mut deck = Deck::new();
6+
deck.shuffle();
7+
let table = Table::new(&mut deck);
8+
println!("{}", table);
49
}

deck/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ version = "0.1.0"
44
edition = "2021"
55

66
[dependencies]
7+
rand = "0.8.5"

deck/src/lib.rs

Lines changed: 3 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,4 @@
1-
#[derive(Debug, PartialEq, Eq)]
2-
pub enum Suit {
3-
Hearts,
4-
Diamonds,
5-
Spades,
6-
Clubs,
7-
}
1+
pub mod models;
82

9-
#[derive(Debug, PartialEq, Eq)]
10-
pub struct Card {
11-
rank: u8, // 1-13 Ace->2->3...King
12-
suit: Suit,
13-
is_showed: bool,
14-
}
15-
16-
impl Card {
17-
pub fn new(rank: u8, suit: Suit) -> Self {
18-
let card_range = 1..=13;
19-
assert!(card_range.contains(&rank), "rank must be in range of cards");
20-
Self {
21-
rank: rank,
22-
suit: suit,
23-
is_showed: false,
24-
}
25-
}
26-
27-
pub fn flip(&mut self) {
28-
self.is_showed = !self.is_showed;
29-
}
30-
}
31-
32-
pub struct Deck {
33-
pub cards: Vec<Card>,
34-
}
35-
36-
impl Deck {
37-
pub fn new() -> Self {
38-
let mut cards = Vec::new();
39-
for rank in 1..=13 {
40-
cards.push(Card::new(rank, Suit::Hearts));
41-
cards.push(Card::new(rank, Suit::Diamonds));
42-
cards.push(Card::new(rank, Suit::Spades));
43-
cards.push(Card::new(rank, Suit::Clubs));
44-
}
45-
Deck { cards: cards }
46-
}
47-
}
48-
49-
#[cfg(test)]
50-
mod tests {
51-
use super::*;
52-
53-
#[test]
54-
fn check_card_in_range() {
55-
let suit = Suit::Hearts;
56-
let rank = 1; // check an ace
57-
58-
let result = Card::new(rank, suit);
59-
60-
let expected = Card {
61-
rank: 1,
62-
suit: Suit::Hearts,
63-
is_showed: false,
64-
};
65-
assert_eq!(result, expected);
66-
}
67-
68-
#[test]
69-
#[should_panic]
70-
fn check_card_out_of_range() {
71-
Card::new(100, Suit::Diamonds);
72-
}
73-
74-
#[test]
75-
fn check_flip() {
76-
let mut card = Card::new(1, Suit::Diamonds);
77-
card.flip();
78-
assert_eq!(card.is_showed, true);
79-
}
80-
81-
#[test]
82-
fn check_deck_size() {
83-
let deck = Deck::new();
84-
85-
assert_eq!(deck.cards.len(), 52);
86-
}
87-
}
3+
pub use models::card::Card;
4+
pub use models::suit::Suit;

deck/src/models/card.rs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
use crate::Suit;
2+
use std::fmt;
3+
4+
#[derive(Debug, PartialEq, Eq)]
5+
pub struct Card {
6+
pub rank: u8, // 1-13 Ace->2->3...King
7+
pub suit: Suit,
8+
pub is_showed: bool,
9+
}
10+
11+
impl Card {
12+
pub fn new(rank: u8, suit: Suit) -> Self {
13+
let card_range = 1..=13;
14+
assert!(card_range.contains(&rank), "rank must be in range of cards");
15+
Self {
16+
rank: rank,
17+
suit: suit,
18+
is_showed: false,
19+
}
20+
}
21+
22+
pub fn flip(&mut self) {
23+
self.is_showed = !self.is_showed;
24+
}
25+
}
26+
27+
impl fmt::Display for Card {
28+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29+
let text = if self.is_showed {
30+
match self.rank {
31+
1 => "A".to_string(),
32+
11 => "J".to_string(),
33+
12 => "Q".to_string(),
34+
13 => "K".to_string(),
35+
_ => self.rank.to_string(),
36+
}
37+
} else {
38+
"XX".to_string()
39+
};
40+
41+
if self.is_showed {
42+
write!(f, "{}{}", text, self.suit)
43+
} else {
44+
write!(f, "{}", text)
45+
}
46+
}
47+
}
48+
#[cfg(test)]
49+
mod tests {
50+
use super::*;
51+
52+
#[test]
53+
fn check_card_in_range() {
54+
let suit = Suit::Hearts;
55+
let rank = 1; // check an ace
56+
57+
let result = Card::new(rank, suit);
58+
59+
let expected = Card {
60+
rank: 1,
61+
suit: Suit::Hearts,
62+
is_showed: false,
63+
};
64+
assert_eq!(result, expected);
65+
}
66+
67+
#[test]
68+
#[should_panic]
69+
fn check_card_out_of_range() {
70+
Card::new(100, Suit::Diamonds);
71+
}
72+
73+
#[test]
74+
fn check_flip() {
75+
let mut card = Card::new(1, Suit::Diamonds);
76+
card.flip();
77+
assert_eq!(card.is_showed, true);
78+
}
79+
}

deck/src/models/deck.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
use crate::Card;
2+
use crate::Suit;
3+
use rand::{seq::SliceRandom, thread_rng};
4+
5+
pub struct Deck {
6+
pub cards: Vec<Card>,
7+
}
8+
9+
impl Deck {
10+
pub fn new() -> Self {
11+
let mut cards = Vec::new();
12+
for rank in 1..=13 {
13+
cards.push(Card::new(rank, Suit::Hearts));
14+
cards.push(Card::new(rank, Suit::Diamonds));
15+
cards.push(Card::new(rank, Suit::Spades));
16+
cards.push(Card::new(rank, Suit::Clubs));
17+
}
18+
Deck { cards: cards }
19+
}
20+
21+
pub fn draw(&mut self) -> Option<Card> {
22+
self.cards.pop()
23+
}
24+
25+
pub fn shuffle(&mut self) {
26+
let mut rng = thread_rng();
27+
self.cards.shuffle(&mut rng);
28+
}
29+
}
30+
#[cfg(test)]
31+
mod tests {
32+
use super::*;
33+
34+
#[test]
35+
fn check_deck_size() {
36+
let deck = Deck::new();
37+
38+
assert_eq!(deck.cards.len(), 52);
39+
}
40+
41+
#[test]
42+
fn check_deck_draw() {
43+
let mut deck = Deck::new();
44+
let card = deck.draw();
45+
let expected = Card::new(13, Suit::Clubs);
46+
assert!(card.is_some());
47+
assert_eq!(expected, card.unwrap());
48+
}
49+
}

deck/src/models/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
pub mod card;
2+
pub mod deck;
3+
pub mod suit;
4+
pub mod table;

0 commit comments

Comments
 (0)